diff --git a/Source/Core/VideoBackends/D3D12/D3DUtil.cpp b/Source/Core/VideoBackends/D3D12/D3DUtil.cpp index a1a7c512da..360cd04df9 100644 --- a/Source/Core/VideoBackends/D3D12/D3DUtil.cpp +++ b/Source/Core/VideoBackends/D3D12/D3DUtil.cpp @@ -72,7 +72,7 @@ public: // returns vertex offset to the new data size_t AppendData(const void* data, size_t size, size_t vertex_size) { - m_stream_buffer->AllocateSpaceInBuffer(size, vertex_size); + m_stream_buffer->AllocateSpaceInBuffer(size, vertex_size, false); memcpy(static_cast(m_stream_buffer->GetCPUAddressOfCurrentAllocation()), data, size); @@ -81,7 +81,7 @@ public: size_t BeginAppendData(void** write_ptr, size_t size, size_t vertex_size) { - m_stream_buffer->AllocateSpaceInBuffer(size, vertex_size); + m_stream_buffer->AllocateSpaceInBuffer(size, vertex_size, false); *write_ptr = m_stream_buffer->GetCPUAddressOfCurrentAllocation(); @@ -422,7 +422,7 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw D3D::current_command_list->SetGraphicsRootDescriptorTable(DESCRIPTOR_TABLE_PS_SRV, m_texture12_gpu); // upper bound is nchars * 6, assuming no spaces - m_vertex_buffer->AllocateSpaceInBuffer(static_cast(text.length()) * 6 * sizeof(FONT2DVERTEX), sizeof(FONT2DVERTEX)); + m_vertex_buffer->AllocateSpaceInBuffer(static_cast(text.length()) * 6 * sizeof(FONT2DVERTEX), sizeof(FONT2DVERTEX), false); FONT2DVERTEX* vertices12 = reinterpret_cast(m_vertex_buffer->GetCPUAddressOfCurrentAllocation()); int num_triangles = 0; @@ -588,6 +588,28 @@ void SetLinearCopySampler() D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_SAMPLERS, true); } +void SetViewportAndScissor(u32 top_left_x, u32 top_left_y, u32 width, u32 height, float min_depth, float max_depth) +{ + D3D12_VIEWPORT viewport = { + static_cast(top_left_x), + static_cast(top_left_y), + static_cast(width), + static_cast(height), + min_depth, + max_depth + }; + + D3D12_RECT scissor = { + static_cast(top_left_x), + static_cast(top_left_y), + static_cast(top_left_x + width), + static_cast(top_left_y + height) + }; + + D3D::current_command_list->RSSetViewports(1, &viewport); + D3D::current_command_list->RSSetScissorRects(1, &scissor); +}; + void DrawShadedTexQuad(D3DTexture2D* texture, const D3D12_RECT* rSource, int source_width, @@ -684,13 +706,6 @@ void DrawShadedTexQuad(D3DTexture2D* texture, D3D::current_command_list->SetPipelineState(pso); D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PSO, true); - // In D3D11, the 'resetraststate' has ScissorEnable disabled. In D3D12, scissor testing is always enabled. - // Thus, set the scissor rect to the max texture size, then reset it to the current scissor rect to avoid - // dirtying state. - - // 2 ^ D3D12_MAX_TEXTURE_DIMENSION_2_TO_EXP = 131072 - D3D::current_command_list->RSSetScissorRects(1, &CD3DX12_RECT(0, 0, 131072, 131072)); - D3D::current_command_list->DrawInstanced(4, 1, static_cast(stq_offset), 0); g_renderer->RestoreAPIState(); @@ -840,13 +855,6 @@ void DrawClearQuad(u32 Color, float z, D3D12_BLEND_DESC* blend_desc, D3D12_DEPTH D3D::current_command_list->SetPipelineState(pso); D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PSO, true); - // In D3D11, the 'resetraststate' has ScissorEnable disabled. In D3D12, scissor testing is always enabled. - // Thus, set the scissor rect to the max texture size, then reset it to the current scissor rect to avoid - // dirtying state. - - // 2 ^ D3D12_MAX_TEXTURE_DIMENSION_2_TO_EXP = 131072 - D3D::current_command_list->RSSetScissorRects(1, &CD3DX12_RECT(0, 0, 131072, 131072)); - D3D::current_command_list->DrawInstanced(4, 1, static_cast(clearq_offset), 0); g_renderer->RestoreAPIState(); @@ -865,7 +873,6 @@ void DrawEFBPokeQuads(EFBAccessType type, size_t num_points, D3D12_BLEND_DESC* blend_desc, D3D12_DEPTH_STENCIL_DESC* depth_stencil_desc, - D3D12_VIEWPORT* viewport, D3D12_CPU_DESCRIPTOR_HANDLE* render_target, D3D12_CPU_DESCRIPTOR_HANDLE* depth_buffer, bool rt_multisampled @@ -925,7 +932,6 @@ void DrawEFBPokeQuads(EFBAccessType type, // Corresponding dirty flags set outside loop. D3D::current_command_list->OMSetRenderTargets(1, render_target, FALSE, depth_buffer); - D3D::current_command_list->RSSetViewports(1, viewport); D3D::current_command_list->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); D3D12_VERTEX_BUFFER_VIEW vb_view = { diff --git a/Source/Core/VideoBackends/D3D12/D3DUtil.h b/Source/Core/VideoBackends/D3D12/D3DUtil.h index b000c4ac99..add8516be1 100644 --- a/Source/Core/VideoBackends/D3D12/D3DUtil.h +++ b/Source/Core/VideoBackends/D3D12/D3DUtil.h @@ -74,6 +74,8 @@ void ShutdownUtils(); void SetPointCopySampler(); void SetLinearCopySampler(); +void SetViewportAndScissor(u32 top_left_x, u32 top_left_y, u32 width, u32 height, float min_depth = D3D12_MIN_DEPTH, float max_depth = D3D12_MAX_DEPTH); + void DrawShadedTexQuad(D3DTexture2D* texture, const D3D12_RECT* source, int source_width, @@ -97,7 +99,6 @@ void DrawEFBPokeQuads(EFBAccessType type, size_t num_points, D3D12_BLEND_DESC* blend_desc, D3D12_DEPTH_STENCIL_DESC* depth_stencil_desc, - D3D12_VIEWPORT* viewport, D3D12_CPU_DESCRIPTOR_HANDLE* render_target, D3D12_CPU_DESCRIPTOR_HANDLE* depth_buffer, bool rt_multisampled); diff --git a/Source/Core/VideoBackends/D3D12/FramebufferManager.cpp b/Source/Core/VideoBackends/D3D12/FramebufferManager.cpp index 9b7bebf608..a3c8064318 100644 --- a/Source/Core/VideoBackends/D3D12/FramebufferManager.cpp +++ b/Source/Core/VideoBackends/D3D12/FramebufferManager.cpp @@ -173,9 +173,7 @@ void FramebufferManager::ResolveDepthTexture() { // ResolveSubresource does not work with depth textures. // Instead, we use a shader that selects the minimum depth from all samples. - - const D3D12_VIEWPORT vp12 = { 0.f, 0.f, static_cast(m_target_width), static_cast(m_target_height), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; - D3D::current_command_list->RSSetViewports(1, &vp12); + D3D::SetViewportAndScissor(0, 0, m_target_width, m_target_height); m_efb.resolved_depth_tex->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET); D3D::current_command_list->OMSetRenderTargets(0, nullptr, FALSE, &m_efb.resolved_depth_tex->GetDSV12()); @@ -292,10 +290,9 @@ void FramebufferManager::MapEFBColorAccessCopy() // for non-1xIR or multisampled cases, we need to copy to an intermediate texture first m_efb.color_access_resize_tex->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET); - D3D12_VIEWPORT vp12 = { 0, 0, EFB_WIDTH, EFB_HEIGHT, D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; - D3D::current_command_list->RSSetViewports(1, &vp12); - D3D::current_command_list->OMSetRenderTargets(1, &m_efb.color_access_resize_tex->GetRTV12(), FALSE, nullptr); + D3D::SetViewportAndScissor(0, 0, EFB_WIDTH, EFB_HEIGHT); D3D::SetPointCopySampler(); + D3D::current_command_list->OMSetRenderTargets(1, &m_efb.color_access_resize_tex->GetRTV12(), FALSE, nullptr); CD3DX12_RECT src_rect(0, 0, m_target_width, m_target_height); D3D::DrawShadedTexQuad(m_efb.color_tex, &src_rect, m_target_width, m_target_height, @@ -345,10 +342,9 @@ void FramebufferManager::MapEFBDepthAccessCopy() // for non-1xIR or multisampled cases, we need to copy to an intermediate texture first m_efb.depth_access_resize_tex->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET); - D3D12_VIEWPORT vp12 = { 0, 0, EFB_WIDTH, EFB_HEIGHT, D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; - D3D::current_command_list->RSSetViewports(1, &vp12); - D3D::current_command_list->OMSetRenderTargets(1, &m_efb.depth_access_resize_tex->GetRTV12(), FALSE, nullptr); + D3D::SetViewportAndScissor(0, 0, EFB_WIDTH, EFB_HEIGHT); D3D::SetPointCopySampler(); + D3D::current_command_list->OMSetRenderTargets(1, &m_efb.color_access_resize_tex->GetRTV12(), FALSE, nullptr); CD3DX12_RECT src_rect(0, 0, m_target_width, m_target_height); D3D::DrawShadedTexQuad(m_efb.depth_tex, &src_rect, m_target_width, m_target_height, @@ -425,8 +421,7 @@ void XFBSource::DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight) void XFBSource::CopyEFB(float gamma) { // Copy EFB data to XFB and restore render target again - const D3D12_VIEWPORT vp12 = { 0.f, 0.f, static_cast(texWidth), static_cast(texHeight), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; - D3D::current_command_list->RSSetViewports(1, &vp12); + D3D::SetViewportAndScissor(0, 0, texWidth, texHeight); const D3D12_RECT rect = CD3DX12_RECT(0, 0, texWidth, texHeight); diff --git a/Source/Core/VideoBackends/D3D12/PSTextureEncoder.cpp b/Source/Core/VideoBackends/D3D12/PSTextureEncoder.cpp index 6af30765ba..bd1610adb3 100644 --- a/Source/Core/VideoBackends/D3D12/PSTextureEncoder.cpp +++ b/Source/Core/VideoBackends/D3D12/PSTextureEncoder.cpp @@ -152,8 +152,7 @@ void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_p const u32 words_per_row = bytes_per_row / sizeof(u32); - D3D12_VIEWPORT vp = { 0.f, 0.f, FLOAT(words_per_row), FLOAT(num_blocks_y), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; - D3D::current_command_list->RSSetViewports(1, &vp); + D3D::SetViewportAndScissor(0, 0, words_per_row, num_blocks_y); constexpr EFBRectangle full_src_rect(0, 0, EFB_WIDTH, EFB_HEIGHT); 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, diff --git a/Source/Core/VideoBackends/D3D12/TextureCache.cpp b/Source/Core/VideoBackends/D3D12/TextureCache.cpp index d88fce86c7..37660b9136 100644 --- a/Source/Core/VideoBackends/D3D12/TextureCache.cpp +++ b/Source/Core/VideoBackends/D3D12/TextureCache.cpp @@ -164,15 +164,7 @@ void TextureCache::TCacheEntry::CopyRectangleFromTexture( return; } - const D3D12_VIEWPORT vp = { - float(dst_rect.left), - float(dst_rect.top), - float(dst_rect.GetWidth()), - float(dst_rect.GetHeight()), - D3D12_MIN_DEPTH, - D3D12_MAX_DEPTH - }; - D3D::current_command_list->RSSetViewports(1, &vp); + D3D::SetViewportAndScissor(dst_rect.left, dst_rect.top, dst_rect.GetWidth(), dst_rect.GetHeight()); m_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET); D3D::current_command_list->OMSetRenderTargets(1, &m_texture->GetRTV12(), FALSE, nullptr); @@ -289,18 +281,6 @@ void TextureCache::TCacheEntry::FromRenderTarget(u8* dst, PEControl::PixelFormat FramebufferManager::GetResolvedEFBColorTexture(); } - // stretch picture with increased internal resolution - const D3D12_VIEWPORT vp = { - 0.f, - 0.f, - static_cast(config.width), - static_cast(config.height), - D3D12_MIN_DEPTH, - D3D12_MAX_DEPTH - }; - - D3D::current_command_list->RSSetViewports(1, &vp); - // set transformation if (cbuf_id != old_cbuf_id) { @@ -311,6 +291,9 @@ void TextureCache::TCacheEntry::FromRenderTarget(u8* dst, PEControl::PixelFormat old_cbuf_id = cbuf_id; } + // stretch picture with increased internal resolution + D3D::SetViewportAndScissor(0, 0, config.width, config.height); + D3D::current_command_list->SetGraphicsRootConstantBufferView(DESCRIPTOR_TABLE_PS_CBVONE, s_efb_copy_stream_buffer->GetGPUAddressOfCurrentAllocation()); D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PS_CBV, true); @@ -441,14 +424,13 @@ void main( void TextureCache::ConvertTexture(TCacheEntryBase* entry, TCacheEntryBase* unconverted, void* palette, TlutFormat format) { - // stretch picture with increased internal resolution - const D3D12_VIEWPORT vp = { 0.f, 0.f, static_cast(unconverted->config.width), static_cast(unconverted->config.height), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; - D3D::current_command_list->RSSetViewports(1, &vp); - const unsigned int palette_buffer_allocation_size = 512; m_palette_stream_buffer->AllocateSpaceInBuffer(palette_buffer_allocation_size, 256); memcpy(m_palette_stream_buffer->GetCPUAddressOfCurrentAllocation(), palette, palette_buffer_allocation_size); + // stretch picture with increased internal resolution + D3D::SetViewportAndScissor(0, 0, unconverted->config.width, unconverted->config.height); + // D3D12: Because the second SRV slot is occupied by this buffer, and an arbitrary texture occupies the first SRV slot, // we need to allocate temporary space out of our descriptor heap, place the palette SRV in the second slot, then copy the // existing texture's descriptor into the first slot.