1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-19 05: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() {
if (m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasStorageDescriptors)) {
// FIXME support vertex stage SSBO synchronization
bool fs = m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasFsStorageDescriptors);
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(
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_SHADER_WRITE_BIT,

View File

@ -73,8 +73,13 @@ namespace dxvk {
if (gs != nullptr && gs->hasCapability(spv::CapabilityTransformFeedback))
m_flags.set(DxvkGraphicsPipelineFlag::HasTransformFeedback);
if (m_layout->hasStorageDescriptors())
m_flags.set(DxvkGraphicsPipelineFlag::HasStorageDescriptors);
VkShaderStageFlags stoStages = m_layout->getStorageDescriptorStages();
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.msSampleShadingFactor = 1.0f;

View File

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

View File

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