1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +01:00

[dxvk] Separate gfx resource hazard checking and barrier emission

Otherwise, when performing three draws with the same storage buffers or
storage images bound, we don't emit a barrier between the 2nd and 3rd
draw since the tracking information gets cleared by the second draw.

Fixes #1262.
This commit is contained in:
Philip Rebohle 2019-12-11 13:45:57 +01:00
parent 52301d12a7
commit b9258c0c49
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 42 additions and 34 deletions

View File

@ -4337,8 +4337,10 @@ namespace dxvk {
} }
if (m_state.gp.flags.any(DxvkGraphicsPipelineFlag::HasStorageDescriptors, if (m_state.gp.flags.any(DxvkGraphicsPipelineFlag::HasStorageDescriptors,
DxvkGraphicsPipelineFlag::HasTransformFeedback)) DxvkGraphicsPipelineFlag::HasTransformFeedback)) {
this->commitGraphicsBarriers<Indexed, Indirect>(); this->commitGraphicsBarriers<Indexed, Indirect, false>();
this->commitGraphicsBarriers<Indexed, Indirect, true>();
}
if (m_flags.test(DxvkContextFlag::GpDirtyFramebuffer)) if (m_flags.test(DxvkContextFlag::GpDirtyFramebuffer))
this->updateFramebuffer(); this->updateFramebuffer();
@ -4520,7 +4522,7 @@ namespace dxvk {
} }
template<bool Indexed, bool Indirect> template<bool Indexed, bool Indirect, bool DoEmit>
void DxvkContext::commitGraphicsBarriers() { void DxvkContext::commitGraphicsBarriers() {
auto layout = m_state.gp.pipeline->layout(); auto layout = m_state.gp.pipeline->layout();
@ -4541,7 +4543,7 @@ namespace dxvk {
for (uint32_t i = 0; i < slices.size() && !requiresBarrier; i++) { for (uint32_t i = 0; i < slices.size() && !requiresBarrier; i++) {
if (slices[i]->defined() if (slices[i]->defined()
&& slices[i]->bufferInfo().usage & storageBufferUsage) { && slices[i]->bufferInfo().usage & storageBufferUsage) {
requiresBarrier = this->checkGfxBufferBarrier(*slices[i], requiresBarrier = this->checkGfxBufferBarrier<DoEmit>(*slices[i],
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
VK_ACCESS_INDIRECT_COMMAND_READ_BIT).test(DxvkAccess::Write); VK_ACCESS_INDIRECT_COMMAND_READ_BIT).test(DxvkAccess::Write);
} }
@ -4555,7 +4557,7 @@ namespace dxvk {
if (indexBufferSlice.defined() if (indexBufferSlice.defined()
&& indexBufferSlice.bufferInfo().usage & storageBufferUsage) { && indexBufferSlice.bufferInfo().usage & storageBufferUsage) {
requiresBarrier = this->checkGfxBufferBarrier(indexBufferSlice, requiresBarrier = this->checkGfxBufferBarrier<DoEmit>(indexBufferSlice,
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
VK_ACCESS_INDEX_READ_BIT).test(DxvkAccess::Write); VK_ACCESS_INDEX_READ_BIT).test(DxvkAccess::Write);
} }
@ -4571,7 +4573,7 @@ namespace dxvk {
if (vertexBufferSlice.defined() if (vertexBufferSlice.defined()
&& vertexBufferSlice.bufferInfo().usage & storageBufferUsage) { && vertexBufferSlice.bufferInfo().usage & storageBufferUsage) {
requiresBarrier = this->checkGfxBufferBarrier(vertexBufferSlice, requiresBarrier = this->checkGfxBufferBarrier<DoEmit>(vertexBufferSlice,
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT).test(DxvkAccess::Write); VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT).test(DxvkAccess::Write);
} }
@ -4586,7 +4588,7 @@ namespace dxvk {
const auto& xfbBufferSlice = m_state.xfb.buffers[i]; const auto& xfbBufferSlice = m_state.xfb.buffers[i];
if (xfbBufferSlice.defined()) { if (xfbBufferSlice.defined()) {
requiresBarrier = this->checkGfxBufferBarrier(xfbBufferSlice, requiresBarrier = this->checkGfxBufferBarrier<DoEmit>(xfbBufferSlice,
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT,
VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT) != 0; VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT) != 0;
} }
@ -4611,7 +4613,7 @@ namespace dxvk {
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
if (slot.bufferSlice.defined() if (slot.bufferSlice.defined()
&& slot.bufferSlice.bufferInfo().usage & storageBufferUsage) { && slot.bufferSlice.bufferInfo().usage & storageBufferUsage) {
srcAccess = this->checkGfxBufferBarrier(slot.bufferSlice, srcAccess = this->checkGfxBufferBarrier<DoEmit>(slot.bufferSlice,
binding.stages, binding.access); binding.stages, binding.access);
} }
break; break;
@ -4624,7 +4626,7 @@ namespace dxvk {
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
if (slot.bufferView != nullptr if (slot.bufferView != nullptr
&& slot.bufferView->bufferInfo().usage & storageBufferUsage) { && slot.bufferView->bufferInfo().usage & storageBufferUsage) {
srcAccess = this->checkGfxBufferBarrier(slot.bufferView->slice(), srcAccess = this->checkGfxBufferBarrier<DoEmit>(slot.bufferView->slice(),
binding.stages, binding.access); binding.stages, binding.access);
} }
break; break;
@ -4638,7 +4640,7 @@ namespace dxvk {
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
if (slot.imageView != nullptr if (slot.imageView != nullptr
&& slot.imageView->imageInfo().usage & storageImageUsage) { && slot.imageView->imageInfo().usage & storageImageUsage) {
srcAccess = this->checkGfxImageBarrier(slot.imageView, srcAccess = this->checkGfxImageBarrier<DoEmit>(slot.imageView,
binding.stages, binding.access); binding.stages, binding.access);
} }
break; break;
@ -4667,40 +4669,44 @@ namespace dxvk {
} }
template<bool DoEmit>
DxvkAccessFlags DxvkContext::checkGfxBufferBarrier( DxvkAccessFlags DxvkContext::checkGfxBufferBarrier(
const DxvkBufferSlice& slice, const DxvkBufferSlice& slice,
VkPipelineStageFlags stages, VkPipelineStageFlags stages,
VkAccessFlags access) { VkAccessFlags access) {
auto srcAccess = m_gfxBarriers.getBufferAccess(slice.getSliceHandle()); if constexpr (DoEmit) {
m_gfxBarriers.accessBuffer(
m_gfxBarriers.accessBuffer( slice.getSliceHandle(),
slice.getSliceHandle(), stages, access,
stages, access, slice.bufferInfo().stages,
slice.bufferInfo().stages, slice.bufferInfo().access);
slice.bufferInfo().access); return DxvkAccessFlags();
} else {
return srcAccess; return m_gfxBarriers.getBufferAccess(slice.getSliceHandle());
}
} }
template<bool DoEmit>
DxvkAccessFlags DxvkContext::checkGfxImageBarrier( DxvkAccessFlags DxvkContext::checkGfxImageBarrier(
const Rc<DxvkImageView>& imageView, const Rc<DxvkImageView>& imageView,
VkPipelineStageFlags stages, VkPipelineStageFlags stages,
VkAccessFlags access) { VkAccessFlags access) {
auto srcAccess = m_gfxBarriers.getImageAccess( if constexpr (DoEmit) {
imageView->image(), m_gfxBarriers.accessImage(
imageView->imageSubresources()); imageView->image(),
imageView->imageSubresources(),
m_gfxBarriers.accessImage( imageView->imageInfo().layout,
imageView->image(), stages, access,
imageView->imageSubresources(), imageView->imageInfo().layout,
imageView->imageInfo().layout, imageView->imageInfo().stages,
stages, access, imageView->imageInfo().access);
imageView->imageInfo().layout, return DxvkAccessFlags();
imageView->imageInfo().stages, } else {
imageView->imageInfo().access); return m_gfxBarriers.getImageAccess(
imageView->image(),
return srcAccess; imageView->imageSubresources());
}
} }

View File

@ -1182,14 +1182,16 @@ namespace dxvk {
void commitComputeInitBarriers(); void commitComputeInitBarriers();
void commitComputePostBarriers(); void commitComputePostBarriers();
template<bool Indexed, bool Indirect> template<bool Indexed, bool Indirect, bool DoEmit>
void commitGraphicsBarriers(); void commitGraphicsBarriers();
template<bool DoEmit>
DxvkAccessFlags checkGfxBufferBarrier( DxvkAccessFlags checkGfxBufferBarrier(
const DxvkBufferSlice& slice, const DxvkBufferSlice& slice,
VkPipelineStageFlags stages, VkPipelineStageFlags stages,
VkAccessFlags access); VkAccessFlags access);
template<bool DoEmit>
DxvkAccessFlags checkGfxImageBarrier( DxvkAccessFlags checkGfxImageBarrier(
const Rc<DxvkImageView>& imageView, const Rc<DxvkImageView>& imageView,
VkPipelineStageFlags stages, VkPipelineStageFlags stages,