D3D12: Refactoring and cleanups

Moves render target restoring to RestoreAPIState, this also means no need
to manually restore after allocating in a buffer that caused execution,
because the manager restores it for us.

Remove a method that wasn't used from D3DUtil.cpp, and fixes a few errors
in EFB poke drawing.
This commit is contained in:
Stenzek 2016-03-05 22:38:14 +10:00
parent 7ec1fce741
commit acfa93372e
9 changed files with 23 additions and 161 deletions

View File

@ -121,12 +121,7 @@ void BBox::Set(int index, int value)
memcpy(reinterpret_cast<u8*>(s_bbox_staging_buffer_map) + (index * sizeof(int)), &value, sizeof(int));
}
if (s_bbox_stream_buffer->AllocateSpaceInBuffer(sizeof(int), sizeof(int)))
{
// Command list was executed, reset state
g_renderer->SetViewport();
FramebufferManager::RestoreEFBRenderTargets();
}
s_bbox_stream_buffer->AllocateSpaceInBuffer(sizeof(int), sizeof(int));
// Allocate temporary bytes in upload buffer, then copy to real buffer.
memcpy(s_bbox_stream_buffer->GetCPUAddressOfCurrentAllocation(), &value, sizeof(int));
@ -147,8 +142,6 @@ int BBox::Get(int index)
D3D::ResourceBarrier(D3D::current_command_list, s_bbox_buffer, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, 0);
D3D::command_list_mgr->ExecuteQueuedWork(true);
g_renderer->SetViewport();
FramebufferManager::RestoreEFBRenderTargets();
CheckHR(s_bbox_staging_buffer->Map(0, nullptr, &s_bbox_staging_buffer_map));
}

View File

@ -58,12 +58,7 @@ void ReplaceRGBATexture2D(ID3D12Resource* texture12, const u8* buffer, unsigned
if (!s_texture_upload_stream_buffer)
s_texture_upload_stream_buffer = std::make_unique<D3DStreamBuffer>(INITIAL_TEXTURE_UPLOAD_BUFFER_SIZE, MAXIMUM_TEXTURE_UPLOAD_BUFFER_SIZE, nullptr);
bool current_command_list_executed = s_texture_upload_stream_buffer->AllocateSpaceInBuffer(upload_size, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
if (current_command_list_executed)
{
g_renderer->SetViewport();
FramebufferManager::RestoreEFBRenderTargets();
}
s_texture_upload_stream_buffer->AllocateSpaceInBuffer(upload_size, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
upload_buffer = s_texture_upload_stream_buffer->GetBuffer();
upload_buffer_offset = s_texture_upload_stream_buffer->GetOffsetOfCurrentAllocation();

View File

@ -104,7 +104,6 @@ private:
CD3DFont font;
static std::unique_ptr<UtilVertexBuffer> util_vbuf_stq;
static std::unique_ptr<UtilVertexBuffer> util_vbuf_cq;
static std::unique_ptr<UtilVertexBuffer> util_vbuf_clearq;
static std::unique_ptr<UtilVertexBuffer> util_vbuf_efbpokequads;
@ -502,12 +501,6 @@ struct
float u1, v1, u2, v2, S, G;
} tex_quad_data;
struct
{
float x1, y1, x2, y2, z;
u32 col;
} draw_quad_data;
struct
{
u32 col;
@ -516,13 +509,11 @@ struct
// ring buffer offsets
static size_t stq_offset;
static size_t cq_offset;
static size_t clearq_offset;
void InitUtils()
{
util_vbuf_stq = std::make_unique<UtilVertexBuffer>(0x10000);
util_vbuf_cq = std::make_unique<UtilVertexBuffer>(0x10000);
util_vbuf_clearq = std::make_unique<UtilVertexBuffer>(0x10000);
util_vbuf_efbpokequads = std::make_unique<UtilVertexBuffer>(0x100000);
@ -560,7 +551,6 @@ void InitUtils()
// cached data used to avoid unnecessarily reloading the vertex buffers
memset(&tex_quad_data, 0, sizeof(tex_quad_data));
memset(&draw_quad_data, 0, sizeof(draw_quad_data));
memset(&clear_quad_data, 0, sizeof(clear_quad_data));
font.Init();
@ -571,7 +561,6 @@ void ShutdownUtils()
font.Shutdown();
util_vbuf_stq.reset();
util_vbuf_cq.reset();
util_vbuf_clearq.reset();
util_vbuf_efbpokequads.reset();
}
@ -707,89 +696,6 @@ void DrawShadedTexQuad(D3DTexture2D* texture,
D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PSO, true);
D3D::current_command_list->DrawInstanced(4, 1, static_cast<UINT>(stq_offset), 0);
g_renderer->RestoreAPIState();
}
// Fills a certain area of the current render target with the specified color
// destination coordinates normalized to (-1;1)
void DrawColorQuad(u32 Color, float z, float x1, float y1, float x2, float y2, D3D12_BLEND_DESC* blend_desc, D3D12_DEPTH_STENCIL_DESC* depth_stencil_desc, bool rt_multisampled)
{
ColVertex coords[4] = {
{ x1, y2, z, Color },
{ x2, y2, z, Color },
{ x1, y1, z, Color },
{ x2, y1, z, Color },
};
if (draw_quad_data.x1 != x1 || draw_quad_data.y1 != y1 ||
draw_quad_data.x2 != x2 || draw_quad_data.y2 != y2 ||
draw_quad_data.col != Color || draw_quad_data.z != z)
{
cq_offset = util_vbuf_cq->AppendData(coords, sizeof(coords), sizeof(ColVertex));
draw_quad_data.x1 = x1;
draw_quad_data.y1 = y1;
draw_quad_data.x2 = x2;
draw_quad_data.y2 = y2;
draw_quad_data.col = Color;
draw_quad_data.z = z;
}
D3D::current_command_list->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
D3D::command_list_mgr->SetCommandListPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
D3D12_VERTEX_BUFFER_VIEW vb_view = {
util_vbuf_cq->GetBuffer12()->GetGPUVirtualAddress(), // D3D12_GPU_VIRTUAL_ADDRESS BufferLocation;
static_cast<UINT>(util_vbuf_cq->GetSize()), // UINT SizeInBytes; This is the size of the entire buffer, not just the size of the vertex data for one draw call, since the offsetting is done in the draw call itself.
sizeof(ColVertex) // UINT StrideInBytes;
};
D3D::current_command_list->IASetVertexBuffers(0, 1, &vb_view);
D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_VERTEX_BUFFER, true);
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc = {
default_root_signature, // ID3D12RootSignature *pRootSignature;
StaticShaderCache::GetClearVertexShader(), // D3D12_SHADER_BYTECODE VS;
StaticShaderCache::GetClearPixelShader(), // D3D12_SHADER_BYTECODE PS;
{}, // D3D12_SHADER_BYTECODE DS;
{}, // D3D12_SHADER_BYTECODE HS;
StaticShaderCache::GetClearGeometryShader(), // D3D12_SHADER_BYTECODE GS;
{}, // D3D12_STREAM_OUTPUT_DESC StreamOutput
*blend_desc, // D3D12_BLEND_DESC BlendState;
UINT_MAX, // UINT SampleMask;
Renderer::GetResetRasterizerDesc(), // D3D12_RASTERIZER_DESC RasterizerState
*depth_stencil_desc, // D3D12_DEPTH_STENCIL_DESC DepthStencilState
StaticShaderCache::GetClearVertexShaderInputLayout(), // D3D12_INPUT_LAYOUT_DESC InputLayout
D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF, // D3D12_INDEX_BUFFER_PROPERTIES IndexBufferProperties
D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, // D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType
1, // UINT NumRenderTargets
{ DXGI_FORMAT_R8G8B8A8_UNORM }, // DXGI_FORMAT RTVFormats[8]
DXGI_FORMAT_D32_FLOAT, // DXGI_FORMAT DSVFormat
{ 1 /* UINT Count */, 0 /* UINT Quality */ } // DXGI_SAMPLE_DESC SampleDesc
};
if (rt_multisampled)
{
pso_desc.SampleDesc.Count = g_ActiveConfig.iMultisamples;
}
ID3D12PipelineState* pso = nullptr;
CheckHR(DX12::gx_state_cache.GetPipelineStateObjectFromCache(&pso_desc, &pso));
D3D::current_command_list->SetPipelineState(pso);
D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PSO, true);
// In D3D11, the 'resetraststate' has ScissorEnable disabled. In D3D12, scissor testing is always enabled.
// Thus, set the scissor rect to the max texture size, then reset it to the current scissor rect to avoid
// dirtying state.
// 2 ^ D3D12_MAX_TEXTURE_DIMENSION_2_TO_EXP = 131072
D3D::current_command_list->RSSetScissorRects(1, &CD3DX12_RECT(0, 0, 131072, 131072));
D3D::current_command_list->DrawInstanced(4, 1, static_cast<UINT>(cq_offset), 0);
g_renderer->RestoreAPIState();
}
void DrawClearQuad(u32 Color, float z, D3D12_BLEND_DESC* blend_desc, D3D12_DEPTH_STENCIL_DESC* depth_stencil_desc, bool rt_multisampled)
@ -856,8 +762,6 @@ void DrawClearQuad(u32 Color, float z, D3D12_BLEND_DESC* blend_desc, D3D12_DEPTH
D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PSO, true);
D3D::current_command_list->DrawInstanced(4, 1, static_cast<UINT>(clearq_offset), 0);
g_renderer->RestoreAPIState();
}
static void InitColVertex(ColVertex* vert, float x, float y, float z, u32 col)
@ -933,6 +837,7 @@ void DrawEFBPokeQuads(EFBAccessType type,
// Corresponding dirty flags set outside loop.
D3D::current_command_list->OMSetRenderTargets(1, render_target, FALSE, depth_buffer);
D3D::current_command_list->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
D3D::command_list_mgr->SetCommandListPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
D3D12_VERTEX_BUFFER_VIEW vb_view = {
util_vbuf_efbpokequads->GetBuffer12()->GetGPUVirtualAddress(), // D3D12_GPU_VIRTUAL_ADDRESS BufferLocation;
@ -946,9 +851,6 @@ void DrawEFBPokeQuads(EFBAccessType type,
D3D::current_command_list->SetPipelineState(pso);
D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PSO, true);
// Disable scissor testing.
D3D::current_command_list->RSSetScissorRects(1, &CD3DX12_RECT(0, 0, 131072, 131072));
// generate quads for each efb point
ColVertex* base_vertex_ptr = reinterpret_cast<ColVertex*>(buffer_ptr);
for (size_t i = 0; i < points_to_draw; i++)

View File

@ -92,7 +92,6 @@ void DrawShadedTexQuad(D3DTexture2D* texture,
);
void DrawClearQuad(u32 Color, float z, D3D12_BLEND_DESC* blend_desc, D3D12_DEPTH_STENCIL_DESC* depth_stencil_desc, bool rt_multisampled);
void DrawColorQuad(u32 Color, float z, float x1, float y1, float x2, float y2, D3D12_BLEND_DESC* blend_desc, D3D12_DEPTH_STENCIL_DESC* depth_stencil_desc, bool rt_multisampled);
void DrawEFBPokeQuads(EFBAccessType type,
const EfbPokeData* points,

View File

@ -3,7 +3,6 @@
// Refer to the license.txt file included.
#include "Core/HW/Memmap.h"
#include "VideoBackends/D3D12/BoundingBox.h"
#include "VideoBackends/D3D12/D3DBase.h"
#include "VideoBackends/D3D12/D3DCommandListManager.h"
#include "VideoBackends/D3D12/D3DUtil.h"
@ -198,7 +197,6 @@ void FramebufferManager::ResolveDepthTexture()
FramebufferManager::GetEFBColorTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET);
FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE);
FramebufferManager::RestoreEFBRenderTargets();
// Restores proper viewport/scissor settings.
g_renderer->RestoreAPIState();
@ -209,8 +207,6 @@ void FramebufferManager::RestoreEFBRenderTargets()
D3D::current_command_list->OMSetRenderTargets(1,
&FramebufferManager::GetEFBColorTexture()->GetRTV12(), FALSE,
&FramebufferManager::GetEFBDepthTexture()->GetDSV12());
BBox::Bind();
}
u32 FramebufferManager::ReadEFBColorAccessCopy(u32 x, u32 y)
@ -327,16 +323,12 @@ void FramebufferManager::MapEFBColorAccessCopy()
CD3DX12_TEXTURE_COPY_LOCATION src_location(src_resource, 0);
D3D::current_command_list->CopyTextureRegion(&dst_location, 0, 0, 0, &src_location, nullptr);
// Block until completion
D3D::command_list_mgr->ExecuteQueuedWork(true);
// Restore EFB resource state if it was sourced from here
if (src_resource == m_efb.color_tex->GetTex12())
m_efb.color_tex->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET);
// Restore state after resetting command list
RestoreEFBRenderTargets();
g_renderer->RestoreAPIState();
// Block until completion - state is automatically restored
D3D::command_list_mgr->ExecuteQueuedWork(true);
// Resource copy has finished, so safe to map now
m_efb.color_access_readback_buffer->Map(0, nullptr, reinterpret_cast<void**>(&m_efb.color_access_readback_map));
@ -379,16 +371,12 @@ void FramebufferManager::MapEFBDepthAccessCopy()
CD3DX12_TEXTURE_COPY_LOCATION src_location(src_resource, 0);
D3D::current_command_list->CopyTextureRegion(&dst_location, 0, 0, 0, &src_location, nullptr);
// Block until completion
D3D::command_list_mgr->ExecuteQueuedWork(true);
// Restore EFB resource state if it was sourced from here
if (src_resource == m_efb.depth_tex->GetTex12())
m_efb.depth_tex->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE);
// Restore state after resetting command list
RestoreEFBRenderTargets();
g_renderer->RestoreAPIState();
// Block until completion - state is automatically restored
D3D::command_list_mgr->ExecuteQueuedWork(true);
// Resource copy has finished, so safe to map now
m_efb.depth_access_readback_buffer->Map(0, nullptr, reinterpret_cast<void**>(&m_efb.depth_access_readback_map));
@ -458,7 +446,6 @@ void XFBSource::CopyEFB(float gamma)
FramebufferManager::GetEFBColorTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET);
FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE );
FramebufferManager::RestoreEFBRenderTargets();
// Restores proper viewport/scissor settings.
g_renderer->RestoreAPIState();

View File

@ -215,6 +215,10 @@ void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_p
D3D::ResourceBarrier(D3D::current_command_list, m_out, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE, 0);
D3D::current_command_list->CopyTextureRegion(&dst_location, 0, 0, 0, &src_location, &src_box);
FramebufferManager::GetEFBColorTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET);
FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE);
// State is automatically restored after executing command list.
D3D::command_list_mgr->ExecuteQueuedWork(true);
// Transfer staging buffer to GameCube/Wii RAM
@ -232,13 +236,6 @@ void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_p
}
m_out_readback_buffer->Unmap(0, nullptr);
// Restores proper viewport/scissor settings.
g_renderer->RestoreAPIState();
FramebufferManager::GetEFBColorTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET);
FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE );
FramebufferManager::RestoreEFBRenderTargets();
}
D3D12_SHADER_BYTECODE PSTextureEncoder::SetStaticShader(unsigned int dst_format, PEControl::PixelFormat src_format,

View File

@ -534,7 +534,8 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool color_enable, bool alpha
D3D::DrawClearQuad(rgba_color, 1.0f - (z & 0xFFFFFF) / 16777216.0f, blend_desc, depth_stencil_desc, FramebufferManager::GetEFBColorTexture()->GetMultisampled());
// Restores proper viewport/scissor settings.
g_renderer->RestoreAPIState();
g_renderer->SetViewport();
BPFunctions::SetScissor();
FramebufferManager::InvalidateEFBAccessCopies();
}
@ -582,14 +583,13 @@ void Renderer::ReinterpretPixelData(unsigned int convtype)
FramebufferManager::GetEFBColorTempTexture()->GetMultisampled()
);
// Restores proper viewport/scissor settings.
g_renderer->RestoreAPIState();
FramebufferManager::SwapReinterpretTexture();
FramebufferManager::GetEFBColorTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET);
FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE );
FramebufferManager::RestoreEFBRenderTargets();
FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE);
// Restores proper viewport/scissor settings.
RestoreAPIState();
}
void Renderer::SetBlendMode(bool force_update)
@ -996,14 +996,12 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height
}
// begin next frame
RestoreAPIState();
D3D::BeginFrame();
FramebufferManager::GetEFBColorTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET);
FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE );
FramebufferManager::RestoreEFBRenderTargets();
SetViewport();
RestoreAPIState();
}
void Renderer::ResetAPIState()
@ -1017,6 +1015,9 @@ void Renderer::RestoreAPIState()
// overwritten elsewhere (particularly the viewport).
SetViewport();
BPFunctions::SetScissor();
FramebufferManager::RestoreEFBRenderTargets();
BBox::Bind();
}
static bool s_previous_use_dst_alpha = false;

View File

@ -168,7 +168,6 @@ void TextureCache::TCacheEntry::CopyRectangleFromTexture(
FramebufferManager::GetEFBColorTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET);
FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE);
FramebufferManager::RestoreEFBRenderTargets();
g_renderer->RestoreAPIState();
}
@ -308,7 +307,6 @@ void TextureCache::TCacheEntry::FromRenderTarget(u8* dst, PEControl::PixelFormat
FramebufferManager::GetEFBColorTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET);
FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE);
FramebufferManager::RestoreEFBRenderTargets();
g_renderer->RestoreAPIState();
}
@ -490,7 +488,6 @@ void TextureCache::ConvertTexture(TCacheEntryBase* entry, TCacheEntryBase* uncon
FramebufferManager::GetEFBColorTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET);
FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE );
FramebufferManager::RestoreEFBRenderTargets();
g_renderer->RestoreAPIState();
}

View File

@ -163,10 +163,6 @@ void VertexManager::vFlush(bool use_dst_alpha)
D3D::command_list_mgr->m_draws_since_last_execution = 0;
D3D::command_list_mgr->ExecuteQueuedWork();
g_renderer->SetViewport();
FramebufferManager::RestoreEFBRenderTargets();
}
}
@ -182,7 +178,7 @@ void VertexManager::ResetBuffer(u32 stride)
return;
}
bool command_list_executed = m_vertex_stream_buffer->AllocateSpaceInBuffer(MAXVBUFFERSIZE, stride);
m_vertex_stream_buffer->AllocateSpaceInBuffer(MAXVBUFFERSIZE, stride);
if (m_vertex_stream_buffer_reallocated)
{
@ -195,12 +191,7 @@ void VertexManager::ResetBuffer(u32 stride)
s_pCurBufferPointer = static_cast<u8*>(m_vertex_stream_buffer->GetCPUAddressOfCurrentAllocation());
m_vertex_draw_offset = static_cast<u32>(m_vertex_stream_buffer->GetOffsetOfCurrentAllocation());
command_list_executed |= m_index_stream_buffer->AllocateSpaceInBuffer(MAXIBUFFERSIZE * sizeof(u16), sizeof(u16));
if (command_list_executed)
{
g_renderer->SetViewport();
FramebufferManager::RestoreEFBRenderTargets();
}
m_index_stream_buffer->AllocateSpaceInBuffer(MAXIBUFFERSIZE * sizeof(u16), sizeof(u16));
if (m_index_stream_buffer_reallocated)
{