diff options
author | quou <quou@disroot.org> | 2024-12-26 17:54:40 +1100 |
---|---|---|
committer | quou <quou@disroot.org> | 2024-12-26 17:54:40 +1100 |
commit | 55b21ca1537a0459f5ed11ad92077bfa2a76fbaa (patch) | |
tree | 2022a1ce62fad8e4ea21f1835de4fb77d7895453 | |
parent | b2ece42822225fd67a1286a2ef51f7b76c634255 (diff) |
allow manually creating vertex formats
-rw-r--r-- | video.cpp | 105 | ||||
-rw-r--r-- | video.hpp | 24 |
2 files changed, 91 insertions, 38 deletions
@@ -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, @@ -5,6 +5,7 @@ #include <stdint.h> extern "C" { +#include "sc/sh_enums.h" #include "vid_enums.h" } @@ -214,6 +215,24 @@ struct Sampler_State { bool aniso; }; +struct Vertex_Format_Desc { + struct Binding { + int binding; + int stride; + SBinding_Rate rate; + }; + struct Attribute { + int binding; + int index; + int offset; + SVariable_Type type; + }; + Binding* bindings; + Attribute* attributes; + int binding_count; + int attribute_count; +}; + struct Context; struct Shader; struct Device { @@ -243,6 +262,11 @@ struct Device { Buffer& get_buffer(Buffer_Id id); void destroy_buffer(Buffer_Id id); + Vertex_Format_Id create_vertex_format( + const Vertex_Format_Desc& desc + ); + void destroy_vertex_format(Vertex_Format_Id fmt); + Shader& get_shader(Shader_Id id); Sampler_Id create_sampler(const Sampler_State& state); |