summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2018-06-26 21:05:13 +0200
committerbunnei <bunneidev@gmail.com>2018-06-27 06:08:04 +0200
commit8af1ae46aa5a9303b21839b446d2ebf17ee12802 (patch)
tree0107f0b2e7442bece9a58992c09fdc6532b98871
parentgl_rasterizer_cache: Use SurfaceParams as a key for surface caching. (diff)
downloadyuzu-8af1ae46aa5a9303b21839b446d2ebf17ee12802.tar
yuzu-8af1ae46aa5a9303b21839b446d2ebf17ee12802.tar.gz
yuzu-8af1ae46aa5a9303b21839b446d2ebf17ee12802.tar.bz2
yuzu-8af1ae46aa5a9303b21839b446d2ebf17ee12802.tar.lz
yuzu-8af1ae46aa5a9303b21839b446d2ebf17ee12802.tar.xz
yuzu-8af1ae46aa5a9303b21839b446d2ebf17ee12802.tar.zst
yuzu-8af1ae46aa5a9303b21839b446d2ebf17ee12802.zip
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp63
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h11
2 files changed, 39 insertions, 35 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 59f1a89c9..bd35bdb02 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -41,6 +41,7 @@ struct FormatTuple {
params.type = GetFormatType(params.pixel_format);
params.width = Common::AlignUp(config.tic.Width(), GetCompressionFactor(params.pixel_format));
params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format));
+ params.unaligned_height = config.tic.Height();
params.size_in_bytes = params.SizeInBytes();
return params;
}
@@ -57,6 +58,7 @@ struct FormatTuple {
params.type = GetFormatType(params.pixel_format);
params.width = config.width;
params.height = config.height;
+ params.unaligned_height = config.height;
params.size_in_bytes = params.SizeInBytes();
return params;
}
@@ -108,20 +110,29 @@ static bool IsPixelFormatASTC(PixelFormat format) {
}
}
-static void ConvertASTCToRGBA8(std::vector<u8>& data, PixelFormat format, u32 width, u32 height) {
- u32 block_width{};
- u32 block_height{};
-
+static std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) {
switch (format) {
case PixelFormat::ASTC_2D_4X4:
- block_width = 4;
- block_height = 4;
- break;
+ return {4, 4};
default:
NGLOG_CRITICAL(HW_GPU, "Unhandled format: {}", static_cast<u32>(format));
UNREACHABLE();
}
+}
+MathUtil::Rectangle<u32> SurfaceParams::GetRect() const {
+ u32 actual_height{unaligned_height};
+ if (IsPixelFormatASTC(pixel_format)) {
+ // ASTC formats must stop at the ATSC block size boundary
+ actual_height = Common::AlignDown(actual_height, GetASTCBlockSize(pixel_format).second);
+ }
+ return {0, actual_height, width, 0};
+}
+
+static void ConvertASTCToRGBA8(std::vector<u8>& data, PixelFormat format, u32 width, u32 height) {
+ u32 block_width{};
+ u32 block_height{};
+ std::tie(block_width, block_height) = GetASTCBlockSize(format);
data = Tegra::Texture::ASTC::Decompress(data, width, height, block_width, block_height);
}
@@ -136,12 +147,6 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, Tegra::
*gpu.memory_manager->GpuToCpuAddress(addr),
SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height);
- if (IsPixelFormatASTC(format)) {
- // ASTC formats are converted to RGBA8 in software, as most PC GPUs do not support
- // this
- ConvertASTCToRGBA8(data, format, stride, height);
- }
-
std::memcpy(gl_buffer, data.data(), data.size());
} else {
// TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should
@@ -212,9 +217,10 @@ static void AllocateSurfaceTexture(GLuint texture, const FormatTuple& format_tup
CachedSurface::CachedSurface(const SurfaceParams& params) : params(params), gl_buffer_size(0) {
texture.Create();
+ const auto& rect{params.GetRect()};
AllocateSurfaceTexture(texture.handle,
- GetFormatTuple(params.pixel_format, params.component_type), params.width,
- params.height);
+ GetFormatTuple(params.pixel_format, params.component_type),
+ rect.GetWidth(), rect.GetHeight());
}
MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 64, 192));
@@ -225,21 +231,23 @@ void CachedSurface::LoadGLBuffer() {
ASSERT(texture_src_data);
- if (!gl_buffer) {
- gl_buffer_size = params.width * params.height * GetGLBytesPerPixel(params.pixel_format);
- gl_buffer.reset(new u8[gl_buffer_size]);
- }
+ gl_buffer.resize(params.width * params.height * GetGLBytesPerPixel(params.pixel_format));
MICROPROFILE_SCOPE(OpenGL_SurfaceLoad);
if (!params.is_tiled) {
const u32 bytes_per_pixel{params.GetFormatBpp() >> 3};
- std::memcpy(&gl_buffer[0], texture_src_data,
+ std::memcpy(gl_buffer.data(), texture_src_data,
bytes_per_pixel * params.width * params.height);
} else {
morton_to_gl_fns[static_cast<size_t>(params.pixel_format)](
- params.width, params.block_height, params.height, &gl_buffer[0], params.addr);
+ params.width, params.block_height, params.height, gl_buffer.data(), params.addr);
+ }
+
+ if (IsPixelFormatASTC(params.pixel_format)) {
+ // ASTC formats are converted to RGBA8 in software, as most PC GPUs do not support this
+ ConvertASTCToRGBA8(gl_buffer, params.pixel_format, params.width, params.height);
}
}
@@ -248,16 +256,16 @@ void CachedSurface::FlushGLBuffer() {
u8* const dst_buffer = Memory::GetPointer(params.GetCpuAddr());
ASSERT(dst_buffer);
- ASSERT(gl_buffer_size ==
+ ASSERT(gl_buffer.size() ==
params.width * params.height * GetGLBytesPerPixel(params.pixel_format));
MICROPROFILE_SCOPE(OpenGL_SurfaceFlush);
if (!params.is_tiled) {
- std::memcpy(dst_buffer, &gl_buffer[0], params.size_in_bytes);
+ std::memcpy(dst_buffer, gl_buffer.data(), params.size_in_bytes);
} else {
gl_to_morton_fns[static_cast<size_t>(params.pixel_format)](
- params.width, params.block_height, params.height, &gl_buffer[0], params.addr);
+ params.width, params.block_height, params.height, gl_buffer.data(), params.addr);
}
}
@@ -268,7 +276,7 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle
MICROPROFILE_SCOPE(OpenGL_TextureUL);
- ASSERT(gl_buffer_size ==
+ ASSERT(gl_buffer.size() ==
params.width * params.height * GetGLBytesPerPixel(params.pixel_format));
const auto& rect{params.GetRect()};
@@ -315,10 +323,7 @@ void CachedSurface::DownloadGLTexture(GLuint read_fb_handle, GLuint draw_fb_hand
MICROPROFILE_SCOPE(OpenGL_TextureDL);
- if (!gl_buffer) {
- gl_buffer_size = params.width * params.height * GetGLBytesPerPixel(params.pixel_format);
- gl_buffer.reset(new u8[gl_buffer_size]);
- }
+ gl_buffer.resize(params.width * params.height * GetGLBytesPerPixel(params.pixel_format));
OpenGLState state = OpenGLState::GetCurState();
OpenGLState prev_state = state;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index bf36f6c24..84bdec652 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -7,6 +7,7 @@
#include <array>
#include <map>
#include <memory>
+#include <vector>
#include "common/common_types.h"
#include "common/hash.h"
@@ -79,7 +80,7 @@ struct SurfaceParams {
4, // DXT23
4, // DXT45
4, // DXN1
- 1, // ASTC_2D_4X4
+ 4, // ASTC_2D_4X4
}};
ASSERT(static_cast<size_t>(format) < compression_factor_table.size());
@@ -242,9 +243,7 @@ struct SurfaceParams {
return SurfaceType::Invalid;
}
- MathUtil::Rectangle<u32> GetRect() const {
- return {0, height, width, 0};
- }
+ MathUtil::Rectangle<u32> GetRect() const;
size_t SizeInBytes() const {
const u32 compression_factor{GetCompressionFactor(pixel_format)};
@@ -269,6 +268,7 @@ struct SurfaceParams {
SurfaceType type;
u32 width;
u32 height;
+ u32 unaligned_height;
size_t size_in_bytes;
};
@@ -318,8 +318,7 @@ public:
private:
OGLTexture texture;
- std::unique_ptr<u8[]> gl_buffer;
- size_t gl_buffer_size;
+ std::vector<u8> gl_buffer;
SurfaceParams params;
};