d3d12: Do not copy fbo, just use new one

This commit is contained in:
vlj 2015-05-31 20:10:39 +02:00 committed by Vincent Lejeune
parent 5a57564b0c
commit 001dc7cf57
5 changed files with 330 additions and 267 deletions

View File

@ -165,7 +165,7 @@ std::pair<ID3DBlob *, ID3DBlob *> compileF32toU8CS()
} }
D3D12GSRender::D3D12GSRender() D3D12GSRender::D3D12GSRender()
: GSRender(), m_fbo(nullptr), m_PSO(nullptr) : GSRender(), m_PSO(nullptr)
{ {
if (Ini.GSDebugOutputEnable.GetValue()) if (Ini.GSDebugOutputEnable.GetValue())
{ {
@ -328,6 +328,8 @@ D3D12GSRender::D3D12GSRender()
check(m_device->CreateHeap(&hd, IID_PPV_ARGS(&m_UAVHeap.m_heap))); check(m_device->CreateHeap(&hd, IID_PPV_ARGS(&m_UAVHeap.m_heap)));
m_UAVHeap.m_putPos = 0; m_UAVHeap.m_putPos = 0;
m_UAVHeap.m_getPos = 1024 * 1024 * 128 - 1; m_UAVHeap.m_getPos = 1024 * 1024 * 128 - 1;
m_rtts.Init(m_device);
} }
D3D12GSRender::~D3D12GSRender() D3D12GSRender::~D3D12GSRender()
@ -345,8 +347,7 @@ D3D12GSRender::~D3D12GSRender()
m_backBuffer[0]->Release(); m_backBuffer[0]->Release();
m_backbufferAsRendertarget[1]->Release(); m_backbufferAsRendertarget[1]->Release();
m_backBuffer[1]->Release(); m_backBuffer[1]->Release();
if (m_fbo) m_rtts.Release();
delete m_fbo;
m_rootSignature->Release(); m_rootSignature->Release();
m_swapChain->Release(); m_swapChain->Release();
m_device->Release(); m_device->Release();
@ -402,79 +403,152 @@ void copyFBO(ID3D12Device* device, ID3D12Resource *rtt, ID3D12GraphicsCommandLis
void D3D12GSRender::InitDrawBuffers() void D3D12GSRender::InitDrawBuffers()
{ {
// FBO location has changed, previous data might be copied // FBO location has changed, previous data might be copied
if (m_fbo != nullptr) u32 address_a = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000);
u32 address_b = GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000);
u32 address_c = GetAddress(m_surface_offset_c, m_context_dma_color_c - 0xfeed0000);
u32 address_d = GetAddress(m_surface_offset_d, m_context_dma_color_d - 0xfeed0000);
u32 address_z = GetAddress(m_surface_offset_z, m_context_dma_z - 0xfeed0000);
ID3D12GraphicsCommandList *copycmdlist;
check(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_perFrameStorage.m_commandAllocator, nullptr, IID_PPV_ARGS(&copycmdlist)));
m_perFrameStorage.m_inflightCommandList.push_back(copycmdlist);
// Make previous RTTs sampleable
for (unsigned i = 0; i < 4; i++)
{ {
ID3D12GraphicsCommandList *copycmdlist; if (m_rtts.m_currentlyBoundRenderTargets[i] == nullptr)
check(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_perFrameStorage.m_commandAllocator, nullptr, IID_PPV_ARGS(&copycmdlist))); continue;
m_perFrameStorage.m_inflightCommandList.push_back(copycmdlist); copycmdlist->ResourceBarrier(1, &getResourceBarrierTransition(m_rtts.m_currentlyBoundRenderTargets[i], D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_GENERIC_READ));
m_rtts.m_renderTargets[m_rtts.m_currentlyBoundRenderTargetsAddress[i]] = m_rtts.m_currentlyBoundRenderTargets[i];
u32 address_a = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000);
u32 address_b = GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000);
u32 address_c = GetAddress(m_surface_offset_c, m_context_dma_color_c - 0xfeed0000);
u32 address_d = GetAddress(m_surface_offset_d, m_context_dma_color_d - 0xfeed0000);
switch (m_fbo->m_target_type)
{
case CELL_GCM_SURFACE_TARGET_0:
if (m_fbo->m_address_color_a != address_a)
copyFBO(m_device, m_fbo->getRenderTargetTexture(0), copycmdlist, m_texturesRTTs, m_fbo->m_address_color_a, address_a, RSXThread::m_width, RSXThread::m_height);
break;
case CELL_GCM_SURFACE_TARGET_1:
if (m_fbo->m_address_color_b != address_b)
copyFBO(m_device, m_fbo->getRenderTargetTexture(1), copycmdlist, m_texturesRTTs, m_fbo->m_address_color_b, address_b, RSXThread::m_width, RSXThread::m_height);
break;
case CELL_GCM_SURFACE_TARGET_MRT1:
if (m_fbo->m_address_color_a != address_a)
copyFBO(m_device, m_fbo->getRenderTargetTexture(0), copycmdlist, m_texturesRTTs, m_fbo->m_address_color_a, address_a, RSXThread::m_width, RSXThread::m_height);
if (m_fbo->m_address_color_b != address_b)
copyFBO(m_device, m_fbo->getRenderTargetTexture(1), copycmdlist, m_texturesRTTs, m_fbo->m_address_color_b, address_b, RSXThread::m_width, RSXThread::m_height);
break;
case CELL_GCM_SURFACE_TARGET_MRT2:
if (m_fbo->m_address_color_a != address_a)
copyFBO(m_device, m_fbo->getRenderTargetTexture(0), copycmdlist, m_texturesRTTs, m_fbo->m_address_color_a, address_a, RSXThread::m_width, RSXThread::m_height);
if (m_fbo->m_address_color_b != address_b)
copyFBO(m_device, m_fbo->getRenderTargetTexture(1), copycmdlist, m_texturesRTTs, m_fbo->m_address_color_b, address_b, RSXThread::m_width, RSXThread::m_height);
if (m_fbo->m_address_color_c != address_c)
copyFBO(m_device, m_fbo->getRenderTargetTexture(2), copycmdlist, m_texturesRTTs, m_fbo->m_address_color_c, address_c, RSXThread::m_width, RSXThread::m_height);
break;
case CELL_GCM_SURFACE_TARGET_MRT3:
if (m_fbo->m_address_color_a != address_a)
copyFBO(m_device, m_fbo->getRenderTargetTexture(0), copycmdlist, m_texturesRTTs, m_fbo->m_address_color_a, address_a, RSXThread::m_width, RSXThread::m_height);
if (m_fbo->m_address_color_b != address_b)
copyFBO(m_device, m_fbo->getRenderTargetTexture(1), copycmdlist, m_texturesRTTs, m_fbo->m_address_color_b, address_b, RSXThread::m_width, RSXThread::m_height);
if (m_fbo->m_address_color_c != address_c)
copyFBO(m_device, m_fbo->getRenderTargetTexture(2), copycmdlist, m_texturesRTTs, m_fbo->m_address_color_c, address_c, RSXThread::m_width, RSXThread::m_height);
if (m_fbo->m_address_color_d != address_d)
copyFBO(m_device, m_fbo->getRenderTargetTexture(3), copycmdlist, m_texturesRTTs, m_fbo->m_address_color_d, address_d, RSXThread::m_width, RSXThread::m_height);
break;
}
check(copycmdlist->Close());
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)&copycmdlist);
} }
if (m_fbo == nullptr || RSXThread::m_width != m_lastWidth || RSXThread::m_height != m_lastHeight || m_lastDepth != m_surface_depth_format) memset(m_rtts.m_currentlyBoundRenderTargetsAddress, 0, 4 * sizeof(u32));
{ memset(m_rtts.m_currentlyBoundRenderTargets, 0, 4 * sizeof(ID3D12Resource *));
m_rtts.m_currentlyBoundDepthStencil = nullptr;
LOG_WARNING(RSX, "New FBO (%dx%d)", RSXThread::m_width, RSXThread::m_height); m_rtts.m_currentlyBoundDepthStencilAddress = 0;
m_lastWidth = RSXThread::m_width;
m_lastHeight = RSXThread::m_height;
m_lastDepth = m_surface_depth_format;
float clearColor[] =
{
m_clear_surface_color_r / 255.0f,
m_clear_surface_color_g / 255.0f,
m_clear_surface_color_b / 255.0f,
m_clear_surface_color_a / 255.0f
};
m_fbo = new D3D12RenderTargetSets(m_device, (u8)m_lastDepth, m_lastWidth, m_lastHeight, clearColor, 1.f);
D3D12_CPU_DESCRIPTOR_HANDLE Handle = m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart();
size_t g_RTTIncrement = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
switch (m_surface_color_target)
{
case CELL_GCM_SURFACE_TARGET_0:
{
ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0,address_a, RSXThread::m_width, RSXThread::m_height,
m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f);
D3D12_RENDER_TARGET_VIEW_DESC rttViewDesc = {};
rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
m_device->CreateRenderTargetView(rttA, &rttViewDesc, Handle);
break;
} }
m_fbo->m_address_color_a = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000); case CELL_GCM_SURFACE_TARGET_1:
m_fbo->m_address_color_b = GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000); {
m_fbo->m_address_color_c = GetAddress(m_surface_offset_c, m_context_dma_color_c - 0xfeed0000); ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_b, RSXThread::m_width, RSXThread::m_height,
m_fbo->m_address_color_d = GetAddress(m_surface_offset_d, m_context_dma_color_d - 0xfeed0000); m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f);
m_fbo->m_address_z = GetAddress(m_surface_offset_z, m_context_dma_z - 0xfeed0000); D3D12_RENDER_TARGET_VIEW_DESC rttViewDesc = {};
m_fbo->m_target_type = m_surface_color_target; rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
m_device->CreateRenderTargetView(rttB, &rttViewDesc, Handle);
break;
}
case CELL_GCM_SURFACE_TARGET_MRT1:
{
ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_a, RSXThread::m_width, RSXThread::m_height,
m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f);
D3D12_RENDER_TARGET_VIEW_DESC rttViewDesc = {};
rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
m_device->CreateRenderTargetView(rttA, &rttViewDesc, Handle);
Handle.ptr += g_RTTIncrement;
ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 1, address_b, RSXThread::m_width, RSXThread::m_height,
m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f);
rttViewDesc = {};
rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
m_device->CreateRenderTargetView(rttB, &rttViewDesc, Handle);
}
break;
case CELL_GCM_SURFACE_TARGET_MRT2:
{
ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_a, RSXThread::m_width, RSXThread::m_height,
m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f);
D3D12_RENDER_TARGET_VIEW_DESC rttViewDesc = {};
rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
m_device->CreateRenderTargetView(rttA, &rttViewDesc, Handle);
Handle.ptr += g_RTTIncrement;
ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 1, address_b, RSXThread::m_width, RSXThread::m_height,
m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f);
rttViewDesc = {};
rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
m_device->CreateRenderTargetView(rttB, &rttViewDesc, Handle);
Handle.ptr += g_RTTIncrement;
ID3D12Resource *rttC = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 2, address_c, RSXThread::m_width, RSXThread::m_height,
m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f);
rttViewDesc = {};
rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
m_device->CreateRenderTargetView(rttC, &rttViewDesc, Handle);
break;
}
case CELL_GCM_SURFACE_TARGET_MRT3:
{
ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_a, RSXThread::m_width, RSXThread::m_height,
m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f);
D3D12_RENDER_TARGET_VIEW_DESC rttViewDesc = {};
rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
m_device->CreateRenderTargetView(rttA, &rttViewDesc, Handle);
Handle.ptr += g_RTTIncrement;
ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 1,address_b, RSXThread::m_width, RSXThread::m_height,
m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f);
rttViewDesc = {};
rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
m_device->CreateRenderTargetView(rttB, &rttViewDesc, Handle);
Handle.ptr += g_RTTIncrement;
ID3D12Resource *rttC = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 2, address_c, RSXThread::m_width, RSXThread::m_height,
m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f);
rttViewDesc = {};
rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
m_device->CreateRenderTargetView(rttC, &rttViewDesc, Handle);
Handle.ptr += g_RTTIncrement;
ID3D12Resource *rttD = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 3, address_d, RSXThread::m_width, RSXThread::m_height,
m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f);
rttViewDesc = {};
rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
m_device->CreateRenderTargetView(rttD, &rttViewDesc, Handle);
break;
}
}
ID3D12Resource *ds = m_rtts.bindAddressAsDepthStencil(m_device, copycmdlist, address_z, RSXThread::m_width, RSXThread::m_height, m_surface_depth_format, 1., 0);
D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc = {};
switch (m_surface_depth_format)
{
case 0:
break;
case CELL_GCM_SURFACE_Z16:
depthStencilViewDesc.Format = DXGI_FORMAT_D16_UNORM;
break;
case CELL_GCM_SURFACE_Z24S8:
depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
break;
default:
LOG_ERROR(RSX, "Bad depth format! (%d)", m_surface_depth_format);
assert(0);
}
depthStencilViewDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
m_device->CreateDepthStencilView(ds, &depthStencilViewDesc, m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
check(copycmdlist->Close());
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)&copycmdlist);
} }
@ -519,10 +593,10 @@ void D3D12GSRender::ExecCMD(u32 cmd)
// TODO: Merge depth and stencil clear when possible // TODO: Merge depth and stencil clear when possible
if (m_clear_surface_mask & 0x1) if (m_clear_surface_mask & 0x1)
commandList->ClearDepthStencilView(m_fbo->getDSVCPUHandle(), D3D12_CLEAR_FLAG_DEPTH, m_clear_surface_z / (float)0xffffff, 0, 0, nullptr); commandList->ClearDepthStencilView(m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_DEPTH, m_clear_surface_z / (float)0xffffff, 0, 0, nullptr);
if (m_clear_surface_mask & 0x2) if (m_clear_surface_mask & 0x2)
commandList->ClearDepthStencilView(m_fbo->getDSVCPUHandle(), D3D12_CLEAR_FLAG_STENCIL, 0.f, m_clear_surface_s, 0, nullptr); commandList->ClearDepthStencilView(m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_STENCIL, 0.f, m_clear_surface_s, 0, nullptr);
if (m_clear_surface_mask & 0xF0) if (m_clear_surface_mask & 0xF0)
{ {
@ -533,30 +607,37 @@ void D3D12GSRender::ExecCMD(u32 cmd)
m_clear_surface_color_b / 255.0f, m_clear_surface_color_b / 255.0f,
m_clear_surface_color_a / 255.0f m_clear_surface_color_a / 255.0f
}; };
D3D12_CPU_DESCRIPTOR_HANDLE handle = m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart();
size_t g_RTTIncrement = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
switch (m_surface_color_target) switch (m_surface_color_target)
{ {
case CELL_GCM_SURFACE_TARGET_NONE: break; case CELL_GCM_SURFACE_TARGET_NONE: break;
case CELL_GCM_SURFACE_TARGET_0: case CELL_GCM_SURFACE_TARGET_0:
commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(0), clearColor, 0, nullptr);
break;
case CELL_GCM_SURFACE_TARGET_1: case CELL_GCM_SURFACE_TARGET_1:
commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(1), clearColor, 0, nullptr); commandList->ClearRenderTargetView(handle, clearColor, 0, nullptr);
break; break;
case CELL_GCM_SURFACE_TARGET_MRT1: case CELL_GCM_SURFACE_TARGET_MRT1:
commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(0), clearColor, 0, nullptr); commandList->ClearRenderTargetView(handle, clearColor, 0, nullptr);
commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(1), clearColor, 0, nullptr); handle.ptr += g_RTTIncrement;
commandList->ClearRenderTargetView(handle, clearColor, 0, nullptr);
break; break;
case CELL_GCM_SURFACE_TARGET_MRT2: case CELL_GCM_SURFACE_TARGET_MRT2:
commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(0), clearColor, 0, nullptr); commandList->ClearRenderTargetView(handle, clearColor, 0, nullptr);
commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(1), clearColor, 0, nullptr); handle.ptr += g_RTTIncrement;
commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(2), clearColor, 0, nullptr); commandList->ClearRenderTargetView(handle, clearColor, 0, nullptr);
handle.ptr += g_RTTIncrement;
commandList->ClearRenderTargetView(handle, clearColor, 0, nullptr);
break; break;
case CELL_GCM_SURFACE_TARGET_MRT3: case CELL_GCM_SURFACE_TARGET_MRT3:
commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(0), clearColor, 0, nullptr); commandList->ClearRenderTargetView(handle, clearColor, 0, nullptr);
commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(1), clearColor, 0, nullptr); handle.ptr += g_RTTIncrement;
commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(2), clearColor, 0, nullptr); commandList->ClearRenderTargetView(handle, clearColor, 0, nullptr);
commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(3), clearColor, 0, nullptr); handle.ptr += g_RTTIncrement;
commandList->ClearRenderTargetView(handle, clearColor, 0, nullptr);
handle.ptr += g_RTTIncrement;
commandList->ClearRenderTargetView(handle, clearColor, 0, nullptr);
break; break;
default: default:
LOG_ERROR(RSX, "Bad surface color target: %d", m_surface_color_target); LOG_ERROR(RSX, "Bad surface color target: %d", m_surface_color_target);
@ -823,28 +904,30 @@ void D3D12GSRender::ExecCMD()
m_perFrameStorage.m_currentTextureIndex += usedTexture; m_perFrameStorage.m_currentTextureIndex += usedTexture;
D3D12_CPU_DESCRIPTOR_HANDLE *DepthStencilHandle = &m_fbo->getDSVCPUHandle(); size_t numRTT;
switch (m_surface_color_target) switch (m_surface_color_target)
{ {
case CELL_GCM_SURFACE_TARGET_NONE: break; case CELL_GCM_SURFACE_TARGET_NONE: break;
case CELL_GCM_SURFACE_TARGET_0: case CELL_GCM_SURFACE_TARGET_0:
commandList->OMSetRenderTargets(1, &m_fbo->getRTTCPUHandle(0), true, DepthStencilHandle);
break;
case CELL_GCM_SURFACE_TARGET_1: case CELL_GCM_SURFACE_TARGET_1:
commandList->OMSetRenderTargets(1, &m_fbo->getRTTCPUHandle(1), true, DepthStencilHandle); numRTT = 1;
break; break;
case CELL_GCM_SURFACE_TARGET_MRT1: case CELL_GCM_SURFACE_TARGET_MRT1:
commandList->OMSetRenderTargets(2, &m_fbo->getRTTCPUHandle(0), true, DepthStencilHandle); numRTT = 2;
break; break;
case CELL_GCM_SURFACE_TARGET_MRT2: case CELL_GCM_SURFACE_TARGET_MRT2:
commandList->OMSetRenderTargets(3, &m_fbo->getRTTCPUHandle(0), true, DepthStencilHandle); numRTT = 3;
break; break;
case CELL_GCM_SURFACE_TARGET_MRT3: case CELL_GCM_SURFACE_TARGET_MRT3:
commandList->OMSetRenderTargets(4, &m_fbo->getRTTCPUHandle(0), true, DepthStencilHandle); numRTT = 4;
break; break;
default: default:
LOG_ERROR(RSX, "Bad surface color target: %d", m_surface_color_target); LOG_ERROR(RSX, "Bad surface color target: %d", m_surface_color_target);
} }
D3D12_CPU_DESCRIPTOR_HANDLE *DepthStencilHandle = &m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart();
commandList->OMSetRenderTargets(numRTT, &m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(), true, DepthStencilHandle);
D3D12_VIEWPORT viewport = D3D12_VIEWPORT viewport =
{ {
0.f, 0.f,
@ -1231,7 +1314,7 @@ void D3D12GSRender::Flip()
barriers[0].Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST; barriers[0].Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
barriers[1].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; barriers[1].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barriers[1].Transition.pResource = m_fbo->getRenderTargetTexture(0); barriers[1].Transition.pResource = m_rtts.m_currentlyBoundRenderTargets[0];
barriers[1].Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; barriers[1].Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
barriers[1].Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE; barriers[1].Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE;
@ -1239,7 +1322,7 @@ void D3D12GSRender::Flip()
D3D12_TEXTURE_COPY_LOCATION src = {}, dst = {}; D3D12_TEXTURE_COPY_LOCATION src = {}, dst = {};
src.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; src.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
src.SubresourceIndex = 0, dst.SubresourceIndex = 0; src.SubresourceIndex = 0, dst.SubresourceIndex = 0;
src.pResource = m_fbo->getRenderTargetTexture(0), dst.pResource = m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()]; src.pResource = m_rtts.m_currentlyBoundRenderTargets[0], dst.pResource = m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()];
D3D12_BOX box = { 0, 0, 0, RSXThread::m_width, RSXThread::m_height, 1 }; D3D12_BOX box = { 0, 0, 0, RSXThread::m_width, RSXThread::m_height, 1 };
commandList->CopyTextureRegion(&dst, 0, 0, 0, &src, &box); commandList->CopyTextureRegion(&dst, 0, 0, 0, &src, &box);
@ -1263,8 +1346,8 @@ void D3D12GSRender::Flip()
WaitForSingleObject(handle, INFINITE); WaitForSingleObject(handle, INFINITE);
CloseHandle(handle); CloseHandle(handle);
m_perFrameStorage.Reset(); m_perFrameStorage.Reset();
m_texturesRTTs.clear();
m_texturesCache.clear(); m_texturesCache.clear();
m_texturesRTTs.clear();
m_frame->Flip(nullptr); m_frame->Flip(nullptr);
} }
@ -1433,7 +1516,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = 1; srvDesc.Texture2D.MipLevels = 1;
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
m_device->CreateShaderResourceView(m_fbo->getDepthStencilTexture(), &srvDesc, Handle); m_device->CreateShaderResourceView(m_rtts.m_currentlyBoundDepthStencil, &srvDesc, Handle);
Handle.ptr += m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); Handle.ptr += m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {}; D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
uavDesc.Format = DXGI_FORMAT_R8_UNORM; uavDesc.Format = DXGI_FORMAT_R8_UNORM;
@ -1441,7 +1524,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
m_device->CreateUnorderedAccessView(depthConverted, nullptr, &uavDesc, Handle); m_device->CreateUnorderedAccessView(depthConverted, nullptr, &uavDesc, Handle);
// Convert // Convert
convertCommandList->ResourceBarrier(1, &getResourceBarrierTransition(m_fbo->getDepthStencilTexture(), D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_GENERIC_READ)); convertCommandList->ResourceBarrier(1, &getResourceBarrierTransition(m_rtts.m_currentlyBoundDepthStencil, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_GENERIC_READ));
convertCommandList->SetPipelineState(m_convertPSO); convertCommandList->SetPipelineState(m_convertPSO);
convertCommandList->SetComputeRootSignature(m_convertRootSignature); convertCommandList->SetComputeRootSignature(m_convertRootSignature);
@ -1456,7 +1539,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
D3D12_RESOURCE_BARRIER barriers[] = D3D12_RESOURCE_BARRIER barriers[] =
{ {
getResourceBarrierTransition(m_fbo->getDepthStencilTexture(), D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_DEPTH_WRITE), getResourceBarrierTransition(m_rtts.m_currentlyBoundDepthStencil, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_DEPTH_WRITE),
uavbarrier, uavbarrier,
}; };
convertCommandList->ResourceBarrier(2, barriers); convertCommandList->ResourceBarrier(2, barriers);
@ -1498,29 +1581,29 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
break; break;
case CELL_GCM_SURFACE_TARGET_0: case CELL_GCM_SURFACE_TARGET_0:
if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_fbo->getRenderTargetTexture(0), downloadCommandList); if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], downloadCommandList);
break; break;
case CELL_GCM_SURFACE_TARGET_1: case CELL_GCM_SURFACE_TARGET_1:
if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_fbo->getRenderTargetTexture(1), downloadCommandList); if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], downloadCommandList);
break; break;
case CELL_GCM_SURFACE_TARGET_MRT1: case CELL_GCM_SURFACE_TARGET_MRT1:
if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_fbo->getRenderTargetTexture(0), downloadCommandList); if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], downloadCommandList);
if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_fbo->getRenderTargetTexture(1), downloadCommandList); if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[1], downloadCommandList);
break; break;
case CELL_GCM_SURFACE_TARGET_MRT2: case CELL_GCM_SURFACE_TARGET_MRT2:
if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_fbo->getRenderTargetTexture(0), downloadCommandList); if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], downloadCommandList);
if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_fbo->getRenderTargetTexture(1), downloadCommandList); if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[1], downloadCommandList);
if (m_context_dma_color_b) rtt2 = writeColorBuffer(m_fbo->getRenderTargetTexture(2), downloadCommandList); if (m_context_dma_color_b) rtt2 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[2], downloadCommandList);
break; break;
case CELL_GCM_SURFACE_TARGET_MRT3: case CELL_GCM_SURFACE_TARGET_MRT3:
if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_fbo->getRenderTargetTexture(0), downloadCommandList); if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], downloadCommandList);
if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_fbo->getRenderTargetTexture(1), downloadCommandList); if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[1], downloadCommandList);
if (m_context_dma_color_b) rtt2 = writeColorBuffer(m_fbo->getRenderTargetTexture(2), downloadCommandList); if (m_context_dma_color_b) rtt2 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[2], downloadCommandList);
if (m_context_dma_color_b) rtt3 = writeColorBuffer(m_fbo->getRenderTargetTexture(3), downloadCommandList); if (m_context_dma_color_b) rtt3 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[3], downloadCommandList);
break; break;
} }
if (needTransfer) if (needTransfer)

View File

@ -48,7 +48,7 @@ class D3D12GSRender : public GSRender
{ {
private: private:
// Copy of RTT to be used as texture // Copy of RTT to be used as texture
std::unordered_map<u32, Microsoft::WRL::ComPtr<ID3D12Resource> > m_texturesRTTs; std::unordered_map<u32, ID3D12Resource* > m_texturesRTTs;
std::unordered_map<u32, ID3D12Resource*> m_texturesCache; std::unordered_map<u32, ID3D12Resource*> m_texturesCache;
// std::vector<PostDrawObj> m_post_draw_objs; // std::vector<PostDrawObj> m_post_draw_objs;
@ -116,8 +116,9 @@ private:
bool m_forcedIndexBuffer; bool m_forcedIndexBuffer;
size_t indexCount; size_t indexCount;
RenderTargets m_rtts;
std::vector<D3D12_INPUT_ELEMENT_DESC> m_IASet; std::vector<D3D12_INPUT_ELEMENT_DESC> m_IASet;
D3D12RenderTargetSets *m_fbo;
ID3D12Device* m_device; ID3D12Device* m_device;
ID3D12CommandQueue *m_commandQueueCopy; ID3D12CommandQueue *m_commandQueueCopy;
ID3D12CommandQueue *m_commandQueueGraphic; ID3D12CommandQueue *m_commandQueueGraphic;

View File

@ -9,7 +9,106 @@
#include "Emu/System.h" #include "Emu/System.h"
#include "Emu/RSX/GSRender.h" #include "Emu/RSX/GSRender.h"
D3D12RenderTargetSets::D3D12RenderTargetSets(ID3D12Device *device, u8 surfaceDepthFormat, size_t width, size_t height, float clearColor[4], float clearDepth) #include "D3D12.h"
ID3D12Resource *RenderTargets::bindAddressAsRenderTargets(ID3D12Device *device, ID3D12GraphicsCommandList *cmdList, size_t slot, u32 address,
size_t width, size_t height, float clearColorR, float clearColorG, float clearColorB, float clearColorA)
{
ID3D12Resource* rtt;
auto It = m_renderTargets.find(address);
// TODO: Check if sizes match
if (It != m_renderTargets.end())
{
rtt = It->second;
cmdList->ResourceBarrier(1, &getResourceBarrierTransition(rtt, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET));
}
else
{
LOG_WARNING(RSX, "Creating RTT");
D3D12_CLEAR_VALUE clearColorValue = {};
clearColorValue.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
clearColorValue.Color[0] = clearColorR;
clearColorValue.Color[1] = clearColorG;
clearColorValue.Color[2] = clearColorB;
clearColorValue.Color[3] = clearColorA;
D3D12_HEAP_PROPERTIES heapProp = {};
heapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
D3D12_RESOURCE_DESC resourceDesc = getTexture2DResourceDesc(width, height, DXGI_FORMAT_R8G8B8A8_UNORM);
resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
device->CreateCommittedResource(
&heapProp,
D3D12_HEAP_FLAG_NONE,
&resourceDesc,
D3D12_RESOURCE_STATE_RENDER_TARGET,
&clearColorValue,
IID_PPV_ARGS(&rtt)
);
m_renderTargets[address] = rtt;
}
m_currentlyBoundRenderTargetsAddress[slot] = address;
m_currentlyBoundRenderTargets[slot] = rtt;
return rtt;
}
ID3D12Resource * RenderTargets::bindAddressAsDepthStencil(ID3D12Device * device, ID3D12GraphicsCommandList * cmdList, u32 address, size_t width, size_t height, u8 surfaceDepthFormat, float depthClear, u8 stencilClear)
{
ID3D12Resource* ds;
auto It = m_depthStencil.find(address);
// TODO: Check if sizes and surface depth format match
if (It != m_depthStencil.end())
{
ds = It->second;
cmdList->ResourceBarrier(1, &getResourceBarrierTransition(ds, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_DEPTH_WRITE));
}
else
{
D3D12_CLEAR_VALUE clearDepthValue = {};
clearDepthValue.DepthStencil.Depth = depthClear;
D3D12_HEAP_PROPERTIES heapProp = {};
heapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
DXGI_FORMAT dxgiFormat;
switch (surfaceDepthFormat)
{
case 0:
break;
case CELL_GCM_SURFACE_Z16:
dxgiFormat = DXGI_FORMAT_R16_TYPELESS;
clearDepthValue.Format = DXGI_FORMAT_D16_UNORM;
break;
case CELL_GCM_SURFACE_Z24S8:
dxgiFormat = DXGI_FORMAT_R24G8_TYPELESS;
clearDepthValue.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
break;
default:
LOG_ERROR(RSX, "Bad depth format! (%d)", surfaceDepthFormat);
assert(0);
}
D3D12_RESOURCE_DESC resourceDesc = getTexture2DResourceDesc(width, height, dxgiFormat);
resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
device->CreateCommittedResource(
&heapProp,
D3D12_HEAP_FLAG_NONE,
&resourceDesc,
D3D12_RESOURCE_STATE_DEPTH_WRITE,
&clearDepthValue,
IID_PPV_ARGS(&ds)
);
m_depthStencil[address] = ds;
}
m_currentlyBoundDepthStencil = ds;
m_currentlyBoundDepthStencilAddress = address;
return ds;
}
void RenderTargets::Init(ID3D12Device *device)//, u8 surfaceDepthFormat, size_t width, size_t height, float clearColor[4], float clearDepth)
{ {
D3D12_DESCRIPTOR_HEAP_DESC descriptorHeapDesc = {}; D3D12_DESCRIPTOR_HEAP_DESC descriptorHeapDesc = {};
descriptorHeapDesc.NumDescriptors = 1; descriptorHeapDesc.NumDescriptors = 1;
@ -18,140 +117,21 @@ D3D12RenderTargetSets::D3D12RenderTargetSets(ID3D12Device *device, u8 surfaceDep
descriptorHeapDesc.NumDescriptors = 4; descriptorHeapDesc.NumDescriptors = 4;
descriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; descriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(&m_rttDescriptorHeap)); device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(&m_renderTargetsDescriptorsHeap));
D3D12_CLEAR_VALUE clearDepthValue = {}; memset(m_currentlyBoundRenderTargetsAddress, 0, 4 * sizeof(u32));
clearDepthValue.DepthStencil.Depth = clearDepth; memset(m_currentlyBoundRenderTargets, 0, 4 * sizeof(ID3D12Resource*));
m_currentlyBoundDepthStencil = nullptr;
// Every resource are committed for simplicity, later we could use heap m_currentlyBoundDepthStencilAddress = 0;
D3D12_HEAP_PROPERTIES heapProp = {};
heapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
D3D12_RESOURCE_DESC resourceDesc = {};
resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
resourceDesc.Width = (UINT)width;
resourceDesc.Height = (UINT)height;
resourceDesc.SampleDesc.Count = 1;
resourceDesc.DepthOrArraySize = 1;
switch (surfaceDepthFormat)
{
case 0:
break;
case CELL_GCM_SURFACE_Z16:
resourceDesc.Format = DXGI_FORMAT_R16_TYPELESS;
clearDepthValue.Format = DXGI_FORMAT_D16_UNORM;
break;
case CELL_GCM_SURFACE_Z24S8:
resourceDesc.Format = DXGI_FORMAT_R24G8_TYPELESS;
clearDepthValue.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
break;
default:
LOG_ERROR(RSX, "Bad depth format! (%d)", surfaceDepthFormat);
assert(0);
}
device->CreateCommittedResource(
&heapProp,
D3D12_HEAP_FLAG_NONE,
&resourceDesc,
D3D12_RESOURCE_STATE_DEPTH_WRITE,
&clearDepthValue,
IID_PPV_ARGS(&m_depthStencilTexture)
);
D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc = {};
switch (surfaceDepthFormat)
{
case 0:
break;
case CELL_GCM_SURFACE_Z16:
depthStencilViewDesc.Format = DXGI_FORMAT_D16_UNORM;
break;
case CELL_GCM_SURFACE_Z24S8:
depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
break;
default:
LOG_ERROR(RSX, "Bad depth format! (%d)", surfaceDepthFormat);
assert(0);
}
depthStencilViewDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
device->CreateDepthStencilView(m_depthStencilTexture, &depthStencilViewDesc, m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
D3D12_CLEAR_VALUE clearColorValue = {};
clearColorValue.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
clearColorValue.Color[0] = clearColor[0];
clearColorValue.Color[1] = clearColor[1];
clearColorValue.Color[2] = clearColor[2];
clearColorValue.Color[3] = clearColor[3];
g_RTTIncrement = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
D3D12_CPU_DESCRIPTOR_HANDLE Handle = m_rttDescriptorHeap->GetCPUDescriptorHandleForHeapStart();
for (int i = 0; i < 4; ++i)
{
D3D12_RESOURCE_DESC resourceDesc = {};
resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
resourceDesc.Width = (UINT)width;
resourceDesc.Height = (UINT)height;
resourceDesc.DepthOrArraySize = 1;
resourceDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
resourceDesc.SampleDesc.Count = 1;
device->CreateCommittedResource(
&heapProp,
D3D12_HEAP_FLAG_NONE,
&resourceDesc,
D3D12_RESOURCE_STATE_RENDER_TARGET,
&clearColorValue,
IID_PPV_ARGS(&m_rtts[i])
);
D3D12_RENDER_TARGET_VIEW_DESC rttViewDesc = {};
rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
rttViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
device->CreateRenderTargetView(m_rtts[i], &rttViewDesc, Handle);
Handle.ptr += g_RTTIncrement;
}
/*if (!m_set_surface_clip_horizontal)
{
m_surface_clip_x = 0;
m_surface_clip_w = RSXThread::m_width;
}
if (!m_set_surface_clip_vertical)
{
m_surface_clip_y = 0;
m_surface_clip_h = RSXThread::m_height;
}*/
} }
D3D12RenderTargetSets::~D3D12RenderTargetSets() void RenderTargets::Release()
{ {
for (unsigned i = 0; i < 4; i++) for (auto tmp : m_renderTargets)
m_rtts[i]->Release(); tmp.second->Release();
m_rttDescriptorHeap->Release();
m_depthStencilTexture->Release();
m_depthStencilDescriptorHeap->Release(); m_depthStencilDescriptorHeap->Release();
} m_renderTargetsDescriptorsHeap->Release();
for (auto tmp : m_depthStencil)
D3D12_CPU_DESCRIPTOR_HANDLE D3D12RenderTargetSets::getRTTCPUHandle(u8 baseFBO) const tmp.second->Release();
{
D3D12_CPU_DESCRIPTOR_HANDLE Handle = m_rttDescriptorHeap->GetCPUDescriptorHandleForHeapStart();
Handle.ptr += baseFBO * g_RTTIncrement;
return Handle;
}
D3D12_CPU_DESCRIPTOR_HANDLE D3D12RenderTargetSets::getDSVCPUHandle() const
{
return m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart();
}
ID3D12Resource * D3D12RenderTargetSets::getRenderTargetTexture(u8 Id) const
{
return m_rtts[Id];
}
ID3D12Resource * D3D12RenderTargetSets::getDepthStencilTexture() const
{
return m_depthStencilTexture;
} }
#endif #endif

View File

@ -3,30 +3,29 @@
#if defined(DX12_SUPPORT) #if defined(DX12_SUPPORT)
#include <d3d12.h> #include <d3d12.h>
/** struct RenderTargets
* Class that embeds a RenderTargetDescriptor view and eventually a DepthStencil Descriptor View.
* Used to imitate OpenGL FrameBuffer concept.
*/
class D3D12RenderTargetSets
{ {
size_t g_RTTIncrement; std::unordered_map<u32, ID3D12Resource *> m_renderTargets;
ID3D12Resource *m_depthStencilTexture; ID3D12Resource *m_currentlyBoundRenderTargets[4];
ID3D12Resource *m_rtts[4]; u32 m_currentlyBoundRenderTargetsAddress[4];
ID3D12DescriptorHeap *m_rttDescriptorHeap; std::unordered_map<u32, ID3D12Resource *> m_depthStencil;
ID3D12Resource *m_currentlyBoundDepthStencil;
u32 m_currentlyBoundDepthStencilAddress;
ID3D12DescriptorHeap *m_renderTargetsDescriptorsHeap;
ID3D12DescriptorHeap *m_depthStencilDescriptorHeap; ID3D12DescriptorHeap *m_depthStencilDescriptorHeap;
public:
D3D12RenderTargetSets(ID3D12Device *device, u8 surfaceDepthFormat, size_t width, size_t height, float clearColor[4], float clearDepth);
~D3D12RenderTargetSets();
/**
* Return the base descriptor address for the give surface target.
* All rtt's view descriptor are contigous.
*/
D3D12_CPU_DESCRIPTOR_HANDLE getRTTCPUHandle(u8 baseFBO) const;
D3D12_CPU_DESCRIPTOR_HANDLE getDSVCPUHandle() const;
ID3D12Resource *getRenderTargetTexture(u8 Id) const;
ID3D12Resource *getDepthStencilTexture() const;
u32 m_address_color_a, m_address_color_b, m_address_color_c, m_address_color_d, m_address_z; /**
u32 m_target_type; * If render target already exists at address, issue state change operation on cmdList.
* Otherwise create one with width, height, clearColor info.
* returns the corresponding render target resource.
*/
ID3D12Resource *bindAddressAsRenderTargets(ID3D12Device *device, ID3D12GraphicsCommandList *cmdList, size_t slot, u32 address,
size_t width, size_t height, float clearColorR, float clearColorG, float clearColorB, float clearColorA);
ID3D12Resource *bindAddressAsDepthStencil(ID3D12Device *device, ID3D12GraphicsCommandList *cmdList, u32 address,
size_t width, size_t height, u8 surfaceDepthFormat, float depthClear, u8 stencilClear);
void Init(ID3D12Device *device);
void Release();
}; };
#endif #endif

View File

@ -166,11 +166,11 @@ size_t D3D12GSRender::UploadTextures()
} }
ID3D12Resource *vramTexture; ID3D12Resource *vramTexture;
std::unordered_map<u32, Microsoft::WRL::ComPtr<ID3D12Resource> >::const_iterator ItRTT = m_texturesRTTs.find(texaddr); std::unordered_map<u32, ID3D12Resource* >::const_iterator ItRTT = m_rtts.m_renderTargets.find(texaddr);
std::unordered_map<u32, ID3D12Resource* >::const_iterator ItCache = m_texturesCache.find(texaddr); std::unordered_map<u32, ID3D12Resource* >::const_iterator ItCache = m_texturesCache.find(texaddr);
if (ItRTT != m_texturesRTTs.end()) if (ItRTT != m_rtts.m_renderTargets.end())
{ {
vramTexture = ItRTT->second.Get(); vramTexture = ItRTT->second;
} }
else if (ItCache != m_texturesCache.end()) else if (ItCache != m_texturesCache.end())
{ {