summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Subv2018-04-18 14:17:05 -0500
committerGravatar Subv2018-04-18 14:17:28 -0500
commit43d98ca8fee384c5aef462dd37200477e9de2013 (patch)
tree2cd2be881337d77a0da33c6db8a8bcc4007349e9 /src
parentGLCache: Unify texture and framebuffer formats when converting to OpenGL. (diff)
downloadyuzu-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.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp32
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h44
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
37using SurfaceType = SurfaceParams::SurfaceType; 37using SurfaceType = SurfaceParams::SurfaceType;
38using PixelFormat = SurfaceParams::PixelFormat; 38using PixelFormat = SurfaceParams::PixelFormat;
39using ComponentType = SurfaceParams::ComponentType;
39 40
40struct FormatTuple { 41struct 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
55static const FormatTuple& GetFormatTuple(PixelFormat pixel_format) { 56static 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
303bool SurfaceParams::ExactMatch(const SurfaceParams& other_surface) const { 305bool 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
230struct CachedSurface : SurfaceParams { 274struct CachedSurface : SurfaceParams {