From b2a6dde4380a5526e9d936f92a9e3d6ad9393bfa Mon Sep 17 00:00:00 2001 From: FengChen Date: Wed, 10 Aug 2022 10:10:32 +0800 Subject: video_code: support rectangle texture --- .../backend/glasm/emit_glasm_image.cpp | 2 ++ .../backend/glsl/emit_glsl_image.cpp | 1 + .../backend/glsl/glsl_emit_context.cpp | 1 + .../backend/spirv/emit_spirv_image.cpp | 1 + .../backend/spirv/spirv_emit_context.cpp | 1 + src/shader_recompiler/frontend/ir/ir_emitter.cpp | 5 +++++ src/shader_recompiler/frontend/ir/ir_emitter.h | 2 ++ src/shader_recompiler/ir_opt/rescaling_pass.cpp | 7 ++++++- src/shader_recompiler/ir_opt/texture_pass.cpp | 23 ++++++++++++++++++++++ src/shader_recompiler/shader_info.h | 3 ++- 10 files changed, 44 insertions(+), 2 deletions(-) (limited to 'src/shader_recompiler') diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp index a97b143e4..e67e80fac 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp @@ -67,6 +67,7 @@ std::string_view TextureType(IR::TextureInstInfo info) { case TextureType::ColorArray1D: return "SHADOWARRAY1D"; case TextureType::Color2D: + case TextureType::Color2DRect: return "SHADOW2D"; case TextureType::ColorArray2D: return "SHADOWARRAY2D"; @@ -86,6 +87,7 @@ std::string_view TextureType(IR::TextureInstInfo info) { case TextureType::ColorArray1D: return "ARRAY1D"; case TextureType::Color2D: + case TextureType::Color2DRect: return "2D"; case TextureType::ColorArray2D: return "ARRAY2D"; diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp index 6af7e3fe6..cecdbb9d6 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp @@ -466,6 +466,7 @@ void EmitImageQueryDimensions(EmitContext& ctx, IR::Inst& inst, const IR::Value& case TextureType::ColorArray1D: case TextureType::Color2D: case TextureType::ColorCube: + case TextureType::Color2DRect: return ctx.AddU32x4( "{}=uvec4(uvec2(textureSize({},int({}))),0u,uint(textureQueryLevels({})));", inst, texture, lod, texture); diff --git a/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp b/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp index 221b06328..c767a9dc3 100644 --- a/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp @@ -86,6 +86,7 @@ std::string_view SamplerType(TextureType type, bool is_depth) { case TextureType::ColorArray1D: return "sampler1DArray"; case TextureType::Color2D: + case TextureType::Color2DRect: return "sampler2D"; case TextureType::ColorArray2D: return "sampler2DArray"; diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index d8d86c91a..fb5799c42 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp @@ -453,6 +453,7 @@ Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& i case TextureType::ColorArray1D: case TextureType::Color2D: case TextureType::ColorCube: + case TextureType::Color2DRect: return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySizeLod(ctx.U32[2], image, lod), zero, mips()); case TextureType::ColorArray2D: diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index 98dd9035a..aecc4c612 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -41,6 +41,7 @@ Id ImageType(EmitContext& ctx, const TextureDescriptor& desc) { case TextureType::ColorArray1D: return ctx.TypeImage(type, spv::Dim::Dim1D, depth, true, false, 1, format); case TextureType::Color2D: + case TextureType::Color2DRect: return ctx.TypeImage(type, spv::Dim::Dim2D, depth, false, false, 1, format); case TextureType::ColorArray2D: return ctx.TypeImage(type, spv::Dim::Dim2D, depth, true, false, 1, format); diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index d2b658bca..11086ed8c 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp @@ -1832,6 +1832,11 @@ Value IREmitter::ImageQueryDimension(const Value& handle, const IR::U32& lod) { return Inst(op, handle, lod); } +Value IREmitter::ImageQueryDimension(const Value& handle, const IR::U32& lod, + TextureInstInfo info) { + return Inst(Opcode::ImageQueryDimensions, Flags{info}, handle, lod); +} + Value IREmitter::ImageQueryLod(const Value& handle, const Value& coords, TextureInstInfo info) { const Opcode op{handle.IsImmediate() ? Opcode::BoundImageQueryLod : Opcode::BindlessImageQueryLod}; diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index c29bda558..25839a371 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h @@ -315,6 +315,8 @@ public: const F32& dref, const F32& lod, const Value& offset, TextureInstInfo info); [[nodiscard]] Value ImageQueryDimension(const Value& handle, const IR::U32& lod); + [[nodiscard]] Value ImageQueryDimension(const Value& handle, const IR::U32& lod, + TextureInstInfo info); [[nodiscard]] Value ImageQueryLod(const Value& handle, const Value& coords, TextureInstInfo info); diff --git a/src/shader_recompiler/ir_opt/rescaling_pass.cpp b/src/shader_recompiler/ir_opt/rescaling_pass.cpp index 0d5f2e4d8..9198fa5f2 100644 --- a/src/shader_recompiler/ir_opt/rescaling_pass.cpp +++ b/src/shader_recompiler/ir_opt/rescaling_pass.cpp @@ -16,6 +16,7 @@ namespace { switch (type) { case TextureType::Color2D: case TextureType::ColorArray2D: + case TextureType::Color2DRect: return true; case TextureType::Color1D: case TextureType::ColorArray1D: @@ -132,7 +133,8 @@ void PatchImageQueryDimensions(IR::Block& block, IR::Inst& inst) { const IR::U1 is_scaled{ir.IsTextureScaled(ir.Imm32(info.descriptor_index))}; switch (info.type) { case TextureType::Color2D: - case TextureType::ColorArray2D: { + case TextureType::ColorArray2D: + case TextureType::Color2DRect: { const IR::Value new_inst{&*block.PrependNewInst(it, inst)}; const IR::U32 width{DownScale(ir, is_scaled, IR::U32{ir.CompositeExtract(new_inst, 0)})}; const IR::U32 height{DownScale(ir, is_scaled, IR::U32{ir.CompositeExtract(new_inst, 1)})}; @@ -163,6 +165,7 @@ void ScaleIntegerComposite(IR::IREmitter& ir, IR::Inst& inst, const IR::U1& is_s const IR::U32 y{Scale(ir, is_scaled, IR::U32{ir.CompositeExtract(composite, 1)})}; switch (info.type) { case TextureType::Color2D: + case TextureType::Color2DRect: inst.SetArg(index, ir.CompositeConstruct(x, y)); break; case TextureType::ColorArray2D: { @@ -193,6 +196,7 @@ void ScaleIntegerOffsetComposite(IR::IREmitter& ir, IR::Inst& inst, const IR::U1 switch (info.type) { case TextureType::ColorArray2D: case TextureType::Color2D: + case TextureType::Color2DRect: inst.SetArg(index, ir.CompositeConstruct(x, y)); break; case TextureType::Color1D: @@ -216,6 +220,7 @@ void SubScaleCoord(IR::IREmitter& ir, IR::Inst& inst, const IR::U1& is_scaled) { const IR::U32 scaled_y{SubScale(ir, is_scaled, coord_y, IR::Attribute::PositionY)}; switch (info.type) { case TextureType::Color2D: + case TextureType::Color2DRect: inst.SetArg(1, ir.CompositeConstruct(scaled_x, scaled_y)); break; case TextureType::ColorArray2D: { diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp index ca3e306e8..5cead5135 100644 --- a/src/shader_recompiler/ir_opt/texture_pass.cpp +++ b/src/shader_recompiler/ir_opt/texture_pass.cpp @@ -362,6 +362,21 @@ private: TextureDescriptors& texture_descriptors; ImageDescriptors& image_descriptors; }; + +void PatchImageSampleImplicitLod(IR::Block& block, IR::Inst& inst) { + IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; + const auto info{inst.Flags()}; + const IR::Value coord(inst.Arg(1)); + const IR::Value handle(ir.Imm32(0)); + const IR::U32 lod{ir.Imm32(0)}; + const IR::Value texture_size = ir.ImageQueryDimension(handle, lod, info); + inst.SetArg( + 1, ir.CompositeConstruct( + ir.FPMul(IR::F32(ir.CompositeExtract(coord, 0)), + ir.FPRecip(ir.ConvertUToF(32, 32, ir.CompositeExtract(texture_size, 0)))), + ir.FPMul(IR::F32(ir.CompositeExtract(coord, 1)), + ir.FPRecip(ir.ConvertUToF(32, 32, ir.CompositeExtract(texture_size, 1)))))); +} } // Anonymous namespace void TexturePass(Environment& env, IR::Program& program) { @@ -399,6 +414,14 @@ void TexturePass(Environment& env, IR::Program& program) { flags.type.Assign(ReadTextureType(env, cbuf)); inst->SetFlags(flags); break; + case IR::Opcode::ImageSampleImplicitLod: + if (flags.type == TextureType::Color2D) { + auto texture_type = ReadTextureType(env, cbuf); + if (texture_type == TextureType::Color2DRect) { + PatchImageSampleImplicitLod(*texture_inst.block, *texture_inst.inst); + } + } + break; case IR::Opcode::ImageFetch: if (flags.type != TextureType::Color1D) { break; diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h index fd2ef5336..f5690805c 100644 --- a/src/shader_recompiler/shader_info.h +++ b/src/shader_recompiler/shader_info.h @@ -24,8 +24,9 @@ enum class TextureType : u32 { ColorCube, ColorArrayCube, Buffer, + Color2DRect, }; -constexpr u32 NUM_TEXTURE_TYPES = 8; +constexpr u32 NUM_TEXTURE_TYPES = 9; enum class ImageFormat : u32 { Typeless, -- cgit v1.2.3