video_code: support rectangle texture
This commit is contained in:
		| @@ -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"; | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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"; | ||||
|   | ||||
| @@ -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: | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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}; | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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: { | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user