diff options
| author | 2018-04-18 14:17:05 -0500 | |
|---|---|---|
| committer | 2018-04-18 14:17:28 -0500 | |
| commit | 43d98ca8fee384c5aef462dd37200477e9de2013 (patch) | |
| tree | 2cd2be881337d77a0da33c6db8a8bcc4007349e9 /src | |
| parent | GLCache: Unify texture and framebuffer formats when converting to OpenGL. (diff) | |
| download | yuzu-43d98ca8fee384c5aef462dd37200477e9de2013.tar.gz yuzu-43d98ca8fee384c5aef462dd37200477e9de2013.tar.xz yuzu-43d98ca8fee384c5aef462dd37200477e9de2013.zip | |
GLCache: Added boilerplate code to make supporting configurable texture component types.
For now only the UNORM type is supported.
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 32 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 44 |
3 files changed, 69 insertions, 9 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 9522a35ea..13e2a77ce 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -527,6 +527,8 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& framebu | |||
| 527 | src_params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight; | 527 | src_params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight; |
| 528 | src_params.pixel_format = | 528 | src_params.pixel_format = |
| 529 | SurfaceParams::PixelFormatFromGPUPixelFormat(framebuffer.pixel_format); | 529 | SurfaceParams::PixelFormatFromGPUPixelFormat(framebuffer.pixel_format); |
| 530 | src_params.component_type = | ||
| 531 | SurfaceParams::ComponentTypeFromGPUPixelFormat(framebuffer.pixel_format); | ||
| 530 | src_params.UpdateParams(); | 532 | src_params.UpdateParams(); |
| 531 | 533 | ||
| 532 | MathUtil::Rectangle<u32> src_rect; | 534 | MathUtil::Rectangle<u32> src_rect; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 10e9dc5c2..9ccc63090 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | 36 | ||
| 37 | using SurfaceType = SurfaceParams::SurfaceType; | 37 | using SurfaceType = SurfaceParams::SurfaceType; |
| 38 | using PixelFormat = SurfaceParams::PixelFormat; | 38 | using PixelFormat = SurfaceParams::PixelFormat; |
| 39 | using ComponentType = SurfaceParams::ComponentType; | ||
| 39 | 40 | ||
| 40 | struct FormatTuple { | 41 | struct FormatTuple { |
| 41 | GLint internal_format; | 42 | GLint internal_format; |
| @@ -52,11 +53,12 @@ static constexpr std::array<FormatTuple, 2> tex_format_tuples = {{ | |||
| 52 | {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT1 | 53 | {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT1 |
| 53 | }}; | 54 | }}; |
| 54 | 55 | ||
| 55 | static const FormatTuple& GetFormatTuple(PixelFormat pixel_format) { | 56 | static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) { |
| 56 | using Tegra::Texture::ComponentType; | ||
| 57 | const SurfaceType type = SurfaceParams::GetFormatType(pixel_format); | 57 | const SurfaceType type = SurfaceParams::GetFormatType(pixel_format); |
| 58 | if (type == SurfaceType::ColorTexture) { | 58 | if (type == SurfaceType::ColorTexture) { |
| 59 | ASSERT(static_cast<size_t>(pixel_format) < tex_format_tuples.size()); | 59 | ASSERT(static_cast<size_t>(pixel_format) < tex_format_tuples.size()); |
| 60 | // For now only UNORM components are supported | ||
| 61 | ASSERT(component_type == ComponentType::UNorm); | ||
| 60 | return tex_format_tuples[static_cast<unsigned int>(pixel_format)]; | 62 | return tex_format_tuples[static_cast<unsigned int>(pixel_format)]; |
| 61 | } else if (type == SurfaceType::Depth || type == SurfaceType::DepthStencil) { | 63 | } else if (type == SurfaceType::Depth || type == SurfaceType::DepthStencil) { |
| 62 | // TODO(Subv): Implement depth formats | 64 | // TODO(Subv): Implement depth formats |
| @@ -303,8 +305,9 @@ MathUtil::Rectangle<u32> SurfaceParams::GetScaledSubRect(const SurfaceParams& su | |||
| 303 | bool SurfaceParams::ExactMatch(const SurfaceParams& other_surface) const { | 305 | bool SurfaceParams::ExactMatch(const SurfaceParams& other_surface) const { |
| 304 | return std::tie(other_surface.addr, other_surface.width, other_surface.height, | 306 | return std::tie(other_surface.addr, other_surface.width, other_surface.height, |
| 305 | other_surface.stride, other_surface.block_height, other_surface.pixel_format, | 307 | other_surface.stride, other_surface.block_height, other_surface.pixel_format, |
| 306 | other_surface.is_tiled) == | 308 | other_surface.component_type, |
| 307 | std::tie(addr, width, height, stride, block_height, pixel_format, is_tiled) && | 309 | other_surface.is_tiled) == std::tie(addr, width, height, stride, block_height, |
| 310 | pixel_format, component_type, is_tiled) && | ||
| 308 | pixel_format != PixelFormat::Invalid; | 311 | pixel_format != PixelFormat::Invalid; |
| 309 | } | 312 | } |
| 310 | 313 | ||
| @@ -312,6 +315,7 @@ bool SurfaceParams::CanSubRect(const SurfaceParams& sub_surface) const { | |||
| 312 | return sub_surface.addr >= addr && sub_surface.end <= end && | 315 | return sub_surface.addr >= addr && sub_surface.end <= end && |
| 313 | sub_surface.pixel_format == pixel_format && pixel_format != PixelFormat::Invalid && | 316 | sub_surface.pixel_format == pixel_format && pixel_format != PixelFormat::Invalid && |
| 314 | sub_surface.is_tiled == is_tiled && sub_surface.block_height == block_height && | 317 | sub_surface.is_tiled == is_tiled && sub_surface.block_height == block_height && |
| 318 | sub_surface.component_type == component_type && | ||
| 315 | (sub_surface.addr - addr) % BytesInPixels(is_tiled ? 64 : 1) == 0 && | 319 | (sub_surface.addr - addr) % BytesInPixels(is_tiled ? 64 : 1) == 0 && |
| 316 | (sub_surface.stride == stride || sub_surface.height <= (is_tiled ? 8u : 1u)) && | 320 | (sub_surface.stride == stride || sub_surface.height <= (is_tiled ? 8u : 1u)) && |
| 317 | GetSubRect(sub_surface).left + sub_surface.width <= stride; | 321 | GetSubRect(sub_surface).left + sub_surface.width <= stride; |
| @@ -321,7 +325,7 @@ bool SurfaceParams::CanExpand(const SurfaceParams& expanded_surface) const { | |||
| 321 | return pixel_format != PixelFormat::Invalid && pixel_format == expanded_surface.pixel_format && | 325 | return pixel_format != PixelFormat::Invalid && pixel_format == expanded_surface.pixel_format && |
| 322 | addr <= expanded_surface.end && expanded_surface.addr <= end && | 326 | addr <= expanded_surface.end && expanded_surface.addr <= end && |
| 323 | is_tiled == expanded_surface.is_tiled && block_height == expanded_surface.block_height && | 327 | is_tiled == expanded_surface.is_tiled && block_height == expanded_surface.block_height && |
| 324 | stride == expanded_surface.stride && | 328 | component_type == expanded_surface.component_type && stride == expanded_surface.stride && |
| 325 | (std::max(expanded_surface.addr, addr) - std::min(expanded_surface.addr, addr)) % | 329 | (std::max(expanded_surface.addr, addr) - std::min(expanded_surface.addr, addr)) % |
| 326 | BytesInPixels(stride * (is_tiled ? 8 : 1)) == | 330 | BytesInPixels(stride * (is_tiled ? 8 : 1)) == |
| 327 | 0; | 331 | 0; |
| @@ -332,7 +336,8 @@ bool SurfaceParams::CanTexCopy(const SurfaceParams& texcopy_params) const { | |||
| 332 | end < texcopy_params.end) { | 336 | end < texcopy_params.end) { |
| 333 | return false; | 337 | return false; |
| 334 | } | 338 | } |
| 335 | if (texcopy_params.block_height != block_height) | 339 | if (texcopy_params.block_height != block_height || |
| 340 | texcopy_params.component_type != component_type) | ||
| 336 | return false; | 341 | return false; |
| 337 | 342 | ||
| 338 | if (texcopy_params.width != texcopy_params.stride) { | 343 | if (texcopy_params.width != texcopy_params.stride) { |
| @@ -546,7 +551,7 @@ void CachedSurface::UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint | |||
| 546 | GLint y0 = static_cast<GLint>(rect.bottom); | 551 | GLint y0 = static_cast<GLint>(rect.bottom); |
| 547 | size_t buffer_offset = (y0 * stride + x0) * GetGLBytesPerPixel(pixel_format); | 552 | size_t buffer_offset = (y0 * stride + x0) * GetGLBytesPerPixel(pixel_format); |
| 548 | 553 | ||
| 549 | const FormatTuple& tuple = GetFormatTuple(pixel_format); | 554 | const FormatTuple& tuple = GetFormatTuple(pixel_format, component_type); |
| 550 | GLuint target_tex = texture.handle; | 555 | GLuint target_tex = texture.handle; |
| 551 | 556 | ||
| 552 | // If not 1x scale, create 1x texture that we will blit from to replace texture subrect in | 557 | // If not 1x scale, create 1x texture that we will blit from to replace texture subrect in |
| @@ -619,7 +624,7 @@ void CachedSurface::DownloadGLTexture(const MathUtil::Rectangle<u32>& rect, GLui | |||
| 619 | OpenGLState prev_state = state; | 624 | OpenGLState prev_state = state; |
| 620 | SCOPE_EXIT({ prev_state.Apply(); }); | 625 | SCOPE_EXIT({ prev_state.Apply(); }); |
| 621 | 626 | ||
| 622 | const FormatTuple& tuple = GetFormatTuple(pixel_format); | 627 | const FormatTuple& tuple = GetFormatTuple(pixel_format, component_type); |
| 623 | 628 | ||
| 624 | // Ensure no bad interactions with GL_PACK_ALIGNMENT | 629 | // Ensure no bad interactions with GL_PACK_ALIGNMENT |
| 625 | ASSERT(stride * GetGLBytesPerPixel(pixel_format) % 4 == 0); | 630 | ASSERT(stride * GetGLBytesPerPixel(pixel_format) % 4 == 0); |
| @@ -1032,6 +1037,13 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu | |||
| 1032 | params.is_tiled = config.tic.IsTiled(); | 1037 | params.is_tiled = config.tic.IsTiled(); |
| 1033 | params.pixel_format = SurfaceParams::PixelFormatFromTextureFormat(config.tic.format); | 1038 | params.pixel_format = SurfaceParams::PixelFormatFromTextureFormat(config.tic.format); |
| 1034 | 1039 | ||
| 1040 | // TODO(Subv): Different types per component are not supported. | ||
| 1041 | ASSERT(config.tic.r_type.Value() == config.tic.g_type.Value() && | ||
| 1042 | config.tic.r_type.Value() == config.tic.b_type.Value() && | ||
| 1043 | config.tic.r_type.Value() == config.tic.a_type.Value()); | ||
| 1044 | |||
| 1045 | params.component_type = SurfaceParams::ComponentTypeFromTexture(config.tic.r_type.Value()); | ||
| 1046 | |||
| 1035 | if (config.tic.IsTiled()) { | 1047 | if (config.tic.IsTiled()) { |
| 1036 | params.block_height = config.tic.BlockHeight(); | 1048 | params.block_height = config.tic.BlockHeight(); |
| 1037 | } else { | 1049 | } else { |
| @@ -1099,6 +1111,7 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( | |||
| 1099 | 1111 | ||
| 1100 | color_params.addr = memory_manager->PhysicalToVirtualAddress(config.Address()); | 1112 | color_params.addr = memory_manager->PhysicalToVirtualAddress(config.Address()); |
| 1101 | color_params.pixel_format = SurfaceParams::PixelFormatFromRenderTargetFormat(config.format); | 1113 | color_params.pixel_format = SurfaceParams::PixelFormatFromRenderTargetFormat(config.format); |
| 1114 | color_params.component_type = SurfaceParams::ComponentTypeFromRenderTarget(config.format); | ||
| 1102 | color_params.UpdateParams(); | 1115 | color_params.UpdateParams(); |
| 1103 | 1116 | ||
| 1104 | ASSERT_MSG(!using_depth_fb, "depth buffer is unimplemented"); | 1117 | ASSERT_MSG(!using_depth_fb, "depth buffer is unimplemented"); |
| @@ -1355,7 +1368,8 @@ Surface RasterizerCacheOpenGL::CreateSurface(const SurfaceParams& params) { | |||
| 1355 | 1368 | ||
| 1356 | surface->gl_buffer_size = 0; | 1369 | surface->gl_buffer_size = 0; |
| 1357 | surface->invalid_regions.insert(surface->GetInterval()); | 1370 | surface->invalid_regions.insert(surface->GetInterval()); |
| 1358 | AllocateSurfaceTexture(surface->texture.handle, GetFormatTuple(surface->pixel_format), | 1371 | AllocateSurfaceTexture(surface->texture.handle, |
| 1372 | GetFormatTuple(surface->pixel_format, surface->component_type), | ||
| 1359 | surface->GetScaledWidth(), surface->GetScaledHeight()); | 1373 | surface->GetScaledWidth(), surface->GetScaledHeight()); |
| 1360 | 1374 | ||
| 1361 | return surface; | 1375 | return surface; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 434cd2277..0ff0ce90f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -57,6 +57,15 @@ struct SurfaceParams { | |||
| 57 | Invalid = 255, | 57 | Invalid = 255, |
| 58 | }; | 58 | }; |
| 59 | 59 | ||
| 60 | enum class ComponentType { | ||
| 61 | Invalid = 0, | ||
| 62 | SNorm = 1, | ||
| 63 | UNorm = 2, | ||
| 64 | SInt = 3, | ||
| 65 | UInt = 4, | ||
| 66 | Float = 5, | ||
| 67 | }; | ||
| 68 | |||
| 60 | enum class SurfaceType { | 69 | enum class SurfaceType { |
| 61 | ColorTexture = 0, | 70 | ColorTexture = 0, |
| 62 | Depth = 1, | 71 | Depth = 1, |
| @@ -126,6 +135,40 @@ struct SurfaceParams { | |||
| 126 | } | 135 | } |
| 127 | } | 136 | } |
| 128 | 137 | ||
| 138 | static ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) { | ||
| 139 | // TODO(Subv): Implement more component types | ||
| 140 | switch (type) { | ||
| 141 | case Tegra::Texture::ComponentType::UNORM: | ||
| 142 | return ComponentType::UNorm; | ||
| 143 | default: | ||
| 144 | NGLOG_CRITICAL(HW_GPU, "Unimplemented component type={}", static_cast<u32>(type)); | ||
| 145 | UNREACHABLE(); | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | static ComponentType ComponentTypeFromRenderTarget(Tegra::RenderTargetFormat format) { | ||
| 150 | // TODO(Subv): Implement more render targets | ||
| 151 | switch (format) { | ||
| 152 | case Tegra::RenderTargetFormat::RGBA8_UNORM: | ||
| 153 | case Tegra::RenderTargetFormat::RGB10_A2_UNORM: | ||
| 154 | return ComponentType::UNorm; | ||
| 155 | default: | ||
| 156 | NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); | ||
| 157 | UNREACHABLE(); | ||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | static ComponentType ComponentTypeFromGPUPixelFormat( | ||
| 162 | Tegra::FramebufferConfig::PixelFormat format) { | ||
| 163 | switch (format) { | ||
| 164 | case Tegra::FramebufferConfig::PixelFormat::ABGR8: | ||
| 165 | return ComponentType::UNorm; | ||
| 166 | default: | ||
| 167 | NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); | ||
| 168 | UNREACHABLE(); | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 129 | static bool CheckFormatsBlittable(PixelFormat pixel_format_a, PixelFormat pixel_format_b) { | 172 | static bool CheckFormatsBlittable(PixelFormat pixel_format_a, PixelFormat pixel_format_b) { |
| 130 | SurfaceType a_type = GetFormatType(pixel_format_a); | 173 | SurfaceType a_type = GetFormatType(pixel_format_a); |
| 131 | SurfaceType b_type = GetFormatType(pixel_format_b); | 174 | SurfaceType b_type = GetFormatType(pixel_format_b); |
| @@ -225,6 +268,7 @@ struct SurfaceParams { | |||
| 225 | bool is_tiled = false; | 268 | bool is_tiled = false; |
| 226 | PixelFormat pixel_format = PixelFormat::Invalid; | 269 | PixelFormat pixel_format = PixelFormat::Invalid; |
| 227 | SurfaceType type = SurfaceType::Invalid; | 270 | SurfaceType type = SurfaceType::Invalid; |
| 271 | ComponentType component_type = ComponentType::Invalid; | ||
| 228 | }; | 272 | }; |
| 229 | 273 | ||
| 230 | struct CachedSurface : SurfaceParams { | 274 | struct CachedSurface : SurfaceParams { |