From 004bc88e0c944e1801f5a68eaae536c02d6a8d70 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 1 Dec 2017 00:52:39 +0100 Subject: [PATCH] [d3d11] ClearRenderTargetView now handles unbound images as well --- src/d3d11/d3d11_context.cpp | 71 ++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 23c40359..6d3e5f07 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -171,10 +171,14 @@ namespace dxvk { ID3D11RenderTargetView* pRenderTargetView, const FLOAT ColorRGBA[4]) { Com rtv; + pRenderTargetView->QueryInterface( __uuidof(ID3D11RenderTargetViewPrivate), reinterpret_cast(&rtv)); + const Rc dxvkView = rtv->GetDXVKImageView(); + const Rc dxvkImage = dxvkView->image(); + // Find out whether the given attachment is currently bound // or not, and if it is, which attachment index it has. int32_t attachmentIndex = -1; @@ -184,39 +188,42 @@ namespace dxvk { attachmentIndex = static_cast(i); } - if (attachmentIndex < 0) { - // FIXME bind render target, then restore framebuffer or mark dirty - Logger::err("D3D11DeviceContext::ClearRenderTargetView: Render target not bound. This is currently not supported."); - return; + // Copy the clear color into a clear value structure. + // This should also work for images that don nott have + // a floating point format. + VkClearColorValue clearValue; + std::memcpy(clearValue.float32, ColorRGBA, + sizeof(clearValue.float32)); + + if (attachmentIndex >= 0) { + // Image is bound to the pipeline for rendering. We can + // use the clear function that operates on attachments. + VkClearAttachment clearInfo; + clearInfo.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + clearInfo.colorAttachment = static_cast(attachmentIndex); + clearInfo.clearValue.color = clearValue; + + // Clear the full area. On FL 9.x, only the first array + // layer will be cleared, rather than all array layers. + VkClearRect clearRect; + clearRect.rect.offset.x = 0; + clearRect.rect.offset.y = 0; + clearRect.rect.extent.width = dxvkImage->info().extent.width; + clearRect.rect.extent.height = dxvkImage->info().extent.height; + clearRect.baseArrayLayer = 0; + clearRect.layerCount = dxvkImage->info().numLayers; + + if (m_parent->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0) + clearRect.layerCount = 1; + + // Record the clear operation + m_context->clearRenderTarget(clearInfo, clearRect); + } else { + // Image is not bound to the pipeline. We can still clear + // it, but we'll have to use a generic clear function. + m_context->clearColorImage(dxvkImage, + clearValue, dxvkView->subresources()); } - - // Retrieve image info, which we will need in - // order to determine the size of the clear area - const Rc image = rtv->GetDXVKImageView()->image(); - - // Set up attachment info and copy the clear color - VkClearAttachment clearInfo; - clearInfo.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - clearInfo.colorAttachment = static_cast(attachmentIndex); - - std::memcpy(clearInfo.clearValue.color.float32, ColorRGBA, - sizeof(clearInfo.clearValue.color.float32)); - - // Clear the full area. On FL 9.x, only the first array - // layer will be cleared, rather than all array layers. - VkClearRect clearRect; - clearRect.rect.offset.x = 0; - clearRect.rect.offset.y = 0; - clearRect.rect.extent.width = image->info().extent.width; - clearRect.rect.extent.height = image->info().extent.height; - clearRect.baseArrayLayer = 0; - clearRect.layerCount = image->info().numLayers; - - if (m_parent->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0) - clearRect.layerCount = 1; - - // Record the clear operation - m_context->clearRenderTarget(clearInfo, clearRect); }