summaryrefslogtreecommitdiffstats
path: root/tools/gfx/vulkan/render-vk.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gfx/vulkan/render-vk.cpp')
-rw-r--r--tools/gfx/vulkan/render-vk.cpp134
1 files changed, 66 insertions, 68 deletions
diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp
index 2dd5d4041..e7ebf8040 100644
--- a/tools/gfx/vulkan/render-vk.cpp
+++ b/tools/gfx/vulkan/render-vk.cpp
@@ -4,6 +4,7 @@
//WORKING:#include "options.h"
#include "../renderer-shared.h"
#include "../transient-resource-heap-base.h"
+#include "../mutable-shader-object.h"
#include "core/slang-basic.h"
#include "core/slang-blob.h"
@@ -95,6 +96,8 @@ public:
ShaderObjectLayoutBase** outLayout) override;
virtual Result createShaderObject(ShaderObjectLayoutBase* layout, IShaderObject** outObject)
override;
+ virtual Result createMutableShaderObject(ShaderObjectLayoutBase* layout, IShaderObject** outObject)
+ override;
virtual SLANG_NO_THROW Result SLANG_MCALL
createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) override;
@@ -140,6 +143,7 @@ public:
~VKDevice();
public:
+ class TransientResourceHeapImpl;
class Buffer
{
@@ -243,17 +247,9 @@ public:
}
};
- class SamplerStateImpl : public ISamplerState, public ComObject
+ class SamplerStateImpl : public SamplerStateBase
{
public:
- SLANG_COM_OBJECT_IUNKNOWN_ALL
- ISamplerState* getInterface(const Guid& guid)
- {
- if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_ISamplerState)
- return static_cast<ISamplerState*>(this);
- return nullptr;
- }
- public:
VkSampler m_sampler;
RefPtr<VKDevice> m_device;
SamplerStateImpl(VKDevice* device)
@@ -562,20 +558,9 @@ public:
}
};
- class FramebufferImpl
- : public IFramebuffer
- , public ComObject
+ class FramebufferImpl : public FramebufferBase
{
public:
- SLANG_COM_OBJECT_IUNKNOWN_ALL
- IFramebuffer* getInterface(const Guid& guid)
- {
- if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IFramebuffer)
- return static_cast<IFramebuffer*>(this);
- return nullptr;
- }
-
- public:
VkFramebuffer m_handle;
ShortList<ComPtr<IResourceView>> renderTargetViews;
ComPtr<IResourceView> depthStencilView;
@@ -2322,6 +2307,8 @@ public:
memcpy(dest + offset, data, size);
+ m_isConstantBufferDirty = true;
+
return SLANG_OK;
}
@@ -2388,7 +2375,9 @@ public:
{
m_layout = layout;
- m_upToDateConstantBufferHeapVersion = 0;
+ m_constantBufferTransientHeap = nullptr;
+ m_constantBufferTransientHeapVersion = 0;
+ m_isConstantBufferDirty = true;
// If the layout tells us that there is any uniform data,
// then we will allocate a CPU memory buffer to hold that data
@@ -2812,30 +2801,31 @@ public:
}
}
+ bool shouldAllocateConstantBuffer(TransientResourceHeapImpl* transientHeap)
+ {
+ return m_isConstantBufferDirty || m_constantBufferTransientHeap != transientHeap ||
+ m_constantBufferTransientHeapVersion != transientHeap->getVersion();
+ }
+
/// Ensure that the `m_ordinaryDataBuffer` has been created, if it is needed
Result _ensureOrdinaryDataBufferCreatedIfNeeded(
PipelineCommandEncoder* encoder,
ShaderObjectLayoutImpl* specializedLayout)
{
- // If we have already created a buffer to hold ordinary data, then we should
- // simply re-use that buffer rather than re-create it.
- //
- // TODO: Simply re-using the buffer without any kind of validation checks
- // means that we are assuming that users cannot or will not perform any `set`
- // operations on a shader object once an operation has requested this buffer
- // be created. We need to enforce that rule if we want to rely on it.
+ // If data has been changed since last allocation/filling of constant buffer,
+ // we will need to allocate a new one.
//
- if (m_upToDateConstantBufferHeapVersion ==
- encoder->m_commandBuffer->m_transientHeap->getVersion())
+ if (!shouldAllocateConstantBuffer(encoder->m_commandBuffer->m_transientHeap))
{
return SLANG_OK;
}
+ m_isConstantBufferDirty = false;
+ m_constantBufferTransientHeap = encoder->m_commandBuffer->m_transientHeap;
+ m_constantBufferTransientHeapVersion = encoder->m_commandBuffer->m_transientHeap->getVersion();
m_constantBufferSize = specializedLayout->getTotalOrdinaryDataSize();
if (m_constantBufferSize == 0)
{
- m_upToDateConstantBufferHeapVersion =
- encoder->m_commandBuffer->m_transientHeap->getVersion();
return SLANG_OK;
}
@@ -2858,10 +2848,6 @@ public:
m_constantBufferSize,
specializedLayout));
- // Update version tracker so that we don't redundantly alloc and fill in
- // constant buffers for the same transient heap.
- m_upToDateConstantBufferHeapVersion =
- encoder->m_commandBuffer->m_transientHeap->getVersion();
return SLANG_OK;
}
@@ -3213,9 +3199,6 @@ public:
List<CombinedTextureSamplerSlot> m_combinedTextureSamplers;
- // The version number of the transient resource heap that contains up-to-date
- // constant buffer content for this shader object.
- uint64_t m_upToDateConstantBufferHeapVersion;
// The transient constant buffer that holds the GPU copy of the constant data,
// weak referenced.
IBufferResource* m_constantBuffer = nullptr;
@@ -3223,6 +3206,13 @@ public:
size_t m_constantBufferOffset = 0;
size_t m_constantBufferSize = 0;
+ /// Dirty bit tracking whether the constant buffer needs to be updated.
+ bool m_isConstantBufferDirty = true;
+ /// The transient heap from which the constant buffer is allocated.
+ VKDevice::TransientResourceHeapImpl* m_constantBufferTransientHeap;
+ /// The version of the transient heap when the constant buffer is allocated.
+ uint64_t m_constantBufferTransientHeapVersion;
+
/// Get the layout of this shader object with specialization arguments considered
///
/// This operation should only be called after the shader object has been
@@ -3261,6 +3251,9 @@ public:
RefPtr<ShaderObjectLayoutImpl> m_specializedLayout;
};
+ class MutableShaderObjectImpl : public MutableShaderObject<MutableShaderObjectImpl, ShaderObjectLayoutImpl>
+ {};
+
class EntryPointShaderObject : public ShaderObjectImpl
{
typedef ShaderObjectImpl Super;
@@ -3541,8 +3534,6 @@ public:
List<RefPtr<EntryPointShaderObject>> m_entryPoints;
};
- class TransientResourceHeapImpl;
-
class CommandBufferImpl
: public ICommandBuffer
, public ComObject
@@ -4141,7 +4132,7 @@ public:
VkPipelineStageFlagBits dstStage = calcPipelineStageFlags(dst, false);
auto& vkApi = m_commandBuffer->m_renderer->m_api;
- vkApi.vkCmdPipelineBarrier(m_commandBuffer->m_commandBuffer, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, count, barriers.getBuffer());
+ vkApi.vkCmdPipelineBarrier(m_commandBuffer->m_commandBuffer, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, (uint32_t)count, barriers.getBuffer());
}
virtual SLANG_NO_THROW void SLANG_MCALL bufferBarrier(
size_t count,
@@ -4150,7 +4141,7 @@ public:
ResourceState dst)
{
List<VkBufferMemoryBarrier> barriers;
- barriers.setCount(count);
+ barriers.reserve(count);
for (size_t i = 0; i < count; i++)
{
@@ -4171,7 +4162,7 @@ public:
VkPipelineStageFlagBits dstStage = calcPipelineStageFlags(dst, false);
auto& vkApi = m_commandBuffer->m_renderer->m_api;
- vkApi.vkCmdPipelineBarrier(m_commandBuffer->m_commandBuffer, srcStage, dstStage, 0, 0, nullptr, count, barriers.getBuffer(), 0, nullptr);
+ vkApi.vkCmdPipelineBarrier(m_commandBuffer->m_commandBuffer, srcStage, dstStage, 0, 0, nullptr, (uint32_t)count, barriers.getBuffer(), 0, nullptr);
}
virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override
{
@@ -4661,10 +4652,10 @@ public:
};
class TransientResourceHeapImpl
- : public TransientResourceHeapBase<VKDevice, BufferResourceImpl>
+ : public TransientResourceHeapBaseImpl<VKDevice, BufferResourceImpl>
{
private:
- typedef TransientResourceHeapBase<VKDevice, BufferResourceImpl> Super;
+ typedef TransientResourceHeapBaseImpl<VKDevice, BufferResourceImpl> Super;
public:
VkCommandPool m_commandPool;
@@ -4708,19 +4699,9 @@ public:
virtual SLANG_NO_THROW Result SLANG_MCALL synchronizeAndReset() override;
};
- class QueryPoolImpl
- : public IQueryPool
- , public ComObject
+ class QueryPoolImpl : public QueryPoolBase
{
public:
- SLANG_COM_OBJECT_IUNKNOWN_ALL
- IQueryPool* getInterface(const Guid& guid)
- {
- if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IQueryPool)
- return static_cast<IQueryPool*>(this);
- return nullptr;
- }
- public:
Result init(const IQueryPool::Desc& desc, VKDevice* device)
{
m_device = device;
@@ -6177,9 +6158,9 @@ static VkBufferUsageFlagBits _calcBufferUsageFlags(ResourceState state)
return VkBufferUsageFlagBits(0);
}
case ResourceState::UnorderedAccess:
- return VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
+ return (VkBufferUsageFlagBits)(VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
case ResourceState::ShaderResource:
- return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
+ return (VkBufferUsageFlagBits)(VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
case ResourceState::CopySource:
return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
case ResourceState::CopyDestination:
@@ -6302,7 +6283,7 @@ void VKDevice::_transitionImageLayout(VkImage image, VkFormat format, const Text
barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.levelCount = desc.numMipLevels;
barrier.subresourceRange.baseArrayLayer = 0;
- barrier.subresourceRange.layerCount = 1;
+ barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
VkPipelineStageFlags sourceStage;
VkPipelineStageFlags destinationStage;
@@ -6425,7 +6406,6 @@ Result VKDevice::createTextureResource(const ITextureResource::Desc& descIn, con
// Create the image
{
VkImageCreateInfo imageInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
-
switch (desc.type)
{
case IResource::Type::Texture1D:
@@ -6444,6 +6424,7 @@ Result VKDevice::createTextureResource(const ITextureResource::Desc& descIn, con
{
imageInfo.imageType = VK_IMAGE_TYPE_2D;
imageInfo.extent = VkExtent3D{ uint32_t(descIn.size.width), uint32_t(descIn.size.height), 1 };
+ imageInfo.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
break;
}
case IResource::Type::Texture3D:
@@ -6470,9 +6451,8 @@ Result VKDevice::createTextureResource(const ITextureResource::Desc& descIn, con
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageInfo.usage = _calcImageUsageFlags(desc.allowedStates, desc.cpuAccessFlags, initData);
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
-
+
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
- imageInfo.flags = 0; // Optional
SLANG_VK_RETURN_ON_FAIL(m_api.vkCreateImage(m_device, &imageInfo, nullptr, &texture->m_image));
}
@@ -6661,7 +6641,11 @@ Result VKDevice::createBufferResource(const IBufferResource::Desc& descIn, const
{
usage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
}
-
+ if (desc.allowedStates.contains(ResourceState::ShaderResource) &&
+ m_api.m_extendedFeatures.accelerationStructureFeatures.accelerationStructure)
+ {
+ usage |= VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR;
+ }
if (initData)
{
usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
@@ -6861,19 +6845,20 @@ Result VKDevice::createTextureView(ITextureResource* texture, IResourceView::Des
createInfo.format = resourceImpl->m_vkformat;
createInfo.image = resourceImpl->m_image;
createInfo.components = VkComponentMapping{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,VK_COMPONENT_SWIZZLE_B,VK_COMPONENT_SWIZZLE_A };
+ bool isArray = resourceImpl->getDesc()->arraySize != 0;
switch (resourceImpl->getType())
{
case IResource::Type::Texture1D:
- createInfo.viewType = VK_IMAGE_VIEW_TYPE_1D;
+ createInfo.viewType = isArray ? VK_IMAGE_VIEW_TYPE_1D_ARRAY : VK_IMAGE_VIEW_TYPE_1D;
break;
case IResource::Type::Texture2D:
- createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
+ createInfo.viewType = isArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
break;
case IResource::Type::Texture3D:
createInfo.viewType = VK_IMAGE_VIEW_TYPE_3D;
break;
case IResource::Type::TextureCube:
- createInfo.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
+ createInfo.viewType = isArray ? VK_IMAGE_VIEW_TYPE_CUBE_ARRAY : VK_IMAGE_VIEW_TYPE_CUBE;
break;
default:
SLANG_UNIMPLEMENTED_X("Unknown Texture type.");
@@ -7144,6 +7129,19 @@ Result VKDevice::createShaderObject(ShaderObjectLayoutBase* layout, IShaderObjec
return SLANG_OK;
}
+Result VKDevice::createMutableShaderObject(
+ ShaderObjectLayoutBase* layout,
+ IShaderObject** outObject)
+{
+ auto layoutImpl = static_cast<ShaderObjectLayoutImpl*>(layout);
+
+ RefPtr<MutableShaderObjectImpl> result = new MutableShaderObjectImpl();
+ SLANG_RETURN_ON_FAIL(result->init(this, layoutImpl));
+ returnComPtr(outObject, result);
+
+ return SLANG_OK;
+}
+
Result VKDevice::createGraphicsPipelineState(const GraphicsPipelineStateDesc& inDesc, IPipelineState** outState)
{
GraphicsPipelineStateDesc desc = inDesc;