summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/spirv/emit_context.cpp
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-03-08 18:31:53 -0300
committerGravatar ameerj2021-07-22 21:51:23 -0400
commitab463712474de5f99eec137a9c6233e55fe184f0 (patch)
tree30d79ac64dd03d5cfafd07c0c42c2baadc82de98 /src/shader_recompiler/backend/spirv/emit_context.cpp
parentshader: Implement R2P (diff)
downloadyuzu-ab463712474de5f99eec137a9c6233e55fe184f0.tar.gz
yuzu-ab463712474de5f99eec137a9c6233e55fe184f0.tar.xz
yuzu-ab463712474de5f99eec137a9c6233e55fe184f0.zip
shader: Initial support for textures and TEX
Diffstat (limited to 'src/shader_recompiler/backend/spirv/emit_context.cpp')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_context.cpp69
1 files changed, 67 insertions, 2 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp
index d2dbd56d4..21900d387 100644
--- a/src/shader_recompiler/backend/spirv/emit_context.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_context.cpp
@@ -12,6 +12,43 @@
12#include "shader_recompiler/backend/spirv/emit_context.h" 12#include "shader_recompiler/backend/spirv/emit_context.h"
13 13
14namespace Shader::Backend::SPIRV { 14namespace Shader::Backend::SPIRV {
15namespace {
16Id ImageType(EmitContext& ctx, const TextureDescriptor& desc) {
17 const spv::ImageFormat format{spv::ImageFormat::Unknown};
18 const Id type{ctx.F32[1]};
19 switch (desc.type) {
20 case TextureType::Color1D:
21 return ctx.TypeImage(type, spv::Dim::Dim1D, false, false, false, 1, format);
22 case TextureType::ColorArray1D:
23 return ctx.TypeImage(type, spv::Dim::Dim1D, false, true, false, 1, format);
24 case TextureType::Color2D:
25 return ctx.TypeImage(type, spv::Dim::Dim2D, false, false, false, 1, format);
26 case TextureType::ColorArray2D:
27 return ctx.TypeImage(type, spv::Dim::Dim2D, false, true, false, 1, format);
28 case TextureType::Color3D:
29 return ctx.TypeImage(type, spv::Dim::Dim3D, false, false, false, 1, format);
30 case TextureType::ColorCube:
31 return ctx.TypeImage(type, spv::Dim::Cube, false, false, false, 1, format);
32 case TextureType::ColorArrayCube:
33 return ctx.TypeImage(type, spv::Dim::Cube, false, true, false, 1, format);
34 case TextureType::Shadow1D:
35 return ctx.TypeImage(type, spv::Dim::Dim1D, true, false, false, 1, format);
36 case TextureType::ShadowArray1D:
37 return ctx.TypeImage(type, spv::Dim::Dim1D, true, true, false, 1, format);
38 case TextureType::Shadow2D:
39 return ctx.TypeImage(type, spv::Dim::Dim2D, true, false, false, 1, format);
40 case TextureType::ShadowArray2D:
41 return ctx.TypeImage(type, spv::Dim::Dim2D, true, true, false, 1, format);
42 case TextureType::Shadow3D:
43 return ctx.TypeImage(type, spv::Dim::Dim3D, true, false, false, 1, format);
44 case TextureType::ShadowCube:
45 return ctx.TypeImage(type, spv::Dim::Cube, true, false, false, 1, format);
46 case TextureType::ShadowArrayCube:
47 return ctx.TypeImage(type, spv::Dim::Cube, false, true, false, 1, format);
48 }
49 throw InvalidArgument("Invalid texture type {}", desc.type);
50}
51} // Anonymous namespace
15 52
16void VectorTypes::Define(Sirit::Module& sirit_ctx, Id base_type, std::string_view name) { 53void VectorTypes::Define(Sirit::Module& sirit_ctx, Id base_type, std::string_view name) {
17 defs[0] = sirit_ctx.Name(base_type, name); 54 defs[0] = sirit_ctx.Name(base_type, name);
@@ -35,6 +72,7 @@ EmitContext::EmitContext(const Profile& profile_, IR::Program& program)
35 u32 binding{}; 72 u32 binding{};
36 DefineConstantBuffers(program.info, binding); 73 DefineConstantBuffers(program.info, binding);
37 DefineStorageBuffers(program.info, binding); 74 DefineStorageBuffers(program.info, binding);
75 DefineTextures(program.info, binding);
38 76
39 DefineLabels(program); 77 DefineLabels(program);
40} 78}
@@ -46,6 +84,10 @@ Id EmitContext::Def(const IR::Value& value) {
46 return value.Inst()->Definition<Id>(); 84 return value.Inst()->Definition<Id>();
47 } 85 }
48 switch (value.Type()) { 86 switch (value.Type()) {
87 case IR::Type::Void:
88 // Void instructions are used for optional arguments (e.g. texture offsets)
89 // They are not meant to be used in the SPIR-V module
90 return Id{};
49 case IR::Type::U1: 91 case IR::Type::U1:
50 return value.U1() ? true_value : false_value; 92 return value.U1() ? true_value : false_value;
51 case IR::Type::U32: 93 case IR::Type::U32:
@@ -122,7 +164,7 @@ void EmitContext::DefineConstantBuffers(const Info& info, u32& binding) {
122 uniform_u32 = TypePointer(spv::StorageClass::Uniform, U32[1]); 164 uniform_u32 = TypePointer(spv::StorageClass::Uniform, U32[1]);
123 165
124 u32 index{}; 166 u32 index{};
125 for (const Info::ConstantBufferDescriptor& desc : info.constant_buffer_descriptors) { 167 for (const ConstantBufferDescriptor& desc : info.constant_buffer_descriptors) {
126 const Id id{AddGlobalVariable(uniform_type, spv::StorageClass::Uniform)}; 168 const Id id{AddGlobalVariable(uniform_type, spv::StorageClass::Uniform)};
127 Decorate(id, spv::Decoration::Binding, binding); 169 Decorate(id, spv::Decoration::Binding, binding);
128 Decorate(id, spv::Decoration::DescriptorSet, 0U); 170 Decorate(id, spv::Decoration::DescriptorSet, 0U);
@@ -152,7 +194,7 @@ void EmitContext::DefineStorageBuffers(const Info& info, u32& binding) {
152 storage_u32 = TypePointer(spv::StorageClass::StorageBuffer, U32[1]); 194 storage_u32 = TypePointer(spv::StorageClass::StorageBuffer, U32[1]);
153 195
154 u32 index{}; 196 u32 index{};
155 for (const Info::StorageBufferDescriptor& desc : info.storage_buffers_descriptors) { 197 for (const StorageBufferDescriptor& desc : info.storage_buffers_descriptors) {
156 const Id id{AddGlobalVariable(storage_type, spv::StorageClass::StorageBuffer)}; 198 const Id id{AddGlobalVariable(storage_type, spv::StorageClass::StorageBuffer)};
157 Decorate(id, spv::Decoration::Binding, binding); 199 Decorate(id, spv::Decoration::Binding, binding);
158 Decorate(id, spv::Decoration::DescriptorSet, 0U); 200 Decorate(id, spv::Decoration::DescriptorSet, 0U);
@@ -163,6 +205,29 @@ void EmitContext::DefineStorageBuffers(const Info& info, u32& binding) {
163 } 205 }
164} 206}
165 207
208void EmitContext::DefineTextures(const Info& info, u32& binding) {
209 textures.reserve(info.texture_descriptors.size());
210 for (const TextureDescriptor& desc : info.texture_descriptors) {
211 if (desc.count != 1) {
212 throw NotImplementedException("Array of textures");
213 }
214 const Id type{TypeSampledImage(ImageType(*this, desc))};
215 const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, type)};
216 const Id id{AddGlobalVariable(pointer_type, spv::StorageClass::UniformConstant)};
217 Decorate(id, spv::Decoration::Binding, binding);
218 Decorate(id, spv::Decoration::DescriptorSet, 0U);
219 Name(id, fmt::format("tex{}_{:02x}", desc.cbuf_index, desc.cbuf_offset));
220 for (u32 index = 0; index < desc.count; ++index) {
221 // TODO: Pass count info
222 textures.push_back(TextureDefinition{
223 .id{id},
224 .type{type},
225 });
226 }
227 binding += desc.count;
228 }
229}
230
166void EmitContext::DefineLabels(IR::Program& program) { 231void EmitContext::DefineLabels(IR::Program& program) {
167 for (const IR::Function& function : program.functions) { 232 for (const IR::Function& function : program.functions) {
168 for (IR::Block* const block : function.blocks) { 233 for (IR::Block* const block : function.blocks) {