From 1d909ec7a422b261588e860486b01db85e94fa6e Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sun, 21 Feb 2016 17:18:02 +1000 Subject: D3D12: Implement non-blocking EFB access when EFB has not been modified --- Source/Core/VideoBackends/D3D12/Render.cpp | 218 +++++------------------------ 1 file changed, 35 insertions(+), 183 deletions(-) (limited to 'Source/Core/VideoBackends/D3D12/Render.cpp') diff --git a/Source/Core/VideoBackends/D3D12/Render.cpp b/Source/Core/VideoBackends/D3D12/Render.cpp index e3fc160c9d..4f763a68cb 100644 --- a/Source/Core/VideoBackends/D3D12/Render.cpp +++ b/Source/Core/VideoBackends/D3D12/Render.cpp @@ -51,8 +51,6 @@ static bool s_last_xfb_mode = false; static Television s_television; -static ID3D12Resource* s_access_efb_constant_buffer = nullptr; - enum CLEAR_BLEND_DESC { CLEAR_BLEND_DESC_ALL_CHANNELS_ENABLED = 0, @@ -110,25 +108,6 @@ static void SetupDeviceObjects() g_framebuffer_manager = std::make_unique(); - float colmat[20] = { 0.0f }; - colmat[0] = colmat[5] = colmat[10] = 1.0f; - - CheckHR( - D3D::device12->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), - D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC::Buffer(sizeof(colmat)), - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_PPV_ARGS(&s_access_efb_constant_buffer) - ) - ); - - // Copy inital data to access_efb_cbuf12. - void* access_efb_constant_buffer_data = nullptr; - CheckHR(s_access_efb_constant_buffer->Map(0, nullptr, &access_efb_constant_buffer_data)); - memcpy(access_efb_constant_buffer_data, colmat, sizeof(colmat)); - D3D12_DEPTH_STENCIL_DESC depth_desc; depth_desc.DepthEnable = FALSE; depth_desc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO; @@ -197,9 +176,6 @@ static void TeardownDeviceObjects() s_screenshot_texture = nullptr; } - D3D::command_list_mgr->DestroyResourceAfterCurrentCommandListExecuted(s_access_efb_constant_buffer); - s_access_efb_constant_buffer = nullptr; - s_television.Shutdown(); gx_state_cache.Clear(); @@ -394,192 +370,60 @@ void Renderer::SetColorMask() // - GX_PokeZMode (TODO) u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) { - // EXISTINGD3D11TODO: This function currently is broken if anti-aliasing is enabled - - // Convert EFB dimensions to the ones of our render target - EFBRectangle efb_pixel_rc; - efb_pixel_rc.left = x; - efb_pixel_rc.top = y; - efb_pixel_rc.right = x + 1; - efb_pixel_rc.bottom = y + 1; - TargetRectangle target_pixel_rc = Renderer::ConvertEFBRectangle(efb_pixel_rc); - - // Take the mean of the resulting dimensions; TODO: Don't use the center pixel, compute the average color instead - D3D12_RECT rect_to_lock; - if (type == PEEK_COLOR || type == PEEK_Z) - { - rect_to_lock.left = (target_pixel_rc.left + target_pixel_rc.right) / 2; - rect_to_lock.top = (target_pixel_rc.top + target_pixel_rc.bottom) / 2; - rect_to_lock.right = rect_to_lock.left + 1; - rect_to_lock.bottom = rect_to_lock.top + 1; - } - else - { - rect_to_lock.left = target_pixel_rc.left; - rect_to_lock.right = target_pixel_rc.right; - rect_to_lock.top = target_pixel_rc.top; - rect_to_lock.bottom = target_pixel_rc.bottom; - } - - if (type == PEEK_Z) - { - D3D::command_list_mgr->CPUAccessNotify(); - - // depth buffers can only be completely CopySubresourceRegion'ed, so we're using DrawShadedTexQuad instead - // D3D12TODO: Is above statement true on D3D12? - D3D12_VIEWPORT vp12 = { 0.f, 0.f, 1.f, 1.f, D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; - D3D::current_command_list->RSSetViewports(1, &vp12); - - D3D::current_command_list->SetGraphicsRootConstantBufferView(DESCRIPTOR_TABLE_PS_CBVONE, s_access_efb_constant_buffer->GetGPUVirtualAddress()); - D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PS_CBV, true); - - FramebufferManager::GetEFBDepthReadTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET); - D3D::current_command_list->OMSetRenderTargets(1, &FramebufferManager::GetEFBDepthReadTexture()->GetRTV12(), FALSE, nullptr); - - D3D::SetPointCopySampler(); - - D3D::DrawShadedTexQuad( - FramebufferManager::GetEFBDepthTexture(), - &rect_to_lock, - Renderer::GetTargetWidth(), - Renderer::GetTargetHeight(), - StaticShaderCache::GetColorCopyPixelShader(true), - StaticShaderCache::GetSimpleVertexShader(), - StaticShaderCache::GetSimpleVertexShaderInputLayout(), - D3D12_SHADER_BYTECODE(), - 1.0f, - 0, - DXGI_FORMAT_R32_FLOAT, - false, - FramebufferManager::GetEFBDepthReadTexture()->GetMultisampled() - ); - - // copy to system memory - D3D12_BOX src_box = CD3DX12_BOX(0, 0, 0, 1, 1, 1); - ID3D12Resource* readback_buffer = FramebufferManager::GetEFBDepthStagingBuffer(); - - D3D12_TEXTURE_COPY_LOCATION dst_location = {}; - dst_location.pResource = readback_buffer; - dst_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; - dst_location.PlacedFootprint.Offset = 0; - dst_location.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R32_FLOAT; - dst_location.PlacedFootprint.Footprint.Width = 1; - dst_location.PlacedFootprint.Footprint.Height = 1; - dst_location.PlacedFootprint.Footprint.Depth = 1; - dst_location.PlacedFootprint.Footprint.RowPitch = D3D::AlignValue(dst_location.PlacedFootprint.Footprint.Width * 4, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); - - D3D12_TEXTURE_COPY_LOCATION src_location = {}; - src_location.pResource = FramebufferManager::GetEFBDepthReadTexture()->GetTex12(); - src_location.SubresourceIndex = 0; - src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - - FramebufferManager::GetEFBDepthReadTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_COPY_SOURCE); - D3D::current_command_list->CopyTextureRegion(&dst_location, 0, 0, 0, &src_location, &src_box); - - // Need to wait for the CPU to complete the copy (and all prior operations) before we can read it on the CPU. - D3D::command_list_mgr->ExecuteQueuedWork(true); - - FramebufferManager::GetEFBColorTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET); - FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE ); - D3D::current_command_list->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV12(), FALSE, &FramebufferManager::GetEFBDepthTexture()->GetDSV12()); - - // Restores proper viewport/scissor settings. - g_renderer->RestoreAPIState(); - - // read the data from system memory - void* readback_buffer_data = nullptr; - CheckHR(readback_buffer->Map(0, nullptr, &readback_buffer_data)); - - // depth buffer is inverted in the d3d backend - float val = 1.0f - reinterpret_cast(readback_buffer_data)[0]; - u32 ret = 0; - - if (bpmem.zcontrol.pixel_format == PEControl::RGB565_Z16) - { - // if Z is in 16 bit format you must return a 16 bit integer - ret = MathUtil::Clamp(static_cast(val * 65536.0f), 0, 0xFFFF); - } - else - { - ret = MathUtil::Clamp(static_cast(val * 16777216.0f), 0, 0xFFFFFF); - } - - // EXISTINGD3D11TODO: in RE0 this value is often off by one in Video_DX9 (where this code is derived from), which causes lighting to disappear - return ret; - } - else if (type == PEEK_COLOR) + if (type == PEEK_COLOR) { - D3D::command_list_mgr->CPUAccessNotify(); - - ID3D12Resource* readback_buffer = FramebufferManager::GetEFBColorStagingBuffer(); - - D3D12_BOX src_box = CD3DX12_BOX(rect_to_lock.left, rect_to_lock.top, 0, rect_to_lock.right, rect_to_lock.bottom, 1); - - D3D12_TEXTURE_COPY_LOCATION dst_location = {}; - dst_location.pResource = readback_buffer; - dst_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; - dst_location.PlacedFootprint.Offset = 0; - dst_location.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - dst_location.PlacedFootprint.Footprint.Width = 1; - dst_location.PlacedFootprint.Footprint.Height = 1; - dst_location.PlacedFootprint.Footprint.Depth = 1; - dst_location.PlacedFootprint.Footprint.RowPitch = D3D::AlignValue(dst_location.PlacedFootprint.Footprint.Width * 4, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); - - D3D12_TEXTURE_COPY_LOCATION src_location = {}; - src_location.pResource = FramebufferManager::GetResolvedEFBColorTexture()->GetTex12(); - src_location.SubresourceIndex = 0; - src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - - FramebufferManager::GetResolvedEFBColorTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_COPY_SOURCE); - D3D::current_command_list->CopyTextureRegion(&dst_location, 0, 0, 0, &src_location, &src_box); - - // Need to wait for the CPU to complete the copy (and all prior operations) before we can read it on the CPU. - D3D::command_list_mgr->ExecuteQueuedWork(true); - - FramebufferManager::GetEFBColorTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET); - FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE); - D3D::current_command_list->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV12(), FALSE, &FramebufferManager::GetEFBDepthTexture()->GetDSV12()); + u32 color = FramebufferManager::ReadEFBColorAccessCopy(x, y); - // Restores proper viewport/scissor settings. - g_renderer->RestoreAPIState(); - - // read the data from system memory - void* readback_buffer_data = nullptr; - CheckHR(readback_buffer->Map(0, nullptr, &readback_buffer_data)); - - u32 ret = reinterpret_cast(readback_buffer_data)[0]; + // a little-endian value is expected to be returned + color = ((color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000)); // check what to do with the alpha channel (GX_PokeAlphaRead) PixelEngine::UPEAlphaReadReg alpha_read_mode = PixelEngine::GetAlphaReadMode(); if (bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24) { - ret = RGBA8ToRGBA6ToRGBA8(ret); + color = RGBA8ToRGBA6ToRGBA8(color); } else if (bpmem.zcontrol.pixel_format == PEControl::RGB565_Z16) { - ret = RGBA8ToRGB565ToRGBA8(ret); + color = RGBA8ToRGB565ToRGBA8(color); } if (bpmem.zcontrol.pixel_format != PEControl::RGBA6_Z24) { - ret |= 0xFF000000; + color |= 0xFF000000; } if (alpha_read_mode.ReadMode == 2) { - return ret; // GX_READ_NONE + return color; // GX_READ_NONE } else if (alpha_read_mode.ReadMode == 1) { - return (ret | 0xFF000000); // GX_READ_FF + return (color | 0xFF000000); // GX_READ_FF } else /*if(alpha_read_mode.ReadMode == 0)*/ { - return (ret & 0x00FFFFFF); // GX_READ_00 + return (color & 0x00FFFFFF); // GX_READ_00 } } + else // if (type == PEEK_Z) + { + // depth buffer is inverted in the d3d backend + float depth = 1.0f - FramebufferManager::ReadEFBDepthAccessCopy(x, y); + u32 ret = 0; - return 0; + if (bpmem.zcontrol.pixel_format == PEControl::RGB565_Z16) + { + // if Z is in 16 bit format you must return a 16 bit integer + ret = MathUtil::Clamp(static_cast(depth * 65536.0f), 0, 0xFFFF); + } + else + { + ret = MathUtil::Clamp(static_cast(depth * 16777216.0f), 0, 0xFFFFFF); + } + + return ret; + } } void Renderer::PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) @@ -706,6 +550,8 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool color_enable, bool alpha // Restores proper viewport/scissor settings. g_renderer->RestoreAPIState(); + + FramebufferManager::InvalidateEFBAccessCopies(); } void Renderer::ReinterpretPixelData(unsigned int convtype) @@ -906,6 +752,9 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height return; } + // Invalidate EFB access copies. Not strictly necessary, but this avoids having the buffers mapped when calling Present(). + FramebufferManager::InvalidateEFBAccessCopies(); + // Prepare to copy the XFBs to our backbuffer UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); TargetRectangle target_rc = GetTargetRectangle(); @@ -1272,6 +1121,9 @@ void Renderer::ApplyState(bool use_dst_alpha) D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PSO, false); } + + // Always called prior to drawing, so we can invalidate the CPU EFB copies here. + FramebufferManager::InvalidateEFBAccessCopies(); } void Renderer::RestoreState() -- cgit v1.2.3 From 9efe66509d9923c8dedb5948808a4d2c0c7d802e Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sun, 21 Feb 2016 18:55:55 +1000 Subject: D3D12: Fix crash/errors when switching MSAA modes while running --- Source/Core/VideoBackends/D3D12/Render.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'Source/Core/VideoBackends/D3D12/Render.cpp') diff --git a/Source/Core/VideoBackends/D3D12/Render.cpp b/Source/Core/VideoBackends/D3D12/Render.cpp index 4f763a68cb..bf80081ff5 100644 --- a/Source/Core/VideoBackends/D3D12/Render.cpp +++ b/Source/Core/VideoBackends/D3D12/Render.cpp @@ -984,9 +984,16 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height s_last_stereo_mode != (g_ActiveConfig.iStereoMode > 0)) { s_last_xfb_mode = g_ActiveConfig.bUseRealXFB; - s_last_multisamples = g_ActiveConfig.iMultisamples; - StaticShaderCache::InvalidateMSAAShaders(); + // Block on any changes until the GPU catches up, so we can free resources safely. + D3D::command_list_mgr->ExecuteQueuedWork(true); + + if (s_last_multisamples != g_ActiveConfig.iMultisamples) + { + s_last_multisamples = g_ActiveConfig.iMultisamples; + StaticShaderCache::InvalidateMSAAShaders(); + gx_state_cache.OnMSAASettingsChanged(); + } if (window_resized) { -- cgit v1.2.3 From c4d79d6db3192ec3b163c31a611a4f20c03ed8b0 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Tue, 23 Feb 2016 22:18:41 +1000 Subject: D3D12: Add helper method for setting both viewport and scissor rect Simplfies making changes, as well as keeping the two in sync. --- Source/Core/VideoBackends/D3D12/Render.cpp | 79 +++--------------------------- 1 file changed, 8 insertions(+), 71 deletions(-) (limited to 'Source/Core/VideoBackends/D3D12/Render.cpp') diff --git a/Source/Core/VideoBackends/D3D12/Render.cpp b/Source/Core/VideoBackends/D3D12/Render.cpp index bf80081ff5..de63d406a0 100644 --- a/Source/Core/VideoBackends/D3D12/Render.cpp +++ b/Source/Core/VideoBackends/D3D12/Render.cpp @@ -428,7 +428,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) void Renderer::PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) { - D3D12_VIEWPORT vp = { 0.0f, 0.0f, static_cast(GetTargetWidth()), static_cast(GetTargetHeight()), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; + D3D::SetViewportAndScissor(0, 0, GetTargetWidth(), GetTargetHeight()); if (type == POKE_COLOR) { @@ -439,7 +439,6 @@ void Renderer::PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num num_points, &g_reset_blend_desc, &g_reset_depth_desc, - &vp, &FramebufferManager::GetEFBColorTexture()->GetRTV12(), nullptr, FramebufferManager::GetEFBColorTexture()->GetMultisampled() @@ -453,7 +452,6 @@ void Renderer::PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num num_points, &s_clear_blend_descs[CLEAR_BLEND_DESC_ALL_CHANNELS_DISABLED], &s_clear_depth_descs[CLEAR_DEPTH_DESC_DEPTH_ENABLED_WRITES_ENABLED], - &vp, &FramebufferManager::GetEFBColorTexture()->GetRTV12(), &FramebufferManager::GetEFBDepthTexture()->GetDSV12(), FramebufferManager::GetEFBColorTexture()->GetMultisampled() @@ -533,19 +531,9 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool color_enable, bool alpha // Update the view port for clearing the picture TargetRectangle target_rc = Renderer::ConvertEFBRectangle(rc); - D3D12_VIEWPORT vp = { - static_cast(target_rc.left), - static_cast(target_rc.top), - static_cast(target_rc.GetWidth()), - static_cast(target_rc.GetHeight()), - D3D12_MIN_DEPTH, - D3D12_MAX_DEPTH - }; - - D3D::current_command_list->RSSetViewports(1, &vp); - // Color is passed in bgra mode so we need to convert it to rgba u32 rgba_color = (color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000); + D3D::SetViewportAndScissor(target_rc.left, target_rc.top, target_rc.GetWidth(), target_rc.GetHeight()); D3D::DrawClearQuad(rgba_color, 1.0f - (z & 0xFFFFFF) / 16777216.0f, blend_desc, depth_stencil_desc, FramebufferManager::GetEFBColorTexture()->GetMultisampled()); // Restores proper viewport/scissor settings. @@ -575,16 +563,7 @@ void Renderer::ReinterpretPixelData(unsigned int convtype) return; } - D3D12_VIEWPORT vp = { - 0.f, - 0.f, - static_cast(g_renderer->GetTargetWidth()), - static_cast(g_renderer->GetTargetHeight()), - D3D12_MIN_DEPTH, - D3D12_MAX_DEPTH - }; - - D3D::current_command_list->RSSetViewports(1, &vp); + D3D::SetViewportAndScissor(0, 0, g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight()); FramebufferManager::GetEFBColorTempTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET); D3D::current_command_list->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTempTexture()->GetRTV12(), FALSE, nullptr); @@ -765,27 +744,13 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height float clear_color[4] = { 0.f, 0.f, 0.f, 1.f }; D3D::current_command_list->ClearRenderTargetView(D3D::GetBackBuffer()->GetRTV12(), clear_color, 0, nullptr); - // D3D12: Because scissor-testing is always enabled, change scissor rect to backbuffer in case EFB is smaller - // than swap chain back buffer. - D3D12_RECT back_buffer_rect = { 0L, 0L, GetBackbufferWidth(), GetBackbufferHeight() }; - D3D::current_command_list->RSSetScissorRects(1, &back_buffer_rect); - // activate linear filtering for the buffer copies D3D::SetLinearCopySampler(); if (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB) { // EXISTINGD3D11TODO: Television should be used to render Virtual XFB mode as well. - D3D12_VIEWPORT vp12 = { - static_cast(target_rc.left), - static_cast(target_rc.top), - static_cast(target_rc.GetWidth()), - static_cast(target_rc.GetHeight()), - D3D12_MIN_DEPTH, - D3D12_MAX_DEPTH - }; - - D3D::current_command_list->RSSetViewports(1, &vp12); + D3D::SetViewportAndScissor(target_rc.left, target_rc.top, target_rc.GetWidth(), target_rc.GetHeight()); s_television.Submit(xfb_addr, fb_stride, fb_width, fb_height); s_television.Render(); @@ -933,16 +898,7 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height } // Reset viewport for drawing text - D3D12_VIEWPORT vp = { - 0.0f, - 0.0f, - static_cast(GetBackbufferWidth()), - static_cast(GetBackbufferHeight()), - D3D12_MIN_DEPTH, - D3D12_MAX_DEPTH - }; - - D3D::current_command_list->RSSetViewports(1, &vp); + D3D::SetViewportAndScissor(0, 0, GetBackbufferWidth(), GetBackbufferHeight()); Renderer::DrawDebugText(); @@ -1368,30 +1324,12 @@ void Renderer::BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D TargetRectangle left_rc, right_rc; ConvertStereoRectangle(dst, left_rc, right_rc); - D3D12_VIEWPORT left_vp = { - static_cast(left_rc.left), - static_cast(left_rc.top), - static_cast(left_rc.GetWidth()), - static_cast(left_rc.GetHeight()), - D3D12_MIN_DEPTH, - D3D12_MAX_DEPTH - }; - - D3D12_VIEWPORT right_vp = { - static_cast(right_rc.left), - static_cast(right_rc.top), - static_cast(right_rc.GetWidth()), - static_cast(right_rc.GetHeight()), - D3D12_MIN_DEPTH, - D3D12_MAX_DEPTH - }; - // Swap chain backbuffer is never multisampled.. - D3D::current_command_list->RSSetViewports(1, &left_vp); + D3D::SetViewportAndScissor(left_rc.left, left_rc.top, left_rc.GetWidth(), left_rc.GetHeight()); D3D::DrawShadedTexQuad(src_texture, src.AsRECT(), src_width, src_height, StaticShaderCache::GetColorCopyPixelShader(false), StaticShaderCache::GetSimpleVertexShader(), StaticShaderCache::GetSimpleVertexShaderInputLayout(), D3D12_SHADER_BYTECODE(), gamma, 0, DXGI_FORMAT_R8G8B8A8_UNORM, false, false); - D3D::current_command_list->RSSetViewports(1, &right_vp); + D3D::SetViewportAndScissor(right_rc.left, right_rc.top, right_rc.GetWidth(), right_rc.GetHeight()); D3D::DrawShadedTexQuad(src_texture, src.AsRECT(), src_width, src_height, StaticShaderCache::GetColorCopyPixelShader(false), StaticShaderCache::GetSimpleVertexShader(), StaticShaderCache::GetSimpleVertexShaderInputLayout(), D3D12_SHADER_BYTECODE(), gamma, 1, DXGI_FORMAT_R8G8B8A8_UNORM, false, false); } else if (g_ActiveConfig.iStereoMode == STEREO_3DVISION) @@ -1433,8 +1371,7 @@ void Renderer::BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D } else { - D3D12_VIEWPORT vp = { static_cast(dst.left), static_cast(dst.top), static_cast(dst.GetWidth()), static_cast(dst.GetHeight()), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; - D3D::current_command_list->RSSetViewports(1, &vp); + D3D::SetViewportAndScissor(dst.left, dst.top, dst.GetWidth(), dst.GetHeight()); D3D::DrawShadedTexQuad( src_texture, -- cgit v1.2.3 From 74275bdfe3e46008969e13e6bdee968c573132b5 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Tue, 23 Feb 2016 22:21:09 +1000 Subject: D3D12: Don't keep screenshot/encoder buffers mapped Readback heaps do not support persistent mapping. See D3D12 docs. --- Source/Core/VideoBackends/D3D12/Render.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'Source/Core/VideoBackends/D3D12/Render.cpp') diff --git a/Source/Core/VideoBackends/D3D12/Render.cpp b/Source/Core/VideoBackends/D3D12/Render.cpp index de63d406a0..4881fec717 100644 --- a/Source/Core/VideoBackends/D3D12/Render.cpp +++ b/Source/Core/VideoBackends/D3D12/Render.cpp @@ -76,7 +76,6 @@ D3D12_DEPTH_STENCIL_DESC g_reset_depth_desc = {}; D3D12_RASTERIZER_DESC g_reset_rast_desc = {}; static ID3D12Resource* s_screenshot_texture = nullptr; -static void* s_screenshot_texture_data = nullptr; // Nvidia stereo blitting struct defined in "nvstereo.h" from the Nvidia SDK typedef struct _Nv_Stereo_Image_Header @@ -162,7 +161,6 @@ static void SetupDeviceObjects() g_reset_rast_desc = rast_desc; s_screenshot_texture = nullptr; - s_screenshot_texture_data = nullptr; } // Kill off all device objects @@ -200,8 +198,6 @@ void CreateScreenshotTexture() IID_PPV_ARGS(&s_screenshot_texture) ) ); - - CheckHR(s_screenshot_texture->Map(0, nullptr, &s_screenshot_texture_data)); } static D3D12_BOX GetScreenshotSourceBox(const TargetRectangle& target_rc) @@ -677,7 +673,12 @@ bool Renderer::SaveScreenshot(const std::string& filename, const TargetRectangle D3D::command_list_mgr->ExecuteQueuedWork(true); - saved_png = TextureToPng(static_cast(s_screenshot_texture_data), dst_location.PlacedFootprint.Footprint.RowPitch, filename, source_box.right - source_box.left, source_box.bottom - source_box.top, false); + void* screenshot_texture_map; + CheckHR(s_screenshot_texture->Map(0, nullptr, &screenshot_texture_map)); + + saved_png = TextureToPng(static_cast(screenshot_texture_map), dst_location.PlacedFootprint.Footprint.RowPitch, filename, source_box.right - source_box.left, source_box.bottom - source_box.top, false); + + s_screenshot_texture->Unmap(0, nullptr); if (saved_png) { @@ -877,7 +878,12 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height w = s_record_width; h = s_record_height; } - formatBufferDump(static_cast(s_screenshot_texture_data), &frame_data[0], source_width, source_height, dst_location.PlacedFootprint.Footprint.RowPitch); + + void* screenshot_texture_map; + CheckHR(s_screenshot_texture->Map(0, nullptr, &screenshot_texture_map)); + formatBufferDump(static_cast(screenshot_texture_map), &frame_data[0], source_width, source_height, dst_location.PlacedFootprint.Footprint.RowPitch); + s_screenshot_texture->Unmap(0, nullptr); + FlipImageData(&frame_data[0], w, h); AVIDump::AddFrame(&frame_data[0], source_width, source_height); } -- cgit v1.2.3