diff options
| author | lucy96chen <47800040+lucy96chen@users.noreply.github.com> | 2022-02-09 12:23:00 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-02-09 12:23:00 -0800 |
| commit | 59f3fdc0a372d19ce4e989514ee3e9ecbcbf234c (patch) | |
| tree | 5914b550bc689a252dd3dfde3651bfa5b915a70a /tools | |
| parent | 160111a0e27c9325ddfc49a53fbb82d3c6f06c90 (diff) | |
Added a simple test for getFormatSupportedResourceStates() (#2118)
* Checkpoint
* Fixed problem with global variables in supported resource states test, test is functional for both Vulkan and D3D12
* Removed a comment
* Added a loop over all existing formats
* Rerun tests
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/gfx-unit-test/get-supported-resource-states-test.cpp | 202 | ||||
| -rw-r--r-- | tools/gfx/vulkan/render-vk.cpp | 403 |
2 files changed, 404 insertions, 201 deletions
diff --git a/tools/gfx-unit-test/get-supported-resource-states-test.cpp b/tools/gfx-unit-test/get-supported-resource-states-test.cpp new file mode 100644 index 000000000..d1573d3fd --- /dev/null +++ b/tools/gfx-unit-test/get-supported-resource-states-test.cpp @@ -0,0 +1,202 @@ +#include "tools/unit-test/slang-unit-test.h" + +#include "slang-gfx.h" +#include "gfx-test-util.h" +#include "tools/gfx-util/shader-cursor.h" +#include "source/core/slang-basic.h" + +#if SLANG_WINDOWS_FAMILY +#include <d3d12.h> +#endif + +using namespace Slang; +using namespace gfx; + +namespace +{ + using namespace gfx_test; + + struct GetSupportedResourceStatesBase + { + IDevice* device; + UnitTestContext* context; + + ResourceStateSet formatSupportedStates; + ResourceStateSet textureAllowedStates; + ResourceStateSet bufferAllowedStates; + + ComPtr<ITextureResource> texture; + ComPtr<IBufferResource> buffer; + + void init(IDevice* device, UnitTestContext* context) + { + this->device = device; + this->context = context; + } + + Format convertTypelessFormat(Format format) + { + switch (format) + { + case Format::R32G32B32A32_TYPELESS: + return Format::R32G32B32A32_FLOAT; + case Format::R32G32B32_TYPELESS: + return Format::R32G32B32_FLOAT; + case Format::R32G32_TYPELESS: + return Format::R32G32_FLOAT; + case Format::R32_TYPELESS: + return Format::R32_FLOAT; + case Format::R16G16B16A16_TYPELESS: + return Format::R16G16B16A16_FLOAT; + case Format::R16G16_TYPELESS: + return Format::R16G16_FLOAT; + case Format::R16_TYPELESS: + return Format::R16_FLOAT; + case Format::R8G8B8A8_TYPELESS: + return Format::R8G8B8A8_UNORM; + case Format::R8G8_TYPELESS: + return Format::R8G8_UNORM; + case Format::R8_TYPELESS: + return Format::R8_UNORM; + case Format::B8G8R8A8_TYPELESS: + return Format::B8G8R8A8_UNORM; + case Format::R10G10B10A2_TYPELESS: + return Format::R10G10B10A2_UINT; + default: + return Format::Unknown; + } + } + + void transitionResourceStates(IDevice* device) + { + Slang::ComPtr<ITransientResourceHeap> transientHeap; + ITransientResourceHeap::Desc transientHeapDesc = {}; + transientHeapDesc.constantBufferSize = 4096; + GFX_CHECK_CALL_ABORT( + device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef())); + + ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics }; + auto queue = device->createCommandQueue(queueDesc); + + auto commandBuffer = transientHeap->createCommandBuffer(); + auto encoder = commandBuffer->encodeResourceCommands(); + ResourceState currentTextureState = texture->getDesc()->defaultState; + ResourceState currentBufferState = buffer->getDesc()->defaultState; + + for (uint32_t i = 0; i < (uint32_t)ResourceState::_Count; ++i) + { + auto nextState = (ResourceState)i; + if (formatSupportedStates.contains(nextState)) + { + if (bufferAllowedStates.contains(nextState)) + { + encoder->bufferBarrier(buffer, currentBufferState, nextState); + currentBufferState = nextState; + } + if (textureAllowedStates.contains(nextState)) + { + encoder->textureBarrier(texture, currentTextureState, nextState); + currentTextureState = nextState; + } + } + } + encoder->endEncoding(); + commandBuffer->close(); + queue->executeCommandBuffer(commandBuffer); + queue->waitOnHost(); + } + + void run() + { + // Skip Format::Unknown + for (uint32_t i = 1; i < (uint32_t)Format::CountOf; ++i) + { + auto baseFormat = (Format)i; + auto format = gfxIsTypelessFormat(baseFormat) ? convertTypelessFormat(baseFormat) : baseFormat; + GFX_CHECK_CALL_ABORT(device->getFormatSupportedResourceStates(format, &formatSupportedStates)); + + textureAllowedStates.add( + ResourceState::RenderTarget, + ResourceState::DepthRead, + ResourceState::DepthWrite, + ResourceState::Present, + ResourceState::ResolveSource, + ResourceState::ResolveDestination, + ResourceState::Undefined, + ResourceState::ShaderResource, + ResourceState::UnorderedAccess, + ResourceState::CopySource, + ResourceState::CopyDestination); + + bufferAllowedStates.add( + ResourceState::VertexBuffer, + ResourceState::IndexBuffer, + ResourceState::ConstantBuffer, + ResourceState::StreamOutput, + ResourceState::IndirectArgument, + ResourceState::AccelerationStructure, + ResourceState::Undefined, + ResourceState::ShaderResource, + ResourceState::UnorderedAccess, + ResourceState::CopySource, + ResourceState::CopyDestination); + + ResourceState currentState = ResourceState::CopySource; + ITextureResource::Size extent; + extent.width = 4; + extent.height = 4; + extent.depth = 1; + + ITextureResource::Desc texDesc = {}; + texDesc.type = IResource::Type::Texture2D; + texDesc.numMipLevels = 1; + texDesc.arraySize = 1; + texDesc.size = extent; + texDesc.defaultState = currentState; + texDesc.allowedStates = formatSupportedStates & textureAllowedStates; + texDesc.memoryType = MemoryType::DeviceLocal; + texDesc.format = format; + + GFX_CHECK_CALL_ABORT(device->createTextureResource( + texDesc, + nullptr, + texture.writeRef())); + + IBufferResource::Desc bufferDesc = {}; + bufferDesc.sizeInBytes = 256; + bufferDesc.format = gfx::Format::Unknown; + bufferDesc.elementSize = sizeof(float); + bufferDesc.allowedStates = formatSupportedStates & bufferAllowedStates; + bufferDesc.defaultState = currentState; + bufferDesc.memoryType = MemoryType::DeviceLocal; + + GFX_CHECK_CALL_ABORT(device->createBufferResource( + bufferDesc, + nullptr, + buffer.writeRef())); + + transitionResourceStates(device); + } + } + }; + + void supportedResourceStatesTestImpl(IDevice* device, UnitTestContext* context) + { + GetSupportedResourceStatesBase test; + test.init(device, context); + test.run(); + } +} + +namespace gfx_test +{ + SLANG_UNIT_TEST(getSupportedResourceStatesD3D12) + { + runTestImpl(supportedResourceStatesTestImpl, unitTestContext, Slang::RenderApiFlag::D3D12); + } + + SLANG_UNIT_TEST(getSupportedResourceStatesVulkan) + { + runTestImpl(supportedResourceStatesTestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan); + } +} diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp index 6d5516a46..7b6b31366 100644 --- a/tools/gfx/vulkan/render-vk.cpp +++ b/tools/gfx/vulkan/render-vk.cpp @@ -4296,117 +4296,119 @@ public: , public RefObject { public: - static VkImageLayout translateImageLayout(ResourceState state) - { - switch (state) - { - case ResourceState::Undefined: - return VK_IMAGE_LAYOUT_UNDEFINED; - case ResourceState::PreInitialized: - return VK_IMAGE_LAYOUT_PREINITIALIZED; - case ResourceState::UnorderedAccess: - return VK_IMAGE_LAYOUT_GENERAL; - case ResourceState::RenderTarget: - return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - case ResourceState::DepthRead: - return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; - case ResourceState::DepthWrite: - return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - case ResourceState::ShaderResource: - return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - case ResourceState::ResolveDestination: - case ResourceState::CopyDestination: - return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - case ResourceState::ResolveSource: - case ResourceState::CopySource: - return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - case ResourceState::Present: - return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - default: - assert(!"Unsupported"); - return VK_IMAGE_LAYOUT_UNDEFINED; - } - } - - static VkAccessFlagBits calcAccessFlags(ResourceState state) - { - switch (state) - { - case ResourceState::Undefined: - case ResourceState::Present: - case ResourceState::PreInitialized: - return VkAccessFlagBits(0); - case ResourceState::VertexBuffer: - return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; - case ResourceState::ConstantBuffer: - return VK_ACCESS_UNIFORM_READ_BIT; - case ResourceState::IndexBuffer: - return VK_ACCESS_INDEX_READ_BIT; - case ResourceState::RenderTarget: - return VkAccessFlagBits(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT); - case ResourceState::ShaderResource: - return VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; - case ResourceState::UnorderedAccess: - return VkAccessFlagBits(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT); - case ResourceState::DepthRead: - return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; - case ResourceState::DepthWrite: - return VkAccessFlagBits(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT); - case ResourceState::IndirectArgument: - return VK_ACCESS_INDIRECT_COMMAND_READ_BIT; - case ResourceState::ResolveDestination: - case ResourceState::CopyDestination: - return VK_ACCESS_TRANSFER_WRITE_BIT; - case ResourceState::ResolveSource: - case ResourceState::CopySource: - return VK_ACCESS_TRANSFER_READ_BIT; - case ResourceState::AccelerationStructure: - return VkAccessFlagBits(VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR); - default: - assert(!"Unsupported"); - return VkAccessFlagBits(0); - } - } - - static VkPipelineStageFlagBits calcPipelineStageFlags(ResourceState state, bool src) - { - switch (state) - { - case ResourceState::Undefined: - case ResourceState::PreInitialized: - assert(src); - return VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - case ResourceState::IndexBuffer: - return VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; - case ResourceState::ConstantBuffer: - case ResourceState::UnorderedAccess: - return VkPipelineStageFlagBits(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 | - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT); - case ResourceState::ShaderResource: - return VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - case ResourceState::RenderTarget: - return VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - case ResourceState::DepthRead: - case ResourceState::DepthWrite: - return VkPipelineStageFlagBits(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT); - case ResourceState::IndirectArgument: - return VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; - case ResourceState::CopySource: - case ResourceState::CopyDestination: - case ResourceState::ResolveSource: - case ResourceState::ResolveDestination: - return VK_PIPELINE_STAGE_TRANSFER_BIT; - case ResourceState::Present: - return src ? VkPipelineStageFlagBits(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - default: - assert(!"Unsupported"); - return VkPipelineStageFlagBits(0); + static VkImageLayout translateImageLayout(ResourceState state) + { + switch (state) + { + case ResourceState::Undefined: + return VK_IMAGE_LAYOUT_UNDEFINED; + case ResourceState::PreInitialized: + return VK_IMAGE_LAYOUT_PREINITIALIZED; + case ResourceState::UnorderedAccess: + return VK_IMAGE_LAYOUT_GENERAL; + case ResourceState::RenderTarget: + return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + case ResourceState::DepthRead: + return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; + case ResourceState::DepthWrite: + return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + case ResourceState::ShaderResource: + return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + case ResourceState::ResolveDestination: + case ResourceState::CopyDestination: + return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + case ResourceState::ResolveSource: + case ResourceState::CopySource: + return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + case ResourceState::Present: + return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + default: + assert(!"Unsupported"); + return VK_IMAGE_LAYOUT_UNDEFINED; + } } - } + + static VkAccessFlagBits calcAccessFlags(ResourceState state) + { + switch (state) + { + case ResourceState::Undefined: + case ResourceState::Present: + case ResourceState::PreInitialized: + return VkAccessFlagBits(0); + case ResourceState::VertexBuffer: + return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; + case ResourceState::ConstantBuffer: + return VK_ACCESS_UNIFORM_READ_BIT; + case ResourceState::IndexBuffer: + return VK_ACCESS_INDEX_READ_BIT; + case ResourceState::RenderTarget: + return VkAccessFlagBits(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT); + case ResourceState::ShaderResource: + return VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; + case ResourceState::UnorderedAccess: + return VkAccessFlagBits(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT); + case ResourceState::DepthRead: + return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + case ResourceState::DepthWrite: + return VkAccessFlagBits(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT); + case ResourceState::IndirectArgument: + return VK_ACCESS_INDIRECT_COMMAND_READ_BIT; + case ResourceState::ResolveDestination: + case ResourceState::CopyDestination: + return VK_ACCESS_TRANSFER_WRITE_BIT; + case ResourceState::ResolveSource: + case ResourceState::CopySource: + return VK_ACCESS_TRANSFER_READ_BIT; + case ResourceState::AccelerationStructure: + return VkAccessFlagBits(VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR); + default: + assert(!"Unsupported"); + return VkAccessFlagBits(0); + } + } + + static VkPipelineStageFlagBits calcPipelineStageFlags(ResourceState state, bool src) + { + switch (state) + { + case ResourceState::Undefined: + case ResourceState::PreInitialized: + assert(src); + return VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + case ResourceState::VertexBuffer: + case ResourceState::IndexBuffer: + return VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; + case ResourceState::ConstantBuffer: + case ResourceState::UnorderedAccess: + return VkPipelineStageFlagBits(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 | + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT); + case ResourceState::ShaderResource: + return VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + case ResourceState::RenderTarget: + return VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + case ResourceState::DepthRead: + case ResourceState::DepthWrite: + return VkPipelineStageFlagBits(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT); + case ResourceState::IndirectArgument: + return VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; + case ResourceState::CopySource: + case ResourceState::CopyDestination: + case ResourceState::ResolveSource: + case ResourceState::ResolveDestination: + return VK_PIPELINE_STAGE_TRANSFER_BIT; + case ResourceState::Present: + return src ? VkPipelineStageFlagBits(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + default: + assert(!"Unsupported"); + return VkPipelineStageFlagBits(0); + } + } + public: CommandBufferImpl* m_commandBuffer; public: @@ -6284,7 +6286,7 @@ Result VKDevice::initVulkanInstanceAndDevice(const InteropHandle* handles, bool applicationInfo.engineVersion = 1; applicationInfo.applicationVersion = 1; - Array<const char*, 5> instanceExtensions; + Array<const char*, 6> instanceExtensions; instanceExtensions.add(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); instanceExtensions.add(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME); @@ -6294,6 +6296,7 @@ Result VKDevice::initVulkanInstanceAndDevice(const InteropHandle* handles, bool if (!m_api.m_module->isSoftware()) { instanceExtensions.add(VK_KHR_SURFACE_EXTENSION_NAME); + instanceExtensions.add("VK_GOOGLE_surfaceless_query"); #if SLANG_WINDOWS_FAMILY instanceExtensions.add(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); #elif defined(SLANG_ENABLE_XLIB) @@ -7213,6 +7216,71 @@ static VkImageUsageFlags _calcImageUsageFlags( return usage; } +VkAccessFlags calcAccessFlagsFromImageLayout(VkImageLayout layout) +{ + switch (layout) + { + case VK_IMAGE_LAYOUT_UNDEFINED: + case VK_IMAGE_LAYOUT_GENERAL: + case VK_IMAGE_LAYOUT_PREINITIALIZED: + case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: + return (VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT); + case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: + return (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: + case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL: + case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL: + case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: + case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: + return (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT); + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: + case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL: + case VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL: + return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + return VK_ACCESS_SHADER_READ_BIT; + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: + return VK_ACCESS_TRANSFER_READ_BIT; + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: + return VK_ACCESS_TRANSFER_WRITE_BIT; + default: + assert(!"Unsupported VkImageLayout"); + return (VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT); + } +} + +VkPipelineStageFlags calcPipelineStageFlagsFromImageLayout(VkImageLayout layout) +{ + switch (layout) + { + case VK_IMAGE_LAYOUT_UNDEFINED: + case VK_IMAGE_LAYOUT_PREINITIALIZED: + case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: + case VK_IMAGE_LAYOUT_GENERAL: + return VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; + case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: + return VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + return (VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT); + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: + return VK_PIPELINE_STAGE_TRANSFER_BIT; + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: + return VK_PIPELINE_STAGE_TRANSFER_BIT; + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: + case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: + case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: + case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL: + case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL: + case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL: + case VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL: + return (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT); + default: + assert(!"Unsupported VkImageLayout"); + return VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; + } +} + void VKDevice::_transitionImageLayout( VkCommandBuffer commandBuffer, VkImage image, @@ -7243,91 +7311,11 @@ void VKDevice::_transitionImageLayout( barrier.subresourceRange.levelCount = desc.numMipLevels; barrier.subresourceRange.baseArrayLayer = 0; barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; + barrier.srcAccessMask = calcAccessFlagsFromImageLayout(oldLayout); + barrier.dstAccessMask = calcAccessFlagsFromImageLayout(newLayout); - VkPipelineStageFlags sourceStage; - VkPipelineStageFlags destinationStage; - - if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) - { - barrier.srcAccessMask = 0; - barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - - sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT; - } - else if ( - oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && - newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) - { - barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - - sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT; - destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - } - else if ( - oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && - newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) - { - barrier.srcAccessMask = 0; - barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - - sourceStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - destinationStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - } - else if ( - oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && - (newLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL || - newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)) - { - barrier.srcAccessMask = 0; - barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - - sourceStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - destinationStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; - } - else if ( - oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && - newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) - { - barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - barrier.dstAccessMask = 0; - - sourceStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - destinationStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - } - else if ( - oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR && - newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) - { - barrier.srcAccessMask = 0; - barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - - sourceStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - destinationStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - } - else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_GENERAL) - { - barrier.srcAccessMask = 0; - barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT; - - sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - destinationStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - } - else if ( - oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_GENERAL) - { - barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT; - - sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT; - destinationStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - } - else - { - assert(!"unsupported layout transition!"); - return; - } + VkPipelineStageFlags sourceStage = calcPipelineStageFlagsFromImageLayout(oldLayout); + VkPipelineStageFlags destinationStage = calcPipelineStageFlagsFromImageLayout(newLayout); m_api.vkCmdPipelineBarrier( commandBuffer, sourceStage, destinationStage, 0, 0, nullptr, 0, nullptr, 1, &barrier); @@ -8002,11 +7990,25 @@ Result VKDevice::createTextureView(ITextureResource* texture, IResourceView::Des return SLANG_OK; } -// TODO: Buffer vs texture specific? Result VKDevice::getFormatSupportedResourceStates(Format format, ResourceStateSet* outStates) { + // TODO: Add variables to VkDevice to track supported surface presentable formats + VkFormat vkFormat = VulkanUtil::getVkFormat(format); VkFormatProperties supportedProperties; - m_api.vkGetPhysicalDeviceFormatProperties(m_api.m_physicalDevice, VulkanUtil::getVkFormat(format), &supportedProperties); + m_api.vkGetPhysicalDeviceFormatProperties(m_api.m_physicalDevice, vkFormat, &supportedProperties); + + uint32_t surfaceFormatCount = 0; + m_api.vkGetPhysicalDeviceSurfaceFormatsKHR(m_api.m_physicalDevice, VK_NULL_HANDLE, &surfaceFormatCount, nullptr); + + List<VkSurfaceFormatKHR> surfaceFormats; + surfaceFormats.setCount(surfaceFormatCount); + m_api.vkGetPhysicalDeviceSurfaceFormatsKHR(m_api.m_physicalDevice, VK_NULL_HANDLE, &surfaceFormatCount, surfaceFormats.getBuffer()); + + HashSet<VkFormat> presentableFormats; + for (auto surfaceFormat : surfaceFormats) + { + presentableFormats.Add(surfaceFormat.format); + } ResourceStateSet allowedStates; // TODO: Currently only supports VK_IMAGE_TILING_OPTIMAL @@ -8048,7 +8050,9 @@ Result VKDevice::getFormatSupportedResourceStates(Format format, ResourceStateSe allowedStates.add(ResourceState::DepthRead); allowedStates.add(ResourceState::DepthWrite); } - // Present - TODO: Requires VK_GOOGLE_surfaceless_query and calling vkGetPhysicalDeviceSurfaceFormatsKHR + // Present + if (presentableFormats.Contains(vkFormat)) + allowedStates.add(ResourceState::Present); // IndirectArgument allowedStates.add(ResourceState::IndirectArgument); // CopySource, ResolveSource @@ -8066,9 +8070,6 @@ Result VKDevice::getFormatSupportedResourceStates(Format format, ResourceStateSe // AccelerationStructure if (bufferFeatures & VK_FORMAT_FEATURE_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR) allowedStates.add(ResourceState::AccelerationStructure); - // General - VK_IMAGE_LAYOUT_GENERAL supports all types of device access. Should only be set if everything else - // is included? - allowedStates.add(ResourceState::General); *outStates = allowedStates; return SLANG_OK; |
