[D3D12] d3d12_break_on_error + fix PerformSwap descriptor heap wrap

This commit is contained in:
Triang3l
2020-05-17 00:26:04 +03:00
parent 8341a48210
commit b7a5c24bb1
7 changed files with 88 additions and 34 deletions

View File

@@ -1153,16 +1153,23 @@ void D3D12CommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
dirty_gamma_ramp_pwl_ = false;
}
D3D12_CPU_DESCRIPTOR_HANDLE descriptor_cpu_start;
D3D12_GPU_DESCRIPTOR_HANDLE descriptor_gpu_start;
if (RequestViewDescriptors(ui::d3d12::DescriptorHeapPool::kHeapIndexInvalid,
2, 2, descriptor_cpu_start,
descriptor_gpu_start) !=
ui::d3d12::DescriptorHeapPool::kHeapIndexInvalid) {
TextureFormat frontbuffer_format;
if (texture_cache_->RequestSwapTexture(descriptor_cpu_start,
frontbuffer_format)) {
render_target_cache_->FlushAndUnbindRenderTargets();
D3D12_SHADER_RESOURCE_VIEW_DESC swap_texture_srv_desc;
TextureFormat frontbuffer_format;
ID3D12Resource* swap_texture_resource = texture_cache_->RequestSwapTexture(
swap_texture_srv_desc, frontbuffer_format);
if (swap_texture_resource) {
render_target_cache_->FlushAndUnbindRenderTargets();
D3D12_CPU_DESCRIPTOR_HANDLE descriptor_cpu_start;
D3D12_GPU_DESCRIPTOR_HANDLE descriptor_gpu_start;
if (RequestViewDescriptors(ui::d3d12::DescriptorHeapPool::kHeapIndexInvalid,
2, 2, descriptor_cpu_start,
descriptor_gpu_start) !=
ui::d3d12::DescriptorHeapPool::kHeapIndexInvalid) {
// Must not call anything that can change the descriptor heap from now on!
// Create the swap texture descriptor.
device->CreateShaderResourceView(
swap_texture_resource, &swap_texture_srv_desc, descriptor_cpu_start);
// Create the gamma ramp texture descriptor.
// This is according to D3D::InitializePresentationParameters from a game
@@ -1453,6 +1460,7 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
if (!UpdateBindings(vertex_shader, pixel_shader, root_signature)) {
return false;
}
// Must not call anything that can change the descriptor heap from now on!
// Ensure vertex and index buffers are resident and draw.
// TODO(Triang3l): Cache residency for ranges in a way similar to how texture

View File

@@ -261,7 +261,8 @@ class RenderTargetCache {
void CompletedSubmissionUpdated();
void BeginSubmission();
void EndFrame();
// Called in the beginning of a draw call - may bind pipelines.
// Called in the beginning of a draw call - may bind pipelines and change the
// view descriptor heap.
bool UpdateRenderTargets(const D3D12Shader* pixel_shader);
// Returns the host-to-guest mappings and host formats of currently bound
// render targets for pipeline creation and remapping in shaders. They are
@@ -281,7 +282,7 @@ class RenderTargetCache {
void ForceApplyOnNextUpdate() { apply_to_command_list_ = true; }
// Flushes the render targets to EDRAM and unbinds them, for instance, when
// the command processor takes over framebuffer bindings to draw something
// special.
// special. May change the CBV/SRV/UAV descriptor heap.
void FlushAndUnbindRenderTargets();
void WriteEDRAMUint32UAVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle);

View File

@@ -2011,8 +2011,8 @@ void TextureCache::CreateScaledResolveBufferRawUAV(
first_unscaled_4kb_page << 14);
}
bool TextureCache::RequestSwapTexture(D3D12_CPU_DESCRIPTOR_HANDLE handle,
TextureFormat& format_out) {
ID3D12Resource* TextureCache::RequestSwapTexture(
D3D12_SHADER_RESOURCE_VIEW_DESC& srv_desc_out, TextureFormat& format_out) {
auto& regs = *register_file_;
const auto& fetch = regs.Get<xenos::xe_gpu_texture_fetch_t>(
XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0);
@@ -2020,11 +2020,11 @@ bool TextureCache::RequestSwapTexture(D3D12_CPU_DESCRIPTOR_HANDLE handle,
uint32_t swizzle;
BindingInfoFromFetchConstant(fetch, key, &swizzle, nullptr, nullptr);
if (key.base_page == 0 || key.dimension != Dimension::k2D) {
return false;
return nullptr;
}
Texture* texture = FindOrCreateTexture(key);
if (texture == nullptr || !LoadTextureData(texture)) {
return false;
return nullptr;
}
MarkTextureUsed(texture);
// The swap texture is likely to be used only for the presentation pixel
@@ -2034,21 +2034,17 @@ bool TextureCache::RequestSwapTexture(D3D12_CPU_DESCRIPTOR_HANDLE handle,
texture->resource, texture->state,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
texture->state = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
srv_desc.Format = GetDXGIUnormFormat(key);
srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
srv_desc.Shader4ComponentMapping =
srv_desc_out.Format = GetDXGIUnormFormat(key);
srv_desc_out.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
srv_desc_out.Shader4ComponentMapping =
swizzle |
D3D12_SHADER_COMPONENT_MAPPING_ALWAYS_SET_BIT_AVOIDING_ZEROMEM_MISTAKES;
srv_desc.Texture2D.MostDetailedMip = 0;
srv_desc.Texture2D.MipLevels = 1;
srv_desc.Texture2D.PlaneSlice = 0;
srv_desc.Texture2D.ResourceMinLODClamp = 0.0f;
auto device =
command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice();
device->CreateShaderResourceView(texture->resource, &srv_desc, handle);
srv_desc_out.Texture2D.MostDetailedMip = 0;
srv_desc_out.Texture2D.MipLevels = 1;
srv_desc_out.Texture2D.PlaneSlice = 0;
srv_desc_out.Texture2D.ResourceMinLODClamp = 0.0f;
format_out = key.format;
return true;
return texture->resource;
}
bool TextureCache::IsDecompressionNeeded(TextureFormat format, uint32_t width,

View File

@@ -159,9 +159,12 @@ class TextureCache {
uint32_t first_unscaled_4kb_page,
uint32_t unscaled_4kb_page_count);
// Returns a descriptor of the front buffer in PIXEL_SHADER_RESOURCE state.
bool RequestSwapTexture(D3D12_CPU_DESCRIPTOR_HANDLE handle,
TextureFormat& format_out);
// Returns the ID3D12Resource of the front buffer texture (in
// PIXEL_SHADER_RESOURCE state), or nullptr in case of failure, and writes the
// description of its SRV. May call LoadTextureData, so the same restrictions
// (such as about descriptor heap change possibility) apply.
ID3D12Resource* RequestSwapTexture(
D3D12_SHADER_RESOURCE_VIEW_DESC& srv_desc_out, TextureFormat& format_out);
private:
enum class LoadMode {