diff options
14 files changed, 62 insertions, 15 deletions
| 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<IR::TextureInstInfo>()}; +    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, diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 8c0fffc67..99cd11d1e 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -93,6 +93,7 @@ GLenum ImageTarget(Shader::TextureType type, int num_samples = 1) {      case Shader::TextureType::Color1D:          return GL_TEXTURE_1D;      case Shader::TextureType::Color2D: +    case Shader::TextureType::Color2DRect:          return is_multisampled ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;      case Shader::TextureType::ColorCube:          return GL_TEXTURE_CUBE_MAP; @@ -502,6 +503,7 @@ TextureCacheRuntime::TextureCacheRuntime(const Device& device_, ProgramManager&      set_view(Shader::TextureType::ColorArray1D, null_image_1d_array.handle);      set_view(Shader::TextureType::ColorArray2D, null_image_view_2d_array.handle);      set_view(Shader::TextureType::ColorArrayCube, null_image_cube_array.handle); +    set_view(Shader::TextureType::Color2DRect, null_image_view_2d.handle);      if (resolution.active) {          for (size_t i = 0; i < rescale_draw_fbos.size(); ++i) { @@ -1110,6 +1112,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI          flat_range.extent.layers = 1;          [[fallthrough]];      case ImageViewType::e2D: +    case ImageViewType::Rect:          if (True(flags & VideoCommon::ImageViewFlagBits::Slice)) {              // 2D and 2D array views on a 3D textures are used exclusively for render targets              ASSERT(info.range.extent.levels == 1); @@ -1135,9 +1138,6 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI          SetupView(Shader::TextureType::ColorCube);          SetupView(Shader::TextureType::ColorArrayCube);          break; -    case ImageViewType::Rect: -        UNIMPLEMENTED(); -        break;      case ImageViewType::Buffer:          ASSERT(false);          break; @@ -1150,6 +1150,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI          default_handle = Handle(Shader::TextureType::ColorArray1D);          break;      case ImageViewType::e2D: +    case ImageViewType::Rect:          default_handle = Handle(Shader::TextureType::Color2D);          break;      case ImageViewType::e2DArray: @@ -1210,6 +1211,7 @@ GLuint ImageView::MakeView(Shader::TextureType view_type, GLenum view_format) {      case Shader::TextureType::Color1D:      case Shader::TextureType::Color2D:      case Shader::TextureType::ColorCube: +    case Shader::TextureType::Color2DRect:          view_range = flat_range;          break;      case Shader::TextureType::ColorArray1D: @@ -1250,7 +1252,6 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const TSCEntry& config) {      const GLint seamless = config.cubemap_interface_filtering ? GL_TRUE : GL_FALSE;      UNIMPLEMENTED_IF(config.cubemap_anisotropy != 1); -    UNIMPLEMENTED_IF(config.float_coord_normalization != 0);      sampler.Create();      const GLuint handle = sampler.handle; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 43cc94fab..3adad5af4 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -434,7 +434,9 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading                                                   state.statistics.get(), false)};              std::scoped_lock lock{state.mutex}; -            graphics_cache.emplace(key, std::move(pipeline)); +            if (pipeline) { +                graphics_cache.emplace(key, std::move(pipeline)); +            }              ++state.built;              if (state.has_loaded) {                  callback(VideoCore::LoadCallbackStage::Build, state.built, state.total); diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 16463a892..caca79d79 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -230,6 +230,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {      case Shader::TextureType::Color1D:          return VK_IMAGE_VIEW_TYPE_1D;      case Shader::TextureType::Color2D: +    case Shader::TextureType::Color2DRect:          return VK_IMAGE_VIEW_TYPE_2D;      case Shader::TextureType::ColorCube:          return VK_IMAGE_VIEW_TYPE_CUBE; @@ -254,6 +255,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {      case VideoCommon::ImageViewType::e1D:          return VK_IMAGE_VIEW_TYPE_1D;      case VideoCommon::ImageViewType::e2D: +    case VideoCommon::ImageViewType::Rect:          return VK_IMAGE_VIEW_TYPE_2D;      case VideoCommon::ImageViewType::Cube:          return VK_IMAGE_VIEW_TYPE_CUBE; @@ -265,9 +267,6 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {          return VK_IMAGE_VIEW_TYPE_2D_ARRAY;      case VideoCommon::ImageViewType::CubeArray:          return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; -    case VideoCommon::ImageViewType::Rect: -        UNIMPLEMENTED_MSG("Rect image view"); -        return VK_IMAGE_VIEW_TYPE_2D;      case VideoCommon::ImageViewType::Buffer:          ASSERT_MSG(false, "Texture buffers can't be image views");          return VK_IMAGE_VIEW_TYPE_1D; @@ -1579,6 +1578,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI          break;      case VideoCommon::ImageViewType::e2D:      case VideoCommon::ImageViewType::e2DArray: +    case VideoCommon::ImageViewType::Rect:          create(TextureType::Color2D, 1);          create(TextureType::ColorArray2D, std::nullopt);          render_target = Handle(Shader::TextureType::ColorArray2D); @@ -1592,9 +1592,6 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI          create(TextureType::ColorCube, 6);          create(TextureType::ColorArrayCube, std::nullopt);          break; -    case VideoCommon::ImageViewType::Rect: -        UNIMPLEMENTED(); -        break;      case VideoCommon::ImageViewType::Buffer:          ASSERT(false);          break; diff --git a/src/video_core/shader_environment.cpp b/src/video_core/shader_environment.cpp index c4e923bbf..808d88eec 100644 --- a/src/video_core/shader_environment.cpp +++ b/src/video_core/shader_environment.cpp @@ -39,7 +39,11 @@ static Shader::TextureType ConvertType(const Tegra::Texture::TICEntry& entry) {          return Shader::TextureType::Color1D;      case Tegra::Texture::TextureType::Texture2D:      case Tegra::Texture::TextureType::Texture2DNoMipmap: -        return Shader::TextureType::Color2D; +        if (entry.normalized_coords) { +            return Shader::TextureType::Color2D; +        } else { +            return Shader::TextureType::Color2DRect; +        }      case Tegra::Texture::TextureType::Texture3D:          return Shader::TextureType::Color3D;      case Tegra::Texture::TextureType::TextureCubemap: @@ -53,7 +57,8 @@ static Shader::TextureType ConvertType(const Tegra::Texture::TICEntry& entry) {      case Tegra::Texture::TextureType::TextureCubeArray:          return Shader::TextureType::ColorArrayCube;      default: -        throw Shader::NotImplementedException("Unknown texture type"); +        UNIMPLEMENTED(); +        return Shader::TextureType::Color2D;      }  } | 
