diff options
Diffstat (limited to 'src/video_core')
3 files changed, 159 insertions, 71 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 05f153599..ac4db82cf 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -94,11 +94,11 @@ struct FormatTuple { static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // ABGR8U {GL_RGBA8, GL_RGBA, GL_BYTE, ComponentType::SNorm, false}, // ABGR8S - {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, ComponentType::UNorm, false}, // B5G6R5 + {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, ComponentType::UNorm, false}, // B5G6R5U {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, ComponentType::UNorm, - false}, // A2B10G10R10 - {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, ComponentType::UNorm, false}, // A1B5G5R5 - {GL_R8, GL_RED, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // R8 + false}, // A2B10G10R10U + {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, ComponentType::UNorm, false}, // A1B5G5R5U + {GL_R8, GL_RED, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // R8U {GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, ComponentType::UInt, false}, // R8UI {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, ComponentType::Float, false}, // RGBA16F {GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, ComponentType::UNorm, false}, // RGBA16U @@ -126,7 +126,7 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form {GL_RG32F, GL_RG, GL_FLOAT, ComponentType::Float, false}, // RG32F {GL_R32F, GL_RED, GL_FLOAT, ComponentType::Float, false}, // R32F {GL_R16F, GL_RED, GL_HALF_FLOAT, ComponentType::Float, false}, // R16F - {GL_R16, GL_RED, GL_UNSIGNED_SHORT, ComponentType::UNorm, false}, // R16UNORM + {GL_R16, GL_RED, GL_UNSIGNED_SHORT, ComponentType::UNorm, false}, // R16U {GL_R16_SNORM, GL_RED, GL_SHORT, ComponentType::SNorm, false}, // R16S {GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // R16UI {GL_R16I, GL_RED_INTEGER, GL_SHORT, ComponentType::SInt, false}, // R16I @@ -142,14 +142,16 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form {GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // RG32UI {GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // R32UI + // Depth formats + {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, ComponentType::Float, false}, // Z32F + {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, ComponentType::UNorm, + false}, // Z16 + // DepthStencil formats {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, ComponentType::UNorm, false}, // Z24S8 {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, ComponentType::UNorm, - false}, // S8Z24 - {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, ComponentType::Float, false}, // Z32F - {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, ComponentType::UNorm, - false}, // Z16 + false}, // S8Z24 {GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, ComponentType::Float, false}, // Z32FS8 }}; @@ -243,10 +245,10 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU // clang-format off MortonCopy<true, PixelFormat::ABGR8U>, MortonCopy<true, PixelFormat::ABGR8S>, - MortonCopy<true, PixelFormat::B5G6R5>, - MortonCopy<true, PixelFormat::A2B10G10R10>, - MortonCopy<true, PixelFormat::A1B5G5R5>, - MortonCopy<true, PixelFormat::R8>, + MortonCopy<true, PixelFormat::B5G6R5U>, + MortonCopy<true, PixelFormat::A2B10G10R10U>, + MortonCopy<true, PixelFormat::A1B5G5R5U>, + MortonCopy<true, PixelFormat::R8U>, MortonCopy<true, PixelFormat::R8UI>, MortonCopy<true, PixelFormat::RGBA16F>, MortonCopy<true, PixelFormat::RGBA16U>, @@ -268,7 +270,7 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU MortonCopy<true, PixelFormat::RG32F>, MortonCopy<true, PixelFormat::R32F>, MortonCopy<true, PixelFormat::R16F>, - MortonCopy<true, PixelFormat::R16UNORM>, + MortonCopy<true, PixelFormat::R16U>, MortonCopy<true, PixelFormat::R16S>, MortonCopy<true, PixelFormat::R16UI>, MortonCopy<true, PixelFormat::R16I>, @@ -283,10 +285,10 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU MortonCopy<true, PixelFormat::RG8S>, MortonCopy<true, PixelFormat::RG32UI>, MortonCopy<true, PixelFormat::R32UI>, - MortonCopy<true, PixelFormat::Z24S8>, - MortonCopy<true, PixelFormat::S8Z24>, MortonCopy<true, PixelFormat::Z32F>, MortonCopy<true, PixelFormat::Z16>, + MortonCopy<true, PixelFormat::Z24S8>, + MortonCopy<true, PixelFormat::S8Z24>, MortonCopy<true, PixelFormat::Z32FS8>, // clang-format on }; @@ -297,10 +299,10 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU // clang-format off MortonCopy<false, PixelFormat::ABGR8U>, MortonCopy<false, PixelFormat::ABGR8S>, - MortonCopy<false, PixelFormat::B5G6R5>, - MortonCopy<false, PixelFormat::A2B10G10R10>, - MortonCopy<false, PixelFormat::A1B5G5R5>, - MortonCopy<false, PixelFormat::R8>, + MortonCopy<false, PixelFormat::B5G6R5U>, + MortonCopy<false, PixelFormat::A2B10G10R10U>, + MortonCopy<false, PixelFormat::A1B5G5R5U>, + MortonCopy<false, PixelFormat::R8U>, MortonCopy<false, PixelFormat::R8UI>, MortonCopy<false, PixelFormat::RGBA16F>, MortonCopy<false, PixelFormat::RGBA16U>, @@ -324,7 +326,7 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU MortonCopy<false, PixelFormat::RG32F>, MortonCopy<false, PixelFormat::R32F>, MortonCopy<false, PixelFormat::R16F>, - MortonCopy<false, PixelFormat::R16UNORM>, + MortonCopy<false, PixelFormat::R16U>, MortonCopy<false, PixelFormat::R16S>, MortonCopy<false, PixelFormat::R16UI>, MortonCopy<false, PixelFormat::R16I>, @@ -339,10 +341,10 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU MortonCopy<false, PixelFormat::RG8S>, MortonCopy<false, PixelFormat::RG32UI>, MortonCopy<false, PixelFormat::R32UI>, - MortonCopy<false, PixelFormat::Z24S8>, - MortonCopy<false, PixelFormat::S8Z24>, MortonCopy<false, PixelFormat::Z32F>, MortonCopy<false, PixelFormat::Z16>, + MortonCopy<false, PixelFormat::Z24S8>, + MortonCopy<false, PixelFormat::S8Z24>, MortonCopy<false, PixelFormat::Z32FS8>, // clang-format on }; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 37eef5ad0..beec01746 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -25,10 +25,10 @@ struct SurfaceParams { enum class PixelFormat { ABGR8U = 0, ABGR8S = 1, - B5G6R5 = 2, - A2B10G10R10 = 3, - A1B5G5R5 = 4, - R8 = 5, + B5G6R5U = 2, + A2B10G10R10U = 3, + A1B5G5R5U = 4, + R8U = 5, R8UI = 6, RGBA16F = 7, RGBA16U = 8, @@ -50,7 +50,7 @@ struct SurfaceParams { RG32F = 24, R32F = 25, R16F = 26, - R16UNORM = 27, + R16U = 27, R16S = 28, R16UI = 29, R16I = 30, @@ -68,11 +68,15 @@ struct SurfaceParams { MaxColorFormat, + // Depth formats + Z32F = 42, + Z16 = 43, + + MaxDepthFormat, + // DepthStencil formats - Z24S8 = 42, - S8Z24 = 43, - Z32F = 44, - Z16 = 45, + Z24S8 = 44, + S8Z24 = 45, Z32FS8 = 46, MaxDepthStencilFormat, @@ -113,10 +117,10 @@ struct SurfaceParams { constexpr std::array<u32, MaxPixelFormat> compression_factor_table = {{ 1, // ABGR8U 1, // ABGR8S - 1, // B5G6R5 - 1, // A2B10G10R10 - 1, // A1B5G5R5 - 1, // R8 + 1, // B5G6R5U + 1, // A2B10G10R10U + 1, // A1B5G5R5U + 1, // R8U 1, // R8UI 1, // RGBA16F 1, // RGBA16U @@ -138,7 +142,7 @@ struct SurfaceParams { 1, // RG32F 1, // R32F 1, // R16F - 1, // R16UNORM + 1, // R16U 1, // R16S 1, // R16UI 1, // R16I @@ -153,10 +157,10 @@ struct SurfaceParams { 1, // RG8S 1, // RG32UI 1, // R32UI - 1, // Z24S8 - 1, // S8Z24 1, // Z32F 1, // Z16 + 1, // Z24S8 + 1, // S8Z24 1, // Z32FS8 }}; @@ -171,10 +175,10 @@ struct SurfaceParams { constexpr std::array<u32, MaxPixelFormat> bpp_table = {{ 32, // ABGR8U 32, // ABGR8S - 16, // B5G6R5 - 32, // A2B10G10R10 - 16, // A1B5G5R5 - 8, // R8 + 16, // B5G6R5U + 32, // A2B10G10R10U + 16, // A1B5G5R5U + 8, // R8U 8, // R8UI 64, // RGBA16F 64, // RGBA16U @@ -196,7 +200,7 @@ struct SurfaceParams { 64, // RG32F 32, // R32F 16, // R16F - 16, // R16UNORM + 16, // R16U 16, // R16S 16, // R16UI 16, // R16I @@ -211,10 +215,10 @@ struct SurfaceParams { 16, // RG8S 64, // RG32UI 32, // R32UI - 32, // Z24S8 - 32, // S8Z24 32, // Z32F 16, // Z16 + 32, // Z24S8 + 32, // S8Z24 64, // Z32FS8 }}; @@ -256,7 +260,7 @@ struct SurfaceParams { case Tegra::RenderTargetFormat::BGRA8_UNORM: return PixelFormat::BGRA8; case Tegra::RenderTargetFormat::RGB10_A2_UNORM: - return PixelFormat::A2B10G10R10; + return PixelFormat::A2B10G10R10U; case Tegra::RenderTargetFormat::RGBA16_FLOAT: return PixelFormat::RGBA16F; case Tegra::RenderTargetFormat::RGBA16_UNORM: @@ -270,11 +274,11 @@ struct SurfaceParams { case Tegra::RenderTargetFormat::R11G11B10_FLOAT: return PixelFormat::R11FG11FB10F; case Tegra::RenderTargetFormat::B5G6R5_UNORM: - return PixelFormat::B5G6R5; + return PixelFormat::B5G6R5U; case Tegra::RenderTargetFormat::RGBA32_UINT: return PixelFormat::RGBA32UI; case Tegra::RenderTargetFormat::R8_UNORM: - return PixelFormat::R8; + return PixelFormat::R8U; case Tegra::RenderTargetFormat::R8_UINT: return PixelFormat::R8UI; case Tegra::RenderTargetFormat::RG16_FLOAT: @@ -294,7 +298,7 @@ struct SurfaceParams { case Tegra::RenderTargetFormat::R16_FLOAT: return PixelFormat::R16F; case Tegra::RenderTargetFormat::R16_UNORM: - return PixelFormat::R16UNORM; + return PixelFormat::R16U; case Tegra::RenderTargetFormat::R16_SNORM: return PixelFormat::R16S; case Tegra::RenderTargetFormat::R16_UINT: @@ -328,15 +332,33 @@ struct SurfaceParams { static_cast<u32>(component_type)); UNREACHABLE(); case Tegra::Texture::TextureFormat::B5G6R5: - return PixelFormat::B5G6R5; + switch (component_type) { + case Tegra::Texture::ComponentType::UNORM: + return PixelFormat::B5G6R5U; + } + LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", + static_cast<u32>(component_type)); + UNREACHABLE(); case Tegra::Texture::TextureFormat::A2B10G10R10: - return PixelFormat::A2B10G10R10; + switch (component_type) { + case Tegra::Texture::ComponentType::UNORM: + return PixelFormat::A2B10G10R10U; + } + LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", + static_cast<u32>(component_type)); + UNREACHABLE(); case Tegra::Texture::TextureFormat::A1B5G5R5: - return PixelFormat::A1B5G5R5; + switch (component_type) { + case Tegra::Texture::ComponentType::UNORM: + return PixelFormat::A1B5G5R5U; + } + LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", + static_cast<u32>(component_type)); + UNREACHABLE(); case Tegra::Texture::TextureFormat::R8: switch (component_type) { case Tegra::Texture::ComponentType::UNORM: - return PixelFormat::R8; + return PixelFormat::R8U; case Tegra::Texture::ComponentType::UINT: return PixelFormat::R8UI; } @@ -354,9 +376,23 @@ struct SurfaceParams { static_cast<u32>(component_type)); UNREACHABLE(); case Tegra::Texture::TextureFormat::R16_G16_B16_A16: - return PixelFormat::RGBA16F; + switch (component_type) { + case Tegra::Texture::ComponentType::UNORM: + return PixelFormat::RGBA16U; + case Tegra::Texture::ComponentType::FLOAT: + return PixelFormat::RGBA16F; + } + LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", + static_cast<u32>(component_type)); + UNREACHABLE(); case Tegra::Texture::TextureFormat::BF10GF11RF11: - return PixelFormat::R11FG11FB10F; + switch (component_type) { + case Tegra::Texture::ComponentType::FLOAT: + return PixelFormat::R11FG11FB10F; + } + LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", + static_cast<u32>(component_type)); + UNREACHABLE(); case Tegra::Texture::TextureFormat::R32_G32_B32_A32: switch (component_type) { case Tegra::Texture::ComponentType::FLOAT: @@ -378,13 +414,19 @@ struct SurfaceParams { static_cast<u32>(component_type)); UNREACHABLE(); case Tegra::Texture::TextureFormat::R32_G32_B32: - return PixelFormat::RGB32F; + switch (component_type) { + case Tegra::Texture::ComponentType::FLOAT: + return PixelFormat::RGB32F; + } + LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", + static_cast<u32>(component_type)); + UNREACHABLE(); case Tegra::Texture::TextureFormat::R16: switch (component_type) { case Tegra::Texture::ComponentType::FLOAT: return PixelFormat::R16F; case Tegra::Texture::ComponentType::UNORM: - return PixelFormat::R16UNORM; + return PixelFormat::R16U; case Tegra::Texture::ComponentType::SNORM: return PixelFormat::R16S; case Tegra::Texture::ComponentType::UINT: @@ -549,6 +591,10 @@ struct SurfaceParams { return SurfaceType::ColorTexture; } + if (static_cast<size_t>(pixel_format) < static_cast<size_t>(PixelFormat::MaxDepthFormat)) { + return SurfaceType::Depth; + } + if (static_cast<size_t>(pixel_format) < static_cast<size_t>(PixelFormat::MaxDepthStencilFormat)) { return SurfaceType::DepthStencil; diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 5a05c79ef..07006b55e 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -367,20 +367,23 @@ public: } /// Generates code representing a uniform (C buffer) register, interpreted as the input type. - std::string GetUniform(u64 index, u64 offset, GLSLRegister::Type type) { + std::string GetUniform(u64 index, u64 offset, GLSLRegister::Type type, + Register::Size size = Register::Size::Word) { declr_const_buffers[index].MarkAsUsed(index, offset, stage); std::string value = 'c' + std::to_string(index) + '[' + std::to_string(offset / 4) + "][" + std::to_string(offset % 4) + ']'; if (type == GLSLRegister::Type::Float) { - return value; + // Do nothing, default } else if (type == GLSLRegister::Type::Integer) { - return "floatBitsToInt(" + value + ')'; + value = "floatBitsToInt(" + value + ')'; } else if (type == GLSLRegister::Type::UnsignedInteger) { - return "floatBitsToUint(" + value + ')'; + value = "floatBitsToUint(" + value + ')'; } else { UNREACHABLE(); } + + return ConvertIntegerSize(value, size); } std::string GetUniformIndirect(u64 cbuf_index, s64 offset, const std::string& index_str, @@ -1247,20 +1250,41 @@ private: op_a = "abs(" + op_a + ')'; } + if (instr.conversion.negate_a) { + op_a = "-(" + op_a + ')'; + } + regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_output_signed, 0, op_a, 1, 1, instr.alu.saturate_d, 0, instr.conversion.dest_size); break; } - case OpCode::Id::I2F_R: { + case OpCode::Id::I2F_R: + case OpCode::Id::I2F_C: { ASSERT_MSG(instr.conversion.dest_size == Register::Size::Word, "Unimplemented"); ASSERT_MSG(!instr.conversion.selector, "Unimplemented"); - std::string op_a = regs.GetRegisterAsInteger( - instr.gpr20, 0, instr.conversion.is_input_signed, instr.conversion.src_size); + + std::string op_a{}; + + if (instr.is_b_gpr) { + op_a = + regs.GetRegisterAsInteger(instr.gpr20, 0, instr.conversion.is_input_signed, + instr.conversion.src_size); + } else { + op_a = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, + instr.conversion.is_input_signed + ? GLSLRegister::Type::Integer + : GLSLRegister::Type::UnsignedInteger, + instr.conversion.src_size); + } if (instr.conversion.abs_a) { op_a = "abs(" + op_a + ')'; } + if (instr.conversion.negate_a) { + op_a = "-(" + op_a + ')'; + } + regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); break; } @@ -1269,6 +1293,14 @@ private: ASSERT_MSG(instr.conversion.src_size == Register::Size::Word, "Unimplemented"); std::string op_a = regs.GetRegisterAsFloat(instr.gpr20); + if (instr.conversion.abs_a) { + op_a = "abs(" + op_a + ')'; + } + + if (instr.conversion.negate_a) { + op_a = "-(" + op_a + ')'; + } + switch (instr.conversion.f2f.rounding) { case Tegra::Shader::F2fRoundingOp::None: break; @@ -1291,21 +1323,29 @@ private: break; } - if (instr.conversion.abs_a) { - op_a = "abs(" + op_a + ')'; - } - regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1, instr.alu.saturate_d); break; } - case OpCode::Id::F2I_R: { + case OpCode::Id::F2I_R: + case OpCode::Id::F2I_C: { ASSERT_MSG(instr.conversion.src_size == Register::Size::Word, "Unimplemented"); - std::string op_a = regs.GetRegisterAsFloat(instr.gpr20); + std::string op_a{}; + + if (instr.is_b_gpr) { + op_a = regs.GetRegisterAsFloat(instr.gpr20); + } else { + op_a = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, + GLSLRegister::Type::Float); + } if (instr.conversion.abs_a) { op_a = "abs(" + op_a + ')'; } + if (instr.conversion.negate_a) { + op_a = "-(" + op_a + ')'; + } + switch (instr.conversion.f2i.rounding) { case Tegra::Shader::F2iRoundingOp::None: break; |