summaryrefslogtreecommitdiff
path: root/tools/gfx/vulkan/vk-shader-object.h
diff options
context:
space:
mode:
authorlucy96chen <47800040+lucy96chen@users.noreply.github.com>2022-05-26 10:54:35 -0700
committerGitHub <noreply@github.com>2022-05-26 10:54:35 -0700
commit43e1b7cdc70b2fcac8a3e8ee72f5bc91726f4ec5 (patch)
tree1e4701b4ab324a199b81e1f6c671f6660f1050c5 /tools/gfx/vulkan/vk-shader-object.h
parent5ff4f42c636a67724523e4fe60697cfac64908cd (diff)
Split render-vk.h/.cpp into a set of smaller files (#2244)
* Some preliminary work on splitting render-vk * render-vk split, tests currently crash on null reference * fixed circular include
Diffstat (limited to 'tools/gfx/vulkan/vk-shader-object.h')
-rw-r--r--tools/gfx/vulkan/vk-shader-object.h274
1 files changed, 274 insertions, 0 deletions
diff --git a/tools/gfx/vulkan/vk-shader-object.h b/tools/gfx/vulkan/vk-shader-object.h
new file mode 100644
index 000000000..5226d709c
--- /dev/null
+++ b/tools/gfx/vulkan/vk-shader-object.h
@@ -0,0 +1,274 @@
+// vk-shader-object.h
+#pragma once
+
+#include "vk-base.h"
+#include "vk-resource-views.h"
+#include "vk-sampler.h"
+#include "vk-shader-object-layout.h"
+#include "vk-helper-functions.h"
+
+namespace gfx
+{
+
+using namespace Slang;
+
+namespace vk
+{
+
+struct CombinedTextureSamplerSlot
+{
+ RefPtr<TextureResourceViewImpl> textureView;
+ RefPtr<SamplerStateImpl> sampler;
+ operator bool() { return textureView && sampler; }
+};
+
+class ShaderObjectImpl
+ : public ShaderObjectBaseImpl<ShaderObjectImpl, ShaderObjectLayoutImpl, SimpleShaderObjectData>
+{
+public:
+ static Result create(
+ IDevice* device, ShaderObjectLayoutImpl* layout, ShaderObjectImpl** outShaderObject);
+
+ RendererBase* getDevice();
+
+ virtual SLANG_NO_THROW GfxCount SLANG_MCALL getEntryPointCount() override;
+
+ virtual SLANG_NO_THROW Result SLANG_MCALL
+ getEntryPoint(GfxIndex index, IShaderObject** outEntryPoint) override;
+
+ virtual SLANG_NO_THROW const void* SLANG_MCALL getRawData() override;
+
+ virtual SLANG_NO_THROW Size SLANG_MCALL getSize() override;
+
+ // TODO: Changed size_t to Size? inSize assigned to an Index variable inside implementation
+ virtual SLANG_NO_THROW Result SLANG_MCALL
+ setData(ShaderOffset const& inOffset, void const* data, size_t inSize) override;
+
+ virtual SLANG_NO_THROW Result SLANG_MCALL
+ setResource(ShaderOffset const& offset, IResourceView* resourceView) override;
+
+ virtual SLANG_NO_THROW Result SLANG_MCALL
+ setSampler(ShaderOffset const& offset, ISamplerState* sampler) override;
+
+ virtual SLANG_NO_THROW Result SLANG_MCALL setCombinedTextureSampler(
+ ShaderOffset const& offset, IResourceView* textureView, ISamplerState* sampler) override;
+
+protected:
+ friend class RootShaderObjectLayout;
+
+ Result init(IDevice* device, ShaderObjectLayoutImpl* layout);
+
+ /// Write the uniform/ordinary data of this object into the given `dest` buffer at the given
+ /// `offset`
+ Result _writeOrdinaryData(
+ PipelineCommandEncoder* encoder,
+ IBufferResource* buffer,
+ Offset offset,
+ Size destSize,
+ ShaderObjectLayoutImpl* specializedLayout);
+
+public:
+ /// Write a single descriptor using the Vulkan API
+ static void writeDescriptor(RootBindingContext& context, VkWriteDescriptorSet const& write);
+
+ static void writeBufferDescriptor(
+ RootBindingContext& context,
+ BindingOffset const& offset,
+ VkDescriptorType descriptorType,
+ BufferResourceImpl* buffer,
+ Offset bufferOffset,
+ Size bufferSize);
+
+ static void writeBufferDescriptor(
+ RootBindingContext& context,
+ BindingOffset const& offset,
+ VkDescriptorType descriptorType,
+ BufferResourceImpl* buffer);
+
+ static void writePlainBufferDescriptor(
+ RootBindingContext& context,
+ BindingOffset const& offset,
+ VkDescriptorType descriptorType,
+ ArrayView<RefPtr<ResourceViewInternalBase>> resourceViews);
+
+ static void writeTexelBufferDescriptor(
+ RootBindingContext& context,
+ BindingOffset const& offset,
+ VkDescriptorType descriptorType,
+ ArrayView<RefPtr<ResourceViewInternalBase>> resourceViews);
+
+ static void writeTextureSamplerDescriptor(
+ RootBindingContext& context,
+ BindingOffset const& offset,
+ VkDescriptorType descriptorType,
+ ArrayView<CombinedTextureSamplerSlot> slots);
+
+ static void writeAccelerationStructureDescriptor(
+ RootBindingContext& context,
+ BindingOffset const& offset,
+ VkDescriptorType descriptorType,
+ ArrayView<RefPtr<ResourceViewInternalBase>> resourceViews);
+
+ static void writeTextureDescriptor(
+ RootBindingContext& context,
+ BindingOffset const& offset,
+ VkDescriptorType descriptorType,
+ ArrayView<RefPtr<ResourceViewInternalBase>> resourceViews);
+
+ static void writeSamplerDescriptor(
+ RootBindingContext& context,
+ BindingOffset const& offset,
+ VkDescriptorType descriptorType,
+ ArrayView<RefPtr<SamplerStateImpl>> samplers);
+
+ bool shouldAllocateConstantBuffer(TransientResourceHeapImpl* transientHeap);
+
+ /// Ensure that the `m_ordinaryDataBuffer` has been created, if it is needed
+ Result _ensureOrdinaryDataBufferCreatedIfNeeded(
+ PipelineCommandEncoder* encoder, ShaderObjectLayoutImpl* specializedLayout);
+
+public:
+ /// Bind this shader object as a "value"
+ ///
+ /// This is the mode used for binding sub-objects for existential-type
+ /// fields, and is also used as part of the implementation of the
+ /// parameter-block and constant-buffer cases.
+ ///
+ Result bindAsValue(
+ PipelineCommandEncoder* encoder,
+ RootBindingContext& context,
+ BindingOffset const& offset,
+ ShaderObjectLayoutImpl* specializedLayout);
+
+ /// Allocate the descriptor sets needed for binding this object (but not nested parameter
+ /// blocks)
+ Result allocateDescriptorSets(
+ PipelineCommandEncoder* encoder,
+ RootBindingContext& context,
+ BindingOffset const& offset,
+ ShaderObjectLayoutImpl* specializedLayout);
+
+ /// Bind this object as a `ParameterBlock<X>`.
+ Result bindAsParameterBlock(
+ PipelineCommandEncoder* encoder,
+ RootBindingContext& context,
+ BindingOffset const& inOffset,
+ ShaderObjectLayoutImpl* specializedLayout);
+
+ /// Bind the ordinary data buffer if needed.
+ Result bindOrdinaryDataBufferIfNeeded(
+ PipelineCommandEncoder* encoder,
+ RootBindingContext& context,
+ BindingOffset& ioOffset,
+ ShaderObjectLayoutImpl* specializedLayout);
+
+ /// Bind this object as a `ConstantBuffer<X>`.
+ Result bindAsConstantBuffer(
+ PipelineCommandEncoder* encoder,
+ RootBindingContext& context,
+ BindingOffset const& inOffset,
+ ShaderObjectLayoutImpl* specializedLayout);
+
+ List<RefPtr<ResourceViewInternalBase>> m_resourceViews;
+
+ List<RefPtr<SamplerStateImpl>> m_samplers;
+
+ List<CombinedTextureSamplerSlot> m_combinedTextureSamplers;
+
+ // The transient constant buffer that holds the GPU copy of the constant data,
+ // weak referenced.
+ IBufferResource* m_constantBuffer = nullptr;
+ // The offset into the transient constant buffer where the constant data starts.
+ Offset m_constantBufferOffset = 0;
+ Size 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.
+ 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
+ /// fully filled in and finalized.
+ ///
+ Result _getSpecializedLayout(ShaderObjectLayoutImpl** outLayout);
+
+ /// Create the layout for this shader object with specialization arguments considered
+ ///
+ /// This operation is virtual so that it can be customized by `ProgramVars`.
+ ///
+ virtual Result _createSpecializedLayout(ShaderObjectLayoutImpl** outLayout);
+
+ RefPtr<ShaderObjectLayoutImpl> m_specializedLayout;
+};
+
+class MutableShaderObjectImpl
+ : public MutableShaderObject<MutableShaderObjectImpl, ShaderObjectLayoutImpl>
+{};
+
+class EntryPointShaderObject : public ShaderObjectImpl
+{
+ typedef ShaderObjectImpl Super;
+
+public:
+ static Result create(
+ IDevice* device, EntryPointLayout* layout, EntryPointShaderObject** outShaderObject);
+
+ EntryPointLayout* getLayout();
+
+ /// Bind this shader object as an entry point
+ Result bindAsEntryPoint(
+ PipelineCommandEncoder* encoder,
+ RootBindingContext& context,
+ BindingOffset const& inOffset,
+ EntryPointLayout* layout);
+
+protected:
+ Result init(IDevice* device, EntryPointLayout* layout);
+};
+
+class RootShaderObjectImpl : public ShaderObjectImpl
+{
+ using Super = ShaderObjectImpl;
+
+public:
+ // Override default reference counting behavior to disable lifetime management.
+ // Root objects are managed by command buffer and does not need to be freed by the user.
+ virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; }
+ virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; }
+
+public:
+ RootShaderObjectLayout* getLayout();
+
+ RootShaderObjectLayout* getSpecializedLayout();
+
+ List<RefPtr<EntryPointShaderObject>> const& getEntryPoints() const;
+
+ virtual GfxCount SLANG_MCALL getEntryPointCount() override;
+ virtual Result SLANG_MCALL getEntryPoint(GfxIndex index, IShaderObject** outEntryPoint) override;
+
+ virtual SLANG_NO_THROW Result SLANG_MCALL
+ copyFrom(IShaderObject* object, ITransientResourceHeap* transientHeap) override;
+
+ /// Bind this object as a root shader object
+ Result bindAsRoot(
+ PipelineCommandEncoder* encoder,
+ RootBindingContext& context,
+ RootShaderObjectLayout* layout);
+
+ virtual Result collectSpecializationArgs(ExtendedShaderObjectTypeList& args) override;
+
+public:
+ Result init(IDevice* device, RootShaderObjectLayout* layout);
+
+protected:
+ virtual Result _createSpecializedLayout(ShaderObjectLayoutImpl** outLayout) override;
+
+ List<RefPtr<EntryPointShaderObject>> m_entryPoints;
+};
+
+} // namespace vk
+} // namespace gfx