Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/doitsujin/dxvk.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Ashton <joshua@froggi.es>2021-03-11 07:40:50 +0300
committerJoshua Ashton <joshua@froggi.es>2021-03-11 07:40:50 +0300
commit604d86161ceb7c35fc56adc09ee41af775398d61 (patch)
tree273a99c959eccad21f22c82b40ef429f66e9d86a
parent68e6676d68bca6a6bdd851cb4f573dae01e5e256 (diff)
[dxvk] Use image memory barriers for readbackreadback-barrier-work
Targets only the specific subresource of the bound color attachments. From the Vulkan spec: Each of the synchronization scopes and access scopes of a vkCmdPipelineBarrier2KHR or vkCmdPipelineBarrier command inside a render pass instance must be a subset of the scopes of one of the self-dependencies for the current subpass.
-rw-r--r--src/d3d9/d3d9_device.cpp24
-rw-r--r--src/dxvk/dxvk_context.cpp23
-rw-r--r--src/dxvk/dxvk_context.h6
3 files changed, 45 insertions, 8 deletions
diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp
index c04a16a8..7bdc49c6 100644
--- a/src/d3d9/d3d9_device.cpp
+++ b/src/d3d9/d3d9_device.cpp
@@ -5738,9 +5738,27 @@ namespace dxvk {
void D3D9DeviceEx::PrepareDraw(D3DPRIMITIVETYPE PrimitiveType) {
if (unlikely(m_activeHazardsRT != 0)) {
- EmitCs([](DxvkContext* ctx) {
- ctx->emitRenderTargetReadbackBarrier();
- });
+ for (uint32_t rt = m_activeHazardsRT; rt; rt &= rt - 1) {
+ // Guaranteed to not be nullptr...
+ auto surface = m_state.renderTargets[bit::tzcnt(rt)];
+
+ const Rc<DxvkImage>& image =
+ surface->GetCommonTexture()->GetImage();
+
+ VkImageSubresourceRange subresources = {
+ VK_IMAGE_ASPECT_COLOR_BIT,
+ surface->GetMipLevel(), 1,
+ surface->GetFace(), 1
+ };
+
+ EmitCs([
+ cImage = image,
+ cSubresources = subresources
+ ](DxvkContext* ctx) {
+ ctx->emitRenderTargetReadbackBarrier(
+ cImage, cSubresources);
+ });
+ }
if (m_d3d9Options.generalHazards)
MarkRenderHazards();
diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp
index b14c9877..40196b5e 100644
--- a/src/dxvk/dxvk_context.cpp
+++ b/src/dxvk/dxvk_context.cpp
@@ -1427,13 +1427,28 @@ namespace dxvk {
}
- void DxvkContext::emitRenderTargetReadbackBarrier() {
+ void DxvkContext::emitRenderTargetReadbackBarrier(
+ const Rc<DxvkImage>& image,
+ const VkImageSubresourceRange& subresources) {
if (m_flags.test(DxvkContextFlag::GpRenderPassBound)) {
- emitMemoryBarrier(VK_DEPENDENCY_BY_REGION_BIT,
+ VkImageMemoryBarrier barrier;
+ barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ barrier.pNext = nullptr;
+ barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+ barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+ barrier.oldLayout = image->info().layout;
+ barrier.newLayout = image->info().layout;
+ barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.image = image->m_image.image;
+ barrier.subresourceRange = subresources;
+
+ m_cmd->cmdPipelineBarrier(
+ DxvkCmdBuffer::ExecBuffer,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
- VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
- VK_ACCESS_SHADER_READ_BIT);
+ VK_DEPENDENCY_BY_REGION_BIT,
+ 0, nullptr, 0, nullptr, 1, &barrier);
}
}
diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h
index 4b5231f3..7362ac93 100644
--- a/src/dxvk/dxvk_context.h
+++ b/src/dxvk/dxvk_context.h
@@ -615,8 +615,12 @@ namespace dxvk {
*
* Use between draw calls if the fragment shader
* reads one of the currently bound render targets.
+ * \param [in] image Image
+ * \param [in] subresources Image subresources
*/
- void emitRenderTargetReadbackBarrier();
+ void emitRenderTargetReadbackBarrier(
+ const Rc<DxvkImage>& image,
+ const VkImageSubresourceRange& subresources);
/**
* \brief Generates mip maps