diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 7 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 13 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 91 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 80 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.cpp | 13 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.h | 14 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 14 | ||||
| -rw-r--r-- | src/video_core/textures/texture.h | 5 |
8 files changed, 197 insertions, 40 deletions
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index d6978162a..443affc36 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -723,7 +723,11 @@ public: | |||
| 723 | StencilOp stencil_back_op_zpass; | 723 | StencilOp stencil_back_op_zpass; |
| 724 | ComparisonOp stencil_back_func_func; | 724 | ComparisonOp stencil_back_func_func; |
| 725 | 725 | ||
| 726 | INSERT_PADDING_WORDS(0x17); | 726 | INSERT_PADDING_WORDS(0x4); |
| 727 | |||
| 728 | u32 framebuffer_srgb; | ||
| 729 | |||
| 730 | INSERT_PADDING_WORDS(0x12); | ||
| 727 | 731 | ||
| 728 | union { | 732 | union { |
| 729 | BitField<2, 1, u32> coord_origin; | 733 | BitField<2, 1, u32> coord_origin; |
| @@ -1086,6 +1090,7 @@ ASSERT_REG_POSITION(stencil_back_op_fail, 0x566); | |||
| 1086 | ASSERT_REG_POSITION(stencil_back_op_zfail, 0x567); | 1090 | ASSERT_REG_POSITION(stencil_back_op_zfail, 0x567); |
| 1087 | ASSERT_REG_POSITION(stencil_back_op_zpass, 0x568); | 1091 | ASSERT_REG_POSITION(stencil_back_op_zpass, 0x568); |
| 1088 | ASSERT_REG_POSITION(stencil_back_func_func, 0x569); | 1092 | ASSERT_REG_POSITION(stencil_back_func_func, 0x569); |
| 1093 | ASSERT_REG_POSITION(framebuffer_srgb, 0x56E); | ||
| 1089 | ASSERT_REG_POSITION(point_coord_replace, 0x581); | 1094 | ASSERT_REG_POSITION(point_coord_replace, 0x581); |
| 1090 | ASSERT_REG_POSITION(code_address, 0x582); | 1095 | ASSERT_REG_POSITION(code_address, 0x582); |
| 1091 | ASSERT_REG_POSITION(draw, 0x585); | 1096 | ASSERT_REG_POSITION(draw, 0x585); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index cd4216c4e..cb180b93c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -418,6 +418,7 @@ void RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, bool using_dep | |||
| 418 | // Bind the framebuffer surfaces | 418 | // Bind the framebuffer surfaces |
| 419 | state.draw.draw_framebuffer = framebuffer.handle; | 419 | state.draw.draw_framebuffer = framebuffer.handle; |
| 420 | state.Apply(); | 420 | state.Apply(); |
| 421 | state.framebuffer_srgb.enabled = regs.framebuffer_srgb != 0; | ||
| 421 | 422 | ||
| 422 | if (using_color_fb) { | 423 | if (using_color_fb) { |
| 423 | if (single_color_target) { | 424 | if (single_color_target) { |
| @@ -429,6 +430,9 @@ void RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, bool using_dep | |||
| 429 | // Assume that a surface will be written to if it is used as a framebuffer, even if | 430 | // Assume that a surface will be written to if it is used as a framebuffer, even if |
| 430 | // the shader doesn't actually write to it. | 431 | // the shader doesn't actually write to it. |
| 431 | color_surface->MarkAsModified(true, res_cache); | 432 | color_surface->MarkAsModified(true, res_cache); |
| 433 | // Workaround for and issue in nvidia drivers | ||
| 434 | // https://devtalk.nvidia.com/default/topic/776591/opengl/gl_framebuffer_srgb-functions-incorrectly/ | ||
| 435 | state.framebuffer_srgb.enabled |= color_surface->GetSurfaceParams().srgb_conversion; | ||
| 432 | } | 436 | } |
| 433 | 437 | ||
| 434 | glFramebufferTexture2D( | 438 | glFramebufferTexture2D( |
| @@ -446,6 +450,11 @@ void RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, bool using_dep | |||
| 446 | // Assume that a surface will be written to if it is used as a framebuffer, even | 450 | // Assume that a surface will be written to if it is used as a framebuffer, even |
| 447 | // if the shader doesn't actually write to it. | 451 | // if the shader doesn't actually write to it. |
| 448 | color_surface->MarkAsModified(true, res_cache); | 452 | color_surface->MarkAsModified(true, res_cache); |
| 453 | // Enable sRGB only for supported formats | ||
| 454 | // Workaround for and issue in nvidia drivers | ||
| 455 | // https://devtalk.nvidia.com/default/topic/776591/opengl/gl_framebuffer_srgb-functions-incorrectly/ | ||
| 456 | state.framebuffer_srgb.enabled |= | ||
| 457 | color_surface->GetSurfaceParams().srgb_conversion; | ||
| 449 | } | 458 | } |
| 450 | 459 | ||
| 451 | buffers[index] = GL_COLOR_ATTACHMENT0 + regs.rt_control.GetMap(index); | 460 | buffers[index] = GL_COLOR_ATTACHMENT0 + regs.rt_control.GetMap(index); |
| @@ -537,7 +546,9 @@ void RasterizerOpenGL::Clear() { | |||
| 537 | 546 | ||
| 538 | ConfigureFramebuffers(use_color, use_depth || use_stencil, false, | 547 | ConfigureFramebuffers(use_color, use_depth || use_stencil, false, |
| 539 | regs.clear_buffers.RT.Value()); | 548 | regs.clear_buffers.RT.Value()); |
| 540 | 549 | // Copy the sRGB setting to the clear state to avoid problem with | |
| 550 | // specific driver implementations | ||
| 551 | clear_state.framebuffer_srgb.enabled = state.framebuffer_srgb.enabled; | ||
| 541 | clear_state.Apply(); | 552 | clear_state.Apply(); |
| 542 | 553 | ||
| 543 | if (use_color) { | 554 | if (use_color) { |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 04a024137..b057e2efa 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -40,6 +40,10 @@ static bool IsPixelFormatASTC(PixelFormat format) { | |||
| 40 | case PixelFormat::ASTC_2D_5X4: | 40 | case PixelFormat::ASTC_2D_5X4: |
| 41 | case PixelFormat::ASTC_2D_8X8: | 41 | case PixelFormat::ASTC_2D_8X8: |
| 42 | case PixelFormat::ASTC_2D_8X5: | 42 | case PixelFormat::ASTC_2D_8X5: |
| 43 | case PixelFormat::ASTC_2D_4X4_SRGB: | ||
| 44 | case PixelFormat::ASTC_2D_5X4_SRGB: | ||
| 45 | case PixelFormat::ASTC_2D_8X8_SRGB: | ||
| 46 | case PixelFormat::ASTC_2D_8X5_SRGB: | ||
| 43 | return true; | 47 | return true; |
| 44 | default: | 48 | default: |
| 45 | return false; | 49 | return false; |
| @@ -56,6 +60,14 @@ static std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) { | |||
| 56 | return {8, 8}; | 60 | return {8, 8}; |
| 57 | case PixelFormat::ASTC_2D_8X5: | 61 | case PixelFormat::ASTC_2D_8X5: |
| 58 | return {8, 5}; | 62 | return {8, 5}; |
| 63 | case PixelFormat::ASTC_2D_4X4_SRGB: | ||
| 64 | return {4, 4}; | ||
| 65 | case PixelFormat::ASTC_2D_5X4_SRGB: | ||
| 66 | return {5, 4}; | ||
| 67 | case PixelFormat::ASTC_2D_8X8_SRGB: | ||
| 68 | return {8, 8}; | ||
| 69 | case PixelFormat::ASTC_2D_8X5_SRGB: | ||
| 70 | return {8, 5}; | ||
| 59 | default: | 71 | default: |
| 60 | LOG_CRITICAL(HW_GPU, "Unhandled format: {}", static_cast<u32>(format)); | 72 | LOG_CRITICAL(HW_GPU, "Unhandled format: {}", static_cast<u32>(format)); |
| 61 | UNREACHABLE(); | 73 | UNREACHABLE(); |
| @@ -108,8 +120,9 @@ std::size_t SurfaceParams::InnerMemorySize(bool layer_only) const { | |||
| 108 | params.block_width = params.is_tiled ? config.tic.BlockWidth() : 0, | 120 | params.block_width = params.is_tiled ? config.tic.BlockWidth() : 0, |
| 109 | params.block_height = params.is_tiled ? config.tic.BlockHeight() : 0, | 121 | params.block_height = params.is_tiled ? config.tic.BlockHeight() : 0, |
| 110 | params.block_depth = params.is_tiled ? config.tic.BlockDepth() : 0, | 122 | params.block_depth = params.is_tiled ? config.tic.BlockDepth() : 0, |
| 111 | params.pixel_format = | 123 | params.srgb_conversion = config.tic.IsSrgbConversionEnabled(); |
| 112 | PixelFormatFromTextureFormat(config.tic.format, config.tic.r_type.Value()); | 124 | params.pixel_format = PixelFormatFromTextureFormat(config.tic.format, config.tic.r_type.Value(), |
| 125 | params.srgb_conversion); | ||
| 113 | params.component_type = ComponentTypeFromTexture(config.tic.r_type.Value()); | 126 | params.component_type = ComponentTypeFromTexture(config.tic.r_type.Value()); |
| 114 | params.type = GetFormatType(params.pixel_format); | 127 | params.type = GetFormatType(params.pixel_format); |
| 115 | params.width = Common::AlignUp(config.tic.Width(), GetCompressionFactor(params.pixel_format)); | 128 | params.width = Common::AlignUp(config.tic.Width(), GetCompressionFactor(params.pixel_format)); |
| @@ -166,6 +179,8 @@ std::size_t SurfaceParams::InnerMemorySize(bool layer_only) const { | |||
| 166 | params.block_height = 1 << config.memory_layout.block_height; | 179 | params.block_height = 1 << config.memory_layout.block_height; |
| 167 | params.block_depth = 1 << config.memory_layout.block_depth; | 180 | params.block_depth = 1 << config.memory_layout.block_depth; |
| 168 | params.pixel_format = PixelFormatFromRenderTargetFormat(config.format); | 181 | params.pixel_format = PixelFormatFromRenderTargetFormat(config.format); |
| 182 | params.srgb_conversion = config.format == Tegra::RenderTargetFormat::BGRA8_SRGB || | ||
| 183 | config.format == Tegra::RenderTargetFormat::RGBA8_SRGB; | ||
| 169 | params.component_type = ComponentTypeFromRenderTarget(config.format); | 184 | params.component_type = ComponentTypeFromRenderTarget(config.format); |
| 170 | params.type = GetFormatType(params.pixel_format); | 185 | params.type = GetFormatType(params.pixel_format); |
| 171 | params.width = config.width; | 186 | params.width = config.width; |
| @@ -201,6 +216,7 @@ std::size_t SurfaceParams::InnerMemorySize(bool layer_only) const { | |||
| 201 | params.pixel_format = PixelFormatFromDepthFormat(format); | 216 | params.pixel_format = PixelFormatFromDepthFormat(format); |
| 202 | params.component_type = ComponentTypeFromDepthFormat(format); | 217 | params.component_type = ComponentTypeFromDepthFormat(format); |
| 203 | params.type = GetFormatType(params.pixel_format); | 218 | params.type = GetFormatType(params.pixel_format); |
| 219 | params.srgb_conversion = false; | ||
| 204 | params.width = zeta_width; | 220 | params.width = zeta_width; |
| 205 | params.height = zeta_height; | 221 | params.height = zeta_height; |
| 206 | params.unaligned_height = zeta_height; | 222 | params.unaligned_height = zeta_height; |
| @@ -224,6 +240,8 @@ std::size_t SurfaceParams::InnerMemorySize(bool layer_only) const { | |||
| 224 | params.block_height = params.is_tiled ? std::min(config.BlockHeight(), 32U) : 0, | 240 | params.block_height = params.is_tiled ? std::min(config.BlockHeight(), 32U) : 0, |
| 225 | params.block_depth = params.is_tiled ? std::min(config.BlockDepth(), 32U) : 0, | 241 | params.block_depth = params.is_tiled ? std::min(config.BlockDepth(), 32U) : 0, |
| 226 | params.pixel_format = PixelFormatFromRenderTargetFormat(config.format); | 242 | params.pixel_format = PixelFormatFromRenderTargetFormat(config.format); |
| 243 | params.srgb_conversion = config.format == Tegra::RenderTargetFormat::BGRA8_SRGB || | ||
| 244 | config.format == Tegra::RenderTargetFormat::RGBA8_SRGB; | ||
| 227 | params.component_type = ComponentTypeFromRenderTarget(config.format); | 245 | params.component_type = ComponentTypeFromRenderTarget(config.format); |
| 228 | params.type = GetFormatType(params.pixel_format); | 246 | params.type = GetFormatType(params.pixel_format); |
| 229 | params.width = config.width; | 247 | params.width = config.width; |
| @@ -289,14 +307,29 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form | |||
| 289 | {GL_RG16I, GL_RG_INTEGER, GL_SHORT, ComponentType::SInt, false}, // RG16I | 307 | {GL_RG16I, GL_RG_INTEGER, GL_SHORT, ComponentType::SInt, false}, // RG16I |
| 290 | {GL_RG16_SNORM, GL_RG, GL_SHORT, ComponentType::SNorm, false}, // RG16S | 308 | {GL_RG16_SNORM, GL_RG, GL_SHORT, ComponentType::SNorm, false}, // RG16S |
| 291 | {GL_RGB32F, GL_RGB, GL_FLOAT, ComponentType::Float, false}, // RGB32F | 309 | {GL_RGB32F, GL_RGB, GL_FLOAT, ComponentType::Float, false}, // RGB32F |
| 292 | {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // SRGBA8 | 310 | {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, |
| 293 | {GL_RG8, GL_RG, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // RG8U | 311 | false}, // RGBA8_SRGB |
| 294 | {GL_RG8, GL_RG, GL_BYTE, ComponentType::SNorm, false}, // RG8S | 312 | {GL_RG8, GL_RG, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // RG8U |
| 295 | {GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // RG32UI | 313 | {GL_RG8, GL_RG, GL_BYTE, ComponentType::SNorm, false}, // RG8S |
| 296 | {GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // R32UI | 314 | {GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // RG32UI |
| 297 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_8X8 | 315 | {GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // R32UI |
| 298 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_8X5 | 316 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_8X8 |
| 299 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_5X4 | 317 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_8X5 |
| 318 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_5X4 | ||
| 319 | {GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // BGRA8 | ||
| 320 | // Compressed sRGB formats | ||
| 321 | {GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, | ||
| 322 | true}, // DXT1_SRGB | ||
| 323 | {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, | ||
| 324 | true}, // DXT23_SRGB | ||
| 325 | {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, | ||
| 326 | true}, // DXT45_SRGB | ||
| 327 | {GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, | ||
| 328 | ComponentType::UNorm, true}, // BC7U_SRGB | ||
| 329 | {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_4X4_SRGB | ||
| 330 | {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_8X8_SRGB | ||
| 331 | {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_8X5_SRGB | ||
| 332 | {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_5X4_SRGB | ||
| 300 | 333 | ||
| 301 | // Depth formats | 334 | // Depth formats |
| 302 | {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, ComponentType::Float, false}, // Z32F | 335 | {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, ComponentType::Float, false}, // Z32F |
| @@ -361,6 +394,10 @@ static bool IsFormatBCn(PixelFormat format) { | |||
| 361 | case PixelFormat::BC7U: | 394 | case PixelFormat::BC7U: |
| 362 | case PixelFormat::BC6H_UF16: | 395 | case PixelFormat::BC6H_UF16: |
| 363 | case PixelFormat::BC6H_SF16: | 396 | case PixelFormat::BC6H_SF16: |
| 397 | case PixelFormat::DXT1_SRGB: | ||
| 398 | case PixelFormat::DXT23_SRGB: | ||
| 399 | case PixelFormat::DXT45_SRGB: | ||
| 400 | case PixelFormat::BC7U_SRGB: | ||
| 364 | return true; | 401 | return true; |
| 365 | } | 402 | } |
| 366 | return false; | 403 | return false; |
| @@ -432,7 +469,7 @@ static constexpr GLConversionArray morton_to_gl_fns = { | |||
| 432 | MortonCopy<true, PixelFormat::RG16I>, | 469 | MortonCopy<true, PixelFormat::RG16I>, |
| 433 | MortonCopy<true, PixelFormat::RG16S>, | 470 | MortonCopy<true, PixelFormat::RG16S>, |
| 434 | MortonCopy<true, PixelFormat::RGB32F>, | 471 | MortonCopy<true, PixelFormat::RGB32F>, |
| 435 | MortonCopy<true, PixelFormat::SRGBA8>, | 472 | MortonCopy<true, PixelFormat::RGBA8_SRGB>, |
| 436 | MortonCopy<true, PixelFormat::RG8U>, | 473 | MortonCopy<true, PixelFormat::RG8U>, |
| 437 | MortonCopy<true, PixelFormat::RG8S>, | 474 | MortonCopy<true, PixelFormat::RG8S>, |
| 438 | MortonCopy<true, PixelFormat::RG32UI>, | 475 | MortonCopy<true, PixelFormat::RG32UI>, |
| @@ -440,6 +477,15 @@ static constexpr GLConversionArray morton_to_gl_fns = { | |||
| 440 | MortonCopy<true, PixelFormat::ASTC_2D_8X8>, | 477 | MortonCopy<true, PixelFormat::ASTC_2D_8X8>, |
| 441 | MortonCopy<true, PixelFormat::ASTC_2D_8X5>, | 478 | MortonCopy<true, PixelFormat::ASTC_2D_8X5>, |
| 442 | MortonCopy<true, PixelFormat::ASTC_2D_5X4>, | 479 | MortonCopy<true, PixelFormat::ASTC_2D_5X4>, |
| 480 | MortonCopy<true, PixelFormat::BGRA8_SRGB>, | ||
| 481 | MortonCopy<true, PixelFormat::DXT1_SRGB>, | ||
| 482 | MortonCopy<true, PixelFormat::DXT23_SRGB>, | ||
| 483 | MortonCopy<true, PixelFormat::DXT45_SRGB>, | ||
| 484 | MortonCopy<true, PixelFormat::BC7U_SRGB>, | ||
| 485 | MortonCopy<true, PixelFormat::ASTC_2D_4X4_SRGB>, | ||
| 486 | MortonCopy<true, PixelFormat::ASTC_2D_8X8_SRGB>, | ||
| 487 | MortonCopy<true, PixelFormat::ASTC_2D_8X5_SRGB>, | ||
| 488 | MortonCopy<true, PixelFormat::ASTC_2D_5X4_SRGB>, | ||
| 443 | MortonCopy<true, PixelFormat::Z32F>, | 489 | MortonCopy<true, PixelFormat::Z32F>, |
| 444 | MortonCopy<true, PixelFormat::Z16>, | 490 | MortonCopy<true, PixelFormat::Z16>, |
| 445 | MortonCopy<true, PixelFormat::Z24S8>, | 491 | MortonCopy<true, PixelFormat::Z24S8>, |
| @@ -491,7 +537,7 @@ static constexpr GLConversionArray gl_to_morton_fns = { | |||
| 491 | MortonCopy<false, PixelFormat::RG16I>, | 537 | MortonCopy<false, PixelFormat::RG16I>, |
| 492 | MortonCopy<false, PixelFormat::RG16S>, | 538 | MortonCopy<false, PixelFormat::RG16S>, |
| 493 | MortonCopy<false, PixelFormat::RGB32F>, | 539 | MortonCopy<false, PixelFormat::RGB32F>, |
| 494 | MortonCopy<false, PixelFormat::SRGBA8>, | 540 | MortonCopy<false, PixelFormat::RGBA8_SRGB>, |
| 495 | MortonCopy<false, PixelFormat::RG8U>, | 541 | MortonCopy<false, PixelFormat::RG8U>, |
| 496 | MortonCopy<false, PixelFormat::RG8S>, | 542 | MortonCopy<false, PixelFormat::RG8S>, |
| 497 | MortonCopy<false, PixelFormat::RG32UI>, | 543 | MortonCopy<false, PixelFormat::RG32UI>, |
| @@ -499,6 +545,15 @@ static constexpr GLConversionArray gl_to_morton_fns = { | |||
| 499 | nullptr, | 545 | nullptr, |
| 500 | nullptr, | 546 | nullptr, |
| 501 | nullptr, | 547 | nullptr, |
| 548 | MortonCopy<false, PixelFormat::BGRA8_SRGB>, | ||
| 549 | MortonCopy<false, PixelFormat::DXT1_SRGB>, | ||
| 550 | MortonCopy<false, PixelFormat::DXT23_SRGB>, | ||
| 551 | MortonCopy<false, PixelFormat::DXT45_SRGB>, | ||
| 552 | MortonCopy<false, PixelFormat::BC7U_SRGB>, | ||
| 553 | nullptr, | ||
| 554 | nullptr, | ||
| 555 | nullptr, | ||
| 556 | nullptr, | ||
| 502 | MortonCopy<false, PixelFormat::Z32F>, | 557 | MortonCopy<false, PixelFormat::Z32F>, |
| 503 | MortonCopy<false, PixelFormat::Z16>, | 558 | MortonCopy<false, PixelFormat::Z16>, |
| 504 | MortonCopy<false, PixelFormat::Z24S8>, | 559 | MortonCopy<false, PixelFormat::Z24S8>, |
| @@ -546,6 +601,8 @@ static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface, | |||
| 546 | OpenGLState state; | 601 | OpenGLState state; |
| 547 | state.draw.read_framebuffer = read_fb_handle; | 602 | state.draw.read_framebuffer = read_fb_handle; |
| 548 | state.draw.draw_framebuffer = draw_fb_handle; | 603 | state.draw.draw_framebuffer = draw_fb_handle; |
| 604 | // Set sRGB enabled if the destination surfaces need it | ||
| 605 | state.framebuffer_srgb.enabled = dst_params.srgb_conversion; | ||
| 549 | state.Apply(); | 606 | state.Apply(); |
| 550 | 607 | ||
| 551 | u32 buffers{}; | 608 | u32 buffers{}; |
| @@ -881,7 +938,11 @@ static void ConvertFormatAsNeeded_LoadGLBuffer(std::vector<u8>& data, PixelForma | |||
| 881 | case PixelFormat::ASTC_2D_4X4: | 938 | case PixelFormat::ASTC_2D_4X4: |
| 882 | case PixelFormat::ASTC_2D_8X8: | 939 | case PixelFormat::ASTC_2D_8X8: |
| 883 | case PixelFormat::ASTC_2D_8X5: | 940 | case PixelFormat::ASTC_2D_8X5: |
| 884 | case PixelFormat::ASTC_2D_5X4: { | 941 | case PixelFormat::ASTC_2D_5X4: |
| 942 | case PixelFormat::ASTC_2D_4X4_SRGB: | ||
| 943 | case PixelFormat::ASTC_2D_8X8_SRGB: | ||
| 944 | case PixelFormat::ASTC_2D_8X5_SRGB: | ||
| 945 | case PixelFormat::ASTC_2D_5X4_SRGB: { | ||
| 885 | // Convert ASTC pixel formats to RGBA8, as most desktop GPUs do not support ASTC. | 946 | // Convert ASTC pixel formats to RGBA8, as most desktop GPUs do not support ASTC. |
| 886 | u32 block_width{}; | 947 | u32 block_width{}; |
| 887 | u32 block_height{}; | 948 | u32 block_height{}; |
| @@ -913,7 +974,9 @@ static void ConvertFormatAsNeeded_FlushGLBuffer(std::vector<u8>& data, PixelForm | |||
| 913 | case PixelFormat::G8R8U: | 974 | case PixelFormat::G8R8U: |
| 914 | case PixelFormat::G8R8S: | 975 | case PixelFormat::G8R8S: |
| 915 | case PixelFormat::ASTC_2D_4X4: | 976 | case PixelFormat::ASTC_2D_4X4: |
| 916 | case PixelFormat::ASTC_2D_8X8: { | 977 | case PixelFormat::ASTC_2D_8X8: |
| 978 | case PixelFormat::ASTC_2D_4X4_SRGB: | ||
| 979 | case PixelFormat::ASTC_2D_8X8_SRGB: { | ||
| 917 | LOG_CRITICAL(HW_GPU, "Conversion of format {} after texture flushing is not implemented", | 980 | LOG_CRITICAL(HW_GPU, "Conversion of format {} after texture flushing is not implemented", |
| 918 | static_cast<u32>(pixel_format)); | 981 | static_cast<u32>(pixel_format)); |
| 919 | UNREACHABLE(); | 982 | UNREACHABLE(); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 181acfc68..b4701a616 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -69,7 +69,7 @@ struct SurfaceParams { | |||
| 69 | RG16I = 37, | 69 | RG16I = 37, |
| 70 | RG16S = 38, | 70 | RG16S = 38, |
| 71 | RGB32F = 39, | 71 | RGB32F = 39, |
| 72 | SRGBA8 = 40, | 72 | RGBA8_SRGB = 40, |
| 73 | RG8U = 41, | 73 | RG8U = 41, |
| 74 | RG8S = 42, | 74 | RG8S = 42, |
| 75 | RG32UI = 43, | 75 | RG32UI = 43, |
| @@ -77,19 +77,28 @@ struct SurfaceParams { | |||
| 77 | ASTC_2D_8X8 = 45, | 77 | ASTC_2D_8X8 = 45, |
| 78 | ASTC_2D_8X5 = 46, | 78 | ASTC_2D_8X5 = 46, |
| 79 | ASTC_2D_5X4 = 47, | 79 | ASTC_2D_5X4 = 47, |
| 80 | BGRA8_SRGB = 48, | ||
| 81 | DXT1_SRGB = 49, | ||
| 82 | DXT23_SRGB = 50, | ||
| 83 | DXT45_SRGB = 51, | ||
| 84 | BC7U_SRGB = 52, | ||
| 85 | ASTC_2D_4X4_SRGB = 53, | ||
| 86 | ASTC_2D_8X8_SRGB = 54, | ||
| 87 | ASTC_2D_8X5_SRGB = 55, | ||
| 88 | ASTC_2D_5X4_SRGB = 56, | ||
| 80 | 89 | ||
| 81 | MaxColorFormat, | 90 | MaxColorFormat, |
| 82 | 91 | ||
| 83 | // Depth formats | 92 | // Depth formats |
| 84 | Z32F = 48, | 93 | Z32F = 57, |
| 85 | Z16 = 49, | 94 | Z16 = 58, |
| 86 | 95 | ||
| 87 | MaxDepthFormat, | 96 | MaxDepthFormat, |
| 88 | 97 | ||
| 89 | // DepthStencil formats | 98 | // DepthStencil formats |
| 90 | Z24S8 = 50, | 99 | Z24S8 = 59, |
| 91 | S8Z24 = 51, | 100 | S8Z24 = 60, |
| 92 | Z32FS8 = 52, | 101 | Z32FS8 = 61, |
| 93 | 102 | ||
| 94 | MaxDepthStencilFormat, | 103 | MaxDepthStencilFormat, |
| 95 | 104 | ||
| @@ -236,7 +245,7 @@ struct SurfaceParams { | |||
| 236 | 1, // RG16I | 245 | 1, // RG16I |
| 237 | 1, // RG16S | 246 | 1, // RG16S |
| 238 | 1, // RGB32F | 247 | 1, // RGB32F |
| 239 | 1, // SRGBA8 | 248 | 1, // RGBA8_SRGB |
| 240 | 1, // RG8U | 249 | 1, // RG8U |
| 241 | 1, // RG8S | 250 | 1, // RG8S |
| 242 | 1, // RG32UI | 251 | 1, // RG32UI |
| @@ -244,6 +253,15 @@ struct SurfaceParams { | |||
| 244 | 4, // ASTC_2D_8X8 | 253 | 4, // ASTC_2D_8X8 |
| 245 | 4, // ASTC_2D_8X5 | 254 | 4, // ASTC_2D_8X5 |
| 246 | 4, // ASTC_2D_5X4 | 255 | 4, // ASTC_2D_5X4 |
| 256 | 1, // BGRA8_SRGB | ||
| 257 | 4, // DXT1_SRGB | ||
| 258 | 4, // DXT23_SRGB | ||
| 259 | 4, // DXT45_SRGB | ||
| 260 | 4, // BC7U_SRGB | ||
| 261 | 4, // ASTC_2D_4X4_SRGB | ||
| 262 | 4, // ASTC_2D_8X8_SRGB | ||
| 263 | 4, // ASTC_2D_8X5_SRGB | ||
| 264 | 4, // ASTC_2D_5X4_SRGB | ||
| 247 | 1, // Z32F | 265 | 1, // Z32F |
| 248 | 1, // Z16 | 266 | 1, // Z16 |
| 249 | 1, // Z24S8 | 267 | 1, // Z24S8 |
| @@ -299,7 +317,7 @@ struct SurfaceParams { | |||
| 299 | 1, // RG16I | 317 | 1, // RG16I |
| 300 | 1, // RG16S | 318 | 1, // RG16S |
| 301 | 1, // RGB32F | 319 | 1, // RGB32F |
| 302 | 1, // SRGBA8 | 320 | 1, // RGBA8_SRGB |
| 303 | 1, // RG8U | 321 | 1, // RG8U |
| 304 | 1, // RG8S | 322 | 1, // RG8S |
| 305 | 1, // RG32UI | 323 | 1, // RG32UI |
| @@ -307,6 +325,15 @@ struct SurfaceParams { | |||
| 307 | 8, // ASTC_2D_8X8 | 325 | 8, // ASTC_2D_8X8 |
| 308 | 5, // ASTC_2D_8X5 | 326 | 5, // ASTC_2D_8X5 |
| 309 | 4, // ASTC_2D_5X4 | 327 | 4, // ASTC_2D_5X4 |
| 328 | 1, // BGRA8_SRGB | ||
| 329 | 4, // DXT1_SRGB | ||
| 330 | 4, // DXT23_SRGB | ||
| 331 | 4, // DXT45_SRGB | ||
| 332 | 4, // BC7U_SRGB | ||
| 333 | 4, // ASTC_2D_4X4_SRGB | ||
| 334 | 8, // ASTC_2D_8X8_SRGB | ||
| 335 | 5, // ASTC_2D_8X5_SRGB | ||
| 336 | 4, // ASTC_2D_5X4_SRGB | ||
| 310 | 1, // Z32F | 337 | 1, // Z32F |
| 311 | 1, // Z16 | 338 | 1, // Z16 |
| 312 | 1, // Z24S8 | 339 | 1, // Z24S8 |
| @@ -362,7 +389,7 @@ struct SurfaceParams { | |||
| 362 | 32, // RG16I | 389 | 32, // RG16I |
| 363 | 32, // RG16S | 390 | 32, // RG16S |
| 364 | 96, // RGB32F | 391 | 96, // RGB32F |
| 365 | 32, // SRGBA8 | 392 | 32, // RGBA8_SRGB |
| 366 | 16, // RG8U | 393 | 16, // RG8U |
| 367 | 16, // RG8S | 394 | 16, // RG8S |
| 368 | 64, // RG32UI | 395 | 64, // RG32UI |
| @@ -370,6 +397,15 @@ struct SurfaceParams { | |||
| 370 | 16, // ASTC_2D_8X8 | 397 | 16, // ASTC_2D_8X8 |
| 371 | 32, // ASTC_2D_8X5 | 398 | 32, // ASTC_2D_8X5 |
| 372 | 32, // ASTC_2D_5X4 | 399 | 32, // ASTC_2D_5X4 |
| 400 | 32, // BGRA8_SRGB | ||
| 401 | 64, // DXT1_SRGB | ||
| 402 | 128, // DXT23_SRGB | ||
| 403 | 128, // DXT45_SRGB | ||
| 404 | 128, // BC7U | ||
| 405 | 32, // ASTC_2D_4X4_SRGB | ||
| 406 | 16, // ASTC_2D_8X8_SRGB | ||
| 407 | 32, // ASTC_2D_8X5_SRGB | ||
| 408 | 32, // ASTC_2D_5X4_SRGB | ||
| 373 | 32, // Z32F | 409 | 32, // Z32F |
| 374 | 16, // Z16 | 410 | 16, // Z16 |
| 375 | 32, // Z24S8 | 411 | 32, // Z24S8 |
| @@ -408,6 +444,7 @@ struct SurfaceParams { | |||
| 408 | // TODO (Hexagon12): Converting SRGBA to RGBA is a hack and doesn't completely correct the | 444 | // TODO (Hexagon12): Converting SRGBA to RGBA is a hack and doesn't completely correct the |
| 409 | // gamma. | 445 | // gamma. |
| 410 | case Tegra::RenderTargetFormat::RGBA8_SRGB: | 446 | case Tegra::RenderTargetFormat::RGBA8_SRGB: |
| 447 | return PixelFormat::RGBA8_SRGB; | ||
| 411 | case Tegra::RenderTargetFormat::RGBA8_UNORM: | 448 | case Tegra::RenderTargetFormat::RGBA8_UNORM: |
| 412 | return PixelFormat::ABGR8U; | 449 | return PixelFormat::ABGR8U; |
| 413 | case Tegra::RenderTargetFormat::RGBA8_SNORM: | 450 | case Tegra::RenderTargetFormat::RGBA8_SNORM: |
| @@ -415,6 +452,7 @@ struct SurfaceParams { | |||
| 415 | case Tegra::RenderTargetFormat::RGBA8_UINT: | 452 | case Tegra::RenderTargetFormat::RGBA8_UINT: |
| 416 | return PixelFormat::ABGR8UI; | 453 | return PixelFormat::ABGR8UI; |
| 417 | case Tegra::RenderTargetFormat::BGRA8_SRGB: | 454 | case Tegra::RenderTargetFormat::BGRA8_SRGB: |
| 455 | return PixelFormat::BGRA8_SRGB; | ||
| 418 | case Tegra::RenderTargetFormat::BGRA8_UNORM: | 456 | case Tegra::RenderTargetFormat::BGRA8_UNORM: |
| 419 | return PixelFormat::BGRA8; | 457 | return PixelFormat::BGRA8; |
| 420 | case Tegra::RenderTargetFormat::RGB10_A2_UNORM: | 458 | case Tegra::RenderTargetFormat::RGB10_A2_UNORM: |
| @@ -478,10 +516,14 @@ struct SurfaceParams { | |||
| 478 | } | 516 | } |
| 479 | 517 | ||
| 480 | static PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format, | 518 | static PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format, |
| 481 | Tegra::Texture::ComponentType component_type) { | 519 | Tegra::Texture::ComponentType component_type, |
| 520 | bool is_srgb) { | ||
| 482 | // TODO(Subv): Properly implement this | 521 | // TODO(Subv): Properly implement this |
| 483 | switch (format) { | 522 | switch (format) { |
| 484 | case Tegra::Texture::TextureFormat::A8R8G8B8: | 523 | case Tegra::Texture::TextureFormat::A8R8G8B8: |
| 524 | if (is_srgb) { | ||
| 525 | return PixelFormat::RGBA8_SRGB; | ||
| 526 | } | ||
| 485 | switch (component_type) { | 527 | switch (component_type) { |
| 486 | case Tegra::Texture::ComponentType::UNORM: | 528 | case Tegra::Texture::ComponentType::UNORM: |
| 487 | return PixelFormat::ABGR8U; | 529 | return PixelFormat::ABGR8U; |
| @@ -616,11 +658,11 @@ struct SurfaceParams { | |||
| 616 | case Tegra::Texture::TextureFormat::Z24S8: | 658 | case Tegra::Texture::TextureFormat::Z24S8: |
| 617 | return PixelFormat::Z24S8; | 659 | return PixelFormat::Z24S8; |
| 618 | case Tegra::Texture::TextureFormat::DXT1: | 660 | case Tegra::Texture::TextureFormat::DXT1: |
| 619 | return PixelFormat::DXT1; | 661 | return is_srgb ? PixelFormat::DXT1_SRGB : PixelFormat::DXT1; |
| 620 | case Tegra::Texture::TextureFormat::DXT23: | 662 | case Tegra::Texture::TextureFormat::DXT23: |
| 621 | return PixelFormat::DXT23; | 663 | return is_srgb ? PixelFormat::DXT23_SRGB : PixelFormat::DXT23; |
| 622 | case Tegra::Texture::TextureFormat::DXT45: | 664 | case Tegra::Texture::TextureFormat::DXT45: |
| 623 | return PixelFormat::DXT45; | 665 | return is_srgb ? PixelFormat::DXT45_SRGB : PixelFormat::DXT45; |
| 624 | case Tegra::Texture::TextureFormat::DXN1: | 666 | case Tegra::Texture::TextureFormat::DXN1: |
| 625 | return PixelFormat::DXN1; | 667 | return PixelFormat::DXN1; |
| 626 | case Tegra::Texture::TextureFormat::DXN2: | 668 | case Tegra::Texture::TextureFormat::DXN2: |
| @@ -634,19 +676,19 @@ struct SurfaceParams { | |||
| 634 | static_cast<u32>(component_type)); | 676 | static_cast<u32>(component_type)); |
| 635 | UNREACHABLE(); | 677 | UNREACHABLE(); |
| 636 | case Tegra::Texture::TextureFormat::BC7U: | 678 | case Tegra::Texture::TextureFormat::BC7U: |
| 637 | return PixelFormat::BC7U; | 679 | return is_srgb ? PixelFormat::BC7U_SRGB : PixelFormat::BC7U; |
| 638 | case Tegra::Texture::TextureFormat::BC6H_UF16: | 680 | case Tegra::Texture::TextureFormat::BC6H_UF16: |
| 639 | return PixelFormat::BC6H_UF16; | 681 | return PixelFormat::BC6H_UF16; |
| 640 | case Tegra::Texture::TextureFormat::BC6H_SF16: | 682 | case Tegra::Texture::TextureFormat::BC6H_SF16: |
| 641 | return PixelFormat::BC6H_SF16; | 683 | return PixelFormat::BC6H_SF16; |
| 642 | case Tegra::Texture::TextureFormat::ASTC_2D_4X4: | 684 | case Tegra::Texture::TextureFormat::ASTC_2D_4X4: |
| 643 | return PixelFormat::ASTC_2D_4X4; | 685 | return is_srgb ? PixelFormat::ASTC_2D_4X4_SRGB : PixelFormat::ASTC_2D_4X4; |
| 644 | case Tegra::Texture::TextureFormat::ASTC_2D_5X4: | 686 | case Tegra::Texture::TextureFormat::ASTC_2D_5X4: |
| 645 | return PixelFormat::ASTC_2D_5X4; | 687 | return is_srgb ? PixelFormat::ASTC_2D_5X4_SRGB : PixelFormat::ASTC_2D_5X4; |
| 646 | case Tegra::Texture::TextureFormat::ASTC_2D_8X8: | 688 | case Tegra::Texture::TextureFormat::ASTC_2D_8X8: |
| 647 | return PixelFormat::ASTC_2D_8X8; | 689 | return is_srgb ? PixelFormat::ASTC_2D_8X8_SRGB : PixelFormat::ASTC_2D_8X8; |
| 648 | case Tegra::Texture::TextureFormat::ASTC_2D_8X5: | 690 | case Tegra::Texture::TextureFormat::ASTC_2D_8X5: |
| 649 | return PixelFormat::ASTC_2D_8X5; | 691 | return is_srgb ? PixelFormat::ASTC_2D_8X5_SRGB : PixelFormat::ASTC_2D_8X5; |
| 650 | case Tegra::Texture::TextureFormat::R16_G16: | 692 | case Tegra::Texture::TextureFormat::R16_G16: |
| 651 | switch (component_type) { | 693 | switch (component_type) { |
| 652 | case Tegra::Texture::ComponentType::FLOAT: | 694 | case Tegra::Texture::ComponentType::FLOAT: |
| @@ -881,7 +923,7 @@ struct SurfaceParams { | |||
| 881 | SurfaceTarget target; | 923 | SurfaceTarget target; |
| 882 | u32 max_mip_level; | 924 | u32 max_mip_level; |
| 883 | bool is_layered; | 925 | bool is_layered; |
| 884 | 926 | bool srgb_conversion; | |
| 885 | // Parameters used for caching | 927 | // Parameters used for caching |
| 886 | VAddr addr; | 928 | VAddr addr; |
| 887 | Tegra::GPUVAddr gpu_addr; | 929 | Tegra::GPUVAddr gpu_addr; |
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index f9d41ca24..d8a43cc94 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp | |||
| @@ -11,9 +11,10 @@ | |||
| 11 | namespace OpenGL { | 11 | namespace OpenGL { |
| 12 | 12 | ||
| 13 | OpenGLState OpenGLState::cur_state; | 13 | OpenGLState OpenGLState::cur_state; |
| 14 | 14 | bool OpenGLState::s_rgb_used; | |
| 15 | OpenGLState::OpenGLState() { | 15 | OpenGLState::OpenGLState() { |
| 16 | // These all match default OpenGL values | 16 | // These all match default OpenGL values |
| 17 | framebuffer_srgb.enabled = false; | ||
| 17 | cull.enabled = false; | 18 | cull.enabled = false; |
| 18 | cull.mode = GL_BACK; | 19 | cull.mode = GL_BACK; |
| 19 | cull.front_face = GL_CCW; | 20 | cull.front_face = GL_CCW; |
| @@ -89,6 +90,16 @@ OpenGLState::OpenGLState() { | |||
| 89 | } | 90 | } |
| 90 | 91 | ||
| 91 | void OpenGLState::Apply() const { | 92 | void OpenGLState::Apply() const { |
| 93 | // sRGB | ||
| 94 | if (framebuffer_srgb.enabled != cur_state.framebuffer_srgb.enabled) { | ||
| 95 | if (framebuffer_srgb.enabled) { | ||
| 96 | // Track if sRGB is used | ||
| 97 | s_rgb_used = true; | ||
| 98 | glEnable(GL_FRAMEBUFFER_SRGB); | ||
| 99 | } else { | ||
| 100 | glDisable(GL_FRAMEBUFFER_SRGB); | ||
| 101 | } | ||
| 102 | } | ||
| 92 | // Culling | 103 | // Culling |
| 93 | if (cull.enabled != cur_state.cull.enabled) { | 104 | if (cull.enabled != cur_state.cull.enabled) { |
| 94 | if (cull.enabled) { | 105 | if (cull.enabled) { |
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 4334b0d35..9e2c573b5 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h | |||
| @@ -36,6 +36,10 @@ constexpr TextureUnit ProcTexDiffLUT{9}; | |||
| 36 | class OpenGLState { | 36 | class OpenGLState { |
| 37 | public: | 37 | public: |
| 38 | struct { | 38 | struct { |
| 39 | bool enabled; // GL_FRAMEBUFFER_SRGB | ||
| 40 | } framebuffer_srgb; | ||
| 41 | |||
| 42 | struct { | ||
| 39 | bool enabled; // GL_CULL_FACE | 43 | bool enabled; // GL_CULL_FACE |
| 40 | GLenum mode; // GL_CULL_FACE_MODE | 44 | GLenum mode; // GL_CULL_FACE_MODE |
| 41 | GLenum front_face; // GL_FRONT_FACE | 45 | GLenum front_face; // GL_FRONT_FACE |
| @@ -161,7 +165,12 @@ public: | |||
| 161 | static OpenGLState GetCurState() { | 165 | static OpenGLState GetCurState() { |
| 162 | return cur_state; | 166 | return cur_state; |
| 163 | } | 167 | } |
| 164 | 168 | static bool GetsRGBUsed() { | |
| 169 | return s_rgb_used; | ||
| 170 | } | ||
| 171 | static void ClearsRGBUsed() { | ||
| 172 | s_rgb_used = false; | ||
| 173 | } | ||
| 165 | /// Apply this state as the current OpenGL state | 174 | /// Apply this state as the current OpenGL state |
| 166 | void Apply() const; | 175 | void Apply() const; |
| 167 | 176 | ||
| @@ -176,6 +185,9 @@ public: | |||
| 176 | 185 | ||
| 177 | private: | 186 | private: |
| 178 | static OpenGLState cur_state; | 187 | static OpenGLState cur_state; |
| 188 | // Workaround for sRGB problems caused by | ||
| 189 | // QT not supporting srgb output | ||
| 190 | static bool s_rgb_used; | ||
| 179 | }; | 191 | }; |
| 180 | 192 | ||
| 181 | } // namespace OpenGL | 193 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 96d916b07..90b68943d 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -283,7 +283,8 @@ void RendererOpenGL::CreateRasterizer() { | |||
| 283 | if (rasterizer) { | 283 | if (rasterizer) { |
| 284 | return; | 284 | return; |
| 285 | } | 285 | } |
| 286 | 286 | // Initialize sRGB Usage | |
| 287 | OpenGLState::ClearsRGBUsed(); | ||
| 287 | rasterizer = std::make_unique<RasterizerOpenGL>(render_window, screen_info); | 288 | rasterizer = std::make_unique<RasterizerOpenGL>(render_window, screen_info); |
| 288 | } | 289 | } |
| 289 | 290 | ||
| @@ -356,13 +357,20 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, | |||
| 356 | 357 | ||
| 357 | state.texture_units[0].texture = screen_info.display_texture; | 358 | state.texture_units[0].texture = screen_info.display_texture; |
| 358 | state.texture_units[0].swizzle = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA}; | 359 | state.texture_units[0].swizzle = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA}; |
| 360 | // Workaround brigthness problems in SMO by enabling sRGB in the final output | ||
| 361 | // if it has been used in the frame | ||
| 362 | // Needed because of this bug in QT | ||
| 363 | // QTBUG-50987 | ||
| 364 | state.framebuffer_srgb.enabled = OpenGLState::GetsRGBUsed(); | ||
| 359 | state.Apply(); | 365 | state.Apply(); |
| 360 | |||
| 361 | glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices.data()); | 366 | glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices.data()); |
| 362 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | 367 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| 363 | 368 | // restore default state | |
| 369 | state.framebuffer_srgb.enabled = false; | ||
| 364 | state.texture_units[0].texture = 0; | 370 | state.texture_units[0].texture = 0; |
| 365 | state.Apply(); | 371 | state.Apply(); |
| 372 | // Clear sRGB state for the next frame | ||
| 373 | OpenGLState::ClearsRGBUsed(); | ||
| 366 | } | 374 | } |
| 367 | 375 | ||
| 368 | /** | 376 | /** |
diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h index 5947bd2b9..d12d2ecb8 100644 --- a/src/video_core/textures/texture.h +++ b/src/video_core/textures/texture.h | |||
| @@ -173,6 +173,7 @@ struct TICEntry { | |||
| 173 | }; | 173 | }; |
| 174 | union { | 174 | union { |
| 175 | BitField<0, 16, u32> width_minus_1; | 175 | BitField<0, 16, u32> width_minus_1; |
| 176 | BitField<22, 1, u32> srgb_conversion; | ||
| 176 | BitField<23, 4, TextureType> texture_type; | 177 | BitField<23, 4, TextureType> texture_type; |
| 177 | }; | 178 | }; |
| 178 | union { | 179 | union { |
| @@ -227,6 +228,10 @@ struct TICEntry { | |||
| 227 | return header_version == TICHeaderVersion::BlockLinear || | 228 | return header_version == TICHeaderVersion::BlockLinear || |
| 228 | header_version == TICHeaderVersion::BlockLinearColorKey; | 229 | header_version == TICHeaderVersion::BlockLinearColorKey; |
| 229 | } | 230 | } |
| 231 | |||
| 232 | bool IsSrgbConversionEnabled() const { | ||
| 233 | return srgb_conversion != 0; | ||
| 234 | } | ||
| 230 | }; | 235 | }; |
| 231 | static_assert(sizeof(TICEntry) == 0x20, "TICEntry has wrong size"); | 236 | static_assert(sizeof(TICEntry) == 0x20, "TICEntry has wrong size"); |
| 232 | 237 | ||