mirror of https://github.com/RPCS3/rpcs3.git
d3d12: Enable multiple mrt read
This commit is contained in:
parent
8e9cdc5fea
commit
f382ba0319
|
@ -343,57 +343,97 @@ void D3D12GSRender::Close()
|
||||||
m_frame->Hide();
|
m_frame->Hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void copyFBO(ID3D12Device* device, ID3D12Resource *rtt, ID3D12GraphicsCommandList *cmdList,
|
||||||
|
std::unordered_map<u32, Microsoft::WRL::ComPtr<ID3D12Resource> > &texturesRTTs,
|
||||||
|
u32 ¤tFBOAddress, u32 newAddress, size_t width, size_t height)
|
||||||
|
{
|
||||||
|
// TODO : move to texture heap
|
||||||
|
Microsoft::WRL::ComPtr<ID3D12Resource> Texture;
|
||||||
|
D3D12_HEAP_PROPERTIES hp = {};
|
||||||
|
hp.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||||
|
check(
|
||||||
|
device->CreateCommittedResource(
|
||||||
|
&hp,
|
||||||
|
D3D12_HEAP_FLAG_NONE,
|
||||||
|
&getTexture2DResourceDesc(width, height, DXGI_FORMAT_R8G8B8A8_UNORM),
|
||||||
|
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||||
|
nullptr,
|
||||||
|
IID_PPV_ARGS(&Texture)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
cmdList->ResourceBarrier(1, &getResourceBarrierTransition(rtt, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE));
|
||||||
|
|
||||||
|
D3D12_TEXTURE_COPY_LOCATION dst = {}, src = {};
|
||||||
|
dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||||
|
dst.pResource = Texture.Get();
|
||||||
|
src.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||||
|
src.pResource = rtt;
|
||||||
|
|
||||||
|
cmdList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr);
|
||||||
|
|
||||||
|
D3D12_RESOURCE_BARRIER barriers[2] =
|
||||||
|
{
|
||||||
|
getResourceBarrierTransition(rtt, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET),
|
||||||
|
getResourceBarrierTransition(Texture.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_GENERIC_READ),
|
||||||
|
};
|
||||||
|
cmdList->ResourceBarrier(2, barriers);
|
||||||
|
|
||||||
|
texturesRTTs[currentFBOAddress] = Texture;
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
if (m_fbo != nullptr)
|
||||||
{
|
{
|
||||||
// TODO : move to texture heap
|
ID3D12GraphicsCommandList *copycmdlist;
|
||||||
|
check(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_perFrameStorage.m_commandAllocator, nullptr, IID_PPV_ARGS(©cmdlist)));
|
||||||
|
m_perFrameStorage.m_inflightCommandList.push_back(copycmdlist);
|
||||||
|
|
||||||
u32 address_a = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000);
|
u32 address_a = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000);
|
||||||
if (m_fbo->m_address_color_a != address_a)
|
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)
|
||||||
{
|
{
|
||||||
LOG_WARNING(RSX, "Copy draw buffer A");
|
case CELL_GCM_SURFACE_TARGET_0:
|
||||||
Microsoft::WRL::ComPtr<ID3D12Resource> Texture;
|
if (m_fbo->m_address_color_a != address_a)
|
||||||
D3D12_HEAP_PROPERTIES hp = {};
|
copyFBO(m_device, m_fbo->getRenderTargetTexture(0), copycmdlist, m_texturesRTTs, m_fbo->m_address_color_a, address_a, RSXThread::m_width, RSXThread::m_height);
|
||||||
hp.Type = D3D12_HEAP_TYPE_DEFAULT;
|
break;
|
||||||
check(
|
case CELL_GCM_SURFACE_TARGET_1:
|
||||||
m_device->CreateCommittedResource(
|
if (m_fbo->m_address_color_b != address_b)
|
||||||
&hp,
|
copyFBO(m_device, m_fbo->getRenderTargetTexture(1), copycmdlist, m_texturesRTTs, m_fbo->m_address_color_b, address_b, RSXThread::m_width, RSXThread::m_height);
|
||||||
D3D12_HEAP_FLAG_NONE,
|
break;
|
||||||
&getTexture2DResourceDesc(RSXThread::m_width, RSXThread::m_height, DXGI_FORMAT_R8G8B8A8_UNORM),
|
case CELL_GCM_SURFACE_TARGET_MRT1:
|
||||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
if (m_fbo->m_address_color_a != address_a)
|
||||||
nullptr,
|
copyFBO(m_device, m_fbo->getRenderTargetTexture(0), copycmdlist, m_texturesRTTs, m_fbo->m_address_color_a, address_a, RSXThread::m_width, RSXThread::m_height);
|
||||||
IID_PPV_ARGS(&Texture)
|
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:
|
||||||
ID3D12GraphicsCommandList *copycmdlist;
|
if (m_fbo->m_address_color_a != address_a)
|
||||||
check(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_perFrameStorage.m_commandAllocator, nullptr, IID_PPV_ARGS(©cmdlist)));
|
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)
|
||||||
copycmdlist->ResourceBarrier(1, &getResourceBarrierTransition(m_fbo->getRenderTargetTexture(0), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE));
|
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)
|
||||||
D3D12_TEXTURE_COPY_LOCATION dst = {}, src = {};
|
copyFBO(m_device, m_fbo->getRenderTargetTexture(2), copycmdlist, m_texturesRTTs, m_fbo->m_address_color_c, address_c, RSXThread::m_width, RSXThread::m_height);
|
||||||
dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
break;
|
||||||
dst.pResource = Texture.Get();
|
case CELL_GCM_SURFACE_TARGET_MRT3:
|
||||||
src.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
if (m_fbo->m_address_color_a != address_a)
|
||||||
src.pResource = m_fbo->getRenderTargetTexture(0);
|
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)
|
||||||
copycmdlist->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr);
|
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)
|
||||||
D3D12_RESOURCE_BARRIER barriers[2] =
|
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)
|
||||||
getResourceBarrierTransition(m_fbo->getRenderTargetTexture(0), D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET),
|
copyFBO(m_device, m_fbo->getRenderTargetTexture(3), copycmdlist, m_texturesRTTs, m_fbo->m_address_color_d, address_d, RSXThread::m_width, RSXThread::m_height);
|
||||||
getResourceBarrierTransition(Texture.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_GENERIC_READ),
|
break;
|
||||||
};
|
|
||||||
copycmdlist->ResourceBarrier(2, barriers);
|
|
||||||
check(copycmdlist->Close());
|
|
||||||
|
|
||||||
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)©cmdlist);
|
|
||||||
|
|
||||||
m_texturesRTTs[m_fbo->m_address_color_a] = Texture;
|
|
||||||
m_fbo->m_address_color_a = address_a;
|
|
||||||
m_perFrameStorage.m_inflightCommandList.push_back(copycmdlist);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check(copycmdlist->Close());
|
||||||
|
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)©cmdlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_fbo == nullptr || RSXThread::m_width != m_lastWidth || RSXThread::m_height != m_lastHeight || m_lastDepth != m_surface_depth_format)
|
if (m_fbo == nullptr || RSXThread::m_width != m_lastWidth || RSXThread::m_height != m_lastHeight || m_lastDepth != m_surface_depth_format)
|
||||||
|
@ -412,12 +452,13 @@ void D3D12GSRender::InitDrawBuffers()
|
||||||
};
|
};
|
||||||
|
|
||||||
m_fbo = new D3D12RenderTargetSets(m_device, (u8)m_lastDepth, m_lastWidth, m_lastHeight, clearColor, 1.f);
|
m_fbo = new D3D12RenderTargetSets(m_device, (u8)m_lastDepth, m_lastWidth, m_lastHeight, clearColor, 1.f);
|
||||||
m_fbo->m_address_color_a = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000);
|
|
||||||
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);
|
|
||||||
m_fbo->m_address_color_d = GetAddress(m_surface_offset_d, m_context_dma_color_d - 0xfeed0000);
|
|
||||||
m_fbo->m_address_z = GetAddress(m_surface_offset_z, m_context_dma_z - 0xfeed0000);
|
|
||||||
}
|
}
|
||||||
|
m_fbo->m_address_color_a = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000);
|
||||||
|
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);
|
||||||
|
m_fbo->m_address_color_d = GetAddress(m_surface_offset_d, m_context_dma_color_d - 0xfeed0000);
|
||||||
|
m_fbo->m_address_z = GetAddress(m_surface_offset_z, m_context_dma_z - 0xfeed0000);
|
||||||
|
m_fbo->m_target_type = m_surface_color_target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,5 +27,6 @@ public:
|
||||||
ID3D12Resource *getDepthStencilTexture() 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_address_color_a, m_address_color_b, m_address_color_c, m_address_color_d, m_address_z;
|
||||||
|
u32 m_target_type;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue