summaryrefslogtreecommitdiff
path: root/video.cpp
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2024-12-26 17:54:40 +1100
committerquou <quou@disroot.org>2024-12-26 17:54:40 +1100
commit55b21ca1537a0459f5ed11ad92077bfa2a76fbaa (patch)
tree2022a1ce62fad8e4ea21f1835de4fb77d7895453 /video.cpp
parentb2ece42822225fd67a1286a2ef51f7b76c634255 (diff)
allow manually creating vertex formats
Diffstat (limited to 'video.cpp')
-rw-r--r--video.cpp105
1 files changed, 67 insertions, 38 deletions
diff --git a/video.cpp b/video.cpp
index 57b5c73..7335a32 100644
--- a/video.cpp
+++ b/video.cpp
@@ -430,6 +430,7 @@ struct Shader_Vk : public Shader, public Late_Terminated {
return (VkShaderStageFlagBits)0;
}
}
+ static int svariable_type_size(SVariable_Type type);
};
struct Renderpass_Vk;
@@ -628,9 +629,8 @@ struct Vertex_Format_Vk {
VkVertexInputAttributeDescription* attrs;
int attr_count;
- void from_shader(Device_Vk* dev, Shader_Vk& s);
+ void init(Device_Vk* dev, const Vertex_Format_Desc& desc);
void destroy(Device_Vk* dev);
- static int svariable_type_size(SVariable_Type type);
static VkFormat format_from_svar_type(SVariable_Type type);
};
@@ -804,8 +804,6 @@ struct Device_Vk : public Device {
Texture_Id alloc_texture();
Buffer_Id alloc_buffer();
Vertex_Format_Id alloc_vf();
- Vertex_Format_Id create_vf(Shader_Vk& shader);
- void destroy_vf(Vertex_Format_Id id);
Shader_Id alloc_shader();
Sampler_Id alloc_sampler();
@@ -1683,16 +1681,18 @@ Vertex_Format_Id Device_Vk::alloc_vf() {
vertex_formats.set(id, vf);
return id;
}
-Vertex_Format_Id Device_Vk::create_vf(
- Shader_Vk& shader
+Vertex_Format_Id Device::create_vertex_format(
+ const Vertex_Format_Desc& desc
) {
- Vertex_Format_Id id = alloc_vf();
- vertex_formats[id].from_shader(this, shader);
+ Device_Vk* dev = (Device_Vk*)this;
+ Vertex_Format_Id id = dev->alloc_vf();
+ dev->vertex_formats[id].init(dev, desc);
return id;
}
-void Device_Vk::destroy_vf(Vertex_Format_Id id) {
- Vertex_Format_Vk& vf = vertex_formats[id];
- vf.destroy(this);
+void Device::destroy_vertex_format(Vertex_Format_Id id) {
+ Device_Vk* dev = (Device_Vk*)this;
+ Vertex_Format_Vk& vf = dev->vertex_formats[id];
+ vf.destroy(dev);
}
Shader_Id Device_Vk::alloc_shader() {
@@ -2458,7 +2458,7 @@ void Descriptor_Set_Vk::destroy(Device_Vk* dev) {
vkDestroyDescriptorPool(dev->dev, dp, &dev->ac);
}
-int Vertex_Format_Vk::svariable_type_size(SVariable_Type type) {
+int Shader_Vk::svariable_type_size(SVariable_Type type) {
switch (type) {
case svariable_type_float: return 4;
case svariable_type_vec2: return 8;
@@ -2486,44 +2486,41 @@ VkFormat Vertex_Format_Vk::format_from_svar_type(
return (VkFormat)0;
}
-void Vertex_Format_Vk::from_shader(
+void Vertex_Format_Vk::init(
Device_Vk* dev,
- Shader_Vk& s
+ const Vertex_Format_Desc& desc
) {
- Shader_Vk::Vertex_Format& vfd = s.vfd;
int i;
- binding_count = vfd.binding_count;
- attr_count = vfd.attr_count;
+ binding_count = desc.binding_count;
+ attr_count = desc.attribute_count;
bindings = (VkVertexInputBindingDescription*)heap_alloc(
dev->heap,
- vfd.binding_count * sizeof *bindings
+ binding_count * sizeof *bindings
);
attrs = (VkVertexInputAttributeDescription*)heap_alloc(
dev->heap,
- vfd.attr_count * sizeof *attrs
+ attr_count * sizeof *attrs
);
- memset(bindings, 0, vfd.binding_count * sizeof *bindings);
- memset(attrs, 0, vfd.attr_count * sizeof *attrs);
- for (i = 0; i < vfd.binding_count; i++) {
- int j, stride = 0;
- auto& src = vfd.bindings[i];
- auto& dst = bindings[src.index];
- for (j = 0; j < src.attr_count; j++) {
- auto& src_attr = vfd.attributes[src.attributes[j]];
- auto& dst_attr = attrs[src.attributes[j]];
- dst_attr.binding = src.index;
- dst_attr.location = j;
- dst_attr.format = format_from_svar_type(src_attr.type);
- dst_attr.offset = stride;
- stride += svariable_type_size(src_attr.type);
- }
- dst.binding = src.index;
- dst.stride = stride;
+ memset(bindings, 0, binding_count * sizeof *bindings);
+ memset(attrs, 0, attr_count * sizeof *attrs);
+ for (i = 0; i < binding_count; i++) {
+ auto& dst = bindings[i];
+ const auto& src = desc.bindings[i];
+ dst.binding = src.binding;
+ dst.stride = src.stride;
dst.inputRate =
src.rate == sbinding_rate_instance?
VK_VERTEX_INPUT_RATE_INSTANCE:
VK_VERTEX_INPUT_RATE_VERTEX;
}
+ for (i = 0; i < attr_count; i++) {
+ auto& dst = attrs[i];
+ auto& src = desc.attributes[i];
+ dst.binding = src.binding;
+ dst.location = src.index;
+ dst.format = format_from_svar_type(src.type);
+ dst.offset = src.offset;
+ }
}
void Vertex_Format_Vk::destroy(Device_Vk* dev) {
@@ -2661,7 +2658,7 @@ void Shader_Vk::destroy(Device_Vk* dev) {
vkDestroyShaderModule(dev->dev, modules[i], &dev->ac);
vfd.destroy(dev);
heap_free(dev->heap, descs);
- dev->destroy_vf(vf);
+ dev->destroy_vertex_format(vf);
dev->shaders.remove(id);
}
@@ -2875,7 +2872,39 @@ bool Shader_Vk::init(Device_Vk* dev, Pack_File* f) {
vfd.binding_count = binding_count;
if (!vfd.init(dev, f))
return false;
- vf = dev->create_vf(*this);
+ {
+ Vertex_Format_Desc desc{};
+ desc.binding_count = vfd.binding_count;
+ desc.attribute_count = vfd.attr_count;
+ desc.bindings = (Vertex_Format_Desc::Binding*)heap_alloc(
+ dev->heap,
+ sizeof *desc.bindings
+ );
+ desc.attributes = (Vertex_Format_Desc::Attribute*)heap_alloc(
+ dev->heap,
+ sizeof *desc.attributes * desc.attribute_count
+ );
+ for (i = 0; i < vfd.binding_count; i++) {
+ int j, stride = 0;
+ auto& src = vfd.bindings[i];
+ auto& dst = desc.bindings[src.index];
+ for (j = 0; j < src.attr_count; j++) {
+ auto& src_attr = vfd.attributes[src.attributes[j]];
+ auto& dst_attr = desc.attributes[src.attributes[j]];
+ dst_attr.binding = src.index;
+ dst_attr.index = j;
+ dst_attr.type = src_attr.type;
+ dst_attr.offset = stride;
+ stride += svariable_type_size(src_attr.type);
+ }
+ dst.binding = src.index;
+ dst.stride = stride;
+ dst.rate = src.rate;
+ }
+ vf = dev->create_vertex_format(desc);
+ heap_free(dev->heap, desc.attributes);
+ heap_free(dev->heap, desc.bindings);
+ }
pack_seek(
f,
32 * target_count,