diff options
Diffstat (limited to 'src/shader_recompiler/backend/spirv/emit_context.cpp')
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_context.cpp | 63 |
1 files changed, 48 insertions, 15 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index 21900d387..278b26b50 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -104,15 +104,23 @@ void EmitContext::DefineCommonTypes(const Info& info) { | |||
| 104 | 104 | ||
| 105 | U1 = Name(TypeBool(), "u1"); | 105 | U1 = Name(TypeBool(), "u1"); |
| 106 | 106 | ||
| 107 | // TODO: Conditionally define these | ||
| 108 | AddCapability(spv::Capability::Int16); | ||
| 109 | AddCapability(spv::Capability::Int64); | ||
| 110 | U16 = Name(TypeInt(16, false), "u16"); | ||
| 111 | U64 = Name(TypeInt(64, false), "u64"); | ||
| 112 | |||
| 113 | F32.Define(*this, TypeFloat(32), "f32"); | 107 | F32.Define(*this, TypeFloat(32), "f32"); |
| 114 | U32.Define(*this, TypeInt(32, false), "u32"); | 108 | U32.Define(*this, TypeInt(32, false), "u32"); |
| 115 | 109 | ||
| 110 | if (info.uses_int8) { | ||
| 111 | AddCapability(spv::Capability::Int8); | ||
| 112 | U8 = Name(TypeInt(8, false), "u8"); | ||
| 113 | S8 = Name(TypeInt(8, true), "s8"); | ||
| 114 | } | ||
| 115 | if (info.uses_int16) { | ||
| 116 | AddCapability(spv::Capability::Int16); | ||
| 117 | U16 = Name(TypeInt(16, false), "u16"); | ||
| 118 | S16 = Name(TypeInt(16, true), "s16"); | ||
| 119 | } | ||
| 120 | if (info.uses_int64) { | ||
| 121 | AddCapability(spv::Capability::Int64); | ||
| 122 | U64 = Name(TypeInt(64, false), "u64"); | ||
| 123 | } | ||
| 116 | if (info.uses_fp16) { | 124 | if (info.uses_fp16) { |
| 117 | AddCapability(spv::Capability::Float16); | 125 | AddCapability(spv::Capability::Float16); |
| 118 | F16.Define(*this, TypeFloat(16), "f16"); | 126 | F16.Define(*this, TypeFloat(16), "f16"); |
| @@ -151,26 +159,51 @@ void EmitContext::DefineConstantBuffers(const Info& info, u32& binding) { | |||
| 151 | if (info.constant_buffer_descriptors.empty()) { | 159 | if (info.constant_buffer_descriptors.empty()) { |
| 152 | return; | 160 | return; |
| 153 | } | 161 | } |
| 154 | const Id array_type{TypeArray(U32[1], Constant(U32[1], 4096))}; | 162 | if (True(info.used_constant_buffer_types & IR::Type::U8)) { |
| 155 | Decorate(array_type, spv::Decoration::ArrayStride, 4U); | 163 | DefineConstantBuffers(info, &UniformDefinitions::U8, binding, U8, 'u', sizeof(u8)); |
| 164 | DefineConstantBuffers(info, &UniformDefinitions::S8, binding, S8, 's', sizeof(s8)); | ||
| 165 | } | ||
| 166 | if (True(info.used_constant_buffer_types & IR::Type::U16)) { | ||
| 167 | DefineConstantBuffers(info, &UniformDefinitions::U16, binding, U16, 'u', sizeof(u16)); | ||
| 168 | DefineConstantBuffers(info, &UniformDefinitions::S16, binding, S16, 's', sizeof(s16)); | ||
| 169 | } | ||
| 170 | if (True(info.used_constant_buffer_types & IR::Type::U32)) { | ||
| 171 | DefineConstantBuffers(info, &UniformDefinitions::U32, binding, U32[1], 'u', sizeof(u32)); | ||
| 172 | } | ||
| 173 | if (True(info.used_constant_buffer_types & IR::Type::F32)) { | ||
| 174 | DefineConstantBuffers(info, &UniformDefinitions::F32, binding, F32[1], 'f', sizeof(f32)); | ||
| 175 | } | ||
| 176 | if (True(info.used_constant_buffer_types & IR::Type::U64)) { | ||
| 177 | DefineConstantBuffers(info, &UniformDefinitions::U64, binding, U64, 'u', sizeof(u64)); | ||
| 178 | } | ||
| 179 | for (const ConstantBufferDescriptor& desc : info.constant_buffer_descriptors) { | ||
| 180 | binding += desc.count; | ||
| 181 | } | ||
| 182 | } | ||
| 183 | |||
| 184 | void EmitContext::DefineConstantBuffers(const Info& info, Id UniformDefinitions::*member_type, | ||
| 185 | u32 binding, Id type, char type_char, u32 element_size) { | ||
| 186 | const Id array_type{TypeArray(type, Constant(U32[1], 65536U / element_size))}; | ||
| 187 | Decorate(array_type, spv::Decoration::ArrayStride, element_size); | ||
| 156 | 188 | ||
| 157 | const Id struct_type{TypeStruct(array_type)}; | 189 | const Id struct_type{TypeStruct(array_type)}; |
| 158 | Name(struct_type, "cbuf_block"); | 190 | Name(struct_type, fmt::format("cbuf_block_{}{}", type_char, element_size * CHAR_BIT)); |
| 159 | Decorate(struct_type, spv::Decoration::Block); | 191 | Decorate(struct_type, spv::Decoration::Block); |
| 160 | MemberName(struct_type, 0, "data"); | 192 | MemberName(struct_type, 0, "data"); |
| 161 | MemberDecorate(struct_type, 0, spv::Decoration::Offset, 0U); | 193 | MemberDecorate(struct_type, 0, spv::Decoration::Offset, 0U); |
| 162 | 194 | ||
| 163 | const Id uniform_type{TypePointer(spv::StorageClass::Uniform, struct_type)}; | 195 | const Id struct_pointer_type{TypePointer(spv::StorageClass::Uniform, struct_type)}; |
| 164 | uniform_u32 = TypePointer(spv::StorageClass::Uniform, U32[1]); | 196 | const Id uniform_type{TypePointer(spv::StorageClass::Uniform, type)}; |
| 197 | uniform_types.*member_type = uniform_type; | ||
| 165 | 198 | ||
| 166 | u32 index{}; | ||
| 167 | for (const ConstantBufferDescriptor& desc : info.constant_buffer_descriptors) { | 199 | for (const ConstantBufferDescriptor& desc : info.constant_buffer_descriptors) { |
| 168 | const Id id{AddGlobalVariable(uniform_type, spv::StorageClass::Uniform)}; | 200 | const Id id{AddGlobalVariable(struct_pointer_type, spv::StorageClass::Uniform)}; |
| 169 | Decorate(id, spv::Decoration::Binding, binding); | 201 | Decorate(id, spv::Decoration::Binding, binding); |
| 170 | Decorate(id, spv::Decoration::DescriptorSet, 0U); | 202 | Decorate(id, spv::Decoration::DescriptorSet, 0U); |
| 171 | Name(id, fmt::format("c{}", desc.index)); | 203 | Name(id, fmt::format("c{}", desc.index)); |
| 172 | std::fill_n(cbufs.data() + desc.index, desc.count, id); | 204 | for (size_t i = 0; i < desc.count; ++i) { |
| 173 | index += desc.count; | 205 | cbufs[desc.index + i].*member_type = id; |
| 206 | } | ||
| 174 | binding += desc.count; | 207 | binding += desc.count; |
| 175 | } | 208 | } |
| 176 | } | 209 | } |