summaryrefslogtreecommitdiff
path: root/video.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'video.cpp')
-rw-r--r--video.cpp49
1 files changed, 48 insertions, 1 deletions
diff --git a/video.cpp b/video.cpp
index b8b3f51..06bfc30 100644
--- a/video.cpp
+++ b/video.cpp
@@ -828,6 +828,9 @@ struct Vertex_Format_Vk {
void init(Device_Vk* dev, const Vertex_Format_Desc& desc);
void destroy(Device_Vk* dev);
static VkFormat format_from_svar_type(SVariable_Type type);
+
+ void clone(Arena* arena);
+ void optimise(const Vertex_Format_Vk* shadervf);
};
struct Sampler_Vk : public Late_Terminated {
@@ -2608,13 +2611,19 @@ void Pipeline_Vk::init_vertex_input(
VkGraphicsPipelineCreateInfo& info,
const Pipeline& desc
) {
- Vertex_Format_Vk& vf = dev->vertex_formats[desc.vertex_format];
+ Vertex_Format_Vk vf = dev->vertex_formats[desc.vertex_format];
VkPipelineVertexInputStateCreateInfo& vi =
*(VkPipelineVertexInputStateCreateInfo*)arena_alloc(
&scope,
sizeof vi
);
zero(&vi, sizeof vi);
+ auto& shader = dev->get_shader(desc.shader);
+ if (shader.vf != desc.vertex_format) {
+ auto shader_vf = (Vertex_Format_Vk*)&dev->vertex_formats[shader.vf];
+ vf.clone(&scope);
+ vf.optimise(shader_vf);
+ }
vi.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vi.vertexBindingDescriptionCount = vf.binding_count;
vi.pVertexBindingDescriptions = vf.bindings;
@@ -3107,6 +3116,44 @@ void Vertex_Format_Vk::destroy(Device_Vk* dev) {
heap_free(dev->heap, bindings);
}
+void Vertex_Format_Vk::clone(Arena* arena) {
+ int bc = binding_count * sizeof *bindings;
+ int ac = attr_count * sizeof *attrs;
+ auto nb = (VkVertexInputBindingDescription*)arena_alloc(
+ arena,
+ bc
+ );
+ auto na = (VkVertexInputAttributeDescription*)arena_alloc(
+ arena,
+ ac
+ );
+ memcpy(nb, bindings, bc);
+ memcpy(na, attrs, ac);
+ bindings = nb;
+ attrs = na;
+}
+
+void Vertex_Format_Vk::optimise(const Vertex_Format_Vk* shadervf) {
+ int i;
+ if (shadervf->attr_count >= attr_count) return;
+ for (i = attr_count - 1; i >= 0; i--) {
+ auto& a = attrs[i];
+ int j, idx = -1;
+ for (j = 0; j < shadervf->attr_count; j++) {
+ auto& b = shadervf->attrs[j];
+ if (b.binding == a.binding && b.location == a.location) {
+ idx = j;
+ break;
+ }
+ }
+ if (idx == -1) {
+ int last = attr_count - 1;
+ attrs[i] = attrs[last];
+ attr_count = last;
+ }
+ }
+}
+
bool Shader_Vk::init_module(
Device_Vk* dev,
int stage,