summaryrefslogtreecommitdiffstats
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-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:
BitField<12, 1, InvMemoryLayout> type;
} memory_layout;
union {
- BitField<0, 16, u32> array_mode;
+ BitField<0, 16, u32> layers;
BitField<16, 1, u32> volume;
};
u32 layer_stride;
@@ -778,8 +778,12 @@ public:
u32 zeta_width;
u32 zeta_height;
+ union {
+ BitField<0, 16, u32> zeta_layers;
+ BitField<16, 1, u32> zeta_volume;
+ };
- INSERT_UNION_PADDING_WORDS(0x27);
+ INSERT_UNION_PADDING_WORDS(0x26);
u32 depth_test_enable;
@@ -1475,6 +1479,7 @@ ASSERT_REG_POSITION(vertex_attrib_format, 0x458);
ASSERT_REG_POSITION(rt_control, 0x487);
ASSERT_REG_POSITION(zeta_width, 0x48a);
ASSERT_REG_POSITION(zeta_height, 0x48b);
+ASSERT_REG_POSITION(zeta_layers, 0x48c);
ASSERT_REG_POSITION(depth_test_enable, 0x4B3);
ASSERT_REG_POSITION(independent_blend_enable, 0x4B9);
ASSERT_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
CachedSurfaceView::~CachedSurfaceView() = default;
void CachedSurfaceView::Attach(GLenum attachment, GLenum target) const {
- ASSERT(params.num_layers == 1 && params.num_levels == 1);
+ ASSERT(params.num_levels == 1);
- const auto& owner_params = surface.GetSurfaceParams();
+ const GLuint texture = surface.GetTexture();
+ if (params.num_layers > 1) {
+ // Layered framebuffer attachments
+ UNIMPLEMENTED_IF(params.base_layer != 0);
+
+ switch (params.target) {
+ case SurfaceTarget::Texture2DArray:
+ glFramebufferTexture(target, attachment, texture, params.base_level);
+ break;
+ default:
+ UNIMPLEMENTED();
+ }
+ return;
+ }
- switch (owner_params.target) {
+ const GLenum view_target = surface.GetTarget();
+ switch (surface.GetSurfaceParams().target) {
case SurfaceTarget::Texture1D:
- glFramebufferTexture1D(target, attachment, surface.GetTarget(), surface.GetTexture(),
- params.base_level);
+ glFramebufferTexture1D(target, attachment, view_target, texture, params.base_level);
break;
case SurfaceTarget::Texture2D:
- glFramebufferTexture2D(target, attachment, surface.GetTarget(), surface.GetTexture(),
- params.base_level);
+ glFramebufferTexture2D(target, attachment, view_target, texture, params.base_level);
break;
case SurfaceTarget::Texture1DArray:
case SurfaceTarget::Texture2DArray:
case SurfaceTarget::TextureCubemap:
case SurfaceTarget::TextureCubeArray:
- glFramebufferTextureLayer(target, attachment, surface.GetTexture(), params.base_level,
+ glFramebufferTextureLayer(target, attachment, texture, params.base_level,
params.base_layer);
break;
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
std::tuple<vk::Framebuffer, vk::Extent2D> RasterizerVulkan::ConfigureFramebuffers(
vk::RenderPass renderpass) {
FramebufferCacheKey key{renderpass, std::numeric_limits<u32>::max(),
- std::numeric_limits<u32>::max()};
+ std::numeric_limits<u32>::max(), std::numeric_limits<u32>::max()};
- const auto MarkAsModifiedAndPush = [&](const View& view) {
- if (view == nullptr) {
+ const auto try_push = [&](const View& view) {
+ if (!view) {
return false;
}
key.views.push_back(view->GetHandle());
key.width = std::min(key.width, view->GetWidth());
key.height = std::min(key.height, view->GetHeight());
+ key.layers = std::min(key.layers, view->GetNumLayers());
return true;
};
for (std::size_t index = 0; index < std::size(color_attachments); ++index) {
- if (MarkAsModifiedAndPush(color_attachments[index])) {
+ if (try_push(color_attachments[index])) {
texture_cache.MarkColorBufferInUse(index);
}
}
- if (MarkAsModifiedAndPush(zeta_attachment)) {
+ if (try_push(zeta_attachment)) {
texture_cache.MarkDepthBufferInUse();
}
const auto [fbentry, is_cache_miss] = framebuffer_cache.try_emplace(key);
auto& framebuffer = fbentry->second;
if (is_cache_miss) {
- const vk::FramebufferCreateInfo framebuffer_ci({}, key.renderpass,
- static_cast<u32>(key.views.size()),
- key.views.data(), key.width, key.height, 1);
+ const vk::FramebufferCreateInfo framebuffer_ci(
+ {}, key.renderpass, static_cast<u32>(key.views.size()), key.views.data(), key.width,
+ key.height, key.layers);
const auto dev = device.GetLogical();
const auto& dld = device.GetDispatchLoader();
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 {
vk::RenderPass renderpass{};
u32 width = 0;
u32 height = 0;
+ u32 layers = 0;
ImageViewsPack views;
std::size_t Hash() const noexcept {
@@ -65,12 +66,17 @@ struct FramebufferCacheKey {
}
boost::hash_combine(hash, width);
boost::hash_combine(hash, height);
+ boost::hash_combine(hash, layers);
return hash;
}
bool operator==(const FramebufferCacheKey& rhs) const noexcept {
- return std::tie(renderpass, views, width, height) ==
- std::tie(rhs.renderpass, rhs.views, rhs.width, rhs.height);
+ return std::tie(renderpass, views, width, height, layers) ==
+ std::tie(rhs.renderpass, rhs.views, rhs.width, rhs.height, rhs.layers);
+ }
+
+ bool operator!=(const FramebufferCacheKey& rhs) const noexcept {
+ return !operator==(rhs);
}
};
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:
return params.GetMipHeight(base_level);
}
+ u32 GetNumLayers() const {
+ return num_layers;
+ }
+
bool IsBufferView() const {
return buffer_view;
}
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
if (entry.IsShadow() && params.type == SurfaceType::ColorTexture) {
switch (params.pixel_format) {
case PixelFormat::R16U:
- case PixelFormat::R16F: {
+ case PixelFormat::R16F:
params.pixel_format = PixelFormat::Z16;
break;
- }
- case PixelFormat::R32F: {
+ case PixelFormat::R32F:
params.pixel_format = PixelFormat::Z32F;
break;
- }
- default: {
+ default:
UNIMPLEMENTED_MSG("Unimplemented shadow convert format: {}",
static_cast<u32>(params.pixel_format));
}
- }
params.type = GetFormatType(params.pixel_format);
}
params.type = GetFormatType(params.pixel_format);
@@ -168,27 +165,29 @@ SurfaceParams SurfaceParams::CreateForImage(const FormatLookupTable& lookup_tabl
return params;
}
-SurfaceParams SurfaceParams::CreateForDepthBuffer(
- Core::System& system, u32 zeta_width, u32 zeta_height, Tegra::DepthFormat format,
- u32 block_width, u32 block_height, u32 block_depth,
- Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout type) {
+SurfaceParams SurfaceParams::CreateForDepthBuffer(Core::System& system) {
+ const auto& regs = system.GPU().Maxwell3D().regs;
+ regs.zeta_width, regs.zeta_height, regs.zeta.format, regs.zeta.memory_layout.type;
SurfaceParams params;
- params.is_tiled = type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear;
+ params.is_tiled = regs.zeta.memory_layout.type ==
+ Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear;
params.srgb_conversion = false;
- params.block_width = std::min(block_width, 5U);
- params.block_height = std::min(block_height, 5U);
- params.block_depth = std::min(block_depth, 5U);
+ params.block_width = std::min(regs.zeta.memory_layout.block_width.Value(), 5U);
+ params.block_height = std::min(regs.zeta.memory_layout.block_height.Value(), 5U);
+ params.block_depth = std::min(regs.zeta.memory_layout.block_depth.Value(), 5U);
params.tile_width_spacing = 1;
- params.pixel_format = PixelFormatFromDepthFormat(format);
+ params.pixel_format = PixelFormatFromDepthFormat(regs.zeta.format);
params.type = GetFormatType(params.pixel_format);
- params.width = zeta_width;
- params.height = zeta_height;
- params.target = SurfaceTarget::Texture2D;
- params.depth = 1;
+ params.width = regs.zeta_width;
+ params.height = regs.zeta_height;
params.pitch = 0;
params.num_levels = 1;
params.emulated_levels = 1;
- params.is_layered = false;
+
+ const bool is_layered = regs.zeta_layers > 1 && params.block_depth == 0;
+ params.is_layered = is_layered;
+ params.target = is_layered ? SurfaceTarget::Texture2DArray : SurfaceTarget::Texture2D;
+ params.depth = is_layered ? regs.zeta_layers.Value() : 1U;
return params;
}
@@ -214,11 +213,13 @@ SurfaceParams SurfaceParams::CreateForFramebuffer(Core::System& system, std::siz
params.width = params.pitch / bpp;
}
params.height = config.height;
- params.depth = 1;
- params.target = SurfaceTarget::Texture2D;
params.num_levels = 1;
params.emulated_levels = 1;
- params.is_layered = false;
+
+ const bool is_layered = config.layers > 1 && params.block_depth == 0;
+ params.is_layered = is_layered;
+ params.depth = is_layered ? config.layers.Value() : 1;
+ params.target = is_layered ? SurfaceTarget::Texture2DArray : SurfaceTarget::Texture2D;
return params;
}
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:
const VideoCommon::Shader::Image& entry);
/// Creates SurfaceCachedParams for a depth buffer configuration.
- static SurfaceParams CreateForDepthBuffer(
- Core::System& system, u32 zeta_width, u32 zeta_height, Tegra::DepthFormat format,
- u32 block_width, u32 block_height, u32 block_depth,
- Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout type);
+ static SurfaceParams CreateForDepthBuffer(Core::System& system);
/// Creates SurfaceCachedParams from a framebuffer configuration.
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:
SetEmptyDepthBuffer();
return {};
}
- const auto depth_params{SurfaceParams::CreateForDepthBuffer(
- system, regs.zeta_width, regs.zeta_height, regs.zeta.format,
- regs.zeta.memory_layout.block_width, regs.zeta.memory_layout.block_height,
- regs.zeta.memory_layout.block_depth, regs.zeta.memory_layout.type)};
+ const auto depth_params{SurfaceParams::CreateForDepthBuffer(system)};
auto surface_view = GetSurface(gpu_addr, cache_addr, depth_params, preserve_contents, true);
if (depth_buffer.target)
depth_buffer.target->MarkAsRenderTarget(false, NO_RT);