Merge branch 'master' of https://github.com/xenia-project/xenia into canary_experimental

This commit is contained in:
Gliniak
2022-06-02 22:19:43 +02:00
34 changed files with 27061 additions and 27648 deletions

View File

@@ -10,6 +10,7 @@
#include "xenia/gpu/d3d12/d3d12_render_target_cache.h"
#include <algorithm>
#include <array>
#include <cstdint>
#include <cstring>
#include <iterator>
@@ -347,7 +348,7 @@ bool D3D12RenderTargetCache::Initialize() {
bool draw_resolution_scaled = IsDrawResolutionScaled();
// Create the resolve copying root signature.
D3D12_ROOT_PARAMETER resolve_copy_root_parameters[4];
std::array<D3D12_ROOT_PARAMETER, 3> resolve_copy_root_parameters;
// Parameter 0 is constants.
resolve_copy_root_parameters[0].ParameterType =
D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
@@ -390,23 +391,11 @@ bool D3D12RenderTargetCache::Initialize() {
&resolve_copy_source_range;
resolve_copy_root_parameters[2].ShaderVisibility =
D3D12_SHADER_VISIBILITY_ALL;
// Parameter 3 is the resolution scale.
if (draw_resolution_scaled) {
resolve_copy_root_parameters[3].ParameterType =
D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
resolve_copy_root_parameters[3].Constants.ShaderRegister = 1;
resolve_copy_root_parameters[3].Constants.RegisterSpace = 0;
// Binding all of the shared memory at 1x resolution, portions with scaled
// resolution.
resolve_copy_root_parameters[3].Constants.Num32BitValues =
sizeof(draw_util::ResolveResolutionScaleConstant) / sizeof(uint32_t);
resolve_copy_root_parameters[3].ShaderVisibility =
D3D12_SHADER_VISIBILITY_ALL;
}
D3D12_ROOT_SIGNATURE_DESC resolve_copy_root_signature_desc;
resolve_copy_root_signature_desc.NumParameters =
draw_resolution_scaled ? 4 : 3;
resolve_copy_root_signature_desc.pParameters = resolve_copy_root_parameters;
UINT(resolve_copy_root_parameters.size());
resolve_copy_root_signature_desc.pParameters =
resolve_copy_root_parameters.data();
resolve_copy_root_signature_desc.NumStaticSamplers = 0;
resolve_copy_root_signature_desc.pStaticSamplers = nullptr;
resolve_copy_root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
@@ -1031,7 +1020,7 @@ bool D3D12RenderTargetCache::Initialize() {
msaa_2x_supported_ = false;
// Create the resolve EDRAM buffer clearing root signature.
D3D12_ROOT_PARAMETER resolve_rov_clear_root_parameters[3];
std::array<D3D12_ROOT_PARAMETER, 2> resolve_rov_clear_root_parameters;
// Parameter 0 is constants.
resolve_rov_clear_root_parameters[0].ParameterType =
D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
@@ -1058,24 +1047,11 @@ bool D3D12RenderTargetCache::Initialize() {
&resolve_rov_clear_dest_range;
resolve_rov_clear_root_parameters[1].ShaderVisibility =
D3D12_SHADER_VISIBILITY_ALL;
// Parameter 2 is the resolution scale.
if (draw_resolution_scaled) {
resolve_rov_clear_root_parameters[2].ParameterType =
D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
resolve_rov_clear_root_parameters[2].Constants.ShaderRegister = 1;
resolve_rov_clear_root_parameters[2].Constants.RegisterSpace = 0;
// Binding all of the shared memory at 1x resolution, portions with scaled
// resolution.
resolve_rov_clear_root_parameters[2].Constants.Num32BitValues =
sizeof(draw_util::ResolveResolutionScaleConstant) / sizeof(uint32_t);
resolve_rov_clear_root_parameters[2].ShaderVisibility =
D3D12_SHADER_VISIBILITY_ALL;
}
D3D12_ROOT_SIGNATURE_DESC resolve_rov_clear_root_signature_desc;
resolve_rov_clear_root_signature_desc.NumParameters =
draw_resolution_scaled ? 3 : 2;
UINT(resolve_rov_clear_root_parameters.size());
resolve_rov_clear_root_signature_desc.pParameters =
resolve_rov_clear_root_parameters;
resolve_rov_clear_root_parameters.data();
resolve_rov_clear_root_signature_desc.NumStaticSamplers = 0;
resolve_rov_clear_root_signature_desc.pStaticSamplers = nullptr;
resolve_rov_clear_root_signature_desc.Flags =
@@ -1354,26 +1330,24 @@ bool D3D12RenderTargetCache::Resolve(const Memory& memory,
draw_util::ResolveInfo resolve_info;
if (!draw_util::GetResolveInfo(
register_file(), memory, trace_writer_, draw_resolution_scaled,
IsFixed16TruncatedToMinus1To1(), resolve_info)) {
register_file(), memory, trace_writer_, draw_resolution_scale_x(),
draw_resolution_scale_y(), IsFixed16TruncatedToMinus1To1(),
resolve_info)) {
return false;
}
// Nothing to copy/clear.
if (!resolve_info.address.width_div_8 || !resolve_info.address.height_div_8) {
if (!resolve_info.coordinate_info.width_div_8 ||
!resolve_info.coordinate_info.height_div_8) {
return true;
}
draw_util::ResolveResolutionScaleConstant resolution_scale_constant;
resolution_scale_constant.resolution_scale_x = draw_resolution_scale_x();
resolution_scale_constant.resolution_scale_y = draw_resolution_scale_y();
DeferredCommandList& command_list =
command_processor_.GetDeferredCommandList();
// Copying.
bool copied = false;
if (resolve_info.copy_dest_length) {
if (resolve_info.copy_dest_extent_length) {
if (GetPath() == Path::kHostRenderTargets) {
// Dump the current contents of the render targets owning the affected
// range to edram_buffer_.
@@ -1401,14 +1375,21 @@ bool D3D12RenderTargetCache::Resolve(const Memory& memory,
// Make sure there is memory to write to.
bool copy_dest_committed;
if (draw_resolution_scaled) {
copy_dest_committed =
texture_cache.EnsureScaledResolveMemoryCommitted(
resolve_info.copy_dest_base, resolve_info.copy_dest_length) &&
texture_cache.MakeScaledResolveRangeCurrent(
resolve_info.copy_dest_base, resolve_info.copy_dest_length);
// Committing starting with the beginning of the potentially written
// extent, but making the buffer containing the base current as the
// beginning of the bound buffer is the base.
copy_dest_committed = texture_cache.EnsureScaledResolveMemoryCommitted(
resolve_info.copy_dest_extent_start,
resolve_info.copy_dest_extent_length) &&
texture_cache.MakeScaledResolveRangeCurrent(
resolve_info.copy_dest_base,
resolve_info.copy_dest_extent_start -
resolve_info.copy_dest_base +
resolve_info.copy_dest_extent_length);
} else {
copy_dest_committed = shared_memory.RequestRange(
resolve_info.copy_dest_base, resolve_info.copy_dest_length);
copy_dest_committed =
shared_memory.RequestRange(resolve_info.copy_dest_extent_start,
resolve_info.copy_dest_extent_length);
}
if (copy_dest_committed) {
// Write the descriptors and transition the resources.
@@ -1466,11 +1447,6 @@ bool D3D12RenderTargetCache::Resolve(const Memory& memory,
// Submit the resolve.
command_list.D3DSetComputeRootSignature(resolve_copy_root_signature_);
if (draw_resolution_scaled) {
command_list.D3DSetComputeRoot32BitConstants(
3, sizeof(resolution_scale_constant) / sizeof(uint32_t),
&resolution_scale_constant, 0);
}
command_list.D3DSetComputeRootDescriptorTable(
2, descriptor_source.second);
command_list.D3DSetComputeRootDescriptorTable(1,
@@ -1498,10 +1474,11 @@ bool D3D12RenderTargetCache::Resolve(const Memory& memory,
}
// Invalidate textures and mark the range as scaled if needed.
texture_cache.MarkRangeAsResolved(resolve_info.copy_dest_base,
resolve_info.copy_dest_length);
written_address_out = resolve_info.copy_dest_base;
written_length_out = resolve_info.copy_dest_length;
texture_cache.MarkRangeAsResolved(
resolve_info.copy_dest_extent_start,
resolve_info.copy_dest_extent_length);
written_address_out = resolve_info.copy_dest_extent_start;
written_length_out = resolve_info.copy_dest_extent_length;
copied = true;
}
} else {
@@ -1564,11 +1541,6 @@ bool D3D12RenderTargetCache::Resolve(const Memory& memory,
CommitEdramBufferUAVWrites();
command_list.D3DSetComputeRootSignature(
resolve_rov_clear_root_signature_);
if (draw_resolution_scaled) {
command_list.D3DSetComputeRoot32BitConstants(
2, sizeof(resolution_scale_constant) / sizeof(uint32_t),
&resolution_scale_constant, 0);
}
command_list.D3DSetComputeRootDescriptorTable(
1, descriptor_edram.second);
std::pair<uint32_t, uint32_t> clear_group_count =

View File

@@ -1442,19 +1442,30 @@ D3D12TextureCache::D3D12Texture::~D3D12Texture() {
}
bool D3D12TextureCache::IsDecompressionNeeded(xenos::TextureFormat format,
uint32_t width, uint32_t height) {
uint32_t width,
uint32_t height) const {
DXGI_FORMAT dxgi_format_uncompressed =
host_formats_[uint32_t(format)].dxgi_format_uncompressed;
if (dxgi_format_uncompressed == DXGI_FORMAT_UNKNOWN) {
return false;
}
const FormatInfo* format_info = FormatInfo::Get(format);
return (width & (format_info->block_width - 1)) != 0 ||
(height & (format_info->block_height - 1)) != 0;
if (!(width & (format_info->block_width - 1)) &&
!(height & (format_info->block_height - 1))) {
return false;
}
// UnalignedBlockTexturesSupported is for block-compressed textures with the
// block size of 4x4, but not for 2x1 (4:2:2) subsampled formats.
if (format_info->block_width == 4 && format_info->block_height == 4 &&
command_processor_.GetD3D12Provider()
.AreUnalignedBlockTexturesSupported()) {
return false;
}
return true;
}
TextureCache::LoadShaderIndex D3D12TextureCache::GetLoadShaderIndex(
TextureKey key) {
TextureKey key) const {
const HostFormat& host_format = host_formats_[uint32_t(key.format)];
if (key.signed_separate) {
return host_format.load_shader_signed;

View File

@@ -361,30 +361,30 @@ class D3D12TextureCache final : public TextureCache {
// Whether decompression is needed on the host (Direct3D only allows creation
// of block-compressed textures with 4x4-aligned dimensions on PC).
static bool IsDecompressionNeeded(xenos::TextureFormat format, uint32_t width,
uint32_t height);
static DXGI_FORMAT GetDXGIResourceFormat(xenos::TextureFormat format,
uint32_t width, uint32_t height) {
bool IsDecompressionNeeded(xenos::TextureFormat format, uint32_t width,
uint32_t height) const;
DXGI_FORMAT GetDXGIResourceFormat(xenos::TextureFormat format, uint32_t width,
uint32_t height) const {
const HostFormat& host_format = host_formats_[uint32_t(format)];
return IsDecompressionNeeded(format, width, height)
? host_format.dxgi_format_uncompressed
: host_format.dxgi_format_resource;
}
static DXGI_FORMAT GetDXGIResourceFormat(TextureKey key) {
DXGI_FORMAT GetDXGIResourceFormat(TextureKey key) const {
return GetDXGIResourceFormat(key.format, key.GetWidth(), key.GetHeight());
}
static DXGI_FORMAT GetDXGIUnormFormat(xenos::TextureFormat format,
uint32_t width, uint32_t height) {
DXGI_FORMAT GetDXGIUnormFormat(xenos::TextureFormat format, uint32_t width,
uint32_t height) const {
const HostFormat& host_format = host_formats_[uint32_t(format)];
return IsDecompressionNeeded(format, width, height)
? host_format.dxgi_format_uncompressed
: host_format.dxgi_format_unsigned;
}
static DXGI_FORMAT GetDXGIUnormFormat(TextureKey key) {
DXGI_FORMAT GetDXGIUnormFormat(TextureKey key) const {
return GetDXGIUnormFormat(key.format, key.GetWidth(), key.GetHeight());
}
static LoadShaderIndex GetLoadShaderIndex(TextureKey key);
LoadShaderIndex GetLoadShaderIndex(TextureKey key) const;
static constexpr bool AreDimensionsCompatible(
xenos::FetchOpDimension binding_dimension,