diff options
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 69 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 46 |
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 | ||
| 32 | SurfaceParams::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 | ||
| 48 | SurfaceParams::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 | ||
| 56 | static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ | 64 | static 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 | ||
| 360 | Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextureInfo& config) { | 368 | Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextureInfo& config) { |
| 361 | return GetSurface(SurfaceParams(config)); | 369 | return GetSurface(SurfaceParams::CreateForTexture(config)); |
| 362 | } | 370 | } |
| 363 | 371 | ||
| 364 | SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( | 372 | SurfaceSurfaceRect_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 | ||
| 440 | Surface RasterizerCacheOpenGL::TryFindFramebufferSurface(VAddr cpu_addr) const { | 449 | Surface 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 | |||
| 275 | struct SurfaceKey : Common::HashableStruct<SurfaceParams> { | ||
| 276 | static SurfaceKey Create(const SurfaceParams& params) { | ||
| 277 | SurfaceKey res; | ||
| 278 | res.state = params; | ||
| 279 | return res; | ||
| 280 | } | ||
| 281 | }; | ||
| 282 | |||
| 283 | namespace std { | ||
| 284 | template <> | ||
| 285 | struct hash<SurfaceKey> { | ||
| 286 | size_t operator()(const SurfaceKey& k) const { | ||
| 287 | return k.Hash(); | ||
| 288 | } | ||
| 270 | }; | 289 | }; |
| 290 | } // namespace std | ||
| 271 | 291 | ||
| 272 | class CachedSurface final { | 292 | class CachedSurface final { |
| 273 | public: | 293 | public: |
| @@ -317,7 +337,7 @@ public: | |||
| 317 | private: | 337 | private: |
| 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 | }; |