summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj1
-rw-r--r--build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj.filters3
-rw-r--r--slang-gfx.h15
-rw-r--r--tools/gfx-unit-test/get-supported-resource-states-test.cpp202
-rw-r--r--tools/gfx/vulkan/render-vk.cpp403
5 files changed, 423 insertions, 201 deletions
diff --git a/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj b/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj
index ce88fdc0a..0b0be2a07 100644
--- a/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj
+++ b/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj
@@ -281,6 +281,7 @@
<ClCompile Include="..\..\..\tools\gfx-unit-test\get-buffer-resource-handle-test.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\get-cmd-buffer-handle-test.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\get-cmd-queue-handle-test.cpp" />
+ <ClCompile Include="..\..\..\tools\gfx-unit-test\get-supported-resource-states-test.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\get-texture-resource-handle-test.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\gfx-test-util.cpp" />
<ClCompile Include="..\..\..\tools\gfx-unit-test\instanced-draw-tests.cpp" />
diff --git a/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj.filters b/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj.filters
index 3bdfaa778..230aa3893 100644
--- a/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj.filters
+++ b/build/visual-studio/gfx-unit-test-tool/gfx-unit-test-tool.vcxproj.filters
@@ -74,6 +74,9 @@
<ClCompile Include="..\..\..\tools\unit-test\slang-unit-test.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\tools\gfx-unit-test\get-supported-resource-states-test.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\..\tools\gfx-unit-test\buffer-barrier-test.slang">
diff --git a/slang-gfx.h b/slang-gfx.h
index 3489dd398..37eb64935 100644
--- a/slang-gfx.h
+++ b/slang-gfx.h
@@ -418,6 +418,13 @@ public:
add(states...);
}
+ ResourceStateSet operator&(const ResourceStateSet& that) const
+ {
+ ResourceStateSet result;
+ result.m_bitFields = this->m_bitFields & that.m_bitFields;
+ return result;
+ }
+
private:
uint64_t m_bitFields = 0;
void add() {}
@@ -1632,6 +1639,10 @@ public:
ITextureResource* const* textures,
ResourceState src,
ResourceState dst) = 0;
+ void textureBarrier(ITextureResource* texture, ResourceState src, ResourceState dst)
+ {
+ textureBarrier(1, &texture, src, dst);
+ }
virtual SLANG_NO_THROW void SLANG_MCALL textureSubresourceBarrier(
ITextureResource* texture,
SubresourceRange subresourceRange,
@@ -1642,6 +1653,10 @@ public:
IBufferResource* const* buffers,
ResourceState src,
ResourceState dst) = 0;
+ void bufferBarrier(IBufferResource* buffer, ResourceState src, ResourceState dst)
+ {
+ bufferBarrier(1, &buffer, src, dst);
+ }
virtual SLANG_NO_THROW void SLANG_MCALL clearResourceView(
IResourceView* view, ClearValue* clearValue, ClearResourceViewFlags::Enum flags) = 0;
virtual SLANG_NO_THROW void SLANG_MCALL resolveResource(
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;