summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/backend/spirv/emit_spirv_image.cpp')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_image.cpp58
1 files changed, 34 insertions, 24 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
index 90817f161..6008980af 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
@@ -147,24 +147,31 @@ private:
147 spv::ImageOperandsMask mask{}; 147 spv::ImageOperandsMask mask{};
148}; 148};
149 149
150Id Texture(EmitContext& ctx, const IR::Value& index) { 150Id Texture(EmitContext& ctx, IR::TextureInstInfo info, [[maybe_unused]] const IR::Value& index) {
151 if (index.IsImmediate()) { 151 const TextureDefinition& def{ctx.textures.at(info.descriptor_index)};
152 const TextureDefinition def{ctx.textures.at(index.U32())}; 152 if (def.count > 1) {
153 const Id pointer{ctx.OpAccessChain(def.pointer_type, def.id, ctx.Def(index))};
154 return ctx.OpLoad(def.sampled_type, pointer);
155 } else {
153 return ctx.OpLoad(def.sampled_type, def.id); 156 return ctx.OpLoad(def.sampled_type, def.id);
154 } 157 }
155 throw NotImplementedException("Indirect texture sample");
156} 158}
157 159
158Id TextureImage(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) { 160Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info,
159 if (!index.IsImmediate()) { 161 [[maybe_unused]] const IR::Value& index) {
160 throw NotImplementedException("Indirect texture sample");
161 }
162 if (info.type == TextureType::Buffer) { 162 if (info.type == TextureType::Buffer) {
163 const Id sampler_id{ctx.texture_buffers.at(index.U32())}; 163 const TextureBufferDefinition& def{ctx.texture_buffers.at(info.descriptor_index)};
164 if (def.count > 1) {
165 throw NotImplementedException("Indirect texture sample");
166 }
167 const Id sampler_id{def.id};
164 const Id id{ctx.OpLoad(ctx.sampled_texture_buffer_type, sampler_id)}; 168 const Id id{ctx.OpLoad(ctx.sampled_texture_buffer_type, sampler_id)};
165 return ctx.OpImage(ctx.image_buffer_type, id); 169 return ctx.OpImage(ctx.image_buffer_type, id);
166 } else { 170 } else {
167 const TextureDefinition def{ctx.textures.at(index.U32())}; 171 const TextureDefinition& def{ctx.textures.at(info.descriptor_index)};
172 if (def.count > 1) {
173 throw NotImplementedException("Indirect texture sample");
174 }
168 return ctx.OpImage(def.image_type, ctx.OpLoad(def.sampled_type, def.id)); 175 return ctx.OpImage(def.image_type, ctx.OpLoad(def.sampled_type, def.id));
169 } 176 }
170} 177}
@@ -311,7 +318,7 @@ Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value&
311 bias_lc, offset); 318 bias_lc, offset);
312 return Emit(&EmitContext::OpImageSparseSampleImplicitLod, 319 return Emit(&EmitContext::OpImageSparseSampleImplicitLod,
313 &EmitContext::OpImageSampleImplicitLod, ctx, inst, ctx.F32[4], 320 &EmitContext::OpImageSampleImplicitLod, ctx, inst, ctx.F32[4],
314 Texture(ctx, index), coords, operands.Mask(), operands.Span()); 321 Texture(ctx, info, index), coords, operands.Mask(), operands.Span());
315 } else { 322 } else {
316 // We can't use implicit lods on non-fragment stages on SPIR-V. Maxwell hardware behaves as 323 // We can't use implicit lods on non-fragment stages on SPIR-V. Maxwell hardware behaves as
317 // if the lod was explicitly zero. This may change on Turing with implicit compute 324 // if the lod was explicitly zero. This may change on Turing with implicit compute
@@ -320,7 +327,7 @@ Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value&
320 const ImageOperands operands(ctx, false, true, info.has_lod_clamp != 0, lod, offset); 327 const ImageOperands operands(ctx, false, true, info.has_lod_clamp != 0, lod, offset);
321 return Emit(&EmitContext::OpImageSparseSampleExplicitLod, 328 return Emit(&EmitContext::OpImageSparseSampleExplicitLod,
322 &EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4], 329 &EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4],
323 Texture(ctx, index), coords, operands.Mask(), operands.Span()); 330 Texture(ctx, info, index), coords, operands.Mask(), operands.Span());
324 } 331 }
325} 332}
326 333
@@ -329,8 +336,8 @@ Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value&
329 const auto info{inst->Flags<IR::TextureInstInfo>()}; 336 const auto info{inst->Flags<IR::TextureInstInfo>()};
330 const ImageOperands operands(ctx, false, true, info.has_lod_clamp != 0, lod_lc, offset); 337 const ImageOperands operands(ctx, false, true, info.has_lod_clamp != 0, lod_lc, offset);
331 return Emit(&EmitContext::OpImageSparseSampleExplicitLod, 338 return Emit(&EmitContext::OpImageSparseSampleExplicitLod,
332 &EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4], Texture(ctx, index), 339 &EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4],
333 coords, operands.Mask(), operands.Span()); 340 Texture(ctx, info, index), coords, operands.Mask(), operands.Span());
334} 341}
335 342
336Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, 343Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
@@ -340,7 +347,7 @@ Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Va
340 offset); 347 offset);
341 return Emit(&EmitContext::OpImageSparseSampleDrefImplicitLod, 348 return Emit(&EmitContext::OpImageSparseSampleDrefImplicitLod,
342 &EmitContext::OpImageSampleDrefImplicitLod, ctx, inst, ctx.F32[1], 349 &EmitContext::OpImageSampleDrefImplicitLod, ctx, inst, ctx.F32[1],
343 Texture(ctx, index), coords, dref, operands.Mask(), operands.Span()); 350 Texture(ctx, info, index), coords, dref, operands.Mask(), operands.Span());
344} 351}
345 352
346Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, 353Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
@@ -349,7 +356,7 @@ Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Va
349 const ImageOperands operands(ctx, false, true, info.has_lod_clamp != 0, lod_lc, offset); 356 const ImageOperands operands(ctx, false, true, info.has_lod_clamp != 0, lod_lc, offset);
350 return Emit(&EmitContext::OpImageSparseSampleDrefExplicitLod, 357 return Emit(&EmitContext::OpImageSparseSampleDrefExplicitLod,
351 &EmitContext::OpImageSampleDrefExplicitLod, ctx, inst, ctx.F32[1], 358 &EmitContext::OpImageSampleDrefExplicitLod, ctx, inst, ctx.F32[1],
352 Texture(ctx, index), coords, dref, operands.Mask(), operands.Span()); 359 Texture(ctx, info, index), coords, dref, operands.Mask(), operands.Span());
353} 360}
354 361
355Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, 362Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
@@ -357,15 +364,17 @@ Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id
357 const auto info{inst->Flags<IR::TextureInstInfo>()}; 364 const auto info{inst->Flags<IR::TextureInstInfo>()};
358 const ImageOperands operands(ctx, offset, offset2); 365 const ImageOperands operands(ctx, offset, offset2);
359 return Emit(&EmitContext::OpImageSparseGather, &EmitContext::OpImageGather, ctx, inst, 366 return Emit(&EmitContext::OpImageSparseGather, &EmitContext::OpImageGather, ctx, inst,
360 ctx.F32[4], Texture(ctx, index), coords, ctx.Const(info.gather_component), 367 ctx.F32[4], Texture(ctx, info, index), coords, ctx.Const(info.gather_component),
361 operands.Mask(), operands.Span()); 368 operands.Mask(), operands.Span());
362} 369}
363 370
364Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, 371Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
365 const IR::Value& offset, const IR::Value& offset2, Id dref) { 372 const IR::Value& offset, const IR::Value& offset2, Id dref) {
373 const auto info{inst->Flags<IR::TextureInstInfo>()};
366 const ImageOperands operands(ctx, offset, offset2); 374 const ImageOperands operands(ctx, offset, offset2);
367 return Emit(&EmitContext::OpImageSparseDrefGather, &EmitContext::OpImageDrefGather, ctx, inst, 375 return Emit(&EmitContext::OpImageSparseDrefGather, &EmitContext::OpImageDrefGather, ctx, inst,
368 ctx.F32[4], Texture(ctx, index), coords, dref, operands.Mask(), operands.Span()); 376 ctx.F32[4], Texture(ctx, info, index), coords, dref, operands.Mask(),
377 operands.Span());
369} 378}
370 379
371Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, 380Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset,
@@ -376,12 +385,12 @@ Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id c
376 } 385 }
377 const ImageOperands operands(offset, lod, ms); 386 const ImageOperands operands(offset, lod, ms);
378 return Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst, ctx.F32[4], 387 return Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst, ctx.F32[4],
379 TextureImage(ctx, index, info), coords, operands.Mask(), operands.Span()); 388 TextureImage(ctx, info, index), coords, operands.Mask(), operands.Span());
380} 389}
381 390
382Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod) { 391Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod) {
383 const auto info{inst->Flags<IR::TextureInstInfo>()}; 392 const auto info{inst->Flags<IR::TextureInstInfo>()};
384 const Id image{TextureImage(ctx, index, info)}; 393 const Id image{TextureImage(ctx, info, index)};
385 const Id zero{ctx.u32_zero_value}; 394 const Id zero{ctx.u32_zero_value};
386 const auto mips{[&] { return ctx.OpImageQueryLevels(ctx.U32[1], image); }}; 395 const auto mips{[&] { return ctx.OpImageQueryLevels(ctx.U32[1], image); }};
387 switch (info.type) { 396 switch (info.type) {
@@ -405,9 +414,10 @@ Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& i
405 throw LogicError("Unspecified image type {}", info.type.Value()); 414 throw LogicError("Unspecified image type {}", info.type.Value());
406} 415}
407 416
408Id EmitImageQueryLod(EmitContext& ctx, IR::Inst*, const IR::Value& index, Id coords) { 417Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords) {
418 const auto info{inst->Flags<IR::TextureInstInfo>()};
409 const Id zero{ctx.f32_zero_value}; 419 const Id zero{ctx.f32_zero_value};
410 const Id sampler{Texture(ctx, index)}; 420 const Id sampler{Texture(ctx, info, index)};
411 return ctx.OpCompositeConstruct(ctx.F32[4], ctx.OpImageQueryLod(ctx.F32[2], sampler, coords), 421 return ctx.OpCompositeConstruct(ctx.F32[4], ctx.OpImageQueryLod(ctx.F32[2], sampler, coords),
412 zero, zero); 422 zero, zero);
413} 423}
@@ -418,8 +428,8 @@ Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, I
418 const ImageOperands operands(ctx, info.has_lod_clamp != 0, derivates, info.num_derivates, 428 const ImageOperands operands(ctx, info.has_lod_clamp != 0, derivates, info.num_derivates,
419 offset, lod_clamp); 429 offset, lod_clamp);
420 return Emit(&EmitContext::OpImageSparseSampleExplicitLod, 430 return Emit(&EmitContext::OpImageSparseSampleExplicitLod,
421 &EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4], Texture(ctx, index), 431 &EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4],
422 coords, operands.Mask(), operands.Span()); 432 Texture(ctx, info, index), coords, operands.Mask(), operands.Span());
423} 433}
424 434
425Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords) { 435Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords) {