Fixes for d3d12 and d3d11 drivers when using shaders with TATE mode arcades etc (#14678)

Added support for break on errors in d3d12 (development aid)
Added support for DRED (device remove extended data) in d3d12 (development aid)
Made d3d12 viewport and scissors to behave more like vulkan drivers (or be more correct)
Fixed validation error on start up due to buffers not being setup correctly for one frame
This commit is contained in:
MajorPainTheCactus 2022-11-27 09:20:34 +00:00 committed by GitHub
parent d467cbd52d
commit 7ebd8e190a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 118 additions and 18 deletions

View File

@ -211,7 +211,7 @@ typedef struct
D3D11BlendState blend_disable;
D3D11BlendState blend_pipeline;
D3D11Buffer menu_pipeline_vbo;
math_matrix_4x4 mvp, mvp_no_rot;
math_matrix_4x4 mvp, mvp_no_rot, identity;
struct video_viewport vp;
D3D11_VIEWPORT viewport;
D3D11_RECT scissor;

View File

@ -58,6 +58,9 @@ typedef ID3D12Debug* D3D12Debug;
typedef ID3D12DebugDevice* D3D12DebugDevice;
typedef ID3D12DebugCommandQueue* D3D12DebugCommandQueue;
typedef ID3D12DebugCommandList* D3D12DebugCommandList;
#ifdef DEVICE_DEBUG
typedef ID3D12DeviceRemovedExtendedDataSettings* D3D12DeviceRemovedExtendedDataSettings;
#endif /* DEVICE_DEBUG */
#endif
typedef ID3D12InfoQueue* D3D12InfoQueue;
@ -164,6 +167,14 @@ typedef struct
#endif
DXGIAdapter adapter;
D3D12Device device;
#ifdef DEVICE_DEBUG
#ifdef DEBUG
D3D12DebugDevice debug_device;
D3D12InfoQueue info_queue;
D3D12DeviceRemovedExtendedDataSettings device_removed_info;
#endif /* DEBUG */
#endif /* DEVICE_DEBUG */
IDXGIAdapter1 *adapters[D3D12_MAX_GPU_COUNT];
struct string_list *gpu_list;
@ -293,7 +304,7 @@ typedef struct
D3D12_CONSTANT_BUFFER_VIEW_DESC ubo_view;
DXGI_FORMAT format;
D3D12_GPU_DESCRIPTOR_HANDLE samplers[RARCH_FILTER_MAX][RARCH_WRAP_MAX];
math_matrix_4x4 mvp, mvp_no_rot;
math_matrix_4x4 mvp, mvp_no_rot, identity;
struct video_viewport vp;
D3D12Resource menu_pipeline_vbo;
D3D12_VERTEX_BUFFER_VIEW menu_pipeline_vbo_view;

View File

@ -623,7 +623,7 @@ static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const
&d3d11->luts[0].size_data, sizeof(*d3d11->luts)},
},
{
&d3d11->mvp, /* MVP */
i == d3d11->shader_preset->passes - 1 ? &d3d11->mvp : &d3d11->identity, /* MVP */
&d3d11->pass[i].rt.size_data, /* OutputSize */
&d3d11->frame.output_size, /* FinalViewportSize */
&d3d11->pass[i].frame_count, /* FrameCount */
@ -1240,6 +1240,8 @@ static void *d3d11_gfx_init(const video_info_t* video,
goto error;
#endif
matrix_4x4_identity(d3d11->identity);
video_driver_set_size(d3d11->vp.full_width, d3d11->vp.full_height);
d3d11->viewport.Width = d3d11->vp.full_width;
d3d11->viewport.Height = d3d11->vp.full_height;
@ -1378,6 +1380,11 @@ static void *d3d11_gfx_init(const video_info_t* video,
{ { 0.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { -1.0f, -1.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { -1.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, -1.0f }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
};
D3D11_SUBRESOURCE_DATA vertex_data;
@ -1830,6 +1837,9 @@ static void d3d11_init_render_targets(d3d11_video_t* d3d11, unsigned width, unsi
}
else
{
width = retroarch_get_rotation() % 2 ? height : width;
height = retroarch_get_rotation() % 2 ? width : height;
d3d11->pass[i].rt.size_data.x = width;
d3d11->pass[i].rt.size_data.y = height;
d3d11->pass[i].rt.size_data.z = 1.0f / width;
@ -2196,7 +2206,15 @@ D3D11_ST_FLAG_HAS_ALLOW_TEARING)) ? 0 : DXGI_PRESENT_ALLOW_TEARING;
&d3d11->pass[i].rt.rt_view, NULL);
context->lpVtbl->RSSetViewports(context, 1, &d3d11->pass[i].viewport);
context->lpVtbl->Draw(context, 4, 0);
if (i == d3d11->shader_preset->passes - 1)
{
context->lpVtbl->Draw(context, 4, 0);
}
else
{
context->lpVtbl->Draw(context, 4, 4);
}
texture = &d3d11->pass[i].rt;
}
}

View File

@ -493,8 +493,8 @@ static void d3d12_update_viewport(d3d12_video_t *d3d12, bool force_full)
d3d12->frame.viewport.MaxDepth = 1.0f;
/* having to add vp.x and vp.y here doesn't make any sense */
d3d12->frame.scissorRect.top = 0;
d3d12->frame.scissorRect.left = 0;
d3d12->frame.scissorRect.top = d3d12->vp.y;
d3d12->frame.scissorRect.left = d3d12->vp.x;
d3d12->frame.scissorRect.right = d3d12->vp.x + d3d12->vp.width;
d3d12->frame.scissorRect.bottom = d3d12->vp.y + d3d12->vp.height;
@ -669,7 +669,7 @@ static bool d3d12_gfx_set_shader(void* data, enum rarch_shader_type type, const
&d3d12->luts[0].size_data, sizeof(*d3d12->luts)},
},
{
&d3d12->mvp, /* MVP */
i == d3d12->shader_preset->passes - 1 ? &d3d12->mvp : &d3d12->identity, /* MVP */
&d3d12->pass[i].rt.size_data, /* OutputSize */
&d3d12->frame.output_size, /* FinalViewportSize */
&d3d12->pass[i].frame_count, /* FrameCount */
@ -1368,8 +1368,10 @@ static bool d3d12_init_swapchain(d3d12_video_t* d3d12,
d3d12->chain.viewport.Width = width;
d3d12->chain.viewport.Height = height;
d3d12->chain.scissorRect.right = width;
d3d12->chain.scissorRect.bottom = height;
d3d12->chain.scissorRect.left = d3d12->vp.x;
d3d12->chain.scissorRect.top = d3d12->vp.y;
d3d12->chain.scissorRect.right = d3d12->vp.x + width;
d3d12->chain.scissorRect.bottom = d3d12->vp.y + height;
return true;
}
@ -1459,6 +1461,31 @@ static void d3d12_init_base(d3d12_video_t* d3d12)
if (!SUCCEEDED(D3D12CreateDevice_(d3d12->adapter, D3D_FEATURE_LEVEL_11_0, &d3d12->device)))
RARCH_WARN("[D3D12]: Could not create D3D12 device.\n");
}
#ifdef DEVICE_DEBUG
#ifdef DEBUG
if (d3d12->device)
{
if (SUCCEEDED(d3d12->device->lpVtbl->QueryInterface(d3d12->device, uuidof(ID3D12DebugDevice), (void*)&d3d12->debug_device)))
RARCH_WARN("[D3D12]: Could not create D3D12 debug device.\n");
if (SUCCEEDED(d3d12->device->lpVtbl->QueryInterface(d3d12->device, uuidof(ID3D12InfoQueue), (void*)&d3d12->info_queue)))
{
//d3d12->info_queue->lpVtbl->SetBreakOnSeverity(d3d12->info_queue, D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE);
d3d12->info_queue->lpVtbl->SetBreakOnSeverity(d3d12->info_queue, D3D12_MESSAGE_SEVERITY_ERROR, TRUE);
//d3d12->info_queue->lpVtbl->SetBreakOnSeverity(d3d12->info_queue, D3D12_MESSAGE_SEVERITY_WARNING, TRUE);
}
}
if (!SUCCEEDED(D3D12GetDebugInterface(uuidof(ID3D12DeviceRemovedExtendedDataSettings), (void*)&d3d12->device_removed_info)))
RARCH_WARN("[D3D12]: Could not create D3D12 device removed info.\n");
// Turn on AutoBreadcrumbs and Page Fault reporting
d3d12->device_removed_info->lpVtbl->SetAutoBreadcrumbsEnablement(d3d12->device_removed_info, D3D12_DRED_ENABLEMENT_FORCED_ON);
d3d12->device_removed_info->lpVtbl->SetPageFaultEnablement(d3d12->device_removed_info, D3D12_DRED_ENABLEMENT_FORCED_ON);
d3d12->device_removed_info->lpVtbl->SetWatsonDumpEnablement(d3d12->device_removed_info, D3D12_DRED_ENABLEMENT_FORCED_ON);
#endif /* DEBUG */
#endif /* DEVICE_DEBUG */
}
static inline void d3d12_release_descriptor_heap(d3d12_descriptor_heap_t* heap)
@ -1721,6 +1748,11 @@ static void d3d12_create_fullscreen_quad_vbo(
{ { 0.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { -1.0f, -1.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { -1.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, -1.0f }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
};
view->SizeInBytes = sizeof(vertices);
@ -1880,6 +1912,8 @@ static void *d3d12_gfx_init(const video_info_t* video,
}
#endif
matrix_4x4_identity(d3d12->identity);
d3d12_gfx_set_rotation(d3d12, 0);
video_driver_set_size(d3d12->vp.full_width, d3d12->vp.full_height);
d3d12->chain.viewport.Width = d3d12->vp.full_width;
@ -2010,14 +2044,36 @@ static void d3d12_init_render_targets(d3d12_video_t* d3d12, unsigned width, unsi
RARCH_LOG("[D3D12]: Updating framebuffer size %ux%u.\n", width, height);
if (i == (d3d12->shader_preset->passes - 1))
{
d3d12->pass[i].viewport.TopLeftX = d3d12->vp.x;
d3d12->pass[i].viewport.TopLeftY = d3d12->vp.y;
d3d12->pass[i].viewport.Width = width;
d3d12->pass[i].viewport.Height = height;
d3d12->pass[i].viewport.MinDepth = 0.0f;
d3d12->pass[i].viewport.MaxDepth = 1.0f;
d3d12->pass[i].scissorRect.left = d3d12->vp.x;
d3d12->pass[i].scissorRect.top = d3d12->vp.y;
d3d12->pass[i].scissorRect.right = d3d12->vp.x + width;
d3d12->pass[i].scissorRect.bottom = d3d12->vp.y + height;
}
else
{
d3d12->pass[i].viewport.TopLeftX = 0.0f;
d3d12->pass[i].viewport.TopLeftY = 0.0f;
d3d12->pass[i].viewport.Width = width;
d3d12->pass[i].viewport.Height = height;
d3d12->pass[i].viewport.MinDepth = 0.0f;
d3d12->pass[i].viewport.MaxDepth = 1.0f;
d3d12->pass[i].scissorRect.left = 0.0f;
d3d12->pass[i].scissorRect.top = 0.0f;
d3d12->pass[i].scissorRect.right = width;
d3d12->pass[i].scissorRect.bottom = height;
}
if ((i != (d3d12->shader_preset->passes - 1)) || (width != d3d12->vp.width) ||
(height != d3d12->vp.height))
{
d3d12->pass[i].viewport.Width = width;
d3d12->pass[i].viewport.Height = height;
d3d12->pass[i].viewport.MaxDepth = 1.0;
d3d12->pass[i].scissorRect.right = width;
d3d12->pass[i].scissorRect.bottom = height;
d3d12->pass[i].rt.desc.Width = width;
d3d12->pass[i].rt.desc.Height = height;
d3d12->pass[i].rt.desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
@ -2037,6 +2093,9 @@ static void d3d12_init_render_targets(d3d12_video_t* d3d12, unsigned width, unsi
}
else
{
width = retroarch_get_rotation() % 2 ? height : width;
height = retroarch_get_rotation() % 2 ? width : height;
d3d12->pass[i].rt.size_data.x = width;
d3d12->pass[i].rt.size_data.y = height;
d3d12->pass[i].rt.size_data.z = 1.0f / width;
@ -2135,8 +2194,10 @@ static bool d3d12_gfx_frame(
d3d12->chain.viewport.Width = video_width;
d3d12->chain.viewport.Height = video_height;
d3d12->chain.scissorRect.right = video_width;
d3d12->chain.scissorRect.bottom = video_height;
d3d12->chain.scissorRect.left = d3d12->vp.x;
d3d12->chain.scissorRect.top = d3d12->vp.y;
d3d12->chain.scissorRect.right = d3d12->vp.x + video_width;
d3d12->chain.scissorRect.bottom = d3d12->vp.y + video_height;
d3d12->flags &= ~D3D12_ST_FLAG_RESIZE_CHAIN;
d3d12->flags |= D3D12_ST_FLAG_RESIZE_VIEWPORT;
@ -2472,7 +2533,14 @@ static bool d3d12_gfx_frame(
D3D12RSSetScissorRects(d3d12->queue.cmd, 1,
&d3d12->pass[i].scissorRect);
D3D12DrawInstanced(d3d12->queue.cmd, 4, 1, 0, 0);
if (i == d3d12->shader_preset->passes - 1)
{
D3D12DrawInstanced(d3d12->queue.cmd, 4, 1, 0, 0);
}
else
{
D3D12DrawInstanced(d3d12->queue.cmd, 4, 1, 4, 0);
}
d3d12_resource_transition(
d3d12->queue.cmd, d3d12->pass[i].rt.handle,
@ -2548,7 +2616,10 @@ static bool d3d12_gfx_frame(
D3D12RSSetViewports(d3d12->queue.cmd, 1, &d3d12->frame.viewport);
D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &d3d12->frame.scissorRect);
D3D12DrawInstanced(d3d12->queue.cmd, 4, 1, 0, 0);
if (d3d12->shader_preset == NULL || d3d12->pass[0].rt.handle)
{
D3D12DrawInstanced(d3d12->queue.cmd, 4, 1, 0, 0);
}
D3D12SetPipelineState(d3d12->queue.cmd,
d3d12->pipes[VIDEO_SHADER_STOCK_BLEND]);