summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/backend')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_context.cpp29
-rw-r--r--src/shader_recompiler/backend/spirv/emit_context.h5
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.cpp1
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_image.cpp24
4 files changed, 54 insertions, 5 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp
index 2d39ea373..d01633628 100644
--- a/src/shader_recompiler/backend/spirv/emit_context.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_context.cpp
@@ -46,6 +46,8 @@ Id ImageType(EmitContext& ctx, const TextureDescriptor& desc) {
46 return ctx.TypeImage(type, spv::Dim::Cube, true, false, false, 1, format); 46 return ctx.TypeImage(type, spv::Dim::Cube, true, false, false, 1, format);
47 case TextureType::ShadowArrayCube: 47 case TextureType::ShadowArrayCube:
48 return ctx.TypeImage(type, spv::Dim::Cube, true, true, false, 1, format); 48 return ctx.TypeImage(type, spv::Dim::Cube, true, true, false, 1, format);
49 case TextureType::Buffer:
50 break;
49 } 51 }
50 throw InvalidArgument("Invalid texture type {}", desc.type); 52 throw InvalidArgument("Invalid texture type {}", desc.type);
51} 53}
@@ -129,6 +131,7 @@ EmitContext::EmitContext(const Profile& profile_, IR::Program& program, u32& bin
129 DefineConstantBuffers(program.info, binding); 131 DefineConstantBuffers(program.info, binding);
130 DefineStorageBuffers(program.info, binding); 132 DefineStorageBuffers(program.info, binding);
131 DefineTextures(program.info, binding); 133 DefineTextures(program.info, binding);
134 DefineTextureBuffers(program.info, binding);
132 DefineAttributeMemAccess(program.info); 135 DefineAttributeMemAccess(program.info);
133 DefineLabels(program); 136 DefineLabels(program);
134} 137}
@@ -541,6 +544,32 @@ void EmitContext::DefineTextures(const Info& info, u32& binding) {
541 } 544 }
542} 545}
543 546
547void EmitContext::DefineTextureBuffers(const Info& info, u32& binding) {
548 if (info.texture_buffer_descriptors.empty()) {
549 return;
550 }
551 const spv::ImageFormat format{spv::ImageFormat::Unknown};
552 image_buffer_type = TypeImage(F32[1], spv::Dim::Buffer, 0U, false, false, 1, format);
553 sampled_texture_buffer_type = TypeSampledImage(image_buffer_type);
554
555 const Id type{TypePointer(spv::StorageClass::UniformConstant, sampled_texture_buffer_type)};
556 texture_buffers.reserve(info.texture_buffer_descriptors.size());
557 for (const TextureBufferDescriptor& desc : info.texture_buffer_descriptors) {
558 if (desc.count != 1) {
559 throw NotImplementedException("Array of texture buffers");
560 }
561 const Id id{AddGlobalVariable(type, spv::StorageClass::UniformConstant)};
562 Decorate(id, spv::Decoration::Binding, binding);
563 Decorate(id, spv::Decoration::DescriptorSet, 0U);
564 Name(id, fmt::format("texbuf{}_{:02x}", desc.cbuf_index, desc.cbuf_offset));
565 texture_buffers.insert(texture_buffers.end(), desc.count, id);
566 if (profile.supported_spirv >= 0x00010400) {
567 interfaces.push_back(id);
568 }
569 binding += desc.count;
570 }
571}
572
544void EmitContext::DefineLabels(IR::Program& program) { 573void EmitContext::DefineLabels(IR::Program& program) {
545 for (IR::Block* const block : program.blocks) { 574 for (IR::Block* const block : program.blocks) {
546 block->SetDefinition(OpLabel()); 575 block->SetDefinition(OpLabel());
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h
index 7a2ac0511..2a10e94e5 100644
--- a/src/shader_recompiler/backend/spirv/emit_context.h
+++ b/src/shader_recompiler/backend/spirv/emit_context.h
@@ -90,9 +90,13 @@ public:
90 90
91 Id storage_u32{}; 91 Id storage_u32{};
92 92
93 Id image_buffer_type{};
94 Id sampled_texture_buffer_type{};
95
93 std::array<UniformDefinitions, Info::MAX_CBUFS> cbufs{}; 96 std::array<UniformDefinitions, Info::MAX_CBUFS> cbufs{};
94 std::array<Id, Info::MAX_SSBOS> ssbos{}; 97 std::array<Id, Info::MAX_SSBOS> ssbos{};
95 std::vector<TextureDefinition> textures; 98 std::vector<TextureDefinition> textures;
99 std::vector<Id> texture_buffers;
96 100
97 Id workgroup_id{}; 101 Id workgroup_id{};
98 Id local_invocation_id{}; 102 Id local_invocation_id{};
@@ -151,6 +155,7 @@ private:
151 void DefineConstantBuffers(const Info& info, u32& binding); 155 void DefineConstantBuffers(const Info& info, u32& binding);
152 void DefineStorageBuffers(const Info& info, u32& binding); 156 void DefineStorageBuffers(const Info& info, u32& binding);
153 void DefineTextures(const Info& info, u32& binding); 157 void DefineTextures(const Info& info, u32& binding);
158 void DefineTextureBuffers(const Info& info, u32& binding);
154 void DefineAttributeMemAccess(const Info& info); 159 void DefineAttributeMemAccess(const Info& info);
155 void DefineLabels(IR::Program& program); 160 void DefineLabels(IR::Program& program);
156 161
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp
index 191380db0..32512a0e5 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp
@@ -249,6 +249,7 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct
249 // TODO: Track this usage 249 // TODO: Track this usage
250 ctx.AddCapability(spv::Capability::ImageGatherExtended); 250 ctx.AddCapability(spv::Capability::ImageGatherExtended);
251 ctx.AddCapability(spv::Capability::ImageQuery); 251 ctx.AddCapability(spv::Capability::ImageQuery);
252 ctx.AddCapability(spv::Capability::SampledBuffer);
252} 253}
253 254
254Id PhiArgDef(EmitContext& ctx, IR::Inst* inst, size_t index) { 255Id PhiArgDef(EmitContext& ctx, IR::Inst* inst, size_t index) {
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
index fc40615af..525f67c6e 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
@@ -128,12 +128,18 @@ Id Texture(EmitContext& ctx, const IR::Value& index) {
128 throw NotImplementedException("Indirect texture sample"); 128 throw NotImplementedException("Indirect texture sample");
129} 129}
130 130
131Id TextureImage(EmitContext& ctx, const IR::Value& index) { 131Id TextureImage(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) {
132 if (index.IsImmediate()) { 132 if (!index.IsImmediate()) {
133 throw NotImplementedException("Indirect texture sample");
134 }
135 if (info.type == TextureType::Buffer) {
136 const Id sampler_id{ctx.texture_buffers.at(index.U32())};
137 const Id id{ctx.OpLoad(ctx.sampled_texture_buffer_type, sampler_id)};
138 return ctx.OpImage(ctx.image_buffer_type, id);
139 } else {
133 const TextureDefinition def{ctx.textures.at(index.U32())}; 140 const TextureDefinition def{ctx.textures.at(index.U32())};
134 return ctx.OpImage(def.image_type, ctx.OpLoad(def.sampled_type, def.id)); 141 return ctx.OpImage(def.image_type, ctx.OpLoad(def.sampled_type, def.id));
135 } 142 }
136 throw NotImplementedException("Indirect texture sample");
137} 143}
138 144
139Id Decorate(EmitContext& ctx, IR::Inst* inst, Id sample) { 145Id Decorate(EmitContext& ctx, IR::Inst* inst, Id sample) {
@@ -297,17 +303,22 @@ Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
297 ctx.F32[4], Texture(ctx, index), coords, dref, operands.Mask(), operands.Span()); 303 ctx.F32[4], Texture(ctx, index), coords, dref, operands.Mask(), operands.Span());
298} 304}
299 305
306#pragma optimize("", off)
307
300Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, 308Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset,
301 Id lod, Id ms) { 309 Id lod, Id ms) {
302 const auto info{inst->Flags<IR::TextureInstInfo>()}; 310 const auto info{inst->Flags<IR::TextureInstInfo>()};
311 if (info.type == TextureType::Buffer) {
312 lod = Id{};
313 }
303 const ImageOperands operands(offset, lod, ms); 314 const ImageOperands operands(offset, lod, ms);
304 return Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst, ctx.F32[4], 315 return Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst, ctx.F32[4],
305 TextureImage(ctx, index), coords, operands.Mask(), operands.Span()); 316 TextureImage(ctx, index, info), coords, operands.Mask(), operands.Span());
306} 317}
307 318
308Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod) { 319Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod) {
309 const auto info{inst->Flags<IR::TextureInstInfo>()}; 320 const auto info{inst->Flags<IR::TextureInstInfo>()};
310 const Id image{TextureImage(ctx, index)}; 321 const Id image{TextureImage(ctx, index, info)};
311 const Id zero{ctx.u32_zero_value}; 322 const Id zero{ctx.u32_zero_value};
312 const auto mips{[&] { return ctx.OpImageQueryLevels(ctx.U32[1], image); }}; 323 const auto mips{[&] { return ctx.OpImageQueryLevels(ctx.U32[1], image); }};
313 switch (info.type) { 324 switch (info.type) {
@@ -331,6 +342,9 @@ Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& i
331 case TextureType::ShadowArrayCube: 342 case TextureType::ShadowArrayCube:
332 return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySizeLod(ctx.U32[3], image, lod), 343 return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySizeLod(ctx.U32[3], image, lod),
333 mips()); 344 mips());
345 case TextureType::Buffer:
346 return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySize(ctx.U32[1], image), zero,
347 zero, mips());
334 } 348 }
335 throw LogicError("Unspecified image type {}", info.type.Value()); 349 throw LogicError("Unspecified image type {}", info.type.Value());
336} 350}