diff options
| author | 2021-03-28 19:47:52 +0200 | |
|---|---|---|
| committer | 2021-07-22 21:51:25 -0400 | |
| commit | 613b48c4a2ce71a0d0eaba17fe164f4a2e4a3db5 (patch) | |
| tree | a8d2d2eb8284f1b35184e4ee07e25709ecce0596 /src | |
| parent | shader: Implement TLDS (diff) | |
| download | yuzu-613b48c4a2ce71a0d0eaba17fe164f4a2e4a3db5.tar.gz yuzu-613b48c4a2ce71a0d0eaba17fe164f4a2e4a3db5.tar.xz yuzu-613b48c4a2ce71a0d0eaba17fe164f4a2e4a3db5.zip | |
shader,spirv: Implement ImageQueryLod.
Diffstat (limited to 'src')
9 files changed, 38 insertions, 1 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index 5cd505d99..c8ce58254 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -182,6 +182,7 @@ void EmitContext::DefineCommonConstants() { | |||
| 182 | true_value = ConstantTrue(U1); | 182 | true_value = ConstantTrue(U1); |
| 183 | false_value = ConstantFalse(U1); | 183 | false_value = ConstantFalse(U1); |
| 184 | u32_zero_value = Constant(U32[1], 0U); | 184 | u32_zero_value = Constant(U32[1], 0U); |
| 185 | f32_zero_value = Constant(F32[1], 0.0f); | ||
| 185 | } | 186 | } |
| 186 | 187 | ||
| 187 | void EmitContext::DefineInterfaces(const Info& info) { | 188 | void EmitContext::DefineInterfaces(const Info& info) { |
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h index 071e66c2a..3965869f0 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.h +++ b/src/shader_recompiler/backend/spirv/emit_context.h | |||
| @@ -70,6 +70,7 @@ public: | |||
| 70 | Id true_value{}; | 70 | Id true_value{}; |
| 71 | Id false_value{}; | 71 | Id false_value{}; |
| 72 | Id u32_zero_value{}; | 72 | Id u32_zero_value{}; |
| 73 | Id f32_zero_value{}; | ||
| 73 | 74 | ||
| 74 | UniformDefinitions uniform_types; | 75 | UniformDefinitions uniform_types; |
| 75 | 76 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index 3d0c6f7ba..105c23745 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -362,6 +362,7 @@ Id EmitBindlessImageGather(EmitContext&); | |||
| 362 | Id EmitBindlessImageGatherDref(EmitContext&); | 362 | Id EmitBindlessImageGatherDref(EmitContext&); |
| 363 | Id EmitBindlessImageFetch(EmitContext&); | 363 | Id EmitBindlessImageFetch(EmitContext&); |
| 364 | Id EmitBindlessImageQueryDimensions(EmitContext&); | 364 | Id EmitBindlessImageQueryDimensions(EmitContext&); |
| 365 | Id EmitBindlessImageQueryLod(EmitContext&); | ||
| 365 | Id EmitBoundImageSampleImplicitLod(EmitContext&); | 366 | Id EmitBoundImageSampleImplicitLod(EmitContext&); |
| 366 | Id EmitBoundImageSampleExplicitLod(EmitContext&); | 367 | Id EmitBoundImageSampleExplicitLod(EmitContext&); |
| 367 | Id EmitBoundImageSampleDrefImplicitLod(EmitContext&); | 368 | Id EmitBoundImageSampleDrefImplicitLod(EmitContext&); |
| @@ -370,6 +371,7 @@ Id EmitBoundImageGather(EmitContext&); | |||
| 370 | Id EmitBoundImageGatherDref(EmitContext&); | 371 | Id EmitBoundImageGatherDref(EmitContext&); |
| 371 | Id EmitBoundImageFetch(EmitContext&); | 372 | Id EmitBoundImageFetch(EmitContext&); |
| 372 | Id EmitBoundImageQueryDimensions(EmitContext&); | 373 | Id EmitBoundImageQueryDimensions(EmitContext&); |
| 374 | Id EmitBoundImageQueryLod(EmitContext&); | ||
| 373 | Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, | 375 | Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, |
| 374 | Id bias_lc, Id offset); | 376 | Id bias_lc, Id offset); |
| 375 | Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, | 377 | Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, |
| @@ -385,6 +387,7 @@ Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, | |||
| 385 | Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, | 387 | Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, |
| 386 | Id lod, Id ms); | 388 | Id lod, Id ms); |
| 387 | Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod); | 389 | Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod); |
| 390 | Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords); | ||
| 388 | Id EmitVoteAll(EmitContext& ctx, Id pred); | 391 | Id EmitVoteAll(EmitContext& ctx, Id pred); |
| 389 | Id EmitVoteAny(EmitContext& ctx, Id pred); | 392 | Id EmitVoteAny(EmitContext& ctx, Id pred); |
| 390 | Id EmitVoteEqual(EmitContext& ctx, Id pred); | 393 | Id EmitVoteEqual(EmitContext& ctx, Id pred); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index 310cc7af7..2cd6b38c4 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp | |||
| @@ -161,6 +161,10 @@ Id EmitBindlessImageQueryDimensions(EmitContext&) { | |||
| 161 | throw LogicError("Unreachable instruction"); | 161 | throw LogicError("Unreachable instruction"); |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | Id EmitBindlessImageQueryLod(EmitContext&) { | ||
| 165 | throw LogicError("Unreachable instruction"); | ||
| 166 | } | ||
| 167 | |||
| 164 | Id EmitBoundImageSampleImplicitLod(EmitContext&) { | 168 | Id EmitBoundImageSampleImplicitLod(EmitContext&) { |
| 165 | throw LogicError("Unreachable instruction"); | 169 | throw LogicError("Unreachable instruction"); |
| 166 | } | 170 | } |
| @@ -193,6 +197,10 @@ Id EmitBoundImageQueryDimensions(EmitContext&) { | |||
| 193 | throw LogicError("Unreachable instruction"); | 197 | throw LogicError("Unreachable instruction"); |
| 194 | } | 198 | } |
| 195 | 199 | ||
| 200 | Id EmitBoundImageQueryLod(EmitContext&) { | ||
| 201 | throw LogicError("Unreachable instruction"); | ||
| 202 | } | ||
| 203 | |||
| 196 | Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, | 204 | Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, |
| 197 | Id bias_lc, Id offset) { | 205 | Id bias_lc, Id offset) { |
| 198 | const auto info{inst->Flags<IR::TextureInstInfo>()}; | 206 | const auto info{inst->Flags<IR::TextureInstInfo>()}; |
| @@ -287,4 +295,11 @@ Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& i | |||
| 287 | throw LogicError("Unspecified image type {}", info.type.Value()); | 295 | throw LogicError("Unspecified image type {}", info.type.Value()); |
| 288 | } | 296 | } |
| 289 | 297 | ||
| 298 | Id EmitImageQueryLod(EmitContext& ctx, IR::Inst*, const IR::Value& index, Id coords) { | ||
| 299 | const Id zero{ctx.f32_zero_value}; | ||
| 300 | const Id image{TextureImage(ctx, index)}; | ||
| 301 | return ctx.OpCompositeConstruct(ctx.F32[4], ctx.OpImageQueryLod(ctx.F32[2], image, coords), | ||
| 302 | zero, zero); | ||
| 303 | } | ||
| 304 | |||
| 290 | } // namespace Shader::Backend::SPIRV | 305 | } // namespace Shader::Backend::SPIRV |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index 6e7dddead..ba9591727 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -1567,6 +1567,12 @@ Value IREmitter::ImageQueryDimension(const Value& handle, const IR::U32& lod) { | |||
| 1567 | return Inst(op, handle, lod); | 1567 | return Inst(op, handle, lod); |
| 1568 | } | 1568 | } |
| 1569 | 1569 | ||
| 1570 | Value IREmitter::ImageQueryLod(const Value& handle, const Value& coords) { | ||
| 1571 | const Opcode op{handle.IsImmediate() ? Opcode::BoundImageQueryLod | ||
| 1572 | : Opcode::BindlessImageQueryLod}; | ||
| 1573 | return Inst(op, handle, coords); | ||
| 1574 | } | ||
| 1575 | |||
| 1570 | U1 IREmitter::VoteAll(const U1& value) { | 1576 | U1 IREmitter::VoteAll(const U1& value) { |
| 1571 | return Inst<U1>(Opcode::VoteAll, value); | 1577 | return Inst<U1>(Opcode::VoteAll, value); |
| 1572 | } | 1578 | } |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index 8f3325738..9e752b208 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h | |||
| @@ -255,6 +255,8 @@ public: | |||
| 255 | TextureInstInfo info); | 255 | TextureInstInfo info); |
| 256 | [[nodiscard]] Value ImageQueryDimension(const Value& handle, const IR::U32& lod); | 256 | [[nodiscard]] Value ImageQueryDimension(const Value& handle, const IR::U32& lod); |
| 257 | 257 | ||
| 258 | [[nodiscard]] Value ImageQueryLod(const Value& handle, const Value& coords); | ||
| 259 | |||
| 258 | [[nodiscard]] Value ImageGather(const Value& handle, const Value& coords, const Value& offset, | 260 | [[nodiscard]] Value ImageGather(const Value& handle, const Value& coords, const Value& offset, |
| 259 | const Value& offset2, TextureInstInfo info); | 261 | const Value& offset2, TextureInstInfo info); |
| 260 | 262 | ||
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index 302b8471d..49cdcd57f 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc | |||
| @@ -380,6 +380,7 @@ OPCODE(BindlessImageGather, F32x4, U32, | |||
| 380 | OPCODE(BindlessImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) | 380 | OPCODE(BindlessImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) |
| 381 | OPCODE(BindlessImageFetch, F32x4, U32, Opaque, Opaque, Opaque, Opaque, ) | 381 | OPCODE(BindlessImageFetch, F32x4, U32, Opaque, Opaque, Opaque, Opaque, ) |
| 382 | OPCODE(BindlessImageQueryDimensions, U32x4, U32, U32, ) | 382 | OPCODE(BindlessImageQueryDimensions, U32x4, U32, U32, ) |
| 383 | OPCODE(BindlessImageQueryLod, F32x4, U32, Opaque, ) | ||
| 383 | 384 | ||
| 384 | OPCODE(BoundImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) | 385 | OPCODE(BoundImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) |
| 385 | OPCODE(BoundImageSampleExplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) | 386 | OPCODE(BoundImageSampleExplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) |
| @@ -389,6 +390,7 @@ OPCODE(BoundImageGather, F32x4, U32, | |||
| 389 | OPCODE(BoundImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) | 390 | OPCODE(BoundImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) |
| 390 | OPCODE(BoundImageFetch, F32x4, U32, Opaque, Opaque, Opaque, Opaque, ) | 391 | OPCODE(BoundImageFetch, F32x4, U32, Opaque, Opaque, Opaque, Opaque, ) |
| 391 | OPCODE(BoundImageQueryDimensions, U32x4, U32, U32, ) | 392 | OPCODE(BoundImageQueryDimensions, U32x4, U32, U32, ) |
| 393 | OPCODE(BoundImageQueryLod, F32x4, U32, Opaque, ) | ||
| 392 | 394 | ||
| 393 | OPCODE(ImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) | 395 | OPCODE(ImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) |
| 394 | OPCODE(ImageSampleExplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) | 396 | OPCODE(ImageSampleExplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) |
| @@ -398,6 +400,7 @@ OPCODE(ImageGather, F32x4, U32, | |||
| 398 | OPCODE(ImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) | 400 | OPCODE(ImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) |
| 399 | OPCODE(ImageFetch, F32x4, U32, Opaque, Opaque, Opaque, Opaque, ) | 401 | OPCODE(ImageFetch, F32x4, U32, Opaque, Opaque, Opaque, Opaque, ) |
| 400 | OPCODE(ImageQueryDimensions, U32x4, U32, U32, ) | 402 | OPCODE(ImageQueryDimensions, U32x4, U32, U32, ) |
| 403 | OPCODE(ImageQueryLod, F32x4, U32, Opaque, ) | ||
| 401 | 404 | ||
| 402 | // Warp operations | 405 | // Warp operations |
| 403 | OPCODE(VoteAll, U1, U1, ) | 406 | OPCODE(VoteAll, U1, U1, ) |
diff --git a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp index 3b00d7c8c..04e3a4f53 100644 --- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp +++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp | |||
| @@ -383,7 +383,8 @@ void VisitUsages(Info& info, IR::Inst& inst) { | |||
| 383 | case IR::Opcode::ImageGather: | 383 | case IR::Opcode::ImageGather: |
| 384 | case IR::Opcode::ImageGatherDref: | 384 | case IR::Opcode::ImageGatherDref: |
| 385 | case IR::Opcode::ImageFetch: | 385 | case IR::Opcode::ImageFetch: |
| 386 | case IR::Opcode::ImageQueryDimensions: { | 386 | case IR::Opcode::ImageQueryDimensions: |
| 387 | case IR::Opcode::ImageQueryLod: { | ||
| 387 | const TextureType type{inst.Flags<IR::TextureInstInfo>().type}; | 388 | const TextureType type{inst.Flags<IR::TextureInstInfo>().type}; |
| 388 | info.uses_sampled_1d |= type == TextureType::Color1D || type == TextureType::ColorArray1D || | 389 | info.uses_sampled_1d |= type == TextureType::Color1D || type == TextureType::ColorArray1D || |
| 389 | type == TextureType::Shadow1D || type == TextureType::ShadowArray1D; | 390 | type == TextureType::Shadow1D || type == TextureType::ShadowArray1D; |
diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp index dfacf848f..6eb286b83 100644 --- a/src/shader_recompiler/ir_opt/texture_pass.cpp +++ b/src/shader_recompiler/ir_opt/texture_pass.cpp | |||
| @@ -57,6 +57,9 @@ IR::Opcode IndexedInstruction(const IR::Inst& inst) { | |||
| 57 | case IR::Opcode::BoundImageQueryDimensions: | 57 | case IR::Opcode::BoundImageQueryDimensions: |
| 58 | case IR::Opcode::BindlessImageQueryDimensions: | 58 | case IR::Opcode::BindlessImageQueryDimensions: |
| 59 | return IR::Opcode::ImageQueryDimensions; | 59 | return IR::Opcode::ImageQueryDimensions; |
| 60 | case IR::Opcode::BoundImageQueryLod: | ||
| 61 | case IR::Opcode::BindlessImageQueryLod: | ||
| 62 | return IR::Opcode::ImageQueryLod; | ||
| 60 | default: | 63 | default: |
| 61 | return IR::Opcode::Void; | 64 | return IR::Opcode::Void; |
| 62 | } | 65 | } |
| @@ -72,6 +75,7 @@ bool IsBindless(const IR::Inst& inst) { | |||
| 72 | case IR::Opcode::BindlessImageGatherDref: | 75 | case IR::Opcode::BindlessImageGatherDref: |
| 73 | case IR::Opcode::BindlessImageFetch: | 76 | case IR::Opcode::BindlessImageFetch: |
| 74 | case IR::Opcode::BindlessImageQueryDimensions: | 77 | case IR::Opcode::BindlessImageQueryDimensions: |
| 78 | case IR::Opcode::BindlessImageQueryLod: | ||
| 75 | return true; | 79 | return true; |
| 76 | case IR::Opcode::BoundImageSampleImplicitLod: | 80 | case IR::Opcode::BoundImageSampleImplicitLod: |
| 77 | case IR::Opcode::BoundImageSampleExplicitLod: | 81 | case IR::Opcode::BoundImageSampleExplicitLod: |
| @@ -81,6 +85,7 @@ bool IsBindless(const IR::Inst& inst) { | |||
| 81 | case IR::Opcode::BoundImageGatherDref: | 85 | case IR::Opcode::BoundImageGatherDref: |
| 82 | case IR::Opcode::BoundImageFetch: | 86 | case IR::Opcode::BoundImageFetch: |
| 83 | case IR::Opcode::BoundImageQueryDimensions: | 87 | case IR::Opcode::BoundImageQueryDimensions: |
| 88 | case IR::Opcode::BoundImageQueryLod: | ||
| 84 | return false; | 89 | return false; |
| 85 | default: | 90 | default: |
| 86 | throw InvalidArgument("Invalid opcode {}", inst.Opcode()); | 91 | throw InvalidArgument("Invalid opcode {}", inst.Opcode()); |