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

This commit is contained in:
Gliniak
2022-05-25 07:54:16 +02:00
123 changed files with 11627 additions and 4240 deletions

View File

@@ -748,18 +748,6 @@ void D3D12CommandProcessor::SetPrimitiveTopology(
}
}
void D3D12CommandProcessor::NotifyShaderBindingsLayoutUIDsInvalidated() {
if (bindless_resources_used_) {
cbuffer_binding_descriptor_indices_vertex_.up_to_date = false;
cbuffer_binding_descriptor_indices_pixel_.up_to_date = false;
} else {
bindful_textures_written_vertex_ = false;
bindful_textures_written_pixel_ = false;
bindful_samplers_written_vertex_ = false;
bindful_samplers_written_pixel_ = false;
}
}
std::string D3D12CommandProcessor::GetWindowTitleText() const {
std::ostringstream title;
title << "Direct3D 12";
@@ -3052,12 +3040,8 @@ bool D3D12CommandProcessor::EndSubmission(bool is_swap) {
texture_cache_->ClearCache();
pipeline_cache_->ClearCache();
for (auto it : root_signatures_bindful_) {
it.second->Release();
}
root_signatures_bindful_.clear();
// Not clearing the root signatures as they're referenced by pipelines,
// which are not destroyed.
primitive_processor_->ClearCache();

View File

@@ -197,9 +197,6 @@ class D3D12CommandProcessor : public CommandProcessor {
void SetStencilReference(uint32_t stencil_ref);
void SetPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY primitive_topology);
// For the pipeline cache to call when binding layout UIDs may be reused.
void NotifyShaderBindingsLayoutUIDsInvalidated();
// Returns the text to display in the GPU backend name in the window title.
std::string GetWindowTitleText() const;
@@ -565,7 +562,7 @@ class D3D12CommandProcessor : public CommandProcessor {
// Unsubmitted barrier batch.
std::vector<D3D12_RESOURCE_BARRIER> barriers_;
// <Resource, submission where requested>, sorted by the submission number.
// <Submission where requested, resource>, sorted by the submission number.
std::deque<std::pair<uint64_t, ID3D12Resource*>> resources_for_deletion_;
static constexpr uint32_t kScratchBufferSizeIncrement = 16 * 1024 * 1024;

File diff suppressed because it is too large Load Diff

View File

@@ -176,56 +176,8 @@ class D3D12TextureCache final : public TextureCache {
void UpdateTextureBindingsImpl(uint32_t fetch_constant_mask) override;
private:
enum class LoadMode {
k8bpb,
k16bpb,
k32bpb,
k64bpb,
k128bpb,
kR5G5B5A1ToB5G5R5A1,
kR5G6B5ToB5G6R5,
kR5G5B6ToB5G6R5WithRBGASwizzle,
kR4G4B4A4ToB4G4R4A4,
kR10G11B11ToRGBA16,
kR10G11B11ToRGBA16SNorm,
kR11G11B10ToRGBA16,
kR11G11B10ToRGBA16SNorm,
kDXT1ToRGBA8,
kDXT3ToRGBA8,
kDXT5ToRGBA8,
kDXNToRG8,
kDXT3A,
kDXT3AAs1111ToBGRA4,
kDXT5AToR8,
kCTX1,
kDepthUnorm,
kDepthFloat,
kCount,
kUnknown = kCount
};
struct LoadModeInfo {
// Shader without resolution scaling.
const void* shader;
size_t shader_size;
// Shader with resolution scaling, if available. These shaders are separate
// so the majority of the textures are not affected by the code needed for
// resolution scale support, and also to check if the format allows
// resolution scaling.
const void* shader_scaled;
size_t shader_scaled_size;
// Log2 of the sizes, in bytes, of the source (guest) SRV and the
// destination (host) UAV accessed by the copying shader, since the shader
// may copy multiple blocks per one invocation.
uint32_t srv_bpe_log2;
uint32_t uav_bpe_log2;
// Number of host blocks (or texels for uncompressed) along X axis written
// by every compute shader thread - rows in the upload buffer are padded to
// at least this amount.
uint32_t host_x_blocks_per_thread;
};
static constexpr uint32_t kLoadGuestXThreadsPerGroupLog2 = 2;
static constexpr uint32_t kLoadGuestYBlocksPerGroupLog2 = 5;
struct HostFormat {
// Format info for the regular case.
@@ -233,17 +185,17 @@ class D3D12TextureCache final : public TextureCache {
// is used) for the texture resource.
DXGI_FORMAT dxgi_format_resource;
// DXGI format for unsigned normalized or unsigned/signed float SRV.
DXGI_FORMAT dxgi_format_unorm;
// The regular load mode, used when special modes (like signed-specific or
// decompressing) aren't needed.
LoadMode load_mode;
DXGI_FORMAT dxgi_format_unsigned;
// The regular load shader, used when special load shaders (like
// signed-specific or decompressing) aren't needed.
LoadShaderIndex load_shader;
// DXGI format for signed normalized or unsigned/signed float SRV.
DXGI_FORMAT dxgi_format_snorm;
DXGI_FORMAT dxgi_format_signed;
// If the signed version needs a different bit representation on the host,
// this is the load mode for the signed version. Otherwise the regular
// load_mode will be used for the signed version, and a single copy will be
// created if both unsigned and signed are used.
LoadMode load_mode_snorm;
// this is the load shader for the signed version. Otherwise the regular
// load_shader will be used for the signed version, and a single copy will
// be created if both unsigned and signed are used.
LoadShaderIndex load_shader_signed;
// Do NOT add integer DXGI formats to this - they are not filterable, can
// only be read with Load, not Sample! If any game is seen using num_format
@@ -252,8 +204,9 @@ class D3D12TextureCache final : public TextureCache {
// textures and multiplication to the tfetch implementation.
// Whether the DXGI format, if not uncompressing the texture, consists of
// blocks, thus copy regions must be aligned to block size.
bool dxgi_format_block_aligned;
// blocks, thus copy regions must be aligned to block size (assuming it's
// the same as the guest block size).
bool is_block_compressed;
// Uncompression info for when the regular host format for this texture is
// block-compressed, but the size is not block-aligned, and thus such
// texture cannot be created in Direct3D on PC and needs decompression,
@@ -261,7 +214,7 @@ class D3D12TextureCache final : public TextureCache {
// supports unsigned normalized formats - let's hope GPUSIGN_SIGNED was not
// used for DXN and DXT5A.
DXGI_FORMAT dxgi_format_uncompressed;
LoadMode decompress_mode;
LoadShaderIndex load_shader_decompress;
// Mapping of Xenos swizzle components to DXGI format components.
uint32_t swizzle;
@@ -425,13 +378,13 @@ class D3D12TextureCache final : public TextureCache {
const HostFormat& host_format = host_formats_[uint32_t(format)];
return IsDecompressionNeeded(format, width, height)
? host_format.dxgi_format_uncompressed
: host_format.dxgi_format_unorm;
: host_format.dxgi_format_unsigned;
}
static DXGI_FORMAT GetDXGIUnormFormat(TextureKey key) {
return GetDXGIUnormFormat(key.format, key.GetWidth(), key.GetHeight());
}
static LoadMode GetLoadMode(TextureKey key);
static LoadShaderIndex GetLoadShaderIndex(TextureKey key);
static constexpr bool AreDimensionsCompatible(
xenos::FetchOpDimension binding_dimension,
@@ -513,14 +466,11 @@ class D3D12TextureCache final : public TextureCache {
D3D12CommandProcessor& command_processor_;
bool bindless_resources_used_;
static const LoadModeInfo load_mode_info_[];
Microsoft::WRL::ComPtr<ID3D12RootSignature> load_root_signature_;
std::array<Microsoft::WRL::ComPtr<ID3D12PipelineState>,
size_t(LoadMode::kCount)>
std::array<Microsoft::WRL::ComPtr<ID3D12PipelineState>, kLoadShaderCount>
load_pipelines_;
// Load pipelines for resolution-scaled resolve targets.
std::array<Microsoft::WRL::ComPtr<ID3D12PipelineState>,
size_t(LoadMode::kCount)>
std::array<Microsoft::WRL::ComPtr<ID3D12PipelineState>, kLoadShaderCount>
load_pipelines_scaled_;
std::vector<SRVDescriptorCachePage> srv_descriptor_cache_;

View File

@@ -175,9 +175,8 @@ bool PipelineCache::Initialize() {
}
void PipelineCache::Shutdown() {
ClearCache(true);
// Shut down all threads.
// Shut down all threads, before destroying the pipelines since they may be
// creating them.
if (!creation_threads_.empty()) {
{
std::lock_guard<std::mutex> lock(creation_request_lock_);
@@ -191,44 +190,11 @@ void PipelineCache::Shutdown() {
}
creation_completion_event_.reset();
ui::d3d12::util::ReleaseAndNull(dxc_compiler_);
ui::d3d12::util::ReleaseAndNull(dxc_utils_);
ui::d3d12::util::ReleaseAndNull(dxbc_converter_);
}
void PipelineCache::ClearCache(bool shutting_down) {
bool reinitialize_shader_storage =
!shutting_down && storage_write_thread_ != nullptr;
std::filesystem::path shader_storage_cache_root;
uint32_t shader_storage_title_id = shader_storage_title_id_;
if (reinitialize_shader_storage) {
shader_storage_cache_root = shader_storage_cache_root_;
}
// Shut down the persistent shader / pipeline storage.
ShutdownShaderStorage();
// Remove references to the current pipeline.
current_pipeline_ = nullptr;
if (!creation_threads_.empty()) {
// Empty the pipeline creation queue and make sure there are no threads
// currently creating pipelines because pipelines are going to be deleted.
bool await_creation_completion_event = false;
{
std::lock_guard<std::mutex> lock(creation_request_lock_);
creation_queue_.clear();
await_creation_completion_event = creation_threads_busy_ != 0;
if (await_creation_completion_event) {
creation_completion_event_->Reset();
creation_completion_set_event_ = true;
}
}
if (await_creation_completion_event) {
creation_request_cond_.notify_one();
xe::threading::Wait(creation_completion_event_.get(), false);
}
}
// Destroy all pipelines.
current_pipeline_ = nullptr;
for (auto it : pipelines_) {
it.second->state->Release();
delete it.second;
@@ -237,7 +203,6 @@ void PipelineCache::ClearCache(bool shutting_down) {
COUNT_profile_set("gpu/pipeline_cache/pipelines", 0);
// Destroy all shaders.
command_processor_.NotifyShaderBindingsLayoutUIDsInvalidated();
if (bindless_resources_used_) {
bindless_sampler_layout_map_.clear();
bindless_sampler_layouts_.clear();
@@ -250,10 +215,10 @@ void PipelineCache::ClearCache(bool shutting_down) {
shaders_.clear();
shader_storage_index_ = 0;
if (reinitialize_shader_storage) {
InitializeShaderStorage(shader_storage_cache_root, shader_storage_title_id,
false);
}
// Shut down shader translation.
ui::d3d12::util::ReleaseAndNull(dxc_compiler_);
ui::d3d12::util::ReleaseAndNull(dxc_utils_);
ui::d3d12::util::ReleaseAndNull(dxbc_converter_);
}
void PipelineCache::InitializeShaderStorage(

View File

@@ -55,7 +55,10 @@ class PipelineCache {
bool Initialize();
void Shutdown();
void ClearCache(bool shutting_down = false);
// No ClearCache because it's undesirable with the persistent shader storage
// (if the storage is reloaded, effectively nothing is cleared, while the call
// takes a long time, and if it's not, there will be heavy stuttering for the
// rest of the execution of the guest).
void InitializeShaderStorage(const std::filesystem::path& cache_root,
uint32_t title_id, bool blocking);