diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index 983320efb3..134a03d67d 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -165,7 +165,7 @@ std::pair compileF32toU8CS() } D3D12GSRender::D3D12GSRender() - : GSRender(), m_fbo(nullptr), m_PSO(nullptr) + : GSRender(), m_PSO(nullptr) { if (Ini.GSDebugOutputEnable.GetValue()) { @@ -328,6 +328,8 @@ D3D12GSRender::D3D12GSRender() check(m_device->CreateHeap(&hd, IID_PPV_ARGS(&m_UAVHeap.m_heap))); m_UAVHeap.m_putPos = 0; m_UAVHeap.m_getPos = 1024 * 1024 * 128 - 1; + + m_rtts.Init(m_device); } D3D12GSRender::~D3D12GSRender() @@ -345,8 +347,7 @@ D3D12GSRender::~D3D12GSRender() m_backBuffer[0]->Release(); m_backbufferAsRendertarget[1]->Release(); m_backBuffer[1]->Release(); - if (m_fbo) - delete m_fbo; + m_rtts.Release(); m_rootSignature->Release(); m_swapChain->Release(); m_device->Release(); @@ -402,79 +403,152 @@ void copyFBO(ID3D12Device* device, ID3D12Resource *rtt, ID3D12GraphicsCommandLis void D3D12GSRender::InitDrawBuffers() { // 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(©cmdlist))); + m_perFrameStorage.m_inflightCommandList.push_back(copycmdlist); + + // Make previous RTTs sampleable + for (unsigned i = 0; i < 4; i++) { - 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_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**)©cmdlist); + if (m_rtts.m_currentlyBoundRenderTargets[i] == nullptr) + continue; + 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]; } - if (m_fbo == nullptr || RSXThread::m_width != m_lastWidth || RSXThread::m_height != m_lastHeight || m_lastDepth != m_surface_depth_format) - { - - LOG_WARNING(RSX, "New FBO (%dx%d)", RSXThread::m_width, RSXThread::m_height); - 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 - }; + memset(m_rtts.m_currentlyBoundRenderTargetsAddress, 0, 4 * sizeof(u32)); + memset(m_rtts.m_currentlyBoundRenderTargets, 0, 4 * sizeof(ID3D12Resource *)); + m_rtts.m_currentlyBoundDepthStencil = nullptr; + m_rtts.m_currentlyBoundDepthStencilAddress = 0; - 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); - 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; + case CELL_GCM_SURFACE_TARGET_1: + { + ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, 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); + D3D12_RENDER_TARGET_VIEW_DESC 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_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**)©cmdlist); } @@ -519,10 +593,10 @@ void D3D12GSRender::ExecCMD(u32 cmd) // TODO: Merge depth and stencil clear when possible 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) - 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) { @@ -533,30 +607,37 @@ void D3D12GSRender::ExecCMD(u32 cmd) m_clear_surface_color_b / 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) { case CELL_GCM_SURFACE_TARGET_NONE: break; case CELL_GCM_SURFACE_TARGET_0: - commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(0), clearColor, 0, nullptr); - break; case CELL_GCM_SURFACE_TARGET_1: - commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(1), clearColor, 0, nullptr); + commandList->ClearRenderTargetView(handle, clearColor, 0, nullptr); break; case CELL_GCM_SURFACE_TARGET_MRT1: - commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(0), clearColor, 0, nullptr); - commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(1), clearColor, 0, nullptr); + commandList->ClearRenderTargetView(handle, clearColor, 0, nullptr); + handle.ptr += g_RTTIncrement; + commandList->ClearRenderTargetView(handle, clearColor, 0, nullptr); break; case CELL_GCM_SURFACE_TARGET_MRT2: - commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(0), clearColor, 0, nullptr); - commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(1), clearColor, 0, nullptr); - 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); + handle.ptr += g_RTTIncrement; + commandList->ClearRenderTargetView(handle, clearColor, 0, nullptr); break; case CELL_GCM_SURFACE_TARGET_MRT3: - commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(0), clearColor, 0, nullptr); - commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(1), clearColor, 0, nullptr); - commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(2), clearColor, 0, nullptr); - commandList->ClearRenderTargetView(m_fbo->getRTTCPUHandle(3), clearColor, 0, nullptr); + commandList->ClearRenderTargetView(handle, clearColor, 0, nullptr); + handle.ptr += g_RTTIncrement; + commandList->ClearRenderTargetView(handle, clearColor, 0, nullptr); + handle.ptr += g_RTTIncrement; + commandList->ClearRenderTargetView(handle, clearColor, 0, nullptr); + handle.ptr += g_RTTIncrement; + commandList->ClearRenderTargetView(handle, clearColor, 0, nullptr); break; default: LOG_ERROR(RSX, "Bad surface color target: %d", m_surface_color_target); @@ -823,28 +904,30 @@ void D3D12GSRender::ExecCMD() m_perFrameStorage.m_currentTextureIndex += usedTexture; - D3D12_CPU_DESCRIPTOR_HANDLE *DepthStencilHandle = &m_fbo->getDSVCPUHandle(); + size_t numRTT; switch (m_surface_color_target) { case CELL_GCM_SURFACE_TARGET_NONE: break; case CELL_GCM_SURFACE_TARGET_0: - commandList->OMSetRenderTargets(1, &m_fbo->getRTTCPUHandle(0), true, DepthStencilHandle); - break; case CELL_GCM_SURFACE_TARGET_1: - commandList->OMSetRenderTargets(1, &m_fbo->getRTTCPUHandle(1), true, DepthStencilHandle); + numRTT = 1; break; case CELL_GCM_SURFACE_TARGET_MRT1: - commandList->OMSetRenderTargets(2, &m_fbo->getRTTCPUHandle(0), true, DepthStencilHandle); + numRTT = 2; break; case CELL_GCM_SURFACE_TARGET_MRT2: - commandList->OMSetRenderTargets(3, &m_fbo->getRTTCPUHandle(0), true, DepthStencilHandle); + numRTT = 3; break; case CELL_GCM_SURFACE_TARGET_MRT3: - commandList->OMSetRenderTargets(4, &m_fbo->getRTTCPUHandle(0), true, DepthStencilHandle); + numRTT = 4; break; default: 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 = { 0.f, @@ -1231,7 +1314,7 @@ void D3D12GSRender::Flip() barriers[0].Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST; 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.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE; @@ -1239,7 +1322,7 @@ void D3D12GSRender::Flip() D3D12_TEXTURE_COPY_LOCATION src = {}, dst = {}; src.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; 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 }; commandList->CopyTextureRegion(&dst, 0, 0, 0, &src, &box); @@ -1263,8 +1346,8 @@ void D3D12GSRender::Flip() WaitForSingleObject(handle, INFINITE); CloseHandle(handle); m_perFrameStorage.Reset(); - m_texturesRTTs.clear(); m_texturesCache.clear(); + m_texturesRTTs.clear(); m_frame->Flip(nullptr); } @@ -1433,7 +1516,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MipLevels = 1; 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); D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {}; uavDesc.Format = DXGI_FORMAT_R8_UNORM; @@ -1441,7 +1524,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) m_device->CreateUnorderedAccessView(depthConverted, nullptr, &uavDesc, Handle); // 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->SetComputeRootSignature(m_convertRootSignature); @@ -1456,7 +1539,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) 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, }; convertCommandList->ResourceBarrier(2, barriers); @@ -1498,29 +1581,29 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) break; 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; 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; case CELL_GCM_SURFACE_TARGET_MRT1: - if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_fbo->getRenderTargetTexture(0), downloadCommandList); - if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_fbo->getRenderTargetTexture(1), downloadCommandList); + if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], downloadCommandList); + if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[1], downloadCommandList); break; case CELL_GCM_SURFACE_TARGET_MRT2: - if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_fbo->getRenderTargetTexture(0), downloadCommandList); - if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_fbo->getRenderTargetTexture(1), downloadCommandList); - if (m_context_dma_color_b) rtt2 = writeColorBuffer(m_fbo->getRenderTargetTexture(2), downloadCommandList); + if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], downloadCommandList); + if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[1], downloadCommandList); + if (m_context_dma_color_b) rtt2 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[2], downloadCommandList); break; case CELL_GCM_SURFACE_TARGET_MRT3: - if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_fbo->getRenderTargetTexture(0), downloadCommandList); - if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_fbo->getRenderTargetTexture(1), downloadCommandList); - if (m_context_dma_color_b) rtt2 = writeColorBuffer(m_fbo->getRenderTargetTexture(2), downloadCommandList); - if (m_context_dma_color_b) rtt3 = writeColorBuffer(m_fbo->getRenderTargetTexture(3), downloadCommandList); + if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], downloadCommandList); + if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[1], downloadCommandList); + if (m_context_dma_color_b) rtt2 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[2], downloadCommandList); + if (m_context_dma_color_b) rtt3 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[3], downloadCommandList); break; } if (needTransfer) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index f28bc91bbd..6db8df1972 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -48,7 +48,7 @@ class D3D12GSRender : public GSRender { private: // Copy of RTT to be used as texture - std::unordered_map > m_texturesRTTs; + std::unordered_map m_texturesRTTs; std::unordered_map m_texturesCache; // std::vector m_post_draw_objs; @@ -116,8 +116,9 @@ private: bool m_forcedIndexBuffer; size_t indexCount; + RenderTargets m_rtts; + std::vector m_IASet; - D3D12RenderTargetSets *m_fbo; ID3D12Device* m_device; ID3D12CommandQueue *m_commandQueueCopy; ID3D12CommandQueue *m_commandQueueGraphic; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp index b25842192c..2ddc025065 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp @@ -9,7 +9,106 @@ #include "Emu/System.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 = {}; descriptorHeapDesc.NumDescriptors = 1; @@ -18,140 +117,21 @@ D3D12RenderTargetSets::D3D12RenderTargetSets(ID3D12Device *device, u8 surfaceDep descriptorHeapDesc.NumDescriptors = 4; 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 = {}; - clearDepthValue.DepthStencil.Depth = clearDepth; - - // Every resource are committed for simplicity, later we could use heap - 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; - }*/ + memset(m_currentlyBoundRenderTargetsAddress, 0, 4 * sizeof(u32)); + memset(m_currentlyBoundRenderTargets, 0, 4 * sizeof(ID3D12Resource*)); + m_currentlyBoundDepthStencil = nullptr; + m_currentlyBoundDepthStencilAddress = 0; } -D3D12RenderTargetSets::~D3D12RenderTargetSets() +void RenderTargets::Release() { - for (unsigned i = 0; i < 4; i++) - m_rtts[i]->Release(); - m_rttDescriptorHeap->Release(); - m_depthStencilTexture->Release(); + for (auto tmp : m_renderTargets) + tmp.second->Release(); m_depthStencilDescriptorHeap->Release(); -} - -D3D12_CPU_DESCRIPTOR_HANDLE D3D12RenderTargetSets::getRTTCPUHandle(u8 baseFBO) const -{ - 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; + m_renderTargetsDescriptorsHeap->Release(); + for (auto tmp : m_depthStencil) + tmp.second->Release(); } #endif \ No newline at end of file diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h index 89e9792904..493a3d8c21 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h @@ -3,30 +3,29 @@ #if defined(DX12_SUPPORT) #include -/** - * Class that embeds a RenderTargetDescriptor view and eventually a DepthStencil Descriptor View. - * Used to imitate OpenGL FrameBuffer concept. - */ -class D3D12RenderTargetSets +struct RenderTargets { - size_t g_RTTIncrement; - ID3D12Resource *m_depthStencilTexture; - ID3D12Resource *m_rtts[4]; - ID3D12DescriptorHeap *m_rttDescriptorHeap; + std::unordered_map m_renderTargets; + ID3D12Resource *m_currentlyBoundRenderTargets[4]; + u32 m_currentlyBoundRenderTargetsAddress[4]; + std::unordered_map m_depthStencil; + ID3D12Resource *m_currentlyBoundDepthStencil; + u32 m_currentlyBoundDepthStencilAddress; + ID3D12DescriptorHeap *m_renderTargetsDescriptorsHeap; 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 \ No newline at end of file diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp index 535125da3d..879fc06677 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp @@ -166,11 +166,11 @@ size_t D3D12GSRender::UploadTextures() } ID3D12Resource *vramTexture; - std::unordered_map >::const_iterator ItRTT = m_texturesRTTs.find(texaddr); + std::unordered_map::const_iterator ItRTT = m_rtts.m_renderTargets.find(texaddr); std::unordered_map::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()) {