diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2019-02-18 08:27:14 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2019-02-18 08:27:14 +0000 |
| commit | 251cbf3fa84ff8b660714d5f413232c189664a8a (patch) | |
| tree | 78132a8a84b15ea447f2776a1c73d216c12e3755 /Graphics/GraphicsEngineVulkan | |
| parent | Updated GL functions loading on Android (diff) | |
| download | DiligentCore-251cbf3fa84ff8b660714d5f413232c189664a8a.tar.gz DiligentCore-251cbf3fa84ff8b660714d5f413232c189664a8a.zip | |
Disabled all Vulkan features by default
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
7 files changed, 96 insertions, 116 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h index 4ac5a208..d27a5594 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h @@ -31,7 +31,10 @@ namespace VulkanUtilities class VulkanCommandBuffer { public: - VulkanCommandBuffer()noexcept{} + VulkanCommandBuffer(VkPipelineStageFlags EnabledGraphicsShaderStages)noexcept : + m_EnabledGraphicsShaderStages(EnabledGraphicsShaderStages) + {} + VulkanCommandBuffer (const VulkanCommandBuffer&) = delete; VulkanCommandBuffer ( VulkanCommandBuffer&&) = delete; VulkanCommandBuffer& operator = (const VulkanCommandBuffer&) = delete; @@ -269,8 +272,9 @@ namespace VulkanUtilities VkImage Image, VkImageLayout OldLayout, VkImageLayout NewLayout, - const VkImageSubresourceRange& SubresRange, - VkPipelineStageFlags SrcStages = 0, + const VkImageSubresourceRange& SubresRange, + VkPipelineStageFlags EnabledGraphicsShaderStages, + VkPipelineStageFlags SrcStages = 0, VkPipelineStageFlags DestStages = 0); void TransitionImageLayout(VkImage Image, @@ -287,7 +291,7 @@ namespace VulkanUtilities // dependencies between attachments EndRenderPass(); } - TransitionImageLayout(m_VkCmdBuffer, Image, OldLayout, NewLayout, SubresRange, SrcStages, DestStages); + TransitionImageLayout(m_VkCmdBuffer, Image, OldLayout, NewLayout, SubresRange, m_EnabledGraphicsShaderStages, SrcStages, DestStages); } @@ -295,6 +299,7 @@ namespace VulkanUtilities VkBuffer Buffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, + VkPipelineStageFlags EnabledGraphicsShaderStages, VkPipelineStageFlags SrcStages = 0, VkPipelineStageFlags DestStages = 0); @@ -311,7 +316,7 @@ namespace VulkanUtilities // dependencies between attachments EndRenderPass(); } - BufferMemoryBarrier(m_VkCmdBuffer, Buffer, srcAccessMask, dstAccessMask, SrcStages, DestStages); + BufferMemoryBarrier(m_VkCmdBuffer, Buffer, srcAccessMask, dstAccessMask, m_EnabledGraphicsShaderStages, SrcStages, DestStages); } void BindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, @@ -399,5 +404,6 @@ namespace VulkanUtilities private: StateCache m_State; VkCommandBuffer m_VkCmdBuffer = VK_NULL_HANDLE; + const VkPipelineStageFlags m_EnabledGraphicsShaderStages; }; } diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.h index 5e76417c..0cd3bed0 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.h +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.h @@ -148,6 +148,8 @@ namespace VulkanUtilities VkResult ResetDescriptorPool(VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags = 0)const; + VkPipelineStageFlags GetEnabledGraphicsShaderStages()const { return m_EnabledGraphicsShaderStages; } + private: VulkanLogicalDevice(VkPhysicalDevice vkPhysicalDevice, const VkDeviceCreateInfo &DeviceCI, @@ -160,6 +162,7 @@ namespace VulkanUtilities const char* ObjectType)const; VkDevice m_VkDevice = VK_NULL_HANDLE; - const VkAllocationCallbacks* const m_VkAllocator; + const VkAllocationCallbacks* const m_VkAllocator; + VkPipelineStageFlags m_EnabledGraphicsShaderStages = 0; }; } diff --git a/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp index de5bbf9e..d28cfb7a 100644 --- a/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp @@ -220,11 +220,12 @@ BufferVkImpl :: BufferVkImpl(IReferenceCounters* pRefCounters, VkCommandBuffer vkCmdBuff; pRenderDeviceVk->AllocateTransientCmdPool(CmdPool, vkCmdBuff, "Transient command pool to copy staging data to a device buffer"); - VulkanUtilities::VulkanCommandBuffer::BufferMemoryBarrier(vkCmdBuff, StagingBuffer, 0, VK_ACCESS_TRANSFER_READ_BIT); + auto EnabledGraphicsShaderStages = LogicalDevice.GetEnabledGraphicsShaderStages(); + VulkanUtilities::VulkanCommandBuffer::BufferMemoryBarrier(vkCmdBuff, StagingBuffer, 0, VK_ACCESS_TRANSFER_READ_BIT, EnabledGraphicsShaderStages); InitialState = RESOURCE_STATE_COPY_DEST; VkAccessFlags AccessFlags = ResourceStateFlagsToVkAccessFlags(InitialState); VERIFY_EXPR(AccessFlags == VK_ACCESS_TRANSFER_WRITE_BIT); - VulkanUtilities::VulkanCommandBuffer::BufferMemoryBarrier(vkCmdBuff, m_VulkanBuffer, 0, AccessFlags); + VulkanUtilities::VulkanCommandBuffer::BufferMemoryBarrier(vkCmdBuff, m_VulkanBuffer, 0, AccessFlags, EnabledGraphicsShaderStages); // Copy commands MUST be recorded outside of a render pass instance. This is OK here // as copy will be the only command in the cmd buffer diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 0c69d151..c6378abe 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -61,6 +61,7 @@ namespace Diligent bIsDeferred ? std::numeric_limits<decltype(m_NumCommandsToFlush)>::max() : Attribs.NumCommandsToFlushCmdBuffer, bIsDeferred }, + m_CommandBuffer { pDeviceVkImpl->GetLogicalDevice().GetEnabledGraphicsShaderStages() }, m_CmdListAllocator { GetRawAllocator(), sizeof(CommandListVkImpl), 64 }, // Command pools must be thread safe because command buffers are returned into pools by release queues // potentially running in another thread diff --git a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp index 71cf5ae8..f6703fac 100644 --- a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp @@ -189,7 +189,8 @@ TextureVkImpl :: TextureVkImpl(IReferenceCounters* pRefCounters, SubresRange.layerCount = VK_REMAINING_ARRAY_LAYERS; SubresRange.baseMipLevel = 0; SubresRange.levelCount = VK_REMAINING_MIP_LEVELS; - VulkanUtilities::VulkanCommandBuffer::TransitionImageLayout(vkCmdBuff, m_VulkanImage, ImageCI.initialLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, SubresRange); + auto EnabledGraphicsShaderStages = LogicalDevice.GetEnabledGraphicsShaderStages(); + VulkanUtilities::VulkanCommandBuffer::TransitionImageLayout(vkCmdBuff, m_VulkanImage, ImageCI.initialLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, SubresRange, EnabledGraphicsShaderStages); SetState(RESOURCE_STATE_COPY_DEST); const auto CurrentLayout = GetLayout(); VERIFY_EXPR(CurrentLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); @@ -330,7 +331,7 @@ TextureVkImpl :: TextureVkImpl(IReferenceCounters* pRefCounters, err = LogicalDevice.BindBufferMemory(StagingBuffer, StagingBufferMemory, AlignedStagingMemOffset); CHECK_VK_ERROR_AND_THROW(err, "Failed to bind staging bufer memory"); - VulkanUtilities::VulkanCommandBuffer::BufferMemoryBarrier(vkCmdBuff, StagingBuffer, 0, VK_ACCESS_TRANSFER_READ_BIT); + VulkanUtilities::VulkanCommandBuffer::BufferMemoryBarrier(vkCmdBuff, StagingBuffer, 0, VK_ACCESS_TRANSFER_READ_BIT, EnabledGraphicsShaderStages); // Copy commands MUST be recorded outside of a render pass instance. This is OK here // as copy will be the only command in the cmd buffer diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp index 36b8cfe9..78bd6101 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp @@ -27,7 +27,8 @@ namespace VulkanUtilities { -static VkPipelineStageFlags PipelineStageFromAccessFlags(VkAccessFlags AccessFlags) +static VkPipelineStageFlags PipelineStageFromAccessFlags( VkAccessFlags AccessFlags, + const VkPipelineStageFlags EnabledGraphicsShaderStages) { // 6.1.3 VkPipelineStageFlags Stages = 0; @@ -38,13 +39,6 @@ static VkPipelineStageFlags PipelineStageFromAccessFlags(VkAccessFlags AccessFla VERIFY_EXPR( AccessFlag != 0 && (AccessFlag & (AccessFlag-1)) == 0 ); AccessFlags &= ~AccessFlag; - static constexpr VkPipelineStageFlags ALL_GRAPHICS_SHADER_STAGES_BITS = - VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | - VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | - VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | - VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - // An application MUST NOT specify an access flag in a synchronization command if it does not include a // pipeline stage in the corresponding stage mask that is able to perform accesses of that type. // A table that lists, for each access flag, which pipeline stages can perform that type of access is given in 6.1.3. @@ -67,7 +61,7 @@ static VkPipelineStageFlags PipelineStageFromAccessFlags(VkAccessFlags AccessFla // Read access to a uniform buffer case VK_ACCESS_UNIFORM_READ_BIT: - Stages |= ALL_GRAPHICS_SHADER_STAGES_BITS | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + Stages |= EnabledGraphicsShaderStages | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; break; // Read access to an input attachment within a render pass during fragment shading @@ -77,12 +71,12 @@ static VkPipelineStageFlags PipelineStageFromAccessFlags(VkAccessFlags AccessFla // Read access to a storage buffer, uniform texel buffer, storage texel buffer, sampled image, or storage image case VK_ACCESS_SHADER_READ_BIT: - Stages |= ALL_GRAPHICS_SHADER_STAGES_BITS | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + Stages |= EnabledGraphicsShaderStages | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; break; // Write access to a storage buffer, storage texel buffer, or storage image case VK_ACCESS_SHADER_WRITE_BIT: - Stages |= ALL_GRAPHICS_SHADER_STAGES_BITS | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + Stages |= EnabledGraphicsShaderStages | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; break; // Read access to a color attachment, such as via blending, logic operations, or via certain subpass load operations @@ -143,90 +137,90 @@ static VkPipelineStageFlags PipelineStageFromAccessFlags(VkAccessFlags AccessFla return Stages; } -void VulkanCommandBuffer::TransitionImageLayout(VkCommandBuffer CmdBuffer, - VkImage Image, - VkImageLayout OldLayout, - VkImageLayout NewLayout, - const VkImageSubresourceRange& SubresRange, - VkPipelineStageFlags SrcStages, - VkPipelineStageFlags DestStages) -{ - VERIFY_EXPR(CmdBuffer != VK_NULL_HANDLE); - - VkImageMemoryBarrier ImgBarrier = {}; - ImgBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - ImgBarrier.pNext = nullptr; - ImgBarrier.srcAccessMask = 0; - ImgBarrier.dstAccessMask = 0; - ImgBarrier.oldLayout = OldLayout; - ImgBarrier.newLayout = NewLayout; - ImgBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // source queue family for a queue family ownership transfer. - ImgBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // destination queue family for a queue family ownership transfer. - ImgBarrier.image = Image; - ImgBarrier.subresourceRange = SubresRange; - switch (OldLayout) +static VkPipelineStageFlags AccessMaskFromImageLayout(VkImageLayout Layout, + bool IsDstMask // false - source mask + // true - destination mask + ) +{ + VkPipelineStageFlags AccessMask = 0; + switch (Layout) { // does not support device access. This layout must only be used as the initialLayout member // of VkImageCreateInfo or VkAttachmentDescription, or as the oldLayout in an image transition. // When transitioning out of this layout, the contents of the memory are not guaranteed to be preserved (11.4) case VK_IMAGE_LAYOUT_UNDEFINED: + if (IsDstMask) + { + UNEXPECTED("The new layout used in a transition must not be VK_IMAGE_LAYOUT_UNDEFINED. " + "This layout must only be used as the initialLayout member of VkImageCreateInfo " + "or VkAttachmentDescription, or as the oldLayout in an image transition. (11.4)"); + } break; // supports all types of device access case VK_IMAGE_LAYOUT_GENERAL: // VK_IMAGE_LAYOUT_GENERAL must be used for image load/store operations (13.1.1, 13.2.4) - ImgBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + AccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; break; // must only be used as a color or resolve attachment in a VkFramebuffer (11.4) case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: - ImgBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + AccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; break; // must only be used as a depth/stencil attachment in a VkFramebuffer (11.4) case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: - ImgBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + AccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; break; // must only be used as a read-only depth/stencil attachment in a VkFramebuffer and/or as a read-only image in a shader (11.4) case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: - ImgBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + AccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; break; // must only be used as a read-only image in a shader (which can be read as a sampled image, // combined image/sampler and/or input attachment) (11.4) case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: - ImgBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; + AccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; break; // must only be used as a source image of a transfer command (11.4) case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: - ImgBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + AccessMask = VK_ACCESS_TRANSFER_READ_BIT; break; // must only be used as a destination image of a transfer command (11.4) case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: - ImgBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + AccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; break; // does not support device access. This layout must only be used as the initialLayout member // of VkImageCreateInfo or VkAttachmentDescription, or as the oldLayout in an image transition. // When transitioning out of this layout, the contents of the memory are preserved. (11.4) case VK_IMAGE_LAYOUT_PREINITIALIZED: - ImgBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; + if (!IsDstMask) + { + AccessMask = VK_ACCESS_HOST_WRITE_BIT; + } + else + { + UNEXPECTED("The new layout used in a transition must not be VK_IMAGE_LAYOUT_PREINITIALIZED. " + "This layout must only be used as the initialLayout member of VkImageCreateInfo " + "or VkAttachmentDescription, or as the oldLayout in an image transition. (11.4)"); + } break; case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: - ImgBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + AccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; break; case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: - ImgBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + AccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; break; case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: - ImgBarrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT; + AccessMask = VK_ACCESS_MEMORY_READ_BIT; break; default: @@ -234,66 +228,33 @@ void VulkanCommandBuffer::TransitionImageLayout(VkCommandBuffer C break; } + return AccessMask; +} - switch (NewLayout) - { - case VK_IMAGE_LAYOUT_UNDEFINED: - UNEXPECTED("The new layout used in a transition must not be VK_IMAGE_LAYOUT_UNDEFINED. " - "This layout must only be used as the initialLayout member of VkImageCreateInfo " - "or VkAttachmentDescription, or as the oldLayout in an image transition. (11.4)"); - break; - - case VK_IMAGE_LAYOUT_GENERAL: - // VK_IMAGE_LAYOUT_GENERAL must be used for image load/store operations (13.1.1, 13.2.4) - ImgBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; - break; - - case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: - ImgBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - break; - - case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: - ImgBarrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - break; - - case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: - ImgBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; - break; - - case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: - ImgBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; - break; - - case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: - ImgBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - break; - - case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: - ImgBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - break; - - case VK_IMAGE_LAYOUT_PREINITIALIZED: - UNEXPECTED("The new layout used in a transition must not be VK_IMAGE_LAYOUT_PREINITIALIZED. " - "This layout must only be used as the initialLayout member of VkImageCreateInfo " - "or VkAttachmentDescription, or as the oldLayout in an image transition. (11.4)"); - break; - - case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: - ImgBarrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; - break; - - case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: - ImgBarrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; - break; - - case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: - ImgBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; - break; +void VulkanCommandBuffer::TransitionImageLayout(VkCommandBuffer CmdBuffer, + VkImage Image, + VkImageLayout OldLayout, + VkImageLayout NewLayout, + const VkImageSubresourceRange& SubresRange, + VkPipelineStageFlags EnabledGraphicsShaderStages, + VkPipelineStageFlags SrcStages, + VkPipelineStageFlags DestStages) +{ + VERIFY_EXPR(CmdBuffer != VK_NULL_HANDLE); - default: - UNEXPECTED("Unexpected image layout"); - break; - } + VkImageMemoryBarrier ImgBarrier = {}; + ImgBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + ImgBarrier.pNext = nullptr; + ImgBarrier.srcAccessMask = 0; + ImgBarrier.dstAccessMask = 0; + ImgBarrier.oldLayout = OldLayout; + ImgBarrier.newLayout = NewLayout; + ImgBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // source queue family for a queue family ownership transfer. + ImgBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // destination queue family for a queue family ownership transfer. + ImgBarrier.image = Image; + ImgBarrier.subresourceRange = SubresRange; + ImgBarrier.srcAccessMask = AccessMaskFromImageLayout(OldLayout, false); + ImgBarrier.dstAccessMask = AccessMaskFromImageLayout(NewLayout, true); if (SrcStages == 0) { @@ -303,7 +264,7 @@ void VulkanCommandBuffer::TransitionImageLayout(VkCommandBuffer C } else if (ImgBarrier.srcAccessMask != 0) { - SrcStages = PipelineStageFromAccessFlags(ImgBarrier.srcAccessMask); + SrcStages = PipelineStageFromAccessFlags(ImgBarrier.srcAccessMask, EnabledGraphicsShaderStages); } else { @@ -321,7 +282,7 @@ void VulkanCommandBuffer::TransitionImageLayout(VkCommandBuffer C } else if (ImgBarrier.dstAccessMask != 0) { - DestStages = PipelineStageFromAccessFlags(ImgBarrier.dstAccessMask); + DestStages = PipelineStageFromAccessFlags(ImgBarrier.dstAccessMask, EnabledGraphicsShaderStages); } else { @@ -362,6 +323,7 @@ void VulkanCommandBuffer::BufferMemoryBarrier(VkCommandBuffer CmdBuffer, VkBuffer Buffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, + VkPipelineStageFlags EnabledGraphicsShaderStages, VkPipelineStageFlags SrcStages, VkPipelineStageFlags DestStages) { @@ -378,7 +340,7 @@ void VulkanCommandBuffer::BufferMemoryBarrier(VkCommandBuffer CmdBuffer, if (SrcStages == 0) { if (BuffBarrier.srcAccessMask != 0) - SrcStages = PipelineStageFromAccessFlags(BuffBarrier.srcAccessMask); + SrcStages = PipelineStageFromAccessFlags(BuffBarrier.srcAccessMask, EnabledGraphicsShaderStages); else { // An execution dependency with only VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT in the source stage @@ -390,7 +352,7 @@ void VulkanCommandBuffer::BufferMemoryBarrier(VkCommandBuffer CmdBuffer, if (DestStages == 0) { VERIFY(BuffBarrier.dstAccessMask != 0, "Dst access mask must not be zero"); - DestStages = PipelineStageFromAccessFlags(BuffBarrier.dstAccessMask); + DestStages = PipelineStageFromAccessFlags(BuffBarrier.dstAccessMask, EnabledGraphicsShaderStages); } vkCmdPipelineBarrier(CmdBuffer, diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp index ab8b7cd5..01155f6f 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp @@ -49,6 +49,12 @@ namespace VulkanUtilities { auto res = vkCreateDevice(vkPhysicalDevice, &DeviceCI, vkAllocator, &m_VkDevice); CHECK_VK_ERROR_AND_THROW(res, "Failed to create logical device"); + + m_EnabledGraphicsShaderStages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + if (DeviceCI.pEnabledFeatures->geometryShader) + m_EnabledGraphicsShaderStages = VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT; + if (DeviceCI.pEnabledFeatures->tessellationShader) + m_EnabledGraphicsShaderStages = VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT; } VkQueue VulkanLogicalDevice::GetQueue(uint32_t queueFamilyIndex, uint32_t queueIndex) |
