diff options
| author | 2018-04-15 19:55:39 -0500 | |
|---|---|---|
| committer | 2018-04-18 12:52:53 -0500 | |
| commit | a3e82e8e1f5cb39246f30cac045db8e243f0daee (patch) | |
| tree | e62da774cb793880b70cbcbf5c9ba495b3c499b5 /src | |
| parent | GLCache: Added a function to convert cached PixelFormats back to texture form... (diff) | |
| download | yuzu-a3e82e8e1f5cb39246f30cac045db8e243f0daee.tar.gz yuzu-a3e82e8e1f5cb39246f30cac045db8e243f0daee.tar.xz yuzu-a3e82e8e1f5cb39246f30cac045db8e243f0daee.zip | |
GLCache: Take into account the texture's block height when caching and unswizzling.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 82 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 1 |
3 files changed, 43 insertions, 43 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 7b6240e65..9522a35ea 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -523,7 +523,8 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& framebu | |||
| 523 | src_params.width = std::min(framebuffer.width, pixel_stride); | 523 | src_params.width = std::min(framebuffer.width, pixel_stride); |
| 524 | src_params.height = framebuffer.height; | 524 | src_params.height = framebuffer.height; |
| 525 | src_params.stride = pixel_stride; | 525 | src_params.stride = pixel_stride; |
| 526 | src_params.is_tiled = false; | 526 | src_params.is_tiled = true; |
| 527 | src_params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight; | ||
| 527 | src_params.pixel_format = | 528 | src_params.pixel_format = |
| 528 | SurfaceParams::PixelFormatFromGPUPixelFormat(framebuffer.pixel_format); | 529 | SurfaceParams::PixelFormatFromGPUPixelFormat(framebuffer.pixel_format); |
| 529 | src_params.UpdateParams(); | 530 | src_params.UpdateParams(); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 9d005936d..a92773f11 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -102,39 +102,36 @@ static void MortonCopyTile(u32 stride, u8* tile_buffer, u8* gl_buffer) { | |||
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | template <bool morton_to_gl, PixelFormat format> | 104 | template <bool morton_to_gl, PixelFormat format> |
| 105 | void MortonCopy(u32 stride, u32 height, u8* gl_buffer, VAddr base, VAddr start, VAddr end) { | 105 | void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, VAddr base, VAddr start, |
| 106 | VAddr end) { | ||
| 106 | constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / 8; | 107 | constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / 8; |
| 107 | constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(format); | 108 | constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(format); |
| 108 | 109 | ||
| 109 | // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should check the | 110 | if (morton_to_gl) { |
| 110 | // configuration for this and perform more generic un/swizzle | 111 | auto data = Tegra::Texture::UnswizzleTexture( |
| 111 | LOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!"); | 112 | base, SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, |
| 112 | VideoCore::MortonCopyPixels128(stride, height, bytes_per_pixel, gl_bytes_per_pixel, | 113 | block_height); |
| 113 | Memory::GetPointer(base), gl_buffer, morton_to_gl); | 114 | std::memcpy(gl_buffer, data.data(), data.size()); |
| 114 | } | 115 | } else { |
| 115 | 116 | // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should check | |
| 116 | template <> | 117 | // the configuration for this and perform more generic un/swizzle |
| 117 | void MortonCopy<true, PixelFormat::DXT1>(u32 stride, u32 height, u8* gl_buffer, VAddr base, | 118 | LOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!"); |
| 118 | VAddr start, VAddr end) { | 119 | VideoCore::MortonCopyPixels128(stride, height, bytes_per_pixel, gl_bytes_per_pixel, |
| 119 | constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(PixelFormat::DXT1) / 8; | 120 | Memory::GetPointer(base), gl_buffer, morton_to_gl); |
| 120 | constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(PixelFormat::DXT1); | 121 | } |
| 121 | |||
| 122 | // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should check the | ||
| 123 | // configuration for this and perform more generic un/swizzle | ||
| 124 | LOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!"); | ||
| 125 | auto data = | ||
| 126 | Tegra::Texture::UnswizzleTexture(base, Tegra::Texture::TextureFormat::DXT1, stride, height); | ||
| 127 | std::memcpy(gl_buffer, data.data(), data.size()); | ||
| 128 | } | 122 | } |
| 129 | 123 | ||
| 130 | static constexpr std::array<void (*)(u32, u32, u8*, VAddr, VAddr, VAddr), 2> morton_to_gl_fns = { | 124 | static constexpr std::array<void (*)(u32, u32, u32, u8*, VAddr, VAddr, VAddr), 2> morton_to_gl_fns = |
| 131 | MortonCopy<true, PixelFormat::RGBA8>, | 125 | { |
| 132 | MortonCopy<true, PixelFormat::DXT1>, | 126 | MortonCopy<true, PixelFormat::RGBA8>, |
| 127 | MortonCopy<true, PixelFormat::DXT1>, | ||
| 133 | }; | 128 | }; |
| 134 | 129 | ||
| 135 | static constexpr std::array<void (*)(u32, u32, u8*, VAddr, VAddr, VAddr), 2> gl_to_morton_fns = { | 130 | static constexpr std::array<void (*)(u32, u32, u32, u8*, VAddr, VAddr, VAddr), 2> gl_to_morton_fns = |
| 136 | MortonCopy<false, PixelFormat::RGBA8>, | 131 | { |
| 137 | MortonCopy<false, PixelFormat::DXT1>, | 132 | MortonCopy<false, PixelFormat::RGBA8>, |
| 133 | // TODO(Subv): Swizzling the DXT1 format is not yet supported | ||
| 134 | nullptr, | ||
| 138 | }; | 135 | }; |
| 139 | 136 | ||
| 140 | // Allocate an uninitialized texture of appropriate size and format for the surface | 137 | // Allocate an uninitialized texture of appropriate size and format for the surface |
| @@ -311,15 +308,16 @@ MathUtil::Rectangle<u32> SurfaceParams::GetScaledSubRect(const SurfaceParams& su | |||
| 311 | 308 | ||
| 312 | bool SurfaceParams::ExactMatch(const SurfaceParams& other_surface) const { | 309 | bool SurfaceParams::ExactMatch(const SurfaceParams& other_surface) const { |
| 313 | return std::tie(other_surface.addr, other_surface.width, other_surface.height, | 310 | return std::tie(other_surface.addr, other_surface.width, other_surface.height, |
| 314 | other_surface.stride, other_surface.pixel_format, other_surface.is_tiled) == | 311 | other_surface.stride, other_surface.block_height, other_surface.pixel_format, |
| 315 | std::tie(addr, width, height, stride, pixel_format, is_tiled) && | 312 | other_surface.is_tiled) == |
| 313 | std::tie(addr, width, height, stride, block_height, pixel_format, is_tiled) && | ||
| 316 | pixel_format != PixelFormat::Invalid; | 314 | pixel_format != PixelFormat::Invalid; |
| 317 | } | 315 | } |
| 318 | 316 | ||
| 319 | bool SurfaceParams::CanSubRect(const SurfaceParams& sub_surface) const { | 317 | bool SurfaceParams::CanSubRect(const SurfaceParams& sub_surface) const { |
| 320 | return sub_surface.addr >= addr && sub_surface.end <= end && | 318 | return sub_surface.addr >= addr && sub_surface.end <= end && |
| 321 | sub_surface.pixel_format == pixel_format && pixel_format != PixelFormat::Invalid && | 319 | sub_surface.pixel_format == pixel_format && pixel_format != PixelFormat::Invalid && |
| 322 | sub_surface.is_tiled == is_tiled && | 320 | sub_surface.is_tiled == is_tiled && sub_surface.block_height == block_height && |
| 323 | (sub_surface.addr - addr) % BytesInPixels(is_tiled ? 64 : 1) == 0 && | 321 | (sub_surface.addr - addr) % BytesInPixels(is_tiled ? 64 : 1) == 0 && |
| 324 | (sub_surface.stride == stride || sub_surface.height <= (is_tiled ? 8u : 1u)) && | 322 | (sub_surface.stride == stride || sub_surface.height <= (is_tiled ? 8u : 1u)) && |
| 325 | GetSubRect(sub_surface).left + sub_surface.width <= stride; | 323 | GetSubRect(sub_surface).left + sub_surface.width <= stride; |
| @@ -328,7 +326,8 @@ bool SurfaceParams::CanSubRect(const SurfaceParams& sub_surface) const { | |||
| 328 | bool SurfaceParams::CanExpand(const SurfaceParams& expanded_surface) const { | 326 | bool SurfaceParams::CanExpand(const SurfaceParams& expanded_surface) const { |
| 329 | return pixel_format != PixelFormat::Invalid && pixel_format == expanded_surface.pixel_format && | 327 | return pixel_format != PixelFormat::Invalid && pixel_format == expanded_surface.pixel_format && |
| 330 | addr <= expanded_surface.end && expanded_surface.addr <= end && | 328 | addr <= expanded_surface.end && expanded_surface.addr <= end && |
| 331 | is_tiled == expanded_surface.is_tiled && stride == expanded_surface.stride && | 329 | is_tiled == expanded_surface.is_tiled && block_height == expanded_surface.block_height && |
| 330 | stride == expanded_surface.stride && | ||
| 332 | (std::max(expanded_surface.addr, addr) - std::min(expanded_surface.addr, addr)) % | 331 | (std::max(expanded_surface.addr, addr) - std::min(expanded_surface.addr, addr)) % |
| 333 | BytesInPixels(stride * (is_tiled ? 8 : 1)) == | 332 | BytesInPixels(stride * (is_tiled ? 8 : 1)) == |
| 334 | 0; | 333 | 0; |
| @@ -339,6 +338,9 @@ bool SurfaceParams::CanTexCopy(const SurfaceParams& texcopy_params) const { | |||
| 339 | end < texcopy_params.end) { | 338 | end < texcopy_params.end) { |
| 340 | return false; | 339 | return false; |
| 341 | } | 340 | } |
| 341 | if (texcopy_params.block_height != block_height) | ||
| 342 | return false; | ||
| 343 | |||
| 342 | if (texcopy_params.width != texcopy_params.stride) { | 344 | if (texcopy_params.width != texcopy_params.stride) { |
| 343 | const u32 tile_stride = static_cast<u32>(BytesInPixels(stride * (is_tiled ? 8 : 1))); | 345 | const u32 tile_stride = static_cast<u32>(BytesInPixels(stride * (is_tiled ? 8 : 1))); |
| 344 | return (texcopy_params.addr - addr) % BytesInPixels(is_tiled ? 64 : 1) == 0 && | 346 | return (texcopy_params.addr - addr) % BytesInPixels(is_tiled ? 64 : 1) == 0 && |
| @@ -481,18 +483,13 @@ void CachedSurface::LoadGLBuffer(VAddr load_start, VAddr load_end) { | |||
| 481 | const u64 start_offset = load_start - addr; | 483 | const u64 start_offset = load_start - addr; |
| 482 | 484 | ||
| 483 | if (!is_tiled) { | 485 | if (!is_tiled) { |
| 484 | ASSERT(type == SurfaceType::Color); | ||
| 485 | const u32 bytes_per_pixel{GetFormatBpp() >> 3}; | 486 | const u32 bytes_per_pixel{GetFormatBpp() >> 3}; |
| 486 | 487 | ||
| 487 | // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should check | 488 | std::memcpy(&gl_buffer[start_offset], texture_src_data + start_offset, |
| 488 | // the configuration for this and perform more generic un/swizzle | 489 | bytes_per_pixel * width * height); |
| 489 | LOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!"); | ||
| 490 | VideoCore::MortonCopyPixels128(width, height, bytes_per_pixel, 4, | ||
| 491 | texture_src_data + start_offset, &gl_buffer[start_offset], | ||
| 492 | true); | ||
| 493 | } else { | 490 | } else { |
| 494 | morton_to_gl_fns[static_cast<size_t>(pixel_format)](stride, height, &gl_buffer[0], addr, | 491 | morton_to_gl_fns[static_cast<size_t>(pixel_format)]( |
| 495 | load_start, load_end); | 492 | stride, block_height, height, &gl_buffer[0], addr, load_start, load_end); |
| 496 | } | 493 | } |
| 497 | } | 494 | } |
| 498 | 495 | ||
| @@ -533,11 +530,10 @@ void CachedSurface::FlushGLBuffer(VAddr flush_start, VAddr flush_end) { | |||
| 533 | if (backup_bytes) | 530 | if (backup_bytes) |
| 534 | std::memcpy(&dst_buffer[coarse_start_offset], &backup_data[0], backup_bytes); | 531 | std::memcpy(&dst_buffer[coarse_start_offset], &backup_data[0], backup_bytes); |
| 535 | } else if (!is_tiled) { | 532 | } else if (!is_tiled) { |
| 536 | ASSERT(type == SurfaceType::Color); | ||
| 537 | std::memcpy(dst_buffer + start_offset, &gl_buffer[start_offset], flush_end - flush_start); | 533 | std::memcpy(dst_buffer + start_offset, &gl_buffer[start_offset], flush_end - flush_start); |
| 538 | } else { | 534 | } else { |
| 539 | gl_to_morton_fns[static_cast<size_t>(pixel_format)](stride, height, &gl_buffer[0], addr, | 535 | gl_to_morton_fns[static_cast<size_t>(pixel_format)]( |
| 540 | flush_start, flush_end); | 536 | stride, block_height, height, &gl_buffer[0], addr, flush_start, flush_end); |
| 541 | } | 537 | } |
| 542 | } | 538 | } |
| 543 | 539 | ||
| @@ -1103,6 +1099,8 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( | |||
| 1103 | color_params.res_scale = resolution_scale_factor; | 1099 | color_params.res_scale = resolution_scale_factor; |
| 1104 | color_params.width = config.width; | 1100 | color_params.width = config.width; |
| 1105 | color_params.height = config.height; | 1101 | color_params.height = config.height; |
| 1102 | // TODO(Subv): Can framebuffers use a different block height? | ||
| 1103 | color_params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight; | ||
| 1106 | SurfaceParams depth_params = color_params; | 1104 | SurfaceParams depth_params = color_params; |
| 1107 | 1105 | ||
| 1108 | color_params.addr = memory_manager->PhysicalToVirtualAddress(config.Address()); | 1106 | color_params.addr = memory_manager->PhysicalToVirtualAddress(config.Address()); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 0b2e3ffef..26d6c3061 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -225,6 +225,7 @@ struct SurfaceParams { | |||
| 225 | u32 width = 0; | 225 | u32 width = 0; |
| 226 | u32 height = 0; | 226 | u32 height = 0; |
| 227 | u32 stride = 0; | 227 | u32 stride = 0; |
| 228 | u32 block_height = 0; | ||
| 228 | u16 res_scale = 1; | 229 | u16 res_scale = 1; |
| 229 | 230 | ||
| 230 | bool is_tiled = false; | 231 | bool is_tiled = false; |