summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/engines/maxwell_3d.h9
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp28
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp17
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h10
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h4
-rw-r--r--src/video_core/texture_cache/surface_params.cpp47
-rw-r--r--src/video_core/texture_cache/surface_params.h5
-rw-r--r--src/video_core/texture_cache/texture_cache.h5
8 files changed, 74 insertions, 51 deletions
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 0a2af54e5..432596e27 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -520,7 +520,7 @@ public:
520 BitField<12, 1, InvMemoryLayout> type; 520 BitField<12, 1, InvMemoryLayout> type;
521 } memory_layout; 521 } memory_layout;
522 union { 522 union {
523 BitField<0, 16, u32> array_mode; 523 BitField<0, 16, u32> layers;
524 BitField<16, 1, u32> volume; 524 BitField<16, 1, u32> volume;
525 }; 525 };
526 u32 layer_stride; 526 u32 layer_stride;
@@ -778,8 +778,12 @@ public:
778 778
779 u32 zeta_width; 779 u32 zeta_width;
780 u32 zeta_height; 780 u32 zeta_height;
781 union {
782 BitField<0, 16, u32> zeta_layers;
783 BitField<16, 1, u32> zeta_volume;
784 };
781 785
782 INSERT_UNION_PADDING_WORDS(0x27); 786 INSERT_UNION_PADDING_WORDS(0x26);
783 787
784 u32 depth_test_enable; 788 u32 depth_test_enable;
785 789
@@ -1475,6 +1479,7 @@ ASSERT_REG_POSITION(vertex_attrib_format, 0x458);
1475ASSERT_REG_POSITION(rt_control, 0x487); 1479ASSERT_REG_POSITION(rt_control, 0x487);
1476ASSERT_REG_POSITION(zeta_width, 0x48a); 1480ASSERT_REG_POSITION(zeta_width, 0x48a);
1477ASSERT_REG_POSITION(zeta_height, 0x48b); 1481ASSERT_REG_POSITION(zeta_height, 0x48b);
1482ASSERT_REG_POSITION(zeta_layers, 0x48c);
1478ASSERT_REG_POSITION(depth_test_enable, 0x4B3); 1483ASSERT_REG_POSITION(depth_test_enable, 0x4B3);
1479ASSERT_REG_POSITION(independent_blend_enable, 0x4B9); 1484ASSERT_REG_POSITION(independent_blend_enable, 0x4B9);
1480ASSERT_REG_POSITION(depth_write_enabled, 0x4BA); 1485ASSERT_REG_POSITION(depth_write_enabled, 0x4BA);
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index d4b81cd87..af520e332 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -398,24 +398,36 @@ CachedSurfaceView::CachedSurfaceView(CachedSurface& surface, const ViewParams& p
398CachedSurfaceView::~CachedSurfaceView() = default; 398CachedSurfaceView::~CachedSurfaceView() = default;
399 399
400void CachedSurfaceView::Attach(GLenum attachment, GLenum target) const { 400void CachedSurfaceView::Attach(GLenum attachment, GLenum target) const {
401 ASSERT(params.num_layers == 1 && params.num_levels == 1); 401 ASSERT(params.num_levels == 1);
402 402
403 const auto& owner_params = surface.GetSurfaceParams(); 403 const GLuint texture = surface.GetTexture();
404 if (params.num_layers > 1) {
405 // Layered framebuffer attachments
406 UNIMPLEMENTED_IF(params.base_layer != 0);
407
408 switch (params.target) {
409 case SurfaceTarget::Texture2DArray:
410 glFramebufferTexture(target, attachment, texture, params.base_level);
411 break;
412 default:
413 UNIMPLEMENTED();
414 }
415 return;
416 }
404 417
405 switch (owner_params.target) { 418 const GLenum view_target = surface.GetTarget();
419 switch (surface.GetSurfaceParams().target) {
406 case SurfaceTarget::Texture1D: 420 case SurfaceTarget::Texture1D:
407 glFramebufferTexture1D(target, attachment, surface.GetTarget(), surface.GetTexture(), 421 glFramebufferTexture1D(target, attachment, view_target, texture, params.base_level);
408 params.base_level);
409 break; 422 break;
410 case SurfaceTarget::Texture2D: 423 case SurfaceTarget::Texture2D:
411 glFramebufferTexture2D(target, attachment, surface.GetTarget(), surface.GetTexture(), 424 glFramebufferTexture2D(target, attachment, view_target, texture, params.base_level);
412 params.base_level);
413 break; 425 break;
414 case SurfaceTarget::Texture1DArray: 426 case SurfaceTarget::Texture1DArray:
415 case SurfaceTarget::Texture2DArray: 427 case SurfaceTarget::Texture2DArray:
416 case SurfaceTarget::TextureCubemap: 428 case SurfaceTarget::TextureCubemap:
417 case SurfaceTarget::TextureCubeArray: 429 case SurfaceTarget::TextureCubeArray:
418 glFramebufferTextureLayer(target, attachment, surface.GetTexture(), params.base_level, 430 glFramebufferTextureLayer(target, attachment, texture, params.base_level,
419 params.base_layer); 431 params.base_layer);
420 break; 432 break;
421 default: 433 default:
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index aada38702..34044500d 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -602,33 +602,34 @@ bool RasterizerVulkan::WalkAttachmentOverlaps(const CachedSurfaceView& attachmen
602std::tuple<vk::Framebuffer, vk::Extent2D> RasterizerVulkan::ConfigureFramebuffers( 602std::tuple<vk::Framebuffer, vk::Extent2D> RasterizerVulkan::ConfigureFramebuffers(
603 vk::RenderPass renderpass) { 603 vk::RenderPass renderpass) {
604 FramebufferCacheKey key{renderpass, std::numeric_limits<u32>::max(), 604 FramebufferCacheKey key{renderpass, std::numeric_limits<u32>::max(),
605 std::numeric_limits<u32>::max()}; 605 std::numeric_limits<u32>::max(), std::numeric_limits<u32>::max()};
606 606
607 const auto MarkAsModifiedAndPush = [&](const View& view) { 607 const auto try_push = [&](const View& view) {
608 if (view == nullptr) { 608 if (!view) {
609 return false; 609 return false;
610 } 610 }
611 key.views.push_back(view->GetHandle()); 611 key.views.push_back(view->GetHandle());
612 key.width = std::min(key.width, view->GetWidth()); 612 key.width = std::min(key.width, view->GetWidth());
613 key.height = std::min(key.height, view->GetHeight()); 613 key.height = std::min(key.height, view->GetHeight());
614 key.layers = std::min(key.layers, view->GetNumLayers());
614 return true; 615 return true;
615 }; 616 };
616 617
617 for (std::size_t index = 0; index < std::size(color_attachments); ++index) { 618 for (std::size_t index = 0; index < std::size(color_attachments); ++index) {
618 if (MarkAsModifiedAndPush(color_attachments[index])) { 619 if (try_push(color_attachments[index])) {
619 texture_cache.MarkColorBufferInUse(index); 620 texture_cache.MarkColorBufferInUse(index);
620 } 621 }
621 } 622 }
622 if (MarkAsModifiedAndPush(zeta_attachment)) { 623 if (try_push(zeta_attachment)) {
623 texture_cache.MarkDepthBufferInUse(); 624 texture_cache.MarkDepthBufferInUse();
624 } 625 }
625 626
626 const auto [fbentry, is_cache_miss] = framebuffer_cache.try_emplace(key); 627 const auto [fbentry, is_cache_miss] = framebuffer_cache.try_emplace(key);
627 auto& framebuffer = fbentry->second; 628 auto& framebuffer = fbentry->second;
628 if (is_cache_miss) { 629 if (is_cache_miss) {
629 const vk::FramebufferCreateInfo framebuffer_ci({}, key.renderpass, 630 const vk::FramebufferCreateInfo framebuffer_ci(
630 static_cast<u32>(key.views.size()), 631 {}, key.renderpass, static_cast<u32>(key.views.size()), key.views.data(), key.width,
631 key.views.data(), key.width, key.height, 1); 632 key.height, key.layers);
632 const auto dev = device.GetLogical(); 633 const auto dev = device.GetLogical();
633 const auto& dld = device.GetDispatchLoader(); 634 const auto& dld = device.GetDispatchLoader();
634 framebuffer = dev.createFramebufferUnique(framebuffer_ci, nullptr, dld); 635 framebuffer = dev.createFramebufferUnique(framebuffer_ci, nullptr, dld);
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index 7be71e734..209927803 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -55,6 +55,7 @@ struct FramebufferCacheKey {
55 vk::RenderPass renderpass{}; 55 vk::RenderPass renderpass{};
56 u32 width = 0; 56 u32 width = 0;
57 u32 height = 0; 57 u32 height = 0;
58 u32 layers = 0;
58 ImageViewsPack views; 59 ImageViewsPack views;
59 60
60 std::size_t Hash() const noexcept { 61 std::size_t Hash() const noexcept {
@@ -65,12 +66,17 @@ struct FramebufferCacheKey {
65 } 66 }
66 boost::hash_combine(hash, width); 67 boost::hash_combine(hash, width);
67 boost::hash_combine(hash, height); 68 boost::hash_combine(hash, height);
69 boost::hash_combine(hash, layers);
68 return hash; 70 return hash;
69 } 71 }
70 72
71 bool operator==(const FramebufferCacheKey& rhs) const noexcept { 73 bool operator==(const FramebufferCacheKey& rhs) const noexcept {
72 return std::tie(renderpass, views, width, height) == 74 return std::tie(renderpass, views, width, height, layers) ==
73 std::tie(rhs.renderpass, rhs.views, rhs.width, rhs.height); 75 std::tie(rhs.renderpass, rhs.views, rhs.width, rhs.height, rhs.layers);
76 }
77
78 bool operator!=(const FramebufferCacheKey& rhs) const noexcept {
79 return !operator==(rhs);
74 } 80 }
75}; 81};
76 82
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h
index d3edbe80c..22e3d34de 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.h
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.h
@@ -151,6 +151,10 @@ public:
151 return params.GetMipHeight(base_level); 151 return params.GetMipHeight(base_level);
152 } 152 }
153 153
154 u32 GetNumLayers() const {
155 return num_layers;
156 }
157
154 bool IsBufferView() const { 158 bool IsBufferView() const {
155 return buffer_view; 159 return buffer_view;
156 } 160 }
diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp
index 38b3a4ba8..f00839313 100644
--- a/src/video_core/texture_cache/surface_params.cpp
+++ b/src/video_core/texture_cache/surface_params.cpp
@@ -84,19 +84,16 @@ SurfaceParams SurfaceParams::CreateForTexture(const FormatLookupTable& lookup_ta
84 if (entry.IsShadow() && params.type == SurfaceType::ColorTexture) { 84 if (entry.IsShadow() && params.type == SurfaceType::ColorTexture) {
85 switch (params.pixel_format) { 85 switch (params.pixel_format) {
86 case PixelFormat::R16U: 86 case PixelFormat::R16U:
87 case PixelFormat::R16F: { 87 case PixelFormat::R16F:
88 params.pixel_format = PixelFormat::Z16; 88 params.pixel_format = PixelFormat::Z16;
89 break; 89 break;
90 } 90 case PixelFormat::R32F:
91 case PixelFormat::R32F: {
92 params.pixel_format = PixelFormat::Z32F; 91 params.pixel_format = PixelFormat::Z32F;
93 break; 92 break;
94 } 93 default:
95 default: {
96 UNIMPLEMENTED_MSG("Unimplemented shadow convert format: {}", 94 UNIMPLEMENTED_MSG("Unimplemented shadow convert format: {}",
97 static_cast<u32>(params.pixel_format)); 95 static_cast<u32>(params.pixel_format));
98 } 96 }
99 }
100 params.type = GetFormatType(params.pixel_format); 97 params.type = GetFormatType(params.pixel_format);
101 } 98 }
102 params.type = GetFormatType(params.pixel_format); 99 params.type = GetFormatType(params.pixel_format);
@@ -168,27 +165,29 @@ SurfaceParams SurfaceParams::CreateForImage(const FormatLookupTable& lookup_tabl
168 return params; 165 return params;
169} 166}
170 167
171SurfaceParams SurfaceParams::CreateForDepthBuffer( 168SurfaceParams SurfaceParams::CreateForDepthBuffer(Core::System& system) {
172 Core::System& system, u32 zeta_width, u32 zeta_height, Tegra::DepthFormat format, 169 const auto& regs = system.GPU().Maxwell3D().regs;
173 u32 block_width, u32 block_height, u32 block_depth, 170 regs.zeta_width, regs.zeta_height, regs.zeta.format, regs.zeta.memory_layout.type;
174 Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout type) {
175 SurfaceParams params; 171 SurfaceParams params;
176 params.is_tiled = type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; 172 params.is_tiled = regs.zeta.memory_layout.type ==
173 Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear;
177 params.srgb_conversion = false; 174 params.srgb_conversion = false;
178 params.block_width = std::min(block_width, 5U); 175 params.block_width = std::min(regs.zeta.memory_layout.block_width.Value(), 5U);
179 params.block_height = std::min(block_height, 5U); 176 params.block_height = std::min(regs.zeta.memory_layout.block_height.Value(), 5U);
180 params.block_depth = std::min(block_depth, 5U); 177 params.block_depth = std::min(regs.zeta.memory_layout.block_depth.Value(), 5U);
181 params.tile_width_spacing = 1; 178 params.tile_width_spacing = 1;
182 params.pixel_format = PixelFormatFromDepthFormat(format); 179 params.pixel_format = PixelFormatFromDepthFormat(regs.zeta.format);
183 params.type = GetFormatType(params.pixel_format); 180 params.type = GetFormatType(params.pixel_format);
184 params.width = zeta_width; 181 params.width = regs.zeta_width;
185 params.height = zeta_height; 182 params.height = regs.zeta_height;
186 params.target = SurfaceTarget::Texture2D;
187 params.depth = 1;
188 params.pitch = 0; 183 params.pitch = 0;
189 params.num_levels = 1; 184 params.num_levels = 1;
190 params.emulated_levels = 1; 185 params.emulated_levels = 1;
191 params.is_layered = false; 186
187 const bool is_layered = regs.zeta_layers > 1 && params.block_depth == 0;
188 params.is_layered = is_layered;
189 params.target = is_layered ? SurfaceTarget::Texture2DArray : SurfaceTarget::Texture2D;
190 params.depth = is_layered ? regs.zeta_layers.Value() : 1U;
192 return params; 191 return params;
193} 192}
194 193
@@ -214,11 +213,13 @@ SurfaceParams SurfaceParams::CreateForFramebuffer(Core::System& system, std::siz
214 params.width = params.pitch / bpp; 213 params.width = params.pitch / bpp;
215 } 214 }
216 params.height = config.height; 215 params.height = config.height;
217 params.depth = 1;
218 params.target = SurfaceTarget::Texture2D;
219 params.num_levels = 1; 216 params.num_levels = 1;
220 params.emulated_levels = 1; 217 params.emulated_levels = 1;
221 params.is_layered = false; 218
219 const bool is_layered = config.layers > 1 && params.block_depth == 0;
220 params.is_layered = is_layered;
221 params.depth = is_layered ? config.layers.Value() : 1;
222 params.target = is_layered ? SurfaceTarget::Texture2DArray : SurfaceTarget::Texture2D;
222 return params; 223 return params;
223} 224}
224 225
diff --git a/src/video_core/texture_cache/surface_params.h b/src/video_core/texture_cache/surface_params.h
index 9256fd6d9..995cc3818 100644
--- a/src/video_core/texture_cache/surface_params.h
+++ b/src/video_core/texture_cache/surface_params.h
@@ -35,10 +35,7 @@ public:
35 const VideoCommon::Shader::Image& entry); 35 const VideoCommon::Shader::Image& entry);
36 36
37 /// Creates SurfaceCachedParams for a depth buffer configuration. 37 /// Creates SurfaceCachedParams for a depth buffer configuration.
38 static SurfaceParams CreateForDepthBuffer( 38 static SurfaceParams CreateForDepthBuffer(Core::System& system);
39 Core::System& system, u32 zeta_width, u32 zeta_height, Tegra::DepthFormat format,
40 u32 block_width, u32 block_height, u32 block_depth,
41 Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout type);
42 39
43 /// Creates SurfaceCachedParams from a framebuffer configuration. 40 /// Creates SurfaceCachedParams from a framebuffer configuration.
44 static SurfaceParams CreateForFramebuffer(Core::System& system, std::size_t index); 41 static SurfaceParams CreateForFramebuffer(Core::System& system, std::size_t index);
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index f4c015635..a850e7593 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -160,10 +160,7 @@ public:
160 SetEmptyDepthBuffer(); 160 SetEmptyDepthBuffer();
161 return {}; 161 return {};
162 } 162 }
163 const auto depth_params{SurfaceParams::CreateForDepthBuffer( 163 const auto depth_params{SurfaceParams::CreateForDepthBuffer(system)};
164 system, regs.zeta_width, regs.zeta_height, regs.zeta.format,
165 regs.zeta.memory_layout.block_width, regs.zeta.memory_layout.block_height,
166 regs.zeta.memory_layout.block_depth, regs.zeta.memory_layout.type)};
167 auto surface_view = GetSurface(gpu_addr, cache_addr, depth_params, preserve_contents, true); 164 auto surface_view = GetSurface(gpu_addr, cache_addr, depth_params, preserve_contents, true);
168 if (depth_buffer.target) 165 if (depth_buffer.target)
169 depth_buffer.target->MarkAsRenderTarget(false, NO_RT); 166 depth_buffer.target->MarkAsRenderTarget(false, NO_RT);