summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2020-02-24 10:14:50 -0500
committerGravatar GitHub2020-02-24 10:14:50 -0500
commite22ad52cdb18842a12037e8b85d7be854b95206c (patch)
treef60ec07ce5a4e6f56a1c9c5e18884de52de81334 /src
parentMerge pull request #3424 from ReinUsesLisp/spirv-layer (diff)
parenttexture_cache: Implement layered framebuffer attachments (diff)
downloadyuzu-e22ad52cdb18842a12037e8b85d7be854b95206c.tar.gz
yuzu-e22ad52cdb18842a12037e8b85d7be854b95206c.tar.xz
yuzu-e22ad52cdb18842a12037e8b85d7be854b95206c.zip
Merge pull request #3425 from ReinUsesLisp/layered-framebuffer
texture_cache: Implement layered framebuffer attachments
Diffstat (limited to 'src')
-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 26939be3f..6ea7cc6a5 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -542,7 +542,7 @@ public:
542 BitField<12, 1, InvMemoryLayout> type; 542 BitField<12, 1, InvMemoryLayout> type;
543 } memory_layout; 543 } memory_layout;
544 union { 544 union {
545 BitField<0, 16, u32> array_mode; 545 BitField<0, 16, u32> layers;
546 BitField<16, 1, u32> volume; 546 BitField<16, 1, u32> volume;
547 }; 547 };
548 u32 layer_stride; 548 u32 layer_stride;
@@ -800,8 +800,12 @@ public:
800 800
801 u32 zeta_width; 801 u32 zeta_width;
802 u32 zeta_height; 802 u32 zeta_height;
803 union {
804 BitField<0, 16, u32> zeta_layers;
805 BitField<16, 1, u32> zeta_volume;
806 };
803 807
804 INSERT_UNION_PADDING_WORDS(0x27); 808 INSERT_UNION_PADDING_WORDS(0x26);
805 809
806 u32 depth_test_enable; 810 u32 depth_test_enable;
807 811
@@ -1507,6 +1511,7 @@ ASSERT_REG_POSITION(vertex_attrib_format, 0x458);
1507ASSERT_REG_POSITION(rt_control, 0x487); 1511ASSERT_REG_POSITION(rt_control, 0x487);
1508ASSERT_REG_POSITION(zeta_width, 0x48a); 1512ASSERT_REG_POSITION(zeta_width, 0x48a);
1509ASSERT_REG_POSITION(zeta_height, 0x48b); 1513ASSERT_REG_POSITION(zeta_height, 0x48b);
1514ASSERT_REG_POSITION(zeta_layers, 0x48c);
1510ASSERT_REG_POSITION(depth_test_enable, 0x4B3); 1515ASSERT_REG_POSITION(depth_test_enable, 0x4B3);
1511ASSERT_REG_POSITION(independent_blend_enable, 0x4B9); 1516ASSERT_REG_POSITION(independent_blend_enable, 0x4B9);
1512ASSERT_REG_POSITION(depth_write_enabled, 0x4BA); 1517ASSERT_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 5c1ae1418..c4c0bd226 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -405,24 +405,36 @@ CachedSurfaceView::CachedSurfaceView(CachedSurface& surface, const ViewParams& p
405CachedSurfaceView::~CachedSurfaceView() = default; 405CachedSurfaceView::~CachedSurfaceView() = default;
406 406
407void CachedSurfaceView::Attach(GLenum attachment, GLenum target) const { 407void CachedSurfaceView::Attach(GLenum attachment, GLenum target) const {
408 ASSERT(params.num_layers == 1 && params.num_levels == 1); 408 ASSERT(params.num_levels == 1);
409 409
410 const auto& owner_params = surface.GetSurfaceParams(); 410 const GLuint texture = surface.GetTexture();
411 if (params.num_layers > 1) {
412 // Layered framebuffer attachments
413 UNIMPLEMENTED_IF(params.base_layer != 0);
414
415 switch (params.target) {
416 case SurfaceTarget::Texture2DArray:
417 glFramebufferTexture(target, attachment, texture, params.base_level);
418 break;
419 default:
420 UNIMPLEMENTED();
421 }
422 return;
423 }
411 424
412 switch (owner_params.target) { 425 const GLenum view_target = surface.GetTarget();
426 switch (surface.GetSurfaceParams().target) {
413 case SurfaceTarget::Texture1D: 427 case SurfaceTarget::Texture1D:
414 glFramebufferTexture1D(target, attachment, surface.GetTarget(), surface.GetTexture(), 428 glFramebufferTexture1D(target, attachment, view_target, texture, params.base_level);
415 params.base_level);
416 break; 429 break;
417 case SurfaceTarget::Texture2D: 430 case SurfaceTarget::Texture2D:
418 glFramebufferTexture2D(target, attachment, surface.GetTarget(), surface.GetTexture(), 431 glFramebufferTexture2D(target, attachment, view_target, texture, params.base_level);
419 params.base_level);
420 break; 432 break;
421 case SurfaceTarget::Texture1DArray: 433 case SurfaceTarget::Texture1DArray:
422 case SurfaceTarget::Texture2DArray: 434 case SurfaceTarget::Texture2DArray:
423 case SurfaceTarget::TextureCubemap: 435 case SurfaceTarget::TextureCubemap:
424 case SurfaceTarget::TextureCubeArray: 436 case SurfaceTarget::TextureCubeArray:
425 glFramebufferTextureLayer(target, attachment, surface.GetTexture(), params.base_level, 437 glFramebufferTextureLayer(target, attachment, texture, params.base_level,
426 params.base_layer); 438 params.base_layer);
427 break; 439 break;
428 default: 440 default:
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 31c078f6a..3bf86da87 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -611,33 +611,34 @@ bool RasterizerVulkan::WalkAttachmentOverlaps(const CachedSurfaceView& attachmen
611std::tuple<vk::Framebuffer, vk::Extent2D> RasterizerVulkan::ConfigureFramebuffers( 611std::tuple<vk::Framebuffer, vk::Extent2D> RasterizerVulkan::ConfigureFramebuffers(
612 vk::RenderPass renderpass) { 612 vk::RenderPass renderpass) {
613 FramebufferCacheKey key{renderpass, std::numeric_limits<u32>::max(), 613 FramebufferCacheKey key{renderpass, std::numeric_limits<u32>::max(),
614 std::numeric_limits<u32>::max()}; 614 std::numeric_limits<u32>::max(), std::numeric_limits<u32>::max()};
615 615
616 const auto MarkAsModifiedAndPush = [&](const View& view) { 616 const auto try_push = [&](const View& view) {
617 if (view == nullptr) { 617 if (!view) {
618 return false; 618 return false;
619 } 619 }
620 key.views.push_back(view->GetHandle()); 620 key.views.push_back(view->GetHandle());
621 key.width = std::min(key.width, view->GetWidth()); 621 key.width = std::min(key.width, view->GetWidth());
622 key.height = std::min(key.height, view->GetHeight()); 622 key.height = std::min(key.height, view->GetHeight());
623 key.layers = std::min(key.layers, view->GetNumLayers());
623 return true; 624 return true;
624 }; 625 };
625 626
626 for (std::size_t index = 0; index < std::size(color_attachments); ++index) { 627 for (std::size_t index = 0; index < std::size(color_attachments); ++index) {
627 if (MarkAsModifiedAndPush(color_attachments[index])) { 628 if (try_push(color_attachments[index])) {
628 texture_cache.MarkColorBufferInUse(index); 629 texture_cache.MarkColorBufferInUse(index);
629 } 630 }
630 } 631 }
631 if (MarkAsModifiedAndPush(zeta_attachment)) { 632 if (try_push(zeta_attachment)) {
632 texture_cache.MarkDepthBufferInUse(); 633 texture_cache.MarkDepthBufferInUse();
633 } 634 }
634 635
635 const auto [fbentry, is_cache_miss] = framebuffer_cache.try_emplace(key); 636 const auto [fbentry, is_cache_miss] = framebuffer_cache.try_emplace(key);
636 auto& framebuffer = fbentry->second; 637 auto& framebuffer = fbentry->second;
637 if (is_cache_miss) { 638 if (is_cache_miss) {
638 const vk::FramebufferCreateInfo framebuffer_ci({}, key.renderpass, 639 const vk::FramebufferCreateInfo framebuffer_ci(
639 static_cast<u32>(key.views.size()), 640 {}, key.renderpass, static_cast<u32>(key.views.size()), key.views.data(), key.width,
640 key.views.data(), key.width, key.height, 1); 641 key.height, key.layers);
641 const auto dev = device.GetLogical(); 642 const auto dev = device.GetLogical();
642 const auto& dld = device.GetDispatchLoader(); 643 const auto& dld = device.GetDispatchLoader();
643 framebuffer = dev.createFramebufferUnique(framebuffer_ci, nullptr, dld); 644 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 138903d60..4dc8af6e8 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -56,6 +56,7 @@ struct FramebufferCacheKey {
56 vk::RenderPass renderpass{}; 56 vk::RenderPass renderpass{};
57 u32 width = 0; 57 u32 width = 0;
58 u32 height = 0; 58 u32 height = 0;
59 u32 layers = 0;
59 ImageViewsPack views; 60 ImageViewsPack views;
60 61
61 std::size_t Hash() const noexcept { 62 std::size_t Hash() const noexcept {
@@ -66,12 +67,17 @@ struct FramebufferCacheKey {
66 } 67 }
67 boost::hash_combine(hash, width); 68 boost::hash_combine(hash, width);
68 boost::hash_combine(hash, height); 69 boost::hash_combine(hash, height);
70 boost::hash_combine(hash, layers);
69 return hash; 71 return hash;
70 } 72 }
71 73
72 bool operator==(const FramebufferCacheKey& rhs) const noexcept { 74 bool operator==(const FramebufferCacheKey& rhs) const noexcept {
73 return std::tie(renderpass, views, width, height) == 75 return std::tie(renderpass, views, width, height, layers) ==
74 std::tie(rhs.renderpass, rhs.views, rhs.width, rhs.height); 76 std::tie(rhs.renderpass, rhs.views, rhs.width, rhs.height, rhs.layers);
77 }
78
79 bool operator!=(const FramebufferCacheKey& rhs) const noexcept {
80 return !operator==(rhs);
75 } 81 }
76}; 82};
77 83
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 0d105d386..c70e4aec2 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);