1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-31 14:52:11 +01:00

[dxvk] Spill render pass for pipelines that use vertex stage UAVs

We cannot use simple pipeline barriers in this case because of the
extremely strict restrictions surrounding self-dependencies.
This commit is contained in:
Philip Rebohle 2018-10-30 14:43:52 +01:00
parent 76b63efedb
commit e15e693dc4
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 34 additions and 11 deletions

View File

@ -3032,8 +3032,15 @@ namespace dxvk {
void DxvkContext::commitGraphicsPostBarriers() { void DxvkContext::commitGraphicsPostBarriers() {
if (m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasStorageDescriptors)) { bool fs = m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasFsStorageDescriptors);
// FIXME support vertex stage SSBO synchronization bool vs = m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasVsStorageDescriptors);
if (vs) {
// External subpass dependencies serve as full memory
// and execution barriers, so we can use this to allow
// inter-stage synchronization.
this->spillRenderPass();
} else if (fs) {
this->emitMemoryBarrier( this->emitMemoryBarrier(
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT,

View File

@ -73,8 +73,13 @@ namespace dxvk {
if (gs != nullptr && gs->hasCapability(spv::CapabilityTransformFeedback)) if (gs != nullptr && gs->hasCapability(spv::CapabilityTransformFeedback))
m_flags.set(DxvkGraphicsPipelineFlag::HasTransformFeedback); m_flags.set(DxvkGraphicsPipelineFlag::HasTransformFeedback);
if (m_layout->hasStorageDescriptors()) VkShaderStageFlags stoStages = m_layout->getStorageDescriptorStages();
m_flags.set(DxvkGraphicsPipelineFlag::HasStorageDescriptors);
if (stoStages & VK_SHADER_STAGE_FRAGMENT_BIT)
m_flags.set(DxvkGraphicsPipelineFlag::HasFsStorageDescriptors);
if (stoStages & ~VK_SHADER_STAGE_FRAGMENT_BIT)
m_flags.set(DxvkGraphicsPipelineFlag::HasVsStorageDescriptors);
m_common.msSampleShadingEnable = fs != nullptr && fs->hasCapability(spv::CapabilitySampleRateShading); m_common.msSampleShadingEnable = fs != nullptr && fs->hasCapability(spv::CapabilitySampleRateShading);
m_common.msSampleShadingFactor = 1.0f; m_common.msSampleShadingFactor = 1.0f;

View File

@ -21,7 +21,8 @@ namespace dxvk {
*/ */
enum class DxvkGraphicsPipelineFlag { enum class DxvkGraphicsPipelineFlag {
HasTransformFeedback, HasTransformFeedback,
HasStorageDescriptors, HasFsStorageDescriptors,
HasVsStorageDescriptors,
}; };
using DxvkGraphicsPipelineFlags = Flags<DxvkGraphicsPipelineFlag>; using DxvkGraphicsPipelineFlags = Flags<DxvkGraphicsPipelineFlag>;

View File

@ -224,13 +224,23 @@ namespace dxvk {
* It is assumed that storage images and buffers * It is assumed that storage images and buffers
* will be written to if they are present. Used * will be written to if they are present. Used
* for synchronization purposes. * for synchronization purposes.
* \param [in] stages Shader stages to check
*/ */
bool hasStorageDescriptors() const { VkShaderStageFlags getStorageDescriptorStages() const {
return m_descriptorTypes.any( VkShaderStageFlags stages = 0;
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, for (const auto& slot : m_bindingSlots) {
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, bool isStorageDescriptor =
VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER); slot.type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
slot.type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC ||
slot.type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER ||
slot.type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
if (isStorageDescriptor)
stages |= slot.stages;
}
return stages;
} }
private: private: