[Vulkan] Implement tiled_shared_memory for resolution scaling

Adds support for >3x resolution scaling to vulkan by implementing
sparse scaled resolve similar to the d3d12 implementation.
This commit is contained in:
Herman S.
2025-12-22 11:58:13 +09:00
parent a092551735
commit 5897de3eaf
10 changed files with 508 additions and 77 deletions

View File

@@ -851,8 +851,11 @@ bool D3D12CommandProcessor::SetupContext() {
TextureCache::GetConfigDrawResolutionScale(draw_resolution_scale_x,
draw_resolution_scale_y);
if (!D3D12TextureCache::ClampDrawResolutionScaleToMaxSupported(
draw_resolution_scale_x, draw_resolution_scale_y, provider)) {
bool has_tiled_resources =
provider.GetTiledResourcesTier() >= D3D12_TILED_RESOURCES_TIER_1;
if (!TextureCache::ClampDrawResolutionScaleToMaxSupported(
draw_resolution_scale_x, draw_resolution_scale_y, has_tiled_resources,
provider.GetVirtualAddressBitsPerResource())) {
draw_resolution_scale_not_clamped = false;
}
if (!draw_resolution_scale_not_clamped) {

View File

@@ -18,14 +18,8 @@
#include "xenia/gpu/d3d12/d3d12_command_processor.h"
#include "xenia/ui/d3d12/d3d12_util.h"
DEFINE_bool(d3d12_tiled_shared_memory, true,
"Enable tiled resources for shared memory emulation. Disabling "
"them increases video memory usage - a 512 MB buffer is created - "
"but allows graphics debuggers that don't support tiled resources "
"to work.",
"D3D12");
DECLARE_bool(gpu_allow_invalid_upload_range);
DECLARE_bool(tiled_shared_memory);
namespace xe {
namespace gpu {
@@ -50,7 +44,7 @@ bool D3D12SharedMemory::Initialize() {
ui::d3d12::util::FillBufferResourceDesc(
buffer_desc, kBufferSize, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
buffer_state_ = D3D12_RESOURCE_STATE_COPY_DEST;
if (cvars::d3d12_tiled_shared_memory &&
if (cvars::tiled_shared_memory &&
provider.GetTiledResourcesTier() !=
D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED &&
!provider.GetGraphicsAnalysis()) {

View File

@@ -846,40 +846,6 @@ void D3D12TextureCache::WriteSampler(SamplerParameters parameters,
device->CreateSampler(&desc, handle);
}
bool D3D12TextureCache::ClampDrawResolutionScaleToMaxSupported(
uint32_t& scale_x, uint32_t& scale_y,
const ui::d3d12::D3D12Provider& provider) {
bool was_clamped;
if (provider.GetTiledResourcesTier() < D3D12_TILED_RESOURCES_TIER_1) {
was_clamped = scale_x > 1 || scale_y > 1;
scale_x = 1;
scale_y = 1;
return !was_clamped;
}
// Limit to the virtual address space available for a resource.
was_clamped = false;
uint32_t virtual_address_bits_per_resource =
provider.GetVirtualAddressBitsPerResource();
while (scale_x > 1 || scale_y > 1) {
uint64_t highest_scaled_address =
uint64_t(SharedMemory::kBufferSize) * (scale_x * scale_y) - 1;
if (uint32_t(64) - xe::lzcnt(highest_scaled_address) <=
virtual_address_bits_per_resource) {
break;
}
// When reducing from a square size, prefer decreasing the horizontal
// resolution as vertical resolution difference is visible more clearly in
// perspective.
was_clamped = true;
if (scale_x >= scale_y) {
--scale_x;
} else {
--scale_y;
}
}
return !was_clamped;
}
bool D3D12TextureCache::EnsureScaledResolveMemoryCommitted(
uint32_t start_unscaled, uint32_t length_unscaled,
uint32_t length_scaled_alignment_log2) {

View File

@@ -126,10 +126,6 @@ class D3D12TextureCache final : public TextureCache {
void WriteSampler(SamplerParameters parameters,
D3D12_CPU_DESCRIPTOR_HANDLE handle) const;
// Returns whether the actual scale is not smaller than the requested one.
static bool ClampDrawResolutionScaleToMaxSupported(
uint32_t& scale_x, uint32_t& scale_y,
const ui::d3d12::D3D12Provider& provider);
// Ensures the tiles backing the range in the buffers are allocated.
bool EnsureScaledResolveMemoryCommitted(
uint32_t start_unscaled, uint32_t length_unscaled,