summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp69
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h46
2 files changed, 72 insertions, 43 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 919931d64..59f1a89c9 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -29,29 +29,37 @@ struct FormatTuple {
29 bool compressed; 29 bool compressed;
30}; 30};
31 31
32SurfaceParams::SurfaceParams(const Tegra::Texture::FullTextureInfo& config) 32/*static*/ SurfaceParams SurfaceParams::CreateForTexture(
33 : addr(config.tic.Address()), is_tiled(config.tic.IsTiled()), 33 const Tegra::Texture::FullTextureInfo& config) {
34 block_height(is_tiled ? config.tic.BlockHeight() : 0), 34
35 pixel_format(PixelFormatFromTextureFormat(config.tic.format)), 35 SurfaceParams params{};
36 component_type(ComponentTypeFromTexture(config.tic.r_type.Value())), 36 params.addr = config.tic.Address();
37 type(GetFormatType(pixel_format)), 37 params.is_tiled = config.tic.IsTiled();
38 width(Common::AlignUp(config.tic.Width(), GetCompressionFactor(pixel_format))), 38 params.block_height = params.is_tiled ? config.tic.BlockHeight() : 0,
39 height(Common::AlignUp(config.tic.Height(), GetCompressionFactor(pixel_format))), 39 params.pixel_format = PixelFormatFromTextureFormat(config.tic.format);
40 size_in_bytes(SizeInBytes()) { 40 params.component_type = ComponentTypeFromTexture(config.tic.r_type.Value());
41 41 params.type = GetFormatType(params.pixel_format);
42 // TODO(Subv): Different types per component are not supported. 42 params.width = Common::AlignUp(config.tic.Width(), GetCompressionFactor(params.pixel_format));
43 ASSERT(config.tic.r_type.Value() == config.tic.g_type.Value() && 43 params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format));
44 config.tic.r_type.Value() == config.tic.b_type.Value() && 44 params.size_in_bytes = params.SizeInBytes();
45 config.tic.r_type.Value() == config.tic.a_type.Value()); 45 return params;
46} 46}
47 47
48SurfaceParams::SurfaceParams(const Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig& config) 48/*static*/ SurfaceParams SurfaceParams::CreateForFramebuffer(
49 : addr(config.Address()), is_tiled(true), 49 const Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig& config) {
50 block_height(Tegra::Texture::TICEntry::DefaultBlockHeight), 50
51 pixel_format(PixelFormatFromRenderTargetFormat(config.format)), 51 SurfaceParams params{};
52 component_type(ComponentTypeFromRenderTarget(config.format)), 52 params.addr = config.Address();
53 type(GetFormatType(pixel_format)), width(config.width), height(config.height), 53 params.is_tiled = true;
54 size_in_bytes(SizeInBytes()) {} 54 params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight;
55 params.pixel_format = PixelFormatFromRenderTargetFormat(config.format);
56 params.component_type = ComponentTypeFromRenderTarget(config.format);
57 params.type = GetFormatType(params.pixel_format);
58 params.width = config.width;
59 params.height = config.height;
60 params.size_in_bytes = params.SizeInBytes();
61 return params;
62}
55 63
56static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ 64static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{
57 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false}, // ABGR8 65 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false}, // ABGR8
@@ -358,7 +366,7 @@ RasterizerCacheOpenGL::RasterizerCacheOpenGL() {
358} 366}
359 367
360Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextureInfo& config) { 368Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextureInfo& config) {
361 return GetSurface(SurfaceParams(config)); 369 return GetSurface(SurfaceParams::CreateForTexture(config));
362} 370}
363 371
364SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( 372SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(
@@ -369,8 +377,8 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(
369 NGLOG_WARNING(Render_OpenGL, "hard-coded for render target 0!"); 377 NGLOG_WARNING(Render_OpenGL, "hard-coded for render target 0!");
370 378
371 // get color and depth surfaces 379 // get color and depth surfaces
372 SurfaceParams color_params(regs.rt[0]); 380 const SurfaceParams color_params{SurfaceParams::CreateForFramebuffer(regs.rt[0])};
373 SurfaceParams depth_params = color_params; 381 const SurfaceParams depth_params{color_params};
374 382
375 ASSERT_MSG(!using_depth_fb, "depth buffer is unimplemented"); 383 ASSERT_MSG(!using_depth_fb, "depth buffer is unimplemented");
376 384
@@ -423,13 +431,14 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params) {
423 } 431 }
424 432
425 // Check for an exact match in existing surfaces 433 // Check for an exact match in existing surfaces
426 auto search = surface_cache.find(params.addr); 434 const auto& surface_key{SurfaceKey::Create(params)};
435 const auto& search{surface_cache.find(surface_key)};
427 Surface surface; 436 Surface surface;
428 if (search != surface_cache.end()) { 437 if (search != surface_cache.end()) {
429 surface = search->second; 438 surface = search->second;
430 } else { 439 } else {
431 surface = std::make_shared<CachedSurface>(params); 440 surface = std::make_shared<CachedSurface>(params);
432 surface_cache[params.addr] = surface; 441 surface_cache[surface_key] = surface;
433 } 442 }
434 443
435 LoadSurface(surface); 444 LoadSurface(surface);
@@ -439,10 +448,10 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params) {
439 448
440Surface RasterizerCacheOpenGL::TryFindFramebufferSurface(VAddr cpu_addr) const { 449Surface RasterizerCacheOpenGL::TryFindFramebufferSurface(VAddr cpu_addr) const {
441 // Tries to find the GPU address of a framebuffer based on the CPU address. This is because 450 // Tries to find the GPU address of a framebuffer based on the CPU address. This is because
442 // final output framebuffers are specified by CPU address, but internally our GPU cache uses GPU 451 // final output framebuffers are specified by CPU address, but internally our GPU cache uses
443 // addresses. We iterate through all cached framebuffers, and compare their starting CPU address 452 // GPU addresses. We iterate through all cached framebuffers, and compare their starting CPU
444 // to the one provided. This is obviously not great, and won't work if the framebuffer overlaps 453 // address to the one provided. This is obviously not great, and won't work if the
445 // surfaces. 454 // framebuffer overlaps surfaces.
446 455
447 std::vector<Surface> surfaces; 456 std::vector<Surface> surfaces;
448 for (const auto& surface : surface_cache) { 457 for (const auto& surface : surface_cache) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index 53ff2722d..bf36f6c24 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -9,6 +9,7 @@
9#include <memory> 9#include <memory>
10 10
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "common/hash.h"
12#include "common/math_util.h" 13#include "common/math_util.h"
13#include "video_core/engines/maxwell_3d.h" 14#include "video_core/engines/maxwell_3d.h"
14#include "video_core/renderer_opengl/gl_resource_manager.h" 15#include "video_core/renderer_opengl/gl_resource_manager.h"
@@ -253,21 +254,40 @@ struct SurfaceParams {
253 GetFormatBpp(pixel_format) / CHAR_BIT; 254 GetFormatBpp(pixel_format) / CHAR_BIT;
254 } 255 }
255 256
256 SurfaceParams(const Tegra::Texture::FullTextureInfo& config);
257 SurfaceParams(const Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig& config);
258
259 VAddr GetCpuAddr() const; 257 VAddr GetCpuAddr() const;
260 258
261 const Tegra::GPUVAddr addr; 259 static SurfaceParams CreateForTexture(const Tegra::Texture::FullTextureInfo& config);
262 const bool is_tiled; 260
263 const u32 block_height; 261 static SurfaceParams CreateForFramebuffer(
264 const PixelFormat pixel_format; 262 const Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig& config);
265 const ComponentType component_type; 263
266 const SurfaceType type; 264 Tegra::GPUVAddr addr;
267 const u32 width; 265 bool is_tiled;
268 const u32 height; 266 u32 block_height;
269 const size_t size_in_bytes; 267 PixelFormat pixel_format;
268 ComponentType component_type;
269 SurfaceType type;
270 u32 width;
271 u32 height;
272 size_t size_in_bytes;
273};
274
275struct SurfaceKey : Common::HashableStruct<SurfaceParams> {
276 static SurfaceKey Create(const SurfaceParams& params) {
277 SurfaceKey res;
278 res.state = params;
279 return res;
280 }
281};
282
283namespace std {
284template <>
285struct hash<SurfaceKey> {
286 size_t operator()(const SurfaceKey& k) const {
287 return k.Hash();
288 }
270}; 289};
290} // namespace std
271 291
272class CachedSurface final { 292class CachedSurface final {
273public: 293public:
@@ -317,7 +337,7 @@ public:
317private: 337private:
318 Surface GetSurface(const SurfaceParams& params); 338 Surface GetSurface(const SurfaceParams& params);
319 339
320 std::map<Tegra::GPUVAddr, Surface> surface_cache; 340 std::unordered_map<SurfaceKey, Surface> surface_cache;
321 OGLFramebuffer read_framebuffer; 341 OGLFramebuffer read_framebuffer;
322 OGLFramebuffer draw_framebuffer; 342 OGLFramebuffer draw_framebuffer;
323}; 343};