1 #include <msp/core/hash.h>
3 #include "structurebuilder.h"
4 #include "vertexarray.h"
5 #include "vertexformat.h"
6 #include "vertexsetup.h"
7 #include "vertexsetup_backend.h"
15 VulkanVertexSetup::VulkanVertexSetup(VulkanVertexSetup &&other):
16 creation_info(move(other.creation_info))
19 void VulkanVertexSetup::update(unsigned) const
21 const VertexSetup &self = *static_cast<const VertexSetup *>(this);
23 n_bindings = (self.inst_format.empty() ? 1 : 2);
24 unsigned n_attribs = 0;
25 for(VertexAttribute a: self.vertex_format)
26 n_attribs += !is_padding(a);
27 for(VertexAttribute a: self.inst_format)
28 n_attribs += !is_padding(a);
30 StructureBuilder sb(creation_info, 3);
31 VkPipelineVertexInputStateCreateInfo *&input_state = sb.add<VkPipelineVertexInputStateCreateInfo>();
32 VkVertexInputBindingDescription *&bindings = sb.add<VkVertexInputBindingDescription>(n_bindings);
33 VkVertexInputAttributeDescription *&attribs = sb.add<VkVertexInputAttributeDescription>(n_attribs);
35 bindings[0].binding = 0;
36 bindings[0].stride = self.vertex_format.stride();
37 bindings[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
38 update_attributes(self.vertex_format, 0, attribs);
40 if(!self.inst_format.empty())
42 bindings[1].binding = 1;
43 bindings[1].stride = self.inst_format.stride();
44 bindings[1].inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
45 update_attributes(self.inst_format, 1, attribs+self.vertex_format.size());
48 input_state->sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
49 input_state->vertexBindingDescriptionCount = n_bindings;
50 input_state->pVertexBindingDescriptions = bindings;
51 input_state->vertexAttributeDescriptionCount = n_attribs;
52 input_state->pVertexAttributeDescriptions = attribs;
54 buffers[0] = self.vertex_array->get_buffer()->handle;
55 offsets[0] = self.vertex_array->get_offset();
59 buffers[1] = self.inst_array->get_buffer()->handle;
60 offsets[1] = self.inst_array->get_offset();
64 void VulkanVertexSetup::update_attributes(const VertexFormat &fmt, unsigned binding, void *buffer) const
66 VkVertexInputAttributeDescription *attrib = reinterpret_cast<VkVertexInputAttributeDescription *>(buffer);
68 for(VertexAttribute a: fmt)
72 attrib->location = get_attribute_semantic(a);
73 attrib->binding = binding;
74 attrib->format = static_cast<VkFormat>(get_vulkan_attribute_format(a));
75 attrib->offset = offset;
78 offset += get_attribute_size(a);
82 uint64_t VulkanVertexSetup::compute_hash() const
84 const VertexSetup &self = *static_cast<const VertexSetup *>(this);
86 uint64_t result = hash<64>(0, 0);
87 for(VertexAttribute a: self.vertex_format)
88 result = hash_update<64>(result, a);
89 for(VertexAttribute a: self.inst_format)
90 result = hash_update<64>(result, a);