diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..dcf16f8 --- /dev/null +++ b/.clang-format @@ -0,0 +1,244 @@ +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveAssignments: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: true +AlignConsecutiveBitFields: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveMacros: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveShortCaseStatements: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCaseColons: false +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: + Kind: Always + OverEmptyLines: 0 +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowBreakBeforeNoexceptSpecifier: Never +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortCompoundRequirementOnASingleLine: true +AllowShortEnumsOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BitFieldColonSpacing: Both +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterExternBlock: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakAdjacentStringLiterals: true +BreakAfterAttributes: Leave +BreakAfterJavaFieldAnnotations: false +BreakArrays: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: Always +BreakBeforeBraces: Attach +BreakBeforeInlineASMColon: OnlyMultiline +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakInheritanceList: BeforeColon +BreakStringLiterals: true +ColumnLimit: 120 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseBlocks: false +IndentCaseLabels: false +IndentExternBlock: AfterExternBlock +IndentGotoLabels: true +IndentPPDirectives: None +IndentRequiresClause: true +IndentWidth: 2 +IndentWrappedFunctionNames: false +InsertBraces: false +InsertNewlineAtEOF: false +InsertTrailingCommas: None +IntegerLiteralSeparator: + Binary: 0 + BinaryMinDigits: 0 + Decimal: 0 + DecimalMinDigits: 0 + Hex: 0 + HexMinDigits: 0 +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +KeepEmptyLinesAtEOF: false +LambdaBodyIndentation: Signature +LineEnding: DeriveLF +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PackConstructorInitializers: BinPack +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakScopeResolution: 500 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Left +PPIndentWidth: -1 +QualifierAlignment: Leave +ReferenceAlignment: Pointer +ReflowComments: true +RemoveBracesLLVM: false +RemoveParentheses: Leave +RemoveSemicolon: false +RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SkipMacroDefinitionBody: false +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: LexicographicNumeric +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Default +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeJsonColon: false +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + AfterPlacementOperator: true + AfterRequiresInClause: false + AfterRequiresInExpression: false + BeforeNonEmptyParentheses: false +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInContainerLiterals: true +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParens: Never +SpacesInParensOptions: + InCStyleCasts: false + InConditionalStatements: false + InEmptyParentheses: false + Other: false +SpacesInSquareBrackets: false +Standard: Latest +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseTab: Never +VerilogBreakBetweenInstancePorts: true +WhitespaceSensitiveMacros: + - BOOST_PP_STRINGIZE + - CF_SWIFT_NAME + - NS_SWIFT_NAME + - PP_STRINGIZE + - STRINGIZE +... + diff --git a/.vscode/settings.json b/.vscode/settings.json index 615e47b..fd5e29f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -160,4 +160,8 @@ }, "editor.tabSize": 2, "editor.detectIndentation": false, + "lldb.displayFormat": "auto", + "lldb.showDisassembly": "auto", + "lldb.dereferencePointers": true, + "lldb.consoleMode": "commands", } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index f29ecd9..5e8a2d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,10 @@ find_package(Ktx CONFIG REQUIRED) find_package(nlohmann_json CONFIG REQUIRED) find_package(fmt CONFIG REQUIRED) find_package(VulkanMemoryAllocator CONFIG REQUIRED) +find_package(spirv_cross_core CONFIG REQUIRED) +find_package(spirv_cross_glsl CONFIG REQUIRED) +find_package(spirv_cross_msl CONFIG REQUIRED) +find_package(glslang CONFIG REQUIRED) if(UNIX) find_package(Threads REQUIRED) @@ -74,8 +78,9 @@ target_link_libraries(Engine PUBLIC crcpp) target_link_libraries(Engine PUBLIC fmt::fmt) target_link_libraries(Engine PUBLIC GPUOpen::VulkanMemoryAllocator) target_link_libraries(Engine PUBLIC shader-slang) +target_link_libraries(Engine PUBLIC spirv-cross-glsl spirv-cross-msl) +target_link_libraries(Engine PUBLIC glslang::glslang) if(APPLE) - target_link_libraries(Engine PUBLIC /usr/local/lib/libmetalirconverter.dylib) target_link_libraries(Engine PUBLIC metal) SET(CMAKE_OSX_DEPLOYMENT_TARGET 14.3) install(FILES @@ -133,7 +138,6 @@ if(WIN32) elseif(APPLE) add_custom_target(dll_copy ALL COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SLANG_ROOT}bin/libslang.dylib $ - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${EXTERNAL_ROOT}/dxc $ COMMAND_EXPAND_LISTS DEPENDS Editor) else() diff --git a/external/dxc b/external/dxc deleted file mode 100755 index d1aa98b..0000000 Binary files a/external/dxc and /dev/null differ diff --git a/res/shaders/TextPass.slang b/res/shaders/TextPass.slang index 5dfa838..17463b0 100644 --- a/res/shaders/TextPass.slang +++ b/res/shaders/TextPass.slang @@ -9,10 +9,18 @@ struct TextData float4 textColor; float scale; } -ParameterBlock glyphSampler; +struct GlyphSampler +{ + SamplerState s; +} +ParameterBlock glyphSampler; //layout(set = 1) //ShaderBuffer glyphData; -ParameterBuffer[]> pGlyphTextures; +struct GlyphTextures +{ + Texture2D[256] textures; +} +ParameterBlock pGlyphTextures; struct GlyphInstanceData { @@ -25,7 +33,7 @@ struct TextRender StructuredBuffer instances; TextData textData; } -ParameterBuffer pRender; +ParameterBlock pRender; struct VertexInput { @@ -56,9 +64,9 @@ VertexOutput vertexMain(VertexInput input) float4(xpos + w, ypos + h, 1, 0) }; float4 vertex = coordinates[input.vertexId]; - VertexStageOutput output; + VertexOutput output; output.texCoords = vertex.zw; - output.position = mul(viewData.projectionMatrix, float4(vertex.xy, 0, 1)); + output.position = mul(pViewParams.projectionMatrix, float4(vertex.xy, 0, 1)); output.glyphIndex = pRender.instances[input.instanceId].glyphIndex; return output; } @@ -70,5 +78,5 @@ float4 fragmentMain( uint glyphIndex : GLYPHINDEX ) : SV_Target { - return textData.textColor * pGlyphTextures[glyphIndex].Sample(glyphSampler, texCoords); + return pRender.textData.textColor * pGlyphTextures.textures[glyphIndex].Sample(glyphSampler.s, texCoords); } \ No newline at end of file diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index db01d8a..1b5402b 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -48,10 +48,10 @@ int main() #endif GraphicsInitializer initializer; graphics->init(initializer); - graphics->createComputeShader(ShaderCreateInfo { - .entryPoint = "cullLights", - .mainModule = "LightCulling", - .additionalModules = {"LightCulling"}, + graphics->createVertexShader(ShaderCreateInfo { + .entryPoint = "fragmentMain", + .mainModule = "TextPass", + .additionalModules = {"TextPass"}, .name = "Test", }); StaticMeshVertexData* vd = StaticMeshVertexData::getInstance(); diff --git a/src/Engine/Graphics/Buffer.h b/src/Engine/Graphics/Buffer.h index f4e732e..480c7e9 100644 --- a/src/Engine/Graphics/Buffer.h +++ b/src/Engine/Graphics/Buffer.h @@ -1,144 +1,114 @@ #pragma once #include "Resources.h" -namespace Seele -{ -namespace Gfx -{ -class Buffer : public QueueOwnedResource -{ +namespace Seele { +namespace Gfx { +class Buffer : public QueueOwnedResource { public: - Buffer(QueueFamilyMapping mapping, QueueType startQueueType); - virtual ~Buffer(); - virtual void beginFrame() = 0; + Buffer(QueueFamilyMapping mapping, QueueType startQueueType); + virtual ~Buffer(); + protected: - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(QueueType newOwner) = 0; + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; }; -class VertexBuffer : public Buffer -{ +class VertexBuffer : public Buffer { public: - VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType); - virtual ~VertexBuffer(); - constexpr uint32 getNumVertices() const - { - return numVertices; - } - // Size of one vertex in bytes - constexpr uint32 getVertexSize() const - { - return vertexSize; - } + VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType); + virtual ~VertexBuffer(); + constexpr uint32 getNumVertices() const { return numVertices; } + // Size of one vertex in bytes + constexpr uint32 getVertexSize() const { return vertexSize; } + + virtual void updateRegion(DataSource update) = 0; + virtual void download(Array& buffer) = 0; - virtual void updateRegion(DataSource update) = 0; - virtual void download(Array& buffer) = 0; - virtual void beginFrame() = 0; protected: - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(QueueType newOwner) = 0; - virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, - SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; - uint32 numVertices; - uint32 vertexSize; + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; + virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, + SePipelineStageFlags dstStage) = 0; + uint32 numVertices; + uint32 vertexSize; }; DEFINE_REF(VertexBuffer) -class IndexBuffer : public Buffer -{ +class IndexBuffer : public Buffer { public: - IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType index, QueueType startQueueType); - virtual ~IndexBuffer(); - constexpr uint64 getNumIndices() const - { - return numIndices; - } - constexpr Gfx::SeIndexType getIndexType() const - { - return indexType; - } + IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType index, QueueType startQueueType); + virtual ~IndexBuffer(); + constexpr uint64 getNumIndices() const { return numIndices; } + constexpr Gfx::SeIndexType getIndexType() const { return indexType; } + + virtual void download(Array& buffer) = 0; - virtual void download(Array& buffer) = 0; - virtual void beginFrame() = 0; protected: - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(QueueType newOwner) = 0; - virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, - SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; - Gfx::SeIndexType indexType; - uint64 numIndices; + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; + virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, + SePipelineStageFlags dstStage) = 0; + Gfx::SeIndexType indexType; + uint64 numIndices; }; DEFINE_REF(IndexBuffer) DECLARE_REF(UniformBuffer) -class UniformBuffer : public Buffer -{ +class UniformBuffer : public Buffer { public: - UniformBuffer(QueueFamilyMapping mapping, const DataSource& sourceData); - virtual ~UniformBuffer(); - // returns true if an update was performed, false if the old contents == new contents - virtual bool updateContents(const DataSource& sourceData); - bool isDataEquals(PUniformBuffer other) - { - if (other == nullptr) - { - return false; - } - if (contents.size() != other->contents.size()) - { - return false; - } - if (std::memcmp(contents.data(), other->contents.data(), contents.size()) != 0) - { - return false; - } - return true; + UniformBuffer(QueueFamilyMapping mapping, const DataSource& sourceData); + virtual ~UniformBuffer(); + // returns true if an update was performed, false if the old contents == new contents + virtual bool updateContents(const DataSource& sourceData); + bool isDataEquals(PUniformBuffer other) { + if (other == nullptr) { + return false; } - virtual void beginFrame() = 0; + if (contents.size() != other->contents.size()) { + return false; + } + if (std::memcmp(contents.data(), other->contents.data(), contents.size()) != 0) { + return false; + } + return true; + } + protected: - Array contents; - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(QueueType newOwner) = 0; - virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, - SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; + Array contents; + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; + virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, + SePipelineStageFlags dstStage) = 0; }; DEFINE_REF(UniformBuffer) -class ShaderBuffer : public Buffer -{ +class ShaderBuffer : public Buffer { public: - ShaderBuffer(QueueFamilyMapping mapping, uint32 numElements, const DataSource& bulkResourceData); - virtual ~ShaderBuffer(); - virtual bool updateContents(const DataSource& sourceData); - bool isDataEquals(ShaderBuffer* other) - { - if(other == nullptr) - { - return false; - } - if(contents.size() != other->contents.size()) - { - return false; - } - if(std::memcmp(contents.data(), other->contents.data(), contents.size()) != 0) - { - return false; - } - return true; + ShaderBuffer(QueueFamilyMapping mapping, uint32 numElements, const DataSource& bulkResourceData); + virtual ~ShaderBuffer(); + virtual bool updateContents(const DataSource& sourceData); + bool isDataEquals(ShaderBuffer* other) { + if (other == nullptr) { + return false; } - constexpr uint32 getNumElements() const - { - return numElements; + if (contents.size() != other->contents.size()) { + return false; } - virtual void beginFrame() = 0; + if (std::memcmp(contents.data(), other->contents.data(), contents.size()) != 0) { + return false; + } + return true; + } + constexpr uint32 getNumElements() const { return numElements; } + protected: - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(QueueType newOwner) = 0; - virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, - SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; - - Array contents; - uint32 numElements; + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; + virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, + SePipelineStageFlags dstStage) = 0; + + Array contents; + uint32 numElements; }; DEFINE_REF(ShaderBuffer) -} -} \ No newline at end of file +} // namespace Gfx +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/Descriptor.cpp b/src/Engine/Graphics/Descriptor.cpp index 0cf9030..7afc611 100644 --- a/src/Engine/Graphics/Descriptor.cpp +++ b/src/Engine/Graphics/Descriptor.cpp @@ -3,99 +3,70 @@ using namespace Seele; using namespace Seele::Gfx; -DescriptorPool::DescriptorPool() -{ +DescriptorLayout::DescriptorLayout(const std::string& name) : setIndex(0), name(name) {} + +DescriptorLayout::DescriptorLayout(const DescriptorLayout& other) { + descriptorBindings.resize(other.descriptorBindings.size()); + for (uint32 i = 0; i < descriptorBindings.size(); ++i) { + descriptorBindings[i] = other.descriptorBindings[i]; + } } -DescriptorPool::~DescriptorPool() -{ +DescriptorLayout& DescriptorLayout::operator=(const DescriptorLayout& other) { + if (this != &other) { + descriptorBindings.resize(other.descriptorBindings.size()); + for (uint32 i = 0; i < descriptorBindings.size(); ++i) { + descriptorBindings[i] = other.descriptorBindings[i]; + } + } + return *this; } -DescriptorLayout::DescriptorLayout(const std::string& name) - : setIndex(0) - , name(name) -{ +DescriptorLayout::~DescriptorLayout() {} + +void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorType type, uint32 arrayCount, + SeDescriptorBindingFlags bindingFlags, SeShaderStageFlags shaderStages) { + if (descriptorBindings.size() <= bindingIndex) { + descriptorBindings.resize(bindingIndex + 1); + } + descriptorBindings[bindingIndex] = DescriptorBinding{ + .binding = bindingIndex, + .descriptorType = type, + .descriptorCount = arrayCount, + .bindingFlags = bindingFlags, + .shaderStages = shaderStages, + }; } -DescriptorLayout::DescriptorLayout(const DescriptorLayout& other) -{ - descriptorBindings.resize(other.descriptorBindings.size()); - for (uint32 i = 0; i < descriptorBindings.size(); ++i) - { - descriptorBindings[i] = other.descriptorBindings[i]; - } +PDescriptorSet DescriptorLayout::allocateDescriptorSet() { return pool->allocateDescriptorSet(); } + +void DescriptorLayout::reset() { pool->reset(); } + +DescriptorPool::DescriptorPool() {} + +DescriptorPool::~DescriptorPool() {} + +DescriptorSet::DescriptorSet(PDescriptorLayout layout) : layout(layout) {} + +DescriptorSet::~DescriptorSet() {} + +PipelineLayout::PipelineLayout() {} + +PipelineLayout::PipelineLayout(PPipelineLayout baseLayout) { + if (baseLayout != nullptr) { + descriptorSetLayouts = baseLayout->descriptorSetLayouts; + pushConstants = baseLayout->pushConstants; + } } -DescriptorLayout& DescriptorLayout::operator=(const DescriptorLayout& other) -{ - if (this != &other) - { - descriptorBindings.resize(other.descriptorBindings.size()); - for (uint32 i = 0; i < descriptorBindings.size(); ++i) - { - descriptorBindings[i] = other.descriptorBindings[i]; - } - } - return *this; +PipelineLayout::~PipelineLayout() {} + +void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout) { + if (descriptorSetLayouts.size() <= setIndex) { + descriptorSetLayouts.resize(setIndex + 1); + } + descriptorSetLayouts[setIndex] = layout; + layout->setIndex = setIndex; } -DescriptorLayout::~DescriptorLayout() -{ -} - -void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorType type, uint32 arrayCount, SeDescriptorBindingFlags bindingFlags, SeShaderStageFlags shaderStages) -{ - if (descriptorBindings.size() <= bindingIndex) - { - descriptorBindings.resize(bindingIndex + 1); - } - descriptorBindings[bindingIndex] = DescriptorBinding{ - .binding = bindingIndex, - .descriptorType = type, - .descriptorCount = arrayCount, - .bindingFlags = bindingFlags, - .shaderStages = shaderStages, - }; -} - -PDescriptorSet DescriptorLayout::allocateDescriptorSet() -{ - return pool->allocateDescriptorSet(); -} - -void DescriptorLayout::reset() -{ - pool->reset(); -} - -PipelineLayout::PipelineLayout() -{ -} - -PipelineLayout::PipelineLayout(PPipelineLayout baseLayout) -{ - if (baseLayout != nullptr) - { - descriptorSetLayouts = baseLayout->descriptorSetLayouts; - pushConstants = baseLayout->pushConstants; - } -} - -PipelineLayout::~PipelineLayout() -{ -} - -void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout) -{ - if (descriptorSetLayouts.size() <= setIndex) - { - descriptorSetLayouts.resize(setIndex + 1); - } - descriptorSetLayouts[setIndex] = layout; - layout->setIndex = setIndex; -} - -void PipelineLayout::addPushConstants(const SePushConstantRange& pushConstant) -{ - pushConstants.add(pushConstant); -} +void PipelineLayout::addPushConstants(const SePushConstantRange& pushConstant) { pushConstants.add(pushConstant); } diff --git a/src/Engine/Graphics/Descriptor.h b/src/Engine/Graphics/Descriptor.h index 9fdff76..ca5e700 100644 --- a/src/Engine/Graphics/Descriptor.h +++ b/src/Engine/Graphics/Descriptor.h @@ -1,93 +1,96 @@ #pragma once #include "Enums.h" #include "Resources.h" +#include -namespace Seele -{ -namespace Gfx -{ -struct DescriptorBinding -{ - uint32 binding = 0; - SeDescriptorType descriptorType = SE_DESCRIPTOR_TYPE_MAX_ENUM; - uint32 descriptorCount = 0x7fff; - SeDescriptorBindingFlags bindingFlags = 0; - SeShaderStageFlags shaderStages = SE_SHADER_STAGE_ALL; +namespace Seele { +namespace Gfx { +struct DescriptorBinding { + uint32 binding = 0; + SeDescriptorType descriptorType = SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + uint32 descriptorCount = 0x7fff; + SeDescriptorBindingFlags bindingFlags = 0; + SeShaderStageFlags shaderStages = SE_SHADER_STAGE_ALL; + Gfx::SeDescriptorAccessTypeFlags access = SE_DESCRIPTOR_ACCESS_READ_ONLY_BIT; }; -DEFINE_REF(DescriptorBinding) + +DECLARE_REF(DescriptorPool) +DECLARE_REF(DescriptorSet) +class DescriptorLayout { +public: + DescriptorLayout(const std::string& name); + DescriptorLayout(const DescriptorLayout& other); + DescriptorLayout& operator=(const DescriptorLayout& other); + virtual ~DescriptorLayout(); + void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1, + SeDescriptorBindingFlags bindingFlags = 0, + SeShaderStageFlags shaderStages = SeShaderStageFlagBits::SE_SHADER_STAGE_ALL); + void reset(); + PDescriptorSet allocateDescriptorSet(); + virtual void create() = 0; + constexpr const Array& getBindings() const { return descriptorBindings; } + constexpr uint32 getSetIndex() const { return setIndex; } + constexpr void setSetIndex(uint32 _setIndex) { setIndex = _setIndex; } + constexpr uint32 getHash() const { return hash; } + +protected: + Array descriptorBindings; + ODescriptorPool pool; + uint32 setIndex; + std::string name; + uint32 hash = 0; + friend class PipelineLayout; + friend class DescriptorPool; +}; +DEFINE_REF(DescriptorLayout) DECLARE_REF(DescriptorSet) -class DescriptorPool -{ +class DescriptorPool { public: - DescriptorPool(); - virtual ~DescriptorPool(); - virtual PDescriptorSet allocateDescriptorSet() = 0; - virtual void reset() = 0; + DescriptorPool(); + virtual ~DescriptorPool(); + virtual PDescriptorSet allocateDescriptorSet() = 0; + virtual void reset() = 0; }; DEFINE_REF(DescriptorPool) DECLARE_REF(UniformBuffer) DECLARE_REF(ShaderBuffer) DECLARE_REF(Texture) DECLARE_REF(Sampler) -class DescriptorSet -{ +class DescriptorSet { public: - DescriptorSet() {} - virtual ~DescriptorSet() {} - virtual void writeChanges() = 0; - virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0; - virtual void updateBuffer(uint32 binding, PShaderBuffer ShaderBuffer) = 0; - virtual void updateSampler(uint32 binding, PSampler sampler) = 0; - virtual void updateTexture(uint32 binding, PTexture texture, PSampler samplerState = nullptr) = 0; - virtual void updateTextureArray(uint32_t binding, Array texture) = 0; - virtual bool operator<(PDescriptorSet other) = 0; + DescriptorSet(PDescriptorLayout layout); + virtual ~DescriptorSet(); + virtual void writeChanges() = 0; + virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0; + virtual void updateBuffer(uint32 binding, PShaderBuffer ShaderBuffer) = 0; + virtual void updateSampler(uint32 binding, PSampler sampler) = 0; + virtual void updateTexture(uint32 binding, PTexture texture, PSampler samplerState = nullptr) = 0; + virtual void updateTextureArray(uint32_t binding, Array texture) = 0; + bool operator<(PDescriptorSet other); - virtual uint32 getSetIndex() const = 0; + constexpr uint32 getSetIndex() const { return layout->getSetIndex(); } + +protected: + PDescriptorLayout layout; }; DEFINE_REF(DescriptorSet) -class DescriptorLayout -{ +class PipelineLayout { public: - DescriptorLayout(const std::string& name); - DescriptorLayout(const DescriptorLayout& other); - DescriptorLayout& operator=(const DescriptorLayout& other); - virtual ~DescriptorLayout(); - virtual void create() = 0; - virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1, SeDescriptorBindingFlags bindingFlags = 0, SeShaderStageFlags shaderStages = SeShaderStageFlagBits::SE_SHADER_STAGE_ALL); - virtual void reset(); - virtual PDescriptorSet allocateDescriptorSet(); - constexpr const Array& getBindings() const { return descriptorBindings; } - constexpr uint32 getSetIndex() const { return setIndex; } - constexpr void setSetIndex(uint32 _setIndex) { setIndex = _setIndex; } + PipelineLayout(); + PipelineLayout(PPipelineLayout baseLayout); + virtual ~PipelineLayout(); + virtual void create() = 0; + void addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout); + void addPushConstants(const SePushConstantRange& pushConstants); + constexpr uint32 getHash() const { return layoutHash; } protected: - Array descriptorBindings; - ODescriptorPool pool; - uint32 setIndex; - std::string name; - friend class PipelineLayout; - friend class DescriptorPool; -}; -DEFINE_REF(DescriptorLayout) -class PipelineLayout -{ -public: - PipelineLayout(); - PipelineLayout(PPipelineLayout baseLayout); - virtual ~PipelineLayout(); - virtual void create() = 0; - virtual void reset() = 0; - void addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout); - void addPushConstants(const SePushConstantRange& pushConstants); - constexpr uint32 getHash() const { return layoutHash; } - -protected: - uint32 layoutHash; - Array descriptorSetLayouts; - Array pushConstants; + uint32 layoutHash = 0; + Array descriptorSetLayouts; + Array pushConstants; }; DEFINE_REF(PipelineLayout) -} -} +} // namespace Gfx +} // namespace Seele diff --git a/src/Engine/Graphics/Enums.h b/src/Engine/Graphics/Enums.h index 788b9f6..3ebe399 100644 --- a/src/Engine/Graphics/Enums.h +++ b/src/Engine/Graphics/Enums.h @@ -219,12 +219,6 @@ typedef enum SeResult SE_ERROR_NOT_PERMITTED_EXT = -1000174001, SE_ERROR_INVALID_DEVICE_ADDRESS_EXT = -1000244000, SE_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT = -1000255000, - SE_ERROR_OUT_OF_POOL_MEMORY_KHR = SE_ERROR_OUT_OF_POOL_MEMORY, - SE_ERROR_INVALID_EXTERNAL_HANDLE_KHR = SE_ERROR_INVALID_EXTERNAL_HANDLE, - SE_RESULT_BEGIN_RANGE = SE_ERROR_FRAGMENTED_POOL, - SE_RESULT_END_RANGE = SE_INCOMPLETE, - SE_RESULT_RANGE_SIZE = (SE_INCOMPLETE - SE_ERROR_FRAGMENTED_POOL + 1), - SE_RESULT_MAX_ENUM = 0x7FFFFFFF } SeResult; typedef enum SeStructureType @@ -602,76 +596,6 @@ typedef enum SeStructureType SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = 1000276000, SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000, SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = 1000281001, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, - SE_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = SE_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, - SE_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = SE_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, - SE_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR = SE_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, - SE_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR = SE_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, - SE_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR = SE_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2, - SE_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR = SE_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2, - SE_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR = SE_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO, - SE_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO_KHR = SE_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO, - SE_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO_KHR = SE_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO, - SE_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHR = SE_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO, - SE_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO_KHR = SE_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO, - SE_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR = SE_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO, - SE_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR = SE_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES, - SE_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR = SE_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, - SE_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR = SE_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO, - SE_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR = SE_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES, - SE_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR = SE_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO, - SE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR = SE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, - SE_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR = SE_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO, - SE_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR = SE_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES, - SE_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR = SE_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, - SE_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = SE_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, - SE_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT = SE_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO, - SE_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR = SE_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES, - SE_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR = SE_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES, - SE_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR = SE_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO, - SE_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR = SE_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, - SE_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO_KHR = SE_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES, - SE_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR = SE_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, - SE_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = SE_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, - SE_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = SE_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, - SE_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = SE_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, - SE_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = SE_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2, - SE_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR = SE_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, - SE_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = SE_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2, - SE_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR = SE_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO, - SE_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR = SE_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, - SE_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR = SE_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO, - SE_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR = SE_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, - SE_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR = SE_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES, - SE_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR = SE_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO, - SE_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR = SE_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, - SE_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = SE_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT, - SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = SE_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, - SE_STRUCTURE_TYPE_BEGIN_RANGE = SE_STRUCTURE_TYPE_APPLICATION_INFO, - SE_STRUCTURE_TYPE_END_RANGE = SE_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO, - SE_STRUCTURE_TYPE_RANGE_SIZE = (SE_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - SE_STRUCTURE_TYPE_APPLICATION_INFO + 1), - SE_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF } SeStructureType; typedef enum SeSystemAllocationScope @@ -681,19 +605,11 @@ typedef enum SeSystemAllocationScope SE_SYSTEM_ALLOCATION_SCOPE_CACHE = 2, SE_SYSTEM_ALLOCATION_SCOPE_DEVICE = 3, SE_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4, - SE_SYSTEM_ALLOCATION_SCOPE_BEGIN_RANGE = SE_SYSTEM_ALLOCATION_SCOPE_COMMAND, - SE_SYSTEM_ALLOCATION_SCOPE_END_RANGE = SE_SYSTEM_ALLOCATION_SCOPE_INSTANCE, - SE_SYSTEM_ALLOCATION_SCOPE_RANGE_SIZE = (SE_SYSTEM_ALLOCATION_SCOPE_INSTANCE - SE_SYSTEM_ALLOCATION_SCOPE_COMMAND + 1), - SE_SYSTEM_ALLOCATION_SCOPE_MAX_ENUM = 0x7FFFFFFF } SeSystemAllocationScope; typedef enum SeInternalAllocationType { SE_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0, - SE_INTERNAL_ALLOCATION_TYPE_BEGIN_RANGE = SE_INTERNAL_ALLOCATION_TYPE_EXECUTABLE, - SE_INTERNAL_ALLOCATION_TYPE_END_RANGE = SE_INTERNAL_ALLOCATION_TYPE_EXECUTABLE, - SE_INTERNAL_ALLOCATION_TYPE_RANGE_SIZE = (SE_INTERNAL_ALLOCATION_TYPE_EXECUTABLE - SE_INTERNAL_ALLOCATION_TYPE_EXECUTABLE + 1), - SE_INTERNAL_ALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF } SeInternalAllocationType; typedef enum SeFormat @@ -939,10 +855,6 @@ typedef enum SeFormat SE_FORMAT_ASTC_10x10_SFLOAT_BLOCK = 1000066011, SE_FORMAT_ASTC_12x10_SFLOAT_BLOCK = 1000066012, SE_FORMAT_ASTC_12x12_SFLOAT_BLOCK = 1000066013, - SE_FORMAT_BEGIN_RANGE = SE_FORMAT_UNDEFINED, - SE_FORMAT_END_RANGE = SE_FORMAT_ASTC_12x12_SRGB_BLOCK, - SE_FORMAT_RANGE_SIZE = (SE_FORMAT_ASTC_12x12_SRGB_BLOCK - SE_FORMAT_UNDEFINED + 1), - SE_FORMAT_MAX_ENUM = 0x7FFFFFFF } SeFormat; struct FormatCompatibilityInfo @@ -960,21 +872,12 @@ typedef enum SeImageType SE_IMAGE_TYPE_1D = 0, SE_IMAGE_TYPE_2D = 1, SE_IMAGE_TYPE_3D = 2, - SE_IMAGE_TYPE_BEGIN_RANGE = SE_IMAGE_TYPE_1D, - SE_IMAGE_TYPE_END_RANGE = SE_IMAGE_TYPE_3D, - SE_IMAGE_TYPE_RANGE_SIZE = (SE_IMAGE_TYPE_3D - SE_IMAGE_TYPE_1D + 1), - SE_IMAGE_TYPE_MAX_ENUM = 0x7FFFFFFF } SeImageType; typedef enum SeImageTiling { SE_IMAGE_TILING_OPTIMAL = 0, SE_IMAGE_TILING_LINEAR = 1, - SE_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT = 1000158000, - SE_IMAGE_TILING_BEGIN_RANGE = SE_IMAGE_TILING_OPTIMAL, - SE_IMAGE_TILING_END_RANGE = SE_IMAGE_TILING_LINEAR, - SE_IMAGE_TILING_RANGE_SIZE = (SE_IMAGE_TILING_LINEAR - SE_IMAGE_TILING_OPTIMAL + 1), - SE_IMAGE_TILING_MAX_ENUM = 0x7FFFFFFF } SeImageTiling; typedef enum SePhysicalDeviceType @@ -984,10 +887,6 @@ typedef enum SePhysicalDeviceType SE_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2, SE_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3, SE_PHYSICAL_DEVICE_TYPE_CPU = 4, - SE_PHYSICAL_DEVICE_TYPE_BEGIN_RANGE = SE_PHYSICAL_DEVICE_TYPE_OTHER, - SE_PHYSICAL_DEVICE_TYPE_END_RANGE = SE_PHYSICAL_DEVICE_TYPE_CPU, - SE_PHYSICAL_DEVICE_TYPE_RANGE_SIZE = (SE_PHYSICAL_DEVICE_TYPE_CPU - SE_PHYSICAL_DEVICE_TYPE_OTHER + 1), - SE_PHYSICAL_DEVICE_TYPE_MAX_ENUM = 0x7FFFFFFF } SePhysicalDeviceType; typedef enum SeQueryType @@ -998,20 +897,12 @@ typedef enum SeQueryType SE_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT = 1000028004, SE_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV = 1000165000, SE_QUERY_TYPE_PERFORMANCE_QUERY_INTEL = 1000210000, - SE_QUERY_TYPE_BEGIN_RANGE = SE_QUERY_TYPE_OCCLUSION, - SE_QUERY_TYPE_END_RANGE = SE_QUERY_TYPE_TIMESTAMP, - SE_QUERY_TYPE_RANGE_SIZE = (SE_QUERY_TYPE_TIMESTAMP - SE_QUERY_TYPE_OCCLUSION + 1), - SE_QUERY_TYPE_MAX_ENUM = 0x7FFFFFFF } SeQueryType; typedef enum SeSharingMode { SE_SHARING_MODE_EXCLUSIVE = 0, SE_SHARING_MODE_CONCURRENT = 1, - SE_SHARING_MODE_BEGIN_RANGE = SE_SHARING_MODE_EXCLUSIVE, - SE_SHARING_MODE_END_RANGE = SE_SHARING_MODE_CONCURRENT, - SE_SHARING_MODE_RANGE_SIZE = (SE_SHARING_MODE_CONCURRENT - SE_SHARING_MODE_EXCLUSIVE + 1), - SE_SHARING_MODE_MAX_ENUM = 0x7FFFFFFF } SeSharingMode; typedef enum SeImageLayout @@ -1031,12 +922,6 @@ typedef enum SeImageLayout SE_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000, SE_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = 1000164003, SE_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT = 1000218000, - SE_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = SE_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, - SE_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = SE_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, - SE_IMAGE_LAYOUT_BEGIN_RANGE = SE_IMAGE_LAYOUT_UNDEFINED, - SE_IMAGE_LAYOUT_END_RANGE = SE_IMAGE_LAYOUT_PREINITIALIZED, - SE_IMAGE_LAYOUT_RANGE_SIZE = (SE_IMAGE_LAYOUT_PREINITIALIZED - SE_IMAGE_LAYOUT_UNDEFINED + 1), - SE_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF } SeImageLayout; typedef enum SeImageViewType @@ -1048,10 +933,6 @@ typedef enum SeImageViewType SE_IMAGE_VIEW_TYPE_1D_ARRAY = 4, SE_IMAGE_VIEW_TYPE_2D_ARRAY = 5, SE_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6, - SE_IMAGE_VIEW_TYPE_BEGIN_RANGE = SE_IMAGE_VIEW_TYPE_1D, - SE_IMAGE_VIEW_TYPE_END_RANGE = SE_IMAGE_VIEW_TYPE_CUBE_ARRAY, - SE_IMAGE_VIEW_TYPE_RANGE_SIZE = (SE_IMAGE_VIEW_TYPE_CUBE_ARRAY - SE_IMAGE_VIEW_TYPE_1D + 1), - SE_IMAGE_VIEW_TYPE_MAX_ENUM = 0x7FFFFFFF } SeImageViewType; typedef enum SeComponentSwizzle @@ -1063,20 +944,12 @@ typedef enum SeComponentSwizzle SE_COMPONENT_SWIZZLE_G = 4, SE_COMPONENT_SWIZZLE_B = 5, SE_COMPONENT_SWIZZLE_A = 6, - SE_COMPONENT_SWIZZLE_BEGIN_RANGE = SE_COMPONENT_SWIZZLE_IDENTITY, - SE_COMPONENT_SWIZZLE_END_RANGE = SE_COMPONENT_SWIZZLE_A, - SE_COMPONENT_SWIZZLE_RANGE_SIZE = (SE_COMPONENT_SWIZZLE_A - SE_COMPONENT_SWIZZLE_IDENTITY + 1), - SE_COMPONENT_SWIZZLE_MAX_ENUM = 0x7FFFFFFF } SeComponentSwizzle; typedef enum SeVertexInputRate { SE_VERTEX_INPUT_RATE_VERTEX = 0, SE_VERTEX_INPUT_RATE_INSTANCE = 1, - SE_VERTEX_INPUT_RATE_BEGIN_RANGE = SE_VERTEX_INPUT_RATE_VERTEX, - SE_VERTEX_INPUT_RATE_END_RANGE = SE_VERTEX_INPUT_RATE_INSTANCE, - SE_VERTEX_INPUT_RATE_RANGE_SIZE = (SE_VERTEX_INPUT_RATE_INSTANCE - SE_VERTEX_INPUT_RATE_VERTEX + 1), - SE_VERTEX_INPUT_RATE_MAX_ENUM = 0x7FFFFFFF } SeVertexInputRate; typedef enum SePrimitiveTopology @@ -1092,10 +965,6 @@ typedef enum SePrimitiveTopology SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY = 8, SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY = 9, SE_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10, - SE_PRIMITIVE_TOPOLOGY_BEGIN_RANGE = SE_PRIMITIVE_TOPOLOGY_POINT_LIST, - SE_PRIMITIVE_TOPOLOGY_END_RANGE = SE_PRIMITIVE_TOPOLOGY_PATCH_LIST, - SE_PRIMITIVE_TOPOLOGY_RANGE_SIZE = (SE_PRIMITIVE_TOPOLOGY_PATCH_LIST - SE_PRIMITIVE_TOPOLOGY_POINT_LIST + 1), - SE_PRIMITIVE_TOPOLOGY_MAX_ENUM = 0x7FFFFFFF } SePrimitiveTopology; typedef enum SePolygonMode @@ -1104,20 +973,12 @@ typedef enum SePolygonMode SE_POLYGON_MODE_LINE = 1, SE_POLYGON_MODE_POINT = 2, SE_POLYGON_MODE_FILL_RECTANGLE_NV = 1000153000, - SE_POLYGON_MODE_BEGIN_RANGE = SE_POLYGON_MODE_FILL, - SE_POLYGON_MODE_END_RANGE = SE_POLYGON_MODE_POINT, - SE_POLYGON_MODE_RANGE_SIZE = (SE_POLYGON_MODE_POINT - SE_POLYGON_MODE_FILL + 1), - SE_POLYGON_MODE_MAX_ENUM = 0x7FFFFFFF } SePolygonMode; typedef enum SeFrontFace { SE_FRONT_FACE_COUNTER_CLOCKWISE = 0, SE_FRONT_FACE_CLOCKWISE = 1, - SE_FRONT_FACE_BEGIN_RANGE = SE_FRONT_FACE_COUNTER_CLOCKWISE, - SE_FRONT_FACE_END_RANGE = SE_FRONT_FACE_CLOCKWISE, - SE_FRONT_FACE_RANGE_SIZE = (SE_FRONT_FACE_CLOCKWISE - SE_FRONT_FACE_COUNTER_CLOCKWISE + 1), - SE_FRONT_FACE_MAX_ENUM = 0x7FFFFFFF } SeFrontFace; typedef enum SeCompareOp @@ -1130,10 +991,6 @@ typedef enum SeCompareOp SE_COMPARE_OP_NOT_EQUAL = 5, SE_COMPARE_OP_GREATER_OR_EQUAL = 6, SE_COMPARE_OP_ALWAYS = 7, - SE_COMPARE_OP_BEGIN_RANGE = SE_COMPARE_OP_NEVER, - SE_COMPARE_OP_END_RANGE = SE_COMPARE_OP_ALWAYS, - SE_COMPARE_OP_RANGE_SIZE = (SE_COMPARE_OP_ALWAYS - SE_COMPARE_OP_NEVER + 1), - SE_COMPARE_OP_MAX_ENUM = 0x7FFFFFFF } SeCompareOp; typedef enum SeStencilOp @@ -1146,10 +1003,6 @@ typedef enum SeStencilOp SE_STENCIL_OP_INVERT = 5, SE_STENCIL_OP_INCREMENT_AND_WRAP = 6, SE_STENCIL_OP_DECREMENT_AND_WRAP = 7, - SE_STENCIL_OP_BEGIN_RANGE = SE_STENCIL_OP_KEEP, - SE_STENCIL_OP_END_RANGE = SE_STENCIL_OP_DECREMENT_AND_WRAP, - SE_STENCIL_OP_RANGE_SIZE = (SE_STENCIL_OP_DECREMENT_AND_WRAP - SE_STENCIL_OP_KEEP + 1), - SE_STENCIL_OP_MAX_ENUM = 0x7FFFFFFF } SeStencilOp; typedef enum SeLogicOp @@ -1170,10 +1023,6 @@ typedef enum SeLogicOp SE_LOGIC_OP_OR_INVERTED = 13, SE_LOGIC_OP_NAND = 14, SE_LOGIC_OP_SET = 15, - SE_LOGIC_OP_BEGIN_RANGE = SE_LOGIC_OP_CLEAR, - SE_LOGIC_OP_END_RANGE = SE_LOGIC_OP_SET, - SE_LOGIC_OP_RANGE_SIZE = (SE_LOGIC_OP_SET - SE_LOGIC_OP_CLEAR + 1), - SE_LOGIC_OP_MAX_ENUM = 0x7FFFFFFF } SeLogicOp; typedef enum SeBlendFactor @@ -1197,10 +1046,6 @@ typedef enum SeBlendFactor SE_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR = 16, SE_BLEND_FACTOR_SRC1_ALPHA = 17, SE_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA = 18, - SE_BLEND_FACTOR_BEGIN_RANGE = SE_BLEND_FACTOR_ZERO, - SE_BLEND_FACTOR_END_RANGE = SE_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, - SE_BLEND_FACTOR_RANGE_SIZE = (SE_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA - SE_BLEND_FACTOR_ZERO + 1), - SE_BLEND_FACTOR_MAX_ENUM = 0x7FFFFFFF } SeBlendFactor; typedef enum SeBlendOp @@ -1256,10 +1101,6 @@ typedef enum SeBlendOp SE_BLEND_OP_RED_EXT = 1000148043, SE_BLEND_OP_GREEN_EXT = 1000148044, SE_BLEND_OP_BLUE_EXT = 1000148045, - SE_BLEND_OP_BEGIN_RANGE = SE_BLEND_OP_ADD, - SE_BLEND_OP_END_RANGE = SE_BLEND_OP_MAX, - SE_BLEND_OP_RANGE_SIZE = (SE_BLEND_OP_MAX - SE_BLEND_OP_ADD + 1), - SE_BLEND_OP_MAX_ENUM = 0x7FFFFFFF } SeBlendOp; typedef enum SeDynamicState @@ -1280,10 +1121,6 @@ typedef enum SeDynamicState SE_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV = 1000164006, SE_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV = 1000205001, SE_DYNAMIC_STATE_LINE_STIPPLE_EXT = 1000259000, - SE_DYNAMIC_STATE_BEGIN_RANGE = SE_DYNAMIC_STATE_VIEWPORT, - SE_DYNAMIC_STATE_END_RANGE = SE_DYNAMIC_STATE_STENCIL_REFERENCE, - SE_DYNAMIC_STATE_RANGE_SIZE = (SE_DYNAMIC_STATE_STENCIL_REFERENCE - SE_DYNAMIC_STATE_VIEWPORT + 1), - SE_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF } SeDynamicState; typedef enum SeFilter @@ -1291,21 +1128,12 @@ typedef enum SeFilter SE_FILTER_NEAREST = 0, SE_FILTER_LINEAR = 1, SE_FILTER_CUBIC_IMG = 1000015000, - SE_FILTER_CUBIC_EXT = SE_FILTER_CUBIC_IMG, - SE_FILTER_BEGIN_RANGE = SE_FILTER_NEAREST, - SE_FILTER_END_RANGE = SE_FILTER_LINEAR, - SE_FILTER_RANGE_SIZE = (SE_FILTER_LINEAR - SE_FILTER_NEAREST + 1), - SE_FILTER_MAX_ENUM = 0x7FFFFFFF } SeFilter; typedef enum SeSamplerMipmapMode { SE_SAMPLER_MIPMAP_MODE_NEAREST = 0, SE_SAMPLER_MIPMAP_MODE_LINEAR = 1, - SE_SAMPLER_MIPMAP_MODE_BEGIN_RANGE = SE_SAMPLER_MIPMAP_MODE_NEAREST, - SE_SAMPLER_MIPMAP_MODE_END_RANGE = SE_SAMPLER_MIPMAP_MODE_LINEAR, - SE_SAMPLER_MIPMAP_MODE_RANGE_SIZE = (SE_SAMPLER_MIPMAP_MODE_LINEAR - SE_SAMPLER_MIPMAP_MODE_NEAREST + 1), - SE_SAMPLER_MIPMAP_MODE_MAX_ENUM = 0x7FFFFFFF } SeSamplerMipmapMode; typedef enum SeSamplerAddressMode @@ -1315,11 +1143,6 @@ typedef enum SeSamplerAddressMode SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE = 2, SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER = 3, SE_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE = 4, - SE_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE_KHR = SE_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, - SE_SAMPLER_ADDRESS_MODE_BEGIN_RANGE = SE_SAMPLER_ADDRESS_MODE_REPEAT, - SE_SAMPLER_ADDRESS_MODE_END_RANGE = SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, - SE_SAMPLER_ADDRESS_MODE_RANGE_SIZE = (SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER - SE_SAMPLER_ADDRESS_MODE_REPEAT + 1), - SE_SAMPLER_ADDRESS_MODE_MAX_ENUM = 0x7FFFFFFF } SeSamplerAddressMode; typedef enum SeBorderColor @@ -1330,10 +1153,6 @@ typedef enum SeBorderColor SE_BORDER_COLOR_INT_OPAQUE_BLACK = 3, SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE = 4, SE_BORDER_COLOR_INT_OPAQUE_WHITE = 5, - SE_BORDER_COLOR_BEGIN_RANGE = SE_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, - SE_BORDER_COLOR_END_RANGE = SE_BORDER_COLOR_INT_OPAQUE_WHITE, - SE_BORDER_COLOR_RANGE_SIZE = (SE_BORDER_COLOR_INT_OPAQUE_WHITE - SE_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK + 1), - SE_BORDER_COLOR_MAX_ENUM = 0x7FFFFFFF } SeBorderColor; typedef enum SeDescriptorType @@ -1351,10 +1170,6 @@ typedef enum SeDescriptorType SE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, SE_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = 1000138000, SE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, - SE_DESCRIPTOR_TYPE_BEGIN_RANGE = SE_DESCRIPTOR_TYPE_SAMPLER, - SE_DESCRIPTOR_TYPE_END_RANGE = SE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, - SE_DESCRIPTOR_TYPE_RANGE_SIZE = (SE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT - SE_DESCRIPTOR_TYPE_SAMPLER + 1), - SE_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF } SeDescriptorType; typedef enum SeDescriptorBindingFlagBits { @@ -1362,11 +1177,6 @@ typedef enum SeDescriptorBindingFlagBits { SE_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT = 0x00000002, SE_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT = 0x00000004, SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT = 0x00000008, - SE_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = SE_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, - SE_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = SE_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT, - SE_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = SE_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT, - SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT, - SE_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } SeDescriptorBindingFlagBits; typedef SeFlags SeDescriptorBindingFlags; @@ -1375,20 +1185,12 @@ typedef enum SeAttachmentLoadOp SE_ATTACHMENT_LOAD_OP_LOAD = 0, SE_ATTACHMENT_LOAD_OP_CLEAR = 1, SE_ATTACHMENT_LOAD_OP_DONT_CARE = 2, - SE_ATTACHMENT_LOAD_OP_BEGIN_RANGE = SE_ATTACHMENT_LOAD_OP_LOAD, - SE_ATTACHMENT_LOAD_OP_END_RANGE = SE_ATTACHMENT_LOAD_OP_DONT_CARE, - SE_ATTACHMENT_LOAD_OP_RANGE_SIZE = (SE_ATTACHMENT_LOAD_OP_DONT_CARE - SE_ATTACHMENT_LOAD_OP_LOAD + 1), - SE_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF } SeAttachmentLoadOp; typedef enum SeAttachmentStoreOp { SE_ATTACHMENT_STORE_OP_STORE = 0, SE_ATTACHMENT_STORE_OP_DONT_CARE = 1, - SE_ATTACHMENT_STORE_OP_BEGIN_RANGE = SE_ATTACHMENT_STORE_OP_STORE, - SE_ATTACHMENT_STORE_OP_END_RANGE = SE_ATTACHMENT_STORE_OP_DONT_CARE, - SE_ATTACHMENT_STORE_OP_RANGE_SIZE = (SE_ATTACHMENT_STORE_OP_DONT_CARE - SE_ATTACHMENT_STORE_OP_STORE + 1), - SE_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF } SeAttachmentStoreOp; typedef enum SePipelineBindPoint @@ -1396,20 +1198,12 @@ typedef enum SePipelineBindPoint SE_PIPELINE_BIND_POINT_GRAPHICS = 0, SE_PIPELINE_BIND_POINT_COMPUTE = 1, SE_PIPELINE_BIND_POINT_RAY_TRACING_NV = 1000165000, - SE_PIPELINE_BIND_POINT_BEGIN_RANGE = SE_PIPELINE_BIND_POINT_GRAPHICS, - SE_PIPELINE_BIND_POINT_END_RANGE = SE_PIPELINE_BIND_POINT_COMPUTE, - SE_PIPELINE_BIND_POINT_RANGE_SIZE = (SE_PIPELINE_BIND_POINT_COMPUTE - SE_PIPELINE_BIND_POINT_GRAPHICS + 1), - SE_PIPELINE_BIND_POINT_MAX_ENUM = 0x7FFFFFFF } SePipelineBindPoint; typedef enum SeCommandBufferLevel { SE_COMMAND_BUFFER_LEVEL_PRIMARY = 0, SE_COMMAND_BUFFER_LEVEL_SECONDARY = 1, - SE_COMMAND_BUFFER_LEVEL_BEGIN_RANGE = SE_COMMAND_BUFFER_LEVEL_PRIMARY, - SE_COMMAND_BUFFER_LEVEL_END_RANGE = SE_COMMAND_BUFFER_LEVEL_SECONDARY, - SE_COMMAND_BUFFER_LEVEL_RANGE_SIZE = (SE_COMMAND_BUFFER_LEVEL_SECONDARY - SE_COMMAND_BUFFER_LEVEL_PRIMARY + 1), - SE_COMMAND_BUFFER_LEVEL_MAX_ENUM = 0x7FFFFFFF } SeCommandBufferLevel; typedef enum SeIndexType @@ -1418,20 +1212,11 @@ typedef enum SeIndexType SE_INDEX_TYPE_UINT32 = 1, SE_INDEX_TYPE_NONE_NV = 1000165000, SE_INDEX_TYPE_UINT8_EXT = 1000265000, - SE_INDEX_TYPE_BEGIN_RANGE = SE_INDEX_TYPE_UINT16, - SE_INDEX_TYPE_END_RANGE = SE_INDEX_TYPE_UINT32, - SE_INDEX_TYPE_RANGE_SIZE = (SE_INDEX_TYPE_UINT32 - SE_INDEX_TYPE_UINT16 + 1), - SE_INDEX_TYPE_MAX_ENUM = 0x7FFFFFFF } SeIndexType; typedef enum SeSubpassContents { SE_SUBPASS_CONTENTS_INLINE = 0, - SE_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1, - SE_SUBPASS_CONTENTS_BEGIN_RANGE = SE_SUBPASS_CONTENTS_INLINE, - SE_SUBPASS_CONTENTS_END_RANGE = SE_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, - SE_SUBPASS_CONTENTS_RANGE_SIZE = (SE_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS - SE_SUBPASS_CONTENTS_INLINE + 1), - SE_SUBPASS_CONTENTS_MAX_ENUM = 0x7FFFFFFF } SeSubpassContents; typedef enum SeObjectType @@ -1475,12 +1260,6 @@ typedef enum SeObjectType SE_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000, SE_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, SE_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL = 1000210000, - SE_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = SE_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE, - SE_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = SE_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION, - SE_OBJECT_TYPE_BEGIN_RANGE = SE_OBJECT_TYPE_UNKNOWN, - SE_OBJECT_TYPE_END_RANGE = SE_OBJECT_TYPE_COMMAND_POOL, - SE_OBJECT_TYPE_RANGE_SIZE = (SE_OBJECT_TYPE_COMMAND_POOL - SE_OBJECT_TYPE_UNKNOWN + 1), - SE_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF } SeObjectType; typedef enum SeVendorId @@ -1488,10 +1267,6 @@ typedef enum SeVendorId SE_VENDOR_ID_VIV = 0x10001, SE_VENDOR_ID_VSI = 0x10002, SE_VENDOR_ID_KAZAN = 0x10003, - SE_VENDOR_ID_BEGIN_RANGE = SE_VENDOR_ID_VIV, - SE_VENDOR_ID_END_RANGE = SE_VENDOR_ID_KAZAN, - SE_VENDOR_ID_RANGE_SIZE = (SE_VENDOR_ID_KAZAN - SE_VENDOR_ID_VIV + 1), - SE_VENDOR_ID_MAX_ENUM = 0x7FFFFFFF } SeVendorId; typedef SeFlags SeInstanceCreateFlags; @@ -2027,5 +1802,15 @@ typedef union SeClearValue { SeClearDepthStencilValue depthStencil; } SeClearValue; + +typedef enum SeDescriptorAccessTypeFlagBits { + SE_DESCRIPTOR_ACCESS_READ_ONLY_BIT = 0x00000001, + SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT = 0x00000002, + SE_DESCRIPTOR_ACCESS_WRITE_ONLY_BIT = 0x00000004, +} SeDescriptorAccessTypeFlagBits; +typedef SeFlags SeDescriptorAccessTypeFlags; + + + } // namespace Gfx } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/Initializer.h b/src/Engine/Graphics/Initializer.h index d4707ff..e1c23c6 100644 --- a/src/Engine/Graphics/Initializer.h +++ b/src/Engine/Graphics/Initializer.h @@ -36,7 +36,7 @@ struct WindowCreateInfo int32 width; int32 height; const char *title; - Gfx::SeFormat preferredFormat = Gfx::SE_FORMAT_MAX_ENUM; + Gfx::SeFormat preferredFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM; void *windowHandle; }; struct ViewportCreateInfo @@ -178,8 +178,8 @@ struct DepthStencilState SeCompareOp depthCompareOp = Gfx::SE_COMPARE_OP_LESS; uint32 depthBoundsTestEnable = 0; uint32 stencilTestEnable = 0; - SeStencilOp front = Gfx::SE_STENCIL_OP_END_RANGE; - SeStencilOp back = Gfx::SE_STENCIL_OP_END_RANGE; + SeStencilOp front = Gfx::SE_STENCIL_OP_ZERO; + SeStencilOp back = Gfx::SE_STENCIL_OP_ZERO; float minDepthBounds; float maxDepthBounds; }; diff --git a/src/Engine/Graphics/Metal/Buffer.h b/src/Engine/Graphics/Metal/Buffer.h index a759e64..9be497a 100644 --- a/src/Engine/Graphics/Metal/Buffer.h +++ b/src/Engine/Graphics/Metal/Buffer.h @@ -7,65 +7,80 @@ namespace Seele { namespace Metal { DECLARE_REF(Graphics) -class Buffer -{ +class Buffer { public: - Buffer(PGraphics graphics, uint64 size, void* data, bool dynamic); + Buffer(PGraphics graphics, uint64 size, void *data, bool dynamic); virtual ~Buffer(); - MTL::Buffer* getHandle() const - { - return buffers[currentBuffer]; - } - uint64 getSize() const - { - return size; - } - void advanceBuffer() - { - currentBuffer = (currentBuffer + 1) % numBuffers; - } - void* map(bool writeOnly = true); - void* mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly); + MTL::Buffer *getHandle() const { return buffers[currentBuffer]; } + uint64 getSize() const { return size; } + void advanceBuffer() { currentBuffer = (currentBuffer + 1) % numBuffers; } + void *map(bool writeOnly = true); + void *mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly); void unmap(); -private: + +protected: PGraphics graphics; uint32 currentBuffer; uint64 size; - MTL::Buffer* buffers[Gfx::numFramesBuffered]; + MTL::Buffer *buffers[Gfx::numFramesBuffered]; uint32 numBuffers; }; DEFINE_REF(Buffer) -class VertexBuffer : public Gfx::VertexBuffer, public Buffer -{ +class VertexBuffer : public Gfx::VertexBuffer, public Buffer { public: - VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo& createInfo); + VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &createInfo); virtual ~VertexBuffer(); -private: + virtual void updateRegion(DataSource update) override; + virtual void download(Array &buffer) override; + +protected: + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override; + virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override; }; DEFINE_REF(VertexBuffer) -class IndexBuffer : public Gfx::IndexBuffer, public Buffer -{ +class IndexBuffer : public Gfx::IndexBuffer, public Buffer { public: - IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo& createInfo); + IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &createInfo); virtual ~IndexBuffer(); -private: + + virtual void download(Array &buffer) override; +protected: + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override; + virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override; }; DEFINE_REF(IndexBuffer) -class UniformBuffer : public Gfx::UniformBuffer, public Buffer -{ +DEFINE_REF(IndexBuffer) +class UniformBuffer : public Gfx::UniformBuffer, public Buffer { public: - UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo& createInfo); + UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &createInfo); virtual ~UniformBuffer(); -private: + + virtual bool updateContents(const DataSource &sourceData) override; + +protected: + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override; + virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override; }; DEFINE_REF(UniformBuffer) -class ShaderBuffer : public Gfx::ShaderBuffer, public Buffer -{ +class ShaderBuffer : public Gfx::ShaderBuffer, public Buffer { public: - ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& createInfo); + ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &createInfo); virtual ~ShaderBuffer(); -private: + + virtual bool updateContents(const DataSource &sourceData) override; + +protected: + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override; + virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override; }; DEFINE_REF(ShaderBuffer) -} -} \ No newline at end of file +} // namespace Metal +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/Metal/Buffer.mm b/src/Engine/Graphics/Metal/Buffer.mm index caebf12..33b41c9 100644 --- a/src/Engine/Graphics/Metal/Buffer.mm +++ b/src/Engine/Graphics/Metal/Buffer.mm @@ -8,8 +8,7 @@ using namespace Seele; using namespace Seele::Metal; -Buffer::Buffer(PGraphics graphics, uint64 size, void *data, bool dynamic) - : graphics(graphics), size(size) { +Buffer::Buffer(PGraphics graphics, uint64 size, void* data, bool dynamic) : graphics(graphics), size(size) { if (dynamic) { numBuffers = Gfx::numFramesBuffered; } else { @@ -17,11 +16,9 @@ Buffer::Buffer(PGraphics graphics, uint64 size, void *data, bool dynamic) } for (size_t i = 0; i < numBuffers; ++i) { if (data != nullptr) { - buffers[i] = graphics->getDevice()->newBuffer( - data, size, MTL::ResourceOptionCPUCacheModeDefault); + buffers[i] = graphics->getDevice()->newBuffer(data, size, MTL::ResourceOptionCPUCacheModeDefault); } else { - buffers[i] = graphics->getDevice()->newBuffer( - size, MTL::ResourceOptionCPUCacheModeDefault); + buffers[i] = graphics->getDevice()->newBuffer(size, MTL::ResourceOptionCPUCacheModeDefault); } } } @@ -32,45 +29,83 @@ Buffer::~Buffer() { } } -void *Buffer::map(bool) { return getHandle()->contents(); } +void* Buffer::map(bool) { return getHandle()->contents(); } -void *Buffer::mapRegion(uint64 regionOffset, uint64, bool) { - return (char *)getHandle()->contents() + regionOffset; -} +void* Buffer::mapRegion(uint64 regionOffset, uint64, bool) { return (char*)getHandle()->contents() + regionOffset; } void unmap() {} -VertexBuffer::VertexBuffer(PGraphics graphics, - const VertexBufferCreateInfo &createInfo) - : Gfx::VertexBuffer(graphics->getFamilyMapping(), createInfo.numVertices, - createInfo.vertexSize, createInfo.sourceData.owner), - Seele::Metal::Buffer(graphics, createInfo.sourceData.size, - createInfo.sourceData.data, false) {} +VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo& createInfo) + : Gfx::VertexBuffer(graphics->getFamilyMapping(), createInfo.numVertices, createInfo.vertexSize, + createInfo.sourceData.owner), + Seele::Metal::Buffer(graphics, createInfo.sourceData.size, createInfo.sourceData.data, false) {} VertexBuffer::~VertexBuffer() {} -IndexBuffer::IndexBuffer(PGraphics graphics, - const IndexBufferCreateInfo &createInfo) - : Gfx::IndexBuffer(graphics->getFamilyMapping(), createInfo.sourceData.size, - createInfo.indexType, createInfo.sourceData.owner), - Seele::Metal::Buffer(graphics, createInfo.sourceData.size, - createInfo.sourceData.data, false) {} +void VertexBuffer::updateRegion(DataSource update) { + void* data = getHandle()->contents(); + std::memcpy((char*)data + update.offset, update.data, update.size); +} + +void VertexBuffer::download(Array& buffer) { + void* data = getHandle()->contents(); + buffer.resize(size); + std::memcpy(buffer.data(), data, size); +} + +void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; } + +void VertexBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {} + +IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo& createInfo) + : Gfx::IndexBuffer(graphics->getFamilyMapping(), createInfo.sourceData.size, createInfo.indexType, + createInfo.sourceData.owner), + Seele::Metal::Buffer(graphics, createInfo.sourceData.size, createInfo.sourceData.data, false) {} IndexBuffer::~IndexBuffer() {} -UniformBuffer::UniformBuffer(PGraphics graphics, - const UniformBufferCreateInfo &createInfo) +void IndexBuffer::download(Array& buffer) { + void* data = getHandle()->contents(); + buffer.resize(size); + std::memcpy(buffer.data(), data, size); +} +void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; } + +void IndexBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {} + +UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo& createInfo) : Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData), - Seele::Metal::Buffer(graphics, createInfo.sourceData.size, - createInfo.sourceData.data, createInfo.dynamic) {} + Seele::Metal::Buffer(graphics, createInfo.sourceData.size, createInfo.sourceData.data, createInfo.dynamic) {} UniformBuffer::~UniformBuffer() {} -ShaderBuffer::ShaderBuffer(PGraphics graphics, - const ShaderBufferCreateInfo &createInfo) - : Gfx::ShaderBuffer(graphics->getFamilyMapping(), createInfo.numElements, - createInfo.sourceData), - Seele::Metal::Buffer(graphics, createInfo.sourceData.size, - createInfo.sourceData.data, createInfo.dynamic) {} +bool UniformBuffer::updateContents(const DataSource& sourceData) { + void* data = getHandle()->contents(); + std::memcpy((char*)data + sourceData.offset, sourceData.data, sourceData.size); + return true; +} + +void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; } + +void UniformBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {} + +ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& createInfo) + : Gfx::ShaderBuffer(graphics->getFamilyMapping(), createInfo.numElements, createInfo.sourceData), + Seele::Metal::Buffer(graphics, createInfo.sourceData.size, createInfo.sourceData.data, createInfo.dynamic) {} ShaderBuffer::~ShaderBuffer() {} + +bool ShaderBuffer::updateContents(const DataSource& sourceData) { + void* data = getHandle()->contents(); + std::memcpy((char*)data + sourceData.offset, sourceData.data, sourceData.size); + return true; +} + +void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; } + + +void ShaderBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {} \ No newline at end of file diff --git a/src/Engine/Graphics/Metal/CMakeLists.txt b/src/Engine/Graphics/Metal/CMakeLists.txt index e9b54ab..f1a977f 100644 --- a/src/Engine/Graphics/Metal/CMakeLists.txt +++ b/src/Engine/Graphics/Metal/CMakeLists.txt @@ -12,6 +12,8 @@ target_sources(Engine Graphics.mm Pipeline.h Pipeline.mm + PipelineCache.h + PipelineCache.mm PrivateImpl.mm RenderPass.h RenderPass.mm diff --git a/src/Engine/Graphics/Metal/Descriptor.h b/src/Engine/Graphics/Metal/Descriptor.h index 9018bab..1dcd5c3 100644 --- a/src/Engine/Graphics/Metal/Descriptor.h +++ b/src/Engine/Graphics/Metal/Descriptor.h @@ -8,64 +8,75 @@ namespace Seele { namespace Metal { DECLARE_REF(Graphics) -DECLARE_REF(DescriptorPool) class DescriptorLayout : public Gfx::DescriptorLayout { public: - DescriptorLayout(PGraphics graphics, const std::string &name); + DescriptorLayout(PGraphics graphics, const std::string& name); virtual ~DescriptorLayout(); virtual void create() override; - NS::Array* getArguments() const - { - return arguments; - } + + NS::Array* getArguments() const { return arguments; } + private: PGraphics graphics; NS::Array* arguments; }; -class PipelineLayout : public Gfx::PipelineLayout { +DEFINE_REF(DescriptorLayout) + +DECLARE_REF(DescriptorSet) +class DescriptorPool : public Gfx::DescriptorPool { public: - PipelineLayout(PGraphics graphics, Gfx::PPipelineLayout baseLayout) - : Gfx::PipelineLayout(baseLayout), graphics(graphics) {} + DescriptorPool(PGraphics graphics, PDescriptorLayout layout); + virtual ~DescriptorPool(); + virtual Gfx::PDescriptorSet allocateDescriptorSet() override; + virtual void reset() override; + constexpr NS::Array* getArguments() const { return layout->getArguments(); } + constexpr PDescriptorLayout getLayout() const { return layout; } private: PGraphics graphics; + PDescriptorLayout layout; + Array allocatedSets; }; -DEFINE_REF(PipelineLayout) +DEFINE_REF(DescriptorPool) class DescriptorSet : public Gfx::DescriptorSet { public: DescriptorSet(PGraphics graphics, PDescriptorPool owner); virtual ~DescriptorSet(); virtual void writeChanges(); - virtual void updateBuffer(uint32_t binding, - Gfx::PUniformBuffer uniformBuffer); + virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer); virtual void updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer); virtual void updateSampler(uint32_t binding, Gfx::PSampler samplerState); - virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, - Gfx::PSampler sampler = nullptr); - virtual void updateTextureArray(uint32_t binding, - Array texture); + virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler sampler = nullptr); + virtual void updateTextureArray(uint32_t binding, Array texture); virtual bool operator<(Gfx::PDescriptorSet other); + constexpr bool isCurrentlyBound() const { return bindCount > 0; } + constexpr bool isCurrentlyInUse() const { return currentlyInUse; } + constexpr void bind() { bindCount++; } + constexpr void unbind() { bindCount--; } + constexpr void allocate() { currentlyInUse = true; } + constexpr void free() { currentlyInUse = false; } + private: PGraphics graphics; PDescriptorPool owner; MTL::Buffer* buffer; MTL::ArgumentEncoder* encoder; + uint32 bindCount; + bool currentlyInUse; }; DEFINE_REF(DescriptorSet) -class DescriptorPool : public Gfx::DescriptorPool { +class PipelineLayout : public Gfx::PipelineLayout { public: - DescriptorPool(PGraphics graphics, DescriptorLayout& layout); - virtual ~DescriptorPool(); - NS::Array* getArguments() const - { - return layout.getArguments(); - } + PipelineLayout(PGraphics graphics, Gfx::PPipelineLayout baseLayout); + virtual ~PipelineLayout(); + virtual void create() override; + private: PGraphics graphics; - DescriptorLayout& layout; }; +DEFINE_REF(PipelineLayout) } // namespace Metal } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/Metal/Descriptor.mm b/src/Engine/Graphics/Metal/Descriptor.mm index 2c20fa6..d17cc8d 100644 --- a/src/Engine/Graphics/Metal/Descriptor.mm +++ b/src/Engine/Graphics/Metal/Descriptor.mm @@ -1,28 +1,128 @@ #include "Descriptor.h" -#include "Graphics.h" +#include "Buffer.h" +#include "Enums.h" +#include "Graphics/Initializer.h" +#include "Texture.h" using namespace Seele; using namespace Seele::Metal; -DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner) - : graphics(graphics) - , owner(owner) -{ - encoder = graphics->getDevice()->newArgumentEncoder(owner->getArguments()); -} -DescriptorSet::~DescriptorSet() -{ -} -void DescriptorSet::writeChanges() -{ +DescriptorLayout::DescriptorLayout(PGraphics graphics, const std::string& name) + : Gfx::DescriptorLayout(name), graphics(graphics) {} + +DescriptorLayout::~DescriptorLayout() {} + +void DescriptorLayout::create() { + Array descriptors; + for (size_t i = 0; i < descriptorBindings.size(); ++i) { + const auto& binding = descriptorBindings[i]; + auto desc = MTL::ArgumentDescriptor::alloc()->init(); + desc->setAccess(cast(binding.access)); + desc->setArrayLength(binding.descriptorCount); + MTL::DataType dataType; + switch (binding.descriptorType) { + case Gfx::SE_DESCRIPTOR_TYPE_SAMPLER: + case Gfx::SE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + case Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case Gfx::SE_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + case Gfx::SE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: + dataType = MTL::DataTypeTexture; + break; + case Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + case Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: + case Gfx::SE_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: + dataType = MTL::DataTypeStruct; + break; + case Gfx::SE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: + dataType = MTL::DataTypePrimitiveAccelerationStructure; + break; + default: + throw std::logic_error("Nooo"); + } + desc->setDataType(dataType); + descriptors.add(desc); + } + arguments = NS::Array::array(descriptors.data(), descriptors.size()); } - void DescriptorSet::updateBuffer(uint32_t binding, - Gfx::PUniformBuffer uniformBuffer){} - void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer){} - void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState){} - void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, - Gfx::PSampler sampler){} - void DescriptorSet::updateTextureArray(uint32_t binding, - Array texture){} - bool DescriptorSet::operator<(Gfx::PDescriptorSet other){return this < other.getHandle();} +DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout) : graphics(graphics), layout(layout) {} + +DescriptorPool::~DescriptorPool() {} + +Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet() { + for (uint32 setIndex = 0; setIndex < allocatedSets.size(); ++setIndex) { + if (allocatedSets[setIndex]->isCurrentlyBound() || allocatedSets[setIndex]->isCurrentlyInUse()) { + // Currently in use, skip + continue; + } + allocatedSets[setIndex]->allocate(); + + // Found set, stop searching + return PDescriptorSet(allocatedSets[setIndex]); + } + allocatedSets.add(new DescriptorSet(graphics, this)); + return PDescriptorSet(allocatedSets.back()); +} + +void DescriptorPool::reset() { + for (auto& set : allocatedSets) { + set->free(); + } +} + +DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner) + : Gfx::DescriptorSet(owner->getLayout()), graphics(graphics), owner(owner), bindCount(0), currentlyInUse(false) { + encoder = graphics->getDevice()->newArgumentEncoder(owner->getArguments()); + buffer = graphics->getDevice()->newBuffer(encoder->encodedLength(), MTL::ResourceOptionCPUCacheModeDefault); + encoder->setArgumentBuffer(buffer, 0); +} + +DescriptorSet::~DescriptorSet() {} + +void DescriptorSet::writeChanges() {} + +void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) { + PUniformBuffer metalBuffer = uniformBuffer.cast(); + encoder->setBuffer(metalBuffer->getHandle(), 0, binding); +} +void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer) { + PShaderBuffer metalBuffer = uniformBuffer.cast(); + encoder->setBuffer(metalBuffer->getHandle(), 0, binding); +} +void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState) { + PSampler sampler = samplerState.cast(); + encoder->setSamplerState(sampler->getHandle(), binding); +} +void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler samplerState) { + PTextureBase base = texture.cast(); + PSampler sampler = samplerState.cast(); + encoder->setTexture(base->getTexture(), binding); + encoder->setSamplerState(sampler->getHandle(), binding); +} + +void DescriptorSet::updateTextureArray(uint32_t binding, Array array) { + for (auto& t : array) { + PTextureBase metalTexture = t.cast(); + encoder->setTexture(metalTexture->getTexture(), binding++); + } +} + +bool DescriptorSet::operator<(Gfx::PDescriptorSet other) { return this < other.getHandle(); } + +PipelineLayout::PipelineLayout(PGraphics graphics, Gfx::PPipelineLayout baseLayout) + : Gfx::PipelineLayout(baseLayout), graphics(graphics) {} + +PipelineLayout::~PipelineLayout(){} + +void PipelineLayout::create() +{ + for(auto& set : descriptorSetLayouts) + { + uint32 setHash = set->getHash(); + layoutHash = CRC::Calculate(&setHash, sizeof(uint32), CRC::CRC_32(), layoutHash); + } +} \ No newline at end of file diff --git a/src/Engine/Graphics/Metal/Enums.h b/src/Engine/Graphics/Metal/Enums.h index ec7492a..31b600b 100644 --- a/src/Engine/Graphics/Metal/Enums.h +++ b/src/Engine/Graphics/Metal/Enums.h @@ -1,5 +1,7 @@ #pragma once #include "Graphics/Enums.h" +#include "Metal/MTLDepthStencil.hpp" +#include "Metal/MTLSampler.hpp" #include "Resources.h" namespace Seele @@ -12,5 +14,17 @@ MTL::LoadAction cast(Gfx::SeAttachmentLoadOp loadOp); Gfx::SeAttachmentLoadOp cast(MTL::LoadAction loadOp); MTL::StoreAction cast(Gfx::SeAttachmentStoreOp storeOp); Gfx::SeAttachmentStoreOp cast(MTL::StoreAction storeOp); +MTL::BindingAccess cast(Gfx::SeDescriptorAccessTypeFlags access); +Gfx::SeDescriptorAccessTypeFlags cast(MTL::BindingAccess access); +MTL::SamplerBorderColor cast(Gfx::SeBorderColor color); +Gfx::SeBorderColor cast(MTL::SamplerBorderColor color); +MTL::CompareFunction cast(Gfx::SeCompareOp compare); +Gfx::SeCompareOp cast(MTL::CompareFunction compare); +MTL::SamplerMinMagFilter cast(Gfx::SeFilter filter); +Gfx::SeFilter cast(MTL::SamplerMinMagFilter filter); +MTL::SamplerMipFilter cast(Gfx::SeSamplerMipmapMode filter); +Gfx::SeSamplerMipmapMode cast(MTL::SamplerMipFilter filter); +MTL::SamplerAddressMode cast(Gfx::SeSamplerAddressMode mode); +Gfx::SeSamplerAddressMode cast(MTL::SamplerAddressMode mode); } } \ No newline at end of file diff --git a/src/Engine/Graphics/Metal/Enums.mm b/src/Engine/Graphics/Metal/Enums.mm index 7e67260..5aff205 100644 --- a/src/Engine/Graphics/Metal/Enums.mm +++ b/src/Engine/Graphics/Metal/Enums.mm @@ -1,5 +1,8 @@ #include "Enums.h" #include "Graphics/Enums.h" +#include "Metal/MTLArgument.hpp" +#include "Metal/MTLDepthStencil.hpp" +#include "Metal/MTLSampler.hpp" #include using namespace Seele; @@ -587,3 +590,181 @@ Gfx::SeAttachmentStoreOp Seele::Metal::cast(MTL::StoreAction storeOp) { throw std::logic_error("Not implemented"); } } + +MTL::BindingAccess Seele::Metal::cast(Gfx::SeDescriptorAccessTypeFlags access) { + switch (access) { + case Gfx::SE_DESCRIPTOR_ACCESS_READ_ONLY_BIT: + return MTL::ArgumentAccessReadOnly; + case Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT: + return MTL::ArgumentAccessReadWrite; + case Gfx::SE_DESCRIPTOR_ACCESS_WRITE_ONLY_BIT: + return MTL::ArgumentAccessWriteOnly; + default: + throw std::logic_error("Not implemented"); + } +} + +Gfx::SeDescriptorAccessTypeFlags Seele::Metal::cast(MTL::BindingAccess access) { + switch (access) { + case MTL::ArgumentAccessReadOnly: + return Gfx::SE_DESCRIPTOR_ACCESS_READ_ONLY_BIT; + case MTL::ArgumentAccessReadWrite: + return Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT; + case MTL::ArgumentAccessWriteOnly: + return Gfx::SE_DESCRIPTOR_ACCESS_WRITE_ONLY_BIT; + default: + throw std::logic_error("Not implemented"); + } +} + +MTL::SamplerBorderColor Seele::Metal::cast(Gfx::SeBorderColor color) { + switch (color) { + case Gfx::SE_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK: + return MTL::SamplerBorderColorTransparentBlack; + case Gfx::SE_BORDER_COLOR_INT_TRANSPARENT_BLACK: + return MTL::SamplerBorderColorTransparentBlack; + case Gfx::SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK: + return MTL::SamplerBorderColorOpaqueBlack; + case Gfx::SE_BORDER_COLOR_INT_OPAQUE_BLACK: + return MTL::SamplerBorderColorOpaqueBlack; + case Gfx::SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE: + return MTL::SamplerBorderColorOpaqueWhite; + case Gfx::SE_BORDER_COLOR_INT_OPAQUE_WHITE: + return MTL::SamplerBorderColorOpaqueWhite; + default: + throw std::logic_error("Not implemented"); + } +} + +Gfx::SeBorderColor Seele::Metal::cast(MTL::SamplerBorderColor color) { + switch (color) { + case MTL::SamplerBorderColorTransparentBlack: + return Gfx::SE_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; + case MTL::SamplerBorderColorOpaqueBlack: + return Gfx::SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK; + case MTL::SamplerBorderColorOpaqueWhite: + return Gfx::SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE; + default: + throw std::logic_error("Not implemented"); + } +} + +MTL::CompareFunction Seele::Metal::cast(Gfx::SeCompareOp compare) { + switch (compare) { + case Gfx::SE_COMPARE_OP_NEVER: + return MTL::CompareFunctionNever; + case Gfx::SE_COMPARE_OP_LESS: + return MTL::CompareFunctionLess; + case Gfx::SE_COMPARE_OP_EQUAL: + return MTL::CompareFunctionEqual; + case Gfx::SE_COMPARE_OP_LESS_OR_EQUAL: + return MTL::CompareFunctionLessEqual; + case Gfx::SE_COMPARE_OP_GREATER: + return MTL::CompareFunctionGreater; + case Gfx::SE_COMPARE_OP_NOT_EQUAL: + return MTL::CompareFunctionNotEqual; + case Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL: + return MTL::CompareFunctionGreaterEqual; + case Gfx::SE_COMPARE_OP_ALWAYS: + return MTL::CompareFunctionAlways; + default: + throw std::logic_error("Not implemented"); + } +} + +Gfx::SeCompareOp Seele::Metal::cast(MTL::CompareFunction compare) { + switch (compare) { + case MTL::CompareFunctionNever: + return Gfx::SE_COMPARE_OP_NEVER; + case MTL::CompareFunctionLess: + return Gfx::SE_COMPARE_OP_LESS; + case MTL::CompareFunctionEqual: + return Gfx::SE_COMPARE_OP_EQUAL; + case MTL::CompareFunctionLessEqual: + return Gfx::SE_COMPARE_OP_LESS_OR_EQUAL; + case MTL::CompareFunctionGreater: + return Gfx::SE_COMPARE_OP_GREATER; + case MTL::CompareFunctionNotEqual: + return Gfx::SE_COMPARE_OP_NOT_EQUAL; + case MTL::CompareFunctionGreaterEqual: + return Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL; + case MTL::CompareFunctionAlways: + return Gfx::SE_COMPARE_OP_ALWAYS; + } +} + +MTL::SamplerMinMagFilter Seele::Metal::cast(Gfx::SeFilter filter) { + switch (filter) { + case Gfx::SE_FILTER_NEAREST: + return MTL::SamplerMinMagFilterNearest; + case Gfx::SE_FILTER_LINEAR: + return MTL::SamplerMinMagFilterLinear; + case Gfx::SE_FILTER_CUBIC_IMG: + return MTL::SamplerMinMagFilterLinear; + default: + throw std::logic_error("Not implemented"); + } +} + +Gfx::SeFilter Seele::Metal::cast(MTL::SamplerMinMagFilter filter) { + switch (filter) { + case MTL::SamplerMinMagFilterNearest: + return Gfx::SE_FILTER_NEAREST; + case MTL::SamplerMinMagFilterLinear: + return Gfx::SE_FILTER_LINEAR; + } +} + +MTL::SamplerMipFilter Seele::Metal::cast(Gfx::SeSamplerMipmapMode filter) { + switch (filter) { + case Seele::Gfx::SE_SAMPLER_MIPMAP_MODE_NEAREST: + return MTL::SamplerMipFilterNearest; + case Seele::Gfx::SE_SAMPLER_MIPMAP_MODE_LINEAR: + return MTL::SamplerMipFilterLinear; + default: + throw std::logic_error("Not implemented"); + } +} + +Gfx::SeSamplerMipmapMode Seele::Metal::cast(MTL::SamplerMipFilter filter) { + switch (filter) { + case MTL::SamplerMipFilterNotMipmapped: + return Gfx::SE_SAMPLER_MIPMAP_MODE_LINEAR; + case MTL::SamplerMipFilterNearest: + return Gfx::SE_SAMPLER_MIPMAP_MODE_NEAREST; + case MTL::SamplerMipFilterLinear: + return Gfx::SE_SAMPLER_MIPMAP_MODE_LINEAR; + } +} + +MTL::SamplerAddressMode Seele::Metal::cast(Gfx::SeSamplerAddressMode mode) { + switch (mode) { + case Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT: + return MTL::SamplerAddressModeRepeat; + case Gfx::SE_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT: + return MTL::SamplerAddressModeMirrorRepeat; + case Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE: + return MTL::SamplerAddressModeMirrorClampToEdge; + case Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER: + return MTL::SamplerAddressModeClampToBorderColor; + case Gfx::SE_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE: + return MTL::SamplerAddressModeMirrorClampToEdge; + } +} + +Gfx::SeSamplerAddressMode Seele::Metal::cast(MTL::SamplerAddressMode mode) { + switch (mode) { + case MTL::SamplerAddressModeClampToEdge: + return Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + case MTL::SamplerAddressModeMirrorClampToEdge: + return Gfx::SE_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; + case MTL::SamplerAddressModeRepeat: + return Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT; + case MTL::SamplerAddressModeMirrorRepeat: + return Gfx::SE_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + case MTL::SamplerAddressModeClampToZero: + return Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + case MTL::SamplerAddressModeClampToBorderColor: + return Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; + } +} diff --git a/src/Engine/Graphics/Metal/Graphics.mm b/src/Engine/Graphics/Metal/Graphics.mm index 255d43d..460b00d 100644 --- a/src/Engine/Graphics/Metal/Graphics.mm +++ b/src/Engine/Graphics/Metal/Graphics.mm @@ -1,8 +1,10 @@ #include "Graphics.h" -#include "Graphics/Metal/Shader.h" +#include "Graphics/Initializer.h" +#include "Shader.h" #include "RenderPass.h" #include "Command.h" #include "Window.h" +#include "Buffer.h" using namespace Seele; using namespace Seele::Metal; @@ -82,22 +84,22 @@ Gfx::OTextureCube Graphics::createTextureCube(const TextureCreateInfo &createInf Gfx::OUniformBuffer Graphics::createUniformBuffer(const UniformBufferCreateInfo &bulkData) { - + return new UniformBuffer(this, bulkData); } Gfx::OShaderBuffer Graphics::createShaderBuffer(const ShaderBufferCreateInfo &bulkData) { - + return new ShaderBuffer(this, bulkData); } Gfx::OVertexBuffer Graphics::createVertexBuffer(const VertexBufferCreateInfo &bulkData) { - + return new VertexBuffer(this, bulkData); } Gfx::OIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkData) { - + return new IndexBuffer(this, bulkData); } Gfx::ORenderCommand Graphics::createRenderCommand(const std::string& name) @@ -112,11 +114,15 @@ Gfx::OComputeCommand Graphics::createComputeCommand(const std::string& name) Gfx::OVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createInfo) { - + OVertexShader result = new VertexShader(this); + result->create(createInfo); + return result; } Gfx::OFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo) { - + OFragmentShader result = new FragmentShader(this); + result->create(createInfo); + return result; } Gfx::OComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo) { @@ -133,12 +139,16 @@ Gfx::OMeshShader Graphics::createMeshShader(const ShaderCreateInfo& createInfo) } Gfx::OTaskShader Graphics::createTaskShader(const ShaderCreateInfo& createInfo) { - + OTaskShader result = new TaskShader(this); + result->create(createInfo); + return result; } + Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo) { } + Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo) { diff --git a/src/Engine/Graphics/Metal/PipelineCache.h b/src/Engine/Graphics/Metal/PipelineCache.h index 1aabf25..189eee2 100644 --- a/src/Engine/Graphics/Metal/PipelineCache.h +++ b/src/Engine/Graphics/Metal/PipelineCache.h @@ -1,11 +1,23 @@ #pragma once -#include "Graphics/Pipeline.h" +#include "Graphics/Initializer.h" +#include "Pipeline.h" namespace Seele { namespace Metal { class PipelineCache { - +public: + PipelineCache(PGraphics graphics, const std::string& cacheFilePath); + ~PipelineCache(); + PGraphicsPipeline createPipeline(Gfx::LegacyPipelineCreateInfo createInfo); + PGraphicsPipeline createPipeline(Gfx::MeshPipelineCreateInfo createInfo); + PComputePipeline createPipeline(Gfx::ComputePipelineCreateInfo createInfo); +private: + PGraphics graphics; + Map graphicsPipelines; + Map computePipeline; + std::string cacheFile; }; +DEFINE_REF(PipelineCache) } } \ No newline at end of file diff --git a/src/Engine/Graphics/Metal/PipelineCache.mm b/src/Engine/Graphics/Metal/PipelineCache.mm index e69de29..578b4ce 100644 --- a/src/Engine/Graphics/Metal/PipelineCache.mm +++ b/src/Engine/Graphics/Metal/PipelineCache.mm @@ -0,0 +1,70 @@ +#include "PipelineCache.h" +#include "Descriptor.h" +#include "Graphics.h" +#include "Shader.h" +#include "Graphics/Descriptor.h" +#include "Graphics/Enums.h" +#include "Metal/MTLRenderPipeline.hpp" +#include "Metal/MTLVertexDescriptor.hpp" + +using namespace Seele; +using namespace Seele::Metal; + +PipelineCache::PipelineCache(PGraphics graphics, const std::string& name) : graphics(graphics), cacheFile(name) {} + +PipelineCache::~PipelineCache() {} + +PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo createInfo) { + PPipelineLayout layout = Gfx::PPipelineLayout(createInfo.pipelineLayout).cast(); + uint32 hash = layout->getHash(); + MTL::RenderPipelineDescriptor* pipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init(); + + MTL::VertexDescriptor* vertexDescriptor = MTL::VertexDescriptor::alloc()->init(); + + MTL::VertexAttributeDescriptorArray* attributes = vertexDescriptor->attributes(); + + const auto& vertexInfo = createInfo.vertexInput->getInfo(); + + for (size_t attr = 0; attr < vertexInfo.attributes.size(); ++attr) { + MTL::VertexAttributeDescriptor* attribute = MTL::VertexAttributeDescriptor::alloc()->init(); + attribute->setBufferIndex(vertexInfo.attributes[attr].binding); + switch (vertexInfo.attributes[attr].format) { + case Gfx::SE_FORMAT_R32G32B32_SFLOAT: + attribute->setFormat(MTL::VertexFormatFloat3); + break; + default: + throw std::logic_error("TODO"); + } + attribute->setOffset(vertexInfo.attributes[attr].offset); + attributes->setObject(attribute, attr); + } + + MTL::VertexBufferLayoutDescriptorArray* bufferLayout = vertexDescriptor->layouts(); + + for (size_t binding = 0; binding < vertexInfo.bindings.size(); ++binding) { + MTL::VertexBufferLayoutDescriptor* buffer = MTL::VertexBufferLayoutDescriptor::alloc()->init(); + buffer->setStride(vertexInfo.bindings[binding].stride); + buffer->setStepRate(1); + switch (vertexInfo.bindings[binding].inputRate) { + case Gfx::SE_VERTEX_INPUT_RATE_VERTEX: + buffer->setStepFunction(MTL::VertexStepFunctionPerVertex); + break; + case Gfx::SE_VERTEX_INPUT_RATE_INSTANCE: + buffer->setStepFunction(MTL::VertexStepFunctionPerInstance); + break; + } + bufferLayout->setObject(buffer, binding); + } + + pipelineDescriptor->setVertexDescriptor(vertexDescriptor); + + pipelineDescriptor->setVertexFunction(createInfo.vertexShader.cast()->getFunction()); + + + vertexDescriptor->release(); + pipelineDescriptor->release(); +} + +PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo createInfo) {} + +PComputePipeline PipelineCache::createPipeline(Gfx::ComputePipelineCreateInfo createInfo) {} diff --git a/src/Engine/Graphics/Metal/Resources.h b/src/Engine/Graphics/Metal/Resources.h index 88e46a7..53f781d 100644 --- a/src/Engine/Graphics/Metal/Resources.h +++ b/src/Engine/Graphics/Metal/Resources.h @@ -1,5 +1,6 @@ #pragma once #include "Graphics/Resources.h" +#include "Metal/MTLSampler.hpp" #include #include #include @@ -29,5 +30,18 @@ private: MTL::Event *handle; }; DEFINE_REF(Event) +class Sampler : public Gfx::Sampler +{ +public: + Sampler(PGraphics graphics, const SamplerCreateInfo& createInfo); + virtual ~Sampler(); + MTL::SamplerState* getHandle() const + { + return sampler; + } +private: + MTL::SamplerState* sampler; +}; +DEFINE_REF(Sampler) } // namespace Metal } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/Metal/Resources.mm b/src/Engine/Graphics/Metal/Resources.mm index ffb2f80..c84577a 100644 --- a/src/Engine/Graphics/Metal/Resources.mm +++ b/src/Engine/Graphics/Metal/Resources.mm @@ -1,5 +1,7 @@ #include "Resources.h" #include "Graphics.h" +#include "Metal/MTLSampler.hpp" +#include "Enums.h" using namespace Seele; using namespace Seele::Metal; @@ -10,4 +12,30 @@ Fence::~Fence() { handle->release(); } Event::Event(PGraphics graphics) : handle(graphics->getDevice()->newEvent()) {} -Event::~Event() { handle->release(); } \ No newline at end of file +Event::~Event() { handle->release(); } + +Sampler::Sampler(PGraphics graphics, const SamplerCreateInfo& createInfo) +{ + MTL::SamplerDescriptor* desc = MTL::SamplerDescriptor::alloc()->init(); + desc->setBorderColor(cast(createInfo.borderColor)); + desc->setCompareFunction(cast(createInfo.compareOp)); + desc->setLodAverage(createInfo.mipLodBias); + desc->setLodMaxClamp(createInfo.maxLod); + desc->setLodMinClamp(createInfo.minLod); + desc->setMinFilter(cast(createInfo.minFilter)); + desc->setMagFilter(cast(createInfo.magFilter)); + desc->setMipFilter(cast(createInfo.mipmapMode)); + desc->setMaxAnisotropy(createInfo.maxAnisotropy); + desc->setNormalizedCoordinates(!createInfo.unnormalizedCoordinates); + desc->setRAddressMode(cast(createInfo.addressModeU)); + desc->setSAddressMode(cast(createInfo.addressModeV)); + desc->setTAddressMode(cast(createInfo.addressModeW)); + desc->setSupportArgumentBuffers(true); + sampler = graphics->getDevice()->newSamplerState(desc); + desc->release(); +} + +Sampler::~Sampler() +{ + sampler->release(); +} \ No newline at end of file diff --git a/src/Engine/Graphics/Metal/Shader.mm b/src/Engine/Graphics/Metal/Shader.mm index eba39e5..80a0a5f 100644 --- a/src/Engine/Graphics/Metal/Shader.mm +++ b/src/Engine/Graphics/Metal/Shader.mm @@ -1,10 +1,15 @@ #include "Shader.h" +#include "Foundation/NSError.hpp" +#include "Foundation/NSString.hpp" #include "Graphics.h" #include "Graphics/Enums.h" #include "Graphics/slang-compile.h" +#include "Metal/MTLDevice.hpp" +#include "Metal/MTLLibrary.hpp" #include -#include #include +#include +#include using namespace Seele; using namespace Seele::Metal; @@ -20,64 +25,27 @@ Shader::~Shader() { void Shader::create(const ShaderCreateInfo &createInfo) { Slang::ComPtr kernelBlob = - generateShader(createInfo, SLANG_DXIL); - thread_local IRCompiler *pCompiler = nullptr; - if (pCompiler == nullptr) { - pCompiler = IRCompilerCreate(); + generateShader(createInfo, SLANG_SPIRV); + spirv_cross::CompilerMSL comp((const uint32 *)kernelBlob->getBufferPointer(), + kernelBlob->getBufferSize() / 4); + auto options = comp.get_msl_options(); + options.argument_buffers = true; + options.argument_buffers_tier = + spirv_cross::CompilerMSL::Options::ArgumentBuffersTier::Tier2; + options.set_msl_version(3); + comp.set_msl_options(options); + std::string metalCode = comp.compile(); + NS::Error *error = nullptr; + MTL::CompileOptions *mtlOptions = MTL::CompileOptions::alloc()->init(); + + library = graphics->getDevice()->newLibrary( + NS::String::string(metalCode.c_str(), NS::ASCIIStringEncoding), + mtlOptions, &error); + if (error) { + std::cout << error->debugDescription() << std::endl; + assert(false); } - IRCompilerSetEntryPointName(pCompiler, "main"); - - IRObject *pDXIL = IRObjectCreateFromDXIL( - (const uint8 *)kernelBlob->getBufferPointer(), - kernelBlob->getBufferSize(), IRBytecodeOwnershipNone); - - // Compile DXIL to Metal IR: - IRError *pError = nullptr; - IRObject *pOutIR = - IRCompilerAllocCompileAndLink(pCompiler, NULL, pDXIL, &pError); - - if (!pOutIR) { - // Inspect pError to determine cause. - IRErrorDestroy(pError); - } - IRShaderStage irStage; - switch (stage) { - case Gfx::SE_SHADER_STAGE_VERTEX_BIT: irStage = IRShaderStageVertex; - case Gfx::SE_SHADER_STAGE_FRAGMENT_BIT: irStage = IRShaderStageFragment; - case Gfx::SE_SHADER_STAGE_COMPUTE_BIT: irStage = IRShaderStageCompute; - case Gfx::SE_SHADER_STAGE_TASK_BIT_NV: irStage = IRShaderStageAmplification; - case Gfx::SE_SHADER_STAGE_MESH_BIT_NV: irStage = IRShaderStageMesh; - } - // Retrieve Metallib: - IRMetalLibBinary *pMetallib = IRMetalLibBinaryCreate(); - IRObjectGetMetalLibBinary(pOutIR, irStage, pMetallib); - size_t metallibSize = IRMetalLibGetBytecodeSize(pMetallib); - uint8_t *metallib = new uint8_t[metallibSize]; - IRMetalLibGetBytecode(pMetallib, metallib); - - IRShaderReflection* reflection = IRShaderReflectionCreate(); - IRObjectGetReflection(pOutIR, irStage, reflection); - Array locations( - IRShaderReflectionGetResourceCount(reflection)); - IRShaderReflectionGetResourceLocations(reflection, locations.data()); - for(auto l : locations) - { - std::cout << "Resource " << l.resourceName << " Type " << l.resourceType << " size " << l.sizeBytes << " slot " << l.slot << " space " << l.space << " offset " << l.topLevelOffset << std::endl; - } - IRShaderReflectionDestroy(reflection); - - // Store the metallib to custom format or disk, or use to create a MTLLibrary. - NS::Error *__autoreleasing error = nil; - dispatch_data_t data = dispatch_data_create(metallib, metallibSize, - dispatch_get_main_queue(), NULL); - - library = graphics->getDevice()->newLibrary(data, &error); function = library->newFunction(NS::String::string("main", NS::ASCIIStringEncoding)); - - delete[] metallib; - IRMetalLibBinaryDestroy(pMetallib); - IRObjectDestroy(pDXIL); - IRObjectDestroy(pOutIR); - IRCompilerDestroy(pCompiler); + mtlOptions->release(); } \ No newline at end of file diff --git a/src/Engine/Graphics/RenderTarget.h b/src/Engine/Graphics/RenderTarget.h index 0e27c6b..7fbe7d8 100644 --- a/src/Engine/Graphics/RenderTarget.h +++ b/src/Engine/Graphics/RenderTarget.h @@ -1,4 +1,5 @@ #pragma once +#include "Graphics/Enums.h" #include "Resources.h" #include "Texture.h" #include "Window.h" @@ -85,12 +86,12 @@ public: protected: PTexture2D texture = nullptr; PViewport viewport = nullptr; - SeImageLayout initialLayout = SE_IMAGE_LAYOUT_BEGIN_RANGE; - SeImageLayout finalLayout = SE_IMAGE_LAYOUT_BEGIN_RANGE; - SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_BEGIN_RANGE; - SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_BEGIN_RANGE; - SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_BEGIN_RANGE; - SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_BEGIN_RANGE; + SeImageLayout initialLayout = SE_IMAGE_LAYOUT_UNDEFINED; + SeImageLayout finalLayout = SE_IMAGE_LAYOUT_UNDEFINED; + SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE; + SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_DONT_CARE; + SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE; + SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE; }; struct RenderTargetLayout diff --git a/src/Engine/Graphics/Vulkan/Buffer.h b/src/Engine/Graphics/Vulkan/Buffer.h index a30b1f7..bede959 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.h +++ b/src/Engine/Graphics/Vulkan/Buffer.h @@ -1,146 +1,134 @@ #pragma once -#include "Graphics/Buffer.h" #include "Graphics.h" +#include "Graphics/Buffer.h" -namespace Seele -{ -namespace Vulkan -{ -class Buffer -{ +namespace Seele { +namespace Vulkan { +class Buffer { public: - Buffer(PGraphics graphics, - uint64 size, - VkBufferUsageFlags usage, - Gfx::QueueType& queueType, - bool dynamic, - std::string name); - virtual ~Buffer(); - VkBuffer getHandle() const - { - return buffers[currentBuffer].buffer; - } - uint64 getSize() const - { - return size; - } - void advanceBuffer() - { - currentBuffer = (currentBuffer + 1) % numBuffers; - } - void *map(bool writeOnly = true); - void *mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly = true); - void unmap(); + Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, + Gfx::QueueType &queueType, bool dynamic, std::string name); + virtual ~Buffer(); + VkBuffer getHandle() const { return buffers[currentBuffer].buffer; } + uint64 getSize() const { return size; } + void *map(bool writeOnly = true); + void *mapRegion(uint64 regionOffset, uint64 regionSize, + bool writeOnly = true); + void unmap(); protected: - struct BufferAllocation - { - VkBuffer buffer; - VmaAllocation allocation; - VmaAllocationInfo info; - VkMemoryPropertyFlags properties; - }; - PGraphics graphics; - uint32 currentBuffer; - uint64 size; - Gfx::QueueType& owner; - BufferAllocation buffers[Gfx::numFramesBuffered]; - uint32 numBuffers; - std::string name; + struct BufferAllocation { + VkBuffer buffer; + VmaAllocation allocation; + VmaAllocationInfo info; + VkMemoryPropertyFlags properties; + }; + PGraphics graphics; + uint32 currentBuffer; + uint64 size; + Gfx::QueueType &owner; + Array buffers; + uint32 numBuffers; + std::string name; - void executeOwnershipBarrier(Gfx::QueueType newOwner); - void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); - - virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0; + void executeOwnershipBarrier(Gfx::QueueType newOwner); + void executePipelineBarrier(VkAccessFlags srcAccess, + VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, + VkPipelineStageFlags dstStage); - virtual VkAccessFlags getSourceAccessMask() = 0; - virtual VkAccessFlags getDestAccessMask() = 0; + virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0; + + virtual VkAccessFlags getSourceAccessMask() = 0; + virtual VkAccessFlags getDestAccessMask() = 0; }; DEFINE_REF(Buffer) -class UniformBuffer : public Gfx::UniformBuffer, public Buffer -{ +class VertexBuffer : public Gfx::VertexBuffer, public Buffer { public: - UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &sourceData); - virtual ~UniformBuffer(); - virtual bool updateContents(const DataSource &sourceData) override; - - virtual void beginFrame() override; + VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &sourceData); + virtual ~VertexBuffer(); + + virtual void updateRegion(DataSource update) override; + virtual void download(Array &buffer) override; + protected: - // Inherited via Vulkan::Buffer - virtual VkAccessFlags getSourceAccessMask() override; - virtual VkAccessFlags getDestAccessMask() override; - virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override; - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override; - virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) override; + // Inherited via Vulkan::Buffer + virtual VkAccessFlags getSourceAccessMask() override; + virtual VkAccessFlags getDestAccessMask() override; + virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override; + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override; + virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, + Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, + Gfx::SePipelineStageFlags dstStage) override; +}; +DEFINE_REF(VertexBuffer) + +class IndexBuffer : public Gfx::IndexBuffer, public Buffer { +public: + IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &sourceData); + virtual ~IndexBuffer(); + + virtual void download(Array &buffer) override; + +protected: + // Inherited via Vulkan::Buffer + virtual VkAccessFlags getSourceAccessMask() override; + virtual VkAccessFlags getDestAccessMask() override; + virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override; + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override; + virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, + Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, + Gfx::SePipelineStageFlags dstStage) override; +}; +DEFINE_REF(IndexBuffer) +class UniformBuffer : public Gfx::UniformBuffer, public Buffer { +public: + UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &sourceData); + virtual ~UniformBuffer(); + virtual bool updateContents(const DataSource &sourceData) override; + +protected: + // Inherited via Vulkan::Buffer + virtual VkAccessFlags getSourceAccessMask() override; + virtual VkAccessFlags getDestAccessMask() override; + virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override; + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override; + virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, + Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, + Gfx::SePipelineStageFlags dstStage) override; private: }; DEFINE_REF(UniformBuffer) -class ShaderBuffer : public Gfx::ShaderBuffer, public Buffer -{ +class ShaderBuffer : public Gfx::ShaderBuffer, public Buffer { public: - ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &sourceData); - virtual ~ShaderBuffer(); - virtual bool updateContents(const DataSource &sourceData) override; - virtual void beginFrame() override; + ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &sourceData); + virtual ~ShaderBuffer(); + virtual bool updateContents(const DataSource &sourceData) override; protected: - // Inherited via Vulkan::Buffer - virtual VkAccessFlags getSourceAccessMask() override; - virtual VkAccessFlags getDestAccessMask() override; - virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override; - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override; - virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) override; + // Inherited via Vulkan::Buffer + virtual VkAccessFlags getSourceAccessMask() override; + virtual VkAccessFlags getDestAccessMask() override; + virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override; + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override; + virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, + Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, + Gfx::SePipelineStageFlags dstStage) override; + private: }; DEFINE_REF(ShaderBuffer) -class VertexBuffer : public Gfx::VertexBuffer, public Buffer -{ -public: - VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &sourceData); - virtual ~VertexBuffer(); - - virtual void updateRegion(DataSource update) override; - virtual void download(Array& buffer) override; - virtual void beginFrame() override; -protected: - // Inherited via Vulkan::Buffer - virtual VkAccessFlags getSourceAccessMask() override; - virtual VkAccessFlags getDestAccessMask() override; - virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override; - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override; - virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) override; -}; -DEFINE_REF(VertexBuffer) - -class IndexBuffer : public Gfx::IndexBuffer, public Buffer -{ -public: - IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &sourceData); - virtual ~IndexBuffer(); - - virtual void download(Array& buffer) override; - virtual void beginFrame() override; -protected: - // Inherited via Vulkan::Buffer - virtual VkAccessFlags getSourceAccessMask() override; - virtual VkAccessFlags getDestAccessMask() override; - virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override; - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override; - virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, - VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) override; -}; -DEFINE_REF(IndexBuffer) -} -} \ No newline at end of file +} // namespace Vulkan +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/Descriptor.cpp b/src/Engine/Graphics/Vulkan/Descriptor.cpp index 34db576..9d07f85 100644 --- a/src/Engine/Graphics/Vulkan/Descriptor.cpp +++ b/src/Engine/Graphics/Vulkan/Descriptor.cpp @@ -1,433 +1,367 @@ #include "Descriptor.h" -#include "Graphics.h" -#include "Texture.h" #include "Buffer.h" #include "Command.h" +#include "Graphics.h" +#include "Texture.h" using namespace Seele; using namespace Seele::Vulkan; DescriptorLayout::DescriptorLayout(PGraphics graphics, const std::string& name) - : Gfx::DescriptorLayout(name) - , graphics(graphics) - , layoutHandle(VK_NULL_HANDLE) -{ -} -DescriptorLayout::~DescriptorLayout() -{ - if (layoutHandle != VK_NULL_HANDLE) - { - vkDestroyDescriptorSetLayout(graphics->getDevice(), layoutHandle, nullptr); - } + : Gfx::DescriptorLayout(name), graphics(graphics), layoutHandle(VK_NULL_HANDLE) {} + +DescriptorLayout::~DescriptorLayout() { + if (layoutHandle != VK_NULL_HANDLE) { + vkDestroyDescriptorSetLayout(graphics->getDevice(), layoutHandle, nullptr); + } } -void DescriptorLayout::create() -{ - if (layoutHandle != VK_NULL_HANDLE) - { - return; - } - bindings.resize(descriptorBindings.size()); - Array bindingFlags(descriptorBindings.size()); - for (size_t i = 0; i < descriptorBindings.size(); ++i) - { - const Gfx::DescriptorBinding &gfxBinding = descriptorBindings[i]; - bindings[i] = { - .binding = gfxBinding.binding, - .descriptorType = cast(gfxBinding.descriptorType), - .descriptorCount = gfxBinding.descriptorCount, - .stageFlags = gfxBinding.shaderStages, - .pImmutableSamplers = nullptr, - }; - bindingFlags[i] = gfxBinding.bindingFlags; - } - VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, - .pNext = nullptr, - .bindingCount = static_cast(bindingFlags.size()), - .pBindingFlags = bindingFlags.data(), +void DescriptorLayout::create() { + if (layoutHandle != VK_NULL_HANDLE) { + return; + } + bindings.resize(descriptorBindings.size()); + Array bindingFlags(descriptorBindings.size()); + for (size_t i = 0; i < descriptorBindings.size(); ++i) { + const Gfx::DescriptorBinding& gfxBinding = descriptorBindings[i]; + bindings[i] = { + .binding = gfxBinding.binding, + .descriptorType = cast(gfxBinding.descriptorType), + .descriptorCount = gfxBinding.descriptorCount, + .stageFlags = gfxBinding.shaderStages, + .pImmutableSamplers = nullptr, }; - VkDescriptorSetLayoutCreateInfo createInfo = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .pNext = &bindingFlagsInfo, - .flags = 0, - .bindingCount = (uint32)bindings.size(), - .pBindings = bindings.data(), - }; - VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle)); + bindingFlags[i] = gfxBinding.bindingFlags; + } + VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, + .pNext = nullptr, + .bindingCount = static_cast(bindingFlags.size()), + .pBindingFlags = bindingFlags.data(), + }; + VkDescriptorSetLayoutCreateInfo createInfo = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .pNext = &bindingFlagsInfo, + .flags = 0, + .bindingCount = (uint32)bindings.size(), + .pBindings = bindings.data(), + }; + VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle)); - pool = new DescriptorPool(graphics, *this); + pool = new DescriptorPool(graphics, this); - hash = CRC::Calculate(bindings.data(), sizeof(VkDescriptorSetLayoutBinding) * bindings.size(), CRC::CRC_32()); + hash = CRC::Calculate(bindings.data(), sizeof(VkDescriptorSetLayoutBinding) * bindings.size(), CRC::CRC_32()); } -PipelineLayout::~PipelineLayout() -{ -} +DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout) : graphics(graphics), layout(layout) { + for (uint32 i = 0; i < cachedHandles.size(); ++i) { + cachedHandles[i] = nullptr; + } -Map cachedLayouts; - -void PipelineLayout::create() -{ - vulkanDescriptorLayouts.resize(descriptorSetLayouts.size()); - for (size_t i = 0; i < descriptorSetLayouts.size(); ++i) - { - // There could be unused descriptor set indices - if(descriptorSetLayouts[i] == nullptr) - { - vulkanDescriptorLayouts[i] = VK_NULL_HANDLE; - continue; - } - PDescriptorLayout layout = descriptorSetLayouts[i].cast(); - layout->create(); - vulkanDescriptorLayouts[i] = layout->getHandle(); + uint32 perTypeSizes[VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT]; // TODO: FIX ENUM + std::memset(perTypeSizes, 0, sizeof(perTypeSizes)); + for (uint32 i = 0; i < layout->getBindings().size(); ++i) { + auto& binding = layout->getBindings()[i]; + int typeIndex = binding.descriptorType; + perTypeSizes[typeIndex] += 256; + } + Array poolSizes; + for (uint32 i = 0; i < VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; ++i) { + if (perTypeSizes[i] > 0) { + VkDescriptorPoolSize size; + size.descriptorCount = perTypeSizes[i]; + size.type = (VkDescriptorType)i; + poolSizes.add(size); } - - Array vkPushConstants(pushConstants.size()); - for (size_t i = 0; i < pushConstants.size(); i++) - { - vkPushConstants[i].offset = pushConstants[i].offset; - vkPushConstants[i].size = pushConstants[i].size; - vkPushConstants[i].stageFlags = (VkShaderStageFlagBits)pushConstants[i].stageFlags; - } - - VkPipelineLayoutCreateInfo createInfo = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .setLayoutCount = (uint32)vulkanDescriptorLayouts.size(), - .pSetLayouts = vulkanDescriptorLayouts.data(), - .pushConstantRangeCount = (uint32)vkPushConstants.size(), - .pPushConstantRanges = vkPushConstants.data(), - }; - - layoutHash = CRC::Calculate(createInfo.pPushConstantRanges, sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount, CRC::CRC_32()); - layoutHash = CRC::Calculate(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount, CRC::CRC_32(), layoutHash); - - if (cachedLayouts.contains(layoutHash)) - { - layoutHandle = cachedLayouts[layoutHash]; - return; - } - - VK_CHECK(vkCreatePipelineLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle)); - cachedLayouts[layoutHash] = layoutHandle; + } + VkDescriptorPoolCreateInfo createInfo = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .maxSets = maxSets * Gfx::numFramesBuffered, + .poolSizeCount = (uint32)poolSizes.size(), + .pPoolSizes = poolSizes.data(), + }; + VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle)); } -void PipelineLayout::reset() -{ - vkDestroyPipelineLayout(graphics->getDevice(), layoutHandle, nullptr); - descriptorSetLayouts.clear(); - pushConstants.clear(); +DescriptorPool::~DescriptorPool() { + graphics->getDestructionManager()->queueDescriptorPool(graphics->getGraphicsCommands()->getCommands(), poolHandle); + if (nextAlloc) { + delete nextAlloc; + } } -DescriptorSet::~DescriptorSet() -{ -} - -void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) -{ - PUniformBuffer vulkanBuffer = uniformBuffer.cast(); - UniformBuffer* cachedBuffer = reinterpret_cast(cachedData[binding]); - if(vulkanBuffer->isDataEquals(cachedBuffer)) - { - //std::cout << "uniform data equal, skip" << std::endl; - return; +Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet() { + VkDescriptorSetLayout layoutHandle = layout->getHandle(); + VkDescriptorSetVariableDescriptorCountAllocateInfo setCounts = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO, + .pNext = nullptr, + .descriptorSetCount = 1, + }; + VkDescriptorSetAllocateInfo allocInfo = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .pNext = nullptr, + .descriptorPool = poolHandle, + .descriptorSetCount = 1, + .pSetLayouts = &layoutHandle, + }; + uint32 counts = 0; + for (const auto& binding : layout->bindings) { + if (binding.descriptorCount > 0) { + counts = binding.descriptorCount; } - bufferInfos.add(VkDescriptorBufferInfo{ - .buffer = vulkanBuffer->getHandle(), - .offset = 0, - .range = vulkanBuffer->getSize(), - }); + } + if (layout->bindings.size() > 0) { + setCounts.pDescriptorCounts = &counts; + allocInfo.pNext = &setCounts; + } + for (uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex) { + if (cachedHandles[setIndex] == nullptr) { + cachedHandles[setIndex] = new DescriptorSet(graphics, this); + } + if (cachedHandles[setIndex]->isCurrentlyBound() || cachedHandles[setIndex]->isCurrentlyInUse()) { + // Currently in use, skip + continue; + } + if (cachedHandles[setIndex]->getHandle() == VK_NULL_HANDLE) { + // If it hasnt been initialized, allocate it + VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &cachedHandles[setIndex]->setHandle)); + } + cachedHandles[setIndex]->allocate(); - writeDescriptors.add(VkWriteDescriptorSet{ - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = setHandle, - .dstBinding = binding, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .pBufferInfo = &bufferInfos.back(), - }); + PDescriptorSet vulkanSet = cachedHandles[setIndex]; + vulkanSet->cachedData.resize(layout->bindings.size()); + // Not really pretty, but this way the set knows which ones are valid + std::memset(vulkanSet->cachedData.data(), 0, sizeof(void*) * vulkanSet->cachedData.size()); - cachedData[binding] = vulkanBuffer.getHandle(); + // Found set, stop searching + return vulkanSet; + } + if (nextAlloc == nullptr) { + nextAlloc = new DescriptorPool(graphics, layout); + } + // std::cout << "Out of descriptors, forwarding" << std::endl; + return nextAlloc->allocateDescriptorSet(); + // throw std::logic_error("Out of descriptor sets"); } -void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuffer) -{ - PShaderBuffer vulkanBuffer = shaderBuffer.cast(); - ShaderBuffer* cachedBuffer = reinterpret_cast(cachedData[binding]); - if(vulkanBuffer.getHandle() == cachedBuffer) - { - return; +void DescriptorPool::reset() { + for (uint32 i = 0; i < cachedHandles.size(); ++i) { + if (cachedHandles[i] == nullptr) { + return; } - - bufferInfos.add(VkDescriptorBufferInfo{ - .buffer = vulkanBuffer->getHandle(), - .offset = 0, - .range = vulkanBuffer->getSize(), - }); - - writeDescriptors.add(VkWriteDescriptorSet{ - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = setHandle, - .dstBinding = binding, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - .pBufferInfo = &bufferInfos.back(), - }); - - cachedData[binding] = vulkanBuffer.getHandle(); + cachedHandles[i]->free(); + } + if (nextAlloc != nullptr) { + nextAlloc->reset(); + } } -void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState) -{ - PSampler vulkanSampler = samplerState.cast(); - Sampler* cachedSampler = reinterpret_cast(cachedData[binding]); - if(vulkanSampler.getHandle() == cachedSampler) - { - return; - } +DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner) + : Gfx::DescriptorSet(owner->getLayout()), setHandle(VK_NULL_HANDLE), graphics(graphics), owner(owner), bindCount(0), + currentlyInUse(false) {} +DescriptorSet::~DescriptorSet() {} + +void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) { + PUniformBuffer vulkanBuffer = uniformBuffer.cast(); + UniformBuffer* cachedBuffer = reinterpret_cast(cachedData[binding]); + if (vulkanBuffer->isDataEquals(cachedBuffer)) { + // std::cout << "uniform data equal, skip" << std::endl; + return; + } + bufferInfos.add(VkDescriptorBufferInfo{ + .buffer = vulkanBuffer->getHandle(), + .offset = 0, + .range = vulkanBuffer->getSize(), + }); + + writeDescriptors.add(VkWriteDescriptorSet{ + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = setHandle, + .dstBinding = binding, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .pBufferInfo = &bufferInfos.back(), + }); + + cachedData[binding] = vulkanBuffer.getHandle(); +} + +void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuffer) { + PShaderBuffer vulkanBuffer = shaderBuffer.cast(); + ShaderBuffer* cachedBuffer = reinterpret_cast(cachedData[binding]); + if (vulkanBuffer.getHandle() == cachedBuffer) { + return; + } + + bufferInfos.add(VkDescriptorBufferInfo{ + .buffer = vulkanBuffer->getHandle(), + .offset = 0, + .range = vulkanBuffer->getSize(), + }); + + writeDescriptors.add(VkWriteDescriptorSet{ + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = setHandle, + .dstBinding = binding, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .pBufferInfo = &bufferInfos.back(), + }); + + cachedData[binding] = vulkanBuffer.getHandle(); +} + +void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState) { + PSampler vulkanSampler = samplerState.cast(); + Sampler* cachedSampler = reinterpret_cast(cachedData[binding]); + if (vulkanSampler.getHandle() == cachedSampler) { + return; + } + imageInfos.add(VkDescriptorImageInfo{ + .sampler = vulkanSampler->sampler, + .imageView = VK_NULL_HANDLE, + .imageLayout = VK_IMAGE_LAYOUT_UNDEFINED, + }); + + writeDescriptors.add(VkWriteDescriptorSet{ + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = setHandle, + .dstBinding = binding, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, + .pImageInfo = &imageInfos.back(), + }); + + cachedData[binding] = vulkanSampler.getHandle(); +} + +void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler samplerState) { + TextureBase* vulkanTexture = texture.cast().getHandle(); + TextureBase* cachedTexture = reinterpret_cast(cachedData[binding]); + if (vulkanTexture == cachedTexture) { + return; + } + // It is assumed that the image is in the correct layout + imageInfos.add(VkDescriptorImageInfo{ + .sampler = samplerState != nullptr ? samplerState.cast()->sampler : VK_NULL_HANDLE, + .imageView = vulkanTexture->getView(), + .imageLayout = cast(vulkanTexture->getLayout()), + }); + VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + if (samplerState != nullptr) { + descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + } else if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) { + descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + } + writeDescriptors.add(VkWriteDescriptorSet{ + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = setHandle, + .dstBinding = binding, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = descriptorType, + .pImageInfo = &imageInfos.back(), + }); + + cachedData[binding] = vulkanTexture; +} +void DescriptorSet::updateTextureArray(uint32_t binding, Array textures) { + // maybe make this a parameter? + uint32 arrayElement = 0; + for (auto& gfxTexture : textures) { + TextureBase* vulkanTexture = gfxTexture.cast().getHandle(); imageInfos.add(VkDescriptorImageInfo{ - .sampler = vulkanSampler->sampler, - .imageView = VK_NULL_HANDLE, - .imageLayout = VK_IMAGE_LAYOUT_UNDEFINED, - }); - - writeDescriptors.add(VkWriteDescriptorSet{ - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = setHandle, - .dstBinding = binding, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, - .pImageInfo = &imageInfos.back(), - }); - - cachedData[binding] = vulkanSampler.getHandle(); -} - -void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler samplerState) -{ - TextureBase* vulkanTexture = texture.cast().getHandle(); - TextureBase* cachedTexture = reinterpret_cast(cachedData[binding]); - if(vulkanTexture == cachedTexture) - { - return; - } - //It is assumed that the image is in the correct layout - imageInfos.add(VkDescriptorImageInfo{ - .sampler = samplerState != nullptr ? samplerState.cast()->sampler : VK_NULL_HANDLE, + .sampler = VK_NULL_HANDLE, .imageView = vulkanTexture->getView(), .imageLayout = cast(vulkanTexture->getLayout()), }); + VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; - if(samplerState != nullptr) - { - descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - } - else if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) - { - descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) { + descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; } writeDescriptors.add(VkWriteDescriptorSet{ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, .pNext = nullptr, .dstSet = setHandle, .dstBinding = binding, - .dstArrayElement = 0, + .dstArrayElement = arrayElement++, .descriptorCount = 1, .descriptorType = descriptorType, .pImageInfo = &imageInfos.back(), - }); - - cachedData[binding] = vulkanTexture; -} -void DescriptorSet::updateTextureArray(uint32_t binding, Array textures) -{ - // maybe make this a parameter? - uint32 arrayElement = 0; - for(auto& gfxTexture : textures) - { - TextureBase* vulkanTexture = gfxTexture.cast().getHandle(); - imageInfos.add(VkDescriptorImageInfo{ - .sampler = VK_NULL_HANDLE, - .imageView = vulkanTexture->getView(), - .imageLayout = cast(vulkanTexture->getLayout()), - }); - - VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; - if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) - { - descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - } - writeDescriptors.add(VkWriteDescriptorSet{ - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = setHandle, - .dstBinding = binding, - .dstArrayElement = arrayElement++, - .descriptorCount = 1, - .descriptorType = descriptorType, - .pImageInfo = &imageInfos.back(), - }); - } + }); + } } -bool DescriptorSet::operator<(Gfx::PDescriptorSet other) -{ - PDescriptorSet otherSet = other.cast(); - return this < otherSet.getHandle(); +void DescriptorSet::writeChanges() { + if (writeDescriptors.size() > 0) { + if (isCurrentlyBound()) { + std::cout << "Descriptor currently bound, allocate a new one instead" << std::endl; + assert(!isCurrentlyBound()); + } + vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr); + writeDescriptors.clear(); + imageInfos.clear(); + bufferInfos.clear(); + } } -uint32 DescriptorSet::getSetIndex() const -{ - return owner->getLayout().getSetIndex(); -} +PipelineLayout::PipelineLayout(PGraphics graphics, Gfx::PPipelineLayout baseLayout) + : Gfx::PipelineLayout(baseLayout), graphics(graphics), layoutHandle(VK_NULL_HANDLE) {} -void DescriptorSet::writeChanges() -{ - if (writeDescriptors.size() > 0) - { - if(isCurrentlyBound()) - { - std::cout << "Descriptor currently bound, allocate a new one instead" << std::endl; - assert(!isCurrentlyBound()); - } - vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr); - writeDescriptors.clear(); - imageInfos.clear(); - bufferInfos.clear(); - } -} +PipelineLayout::~PipelineLayout() {} -DescriptorPool::DescriptorPool(PGraphics graphics, DescriptorLayout &layout) - : graphics(graphics) - , layout(layout) -{ - for(uint32 i = 0; i < cachedHandles.size(); ++i) - { - cachedHandles[i] = nullptr; - } +Map cachedLayouts; - uint32 perTypeSizes[VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT]; // TODO: FIX ENUM - std::memset(perTypeSizes, 0, sizeof(perTypeSizes)); - for (uint32 i = 0; i < layout.getBindings().size(); ++i) - { - auto &binding = layout.getBindings()[i]; - int typeIndex = binding.descriptorType; - perTypeSizes[typeIndex] += 256; +void PipelineLayout::create() { + vulkanDescriptorLayouts.resize(descriptorSetLayouts.size()); + for (size_t i = 0; i < descriptorSetLayouts.size(); ++i) { + // There could be unused descriptor set indices + if (descriptorSetLayouts[i] == nullptr) { + vulkanDescriptorLayouts[i] = VK_NULL_HANDLE; + continue; } - Array poolSizes; - for (uint32 i = 0; i < VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; ++i) - { - if (perTypeSizes[i] > 0) - { - VkDescriptorPoolSize size; - size.descriptorCount = perTypeSizes[i]; - size.type = (VkDescriptorType)i; - poolSizes.add(size); - } - } - VkDescriptorPoolCreateInfo createInfo = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .maxSets = maxSets * Gfx::numFramesBuffered, - .poolSizeCount = (uint32)poolSizes.size(), - .pPoolSizes = poolSizes.data(), - }; - VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle)); -} + PDescriptorLayout layout = descriptorSetLayouts[i].cast(); + layout->create(); + vulkanDescriptorLayouts[i] = layout->getHandle(); + } -DescriptorPool::~DescriptorPool() -{ - graphics->getDestructionManager()->queueDescriptorPool(graphics->getGraphicsCommands()->getCommands(), poolHandle); - if(nextAlloc) - { - delete nextAlloc; - } -} + Array vkPushConstants(pushConstants.size()); + for (size_t i = 0; i < pushConstants.size(); i++) { + vkPushConstants[i].offset = pushConstants[i].offset; + vkPushConstants[i].size = pushConstants[i].size; + vkPushConstants[i].stageFlags = (VkShaderStageFlagBits)pushConstants[i].stageFlags; + } -Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet() -{ - VkDescriptorSetLayout layoutHandle = layout.getHandle(); - VkDescriptorSetVariableDescriptorCountAllocateInfo setCounts = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO, - .pNext = nullptr, - .descriptorSetCount = 1, - }; - VkDescriptorSetAllocateInfo allocInfo = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .pNext = nullptr, - .descriptorPool = poolHandle, - .descriptorSetCount = 1, - .pSetLayouts = &layoutHandle, - }; - uint32 counts = 0; - for(const auto& binding : layout.bindings) - { - if(binding.descriptorCount > 0) - { - counts = binding.descriptorCount; - } - } - if (layout.bindings.size() > 0) - { - setCounts.pDescriptorCounts = &counts; - allocInfo.pNext = &setCounts; - } - for(uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex) - { - if(cachedHandles[setIndex] == nullptr) - { - cachedHandles[setIndex] = new DescriptorSet(graphics, this); - } - if(cachedHandles[setIndex]->isCurrentlyBound() || cachedHandles[setIndex]->isCurrentlyInUse()) - { - // Currently in use, skip - continue; - } - if(cachedHandles[setIndex]->getHandle() == VK_NULL_HANDLE) - { - //If it hasnt been initialized, allocate it - VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &cachedHandles[setIndex]->setHandle)); - } - cachedHandles[setIndex]->allocate(); - - PDescriptorSet vulkanSet = cachedHandles[setIndex]; - vulkanSet->cachedData.resize(layout.bindings.size()); - // Not really pretty, but this way the set knows which ones are valid - std::memset(vulkanSet->cachedData.data(), 0, sizeof(void*) * vulkanSet->cachedData.size()); - - //Found set, stop searching - return vulkanSet; - } - if(nextAlloc == nullptr) - { - nextAlloc = new DescriptorPool(graphics, layout); - } - //std::cout << "Out of descriptors, forwarding" << std::endl; - return nextAlloc->allocateDescriptorSet(); - //throw std::logic_error("Out of descriptor sets"); -} + VkPipelineLayoutCreateInfo createInfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .setLayoutCount = (uint32)vulkanDescriptorLayouts.size(), + .pSetLayouts = vulkanDescriptorLayouts.data(), + .pushConstantRangeCount = (uint32)vkPushConstants.size(), + .pPushConstantRanges = vkPushConstants.data(), + }; -void DescriptorPool::reset() -{ - for(uint32 i = 0; i < cachedHandles.size(); ++i) - { - if(cachedHandles[i] == nullptr) - { - return; - } - cachedHandles[i]->free(); - } - if(nextAlloc != nullptr) - { - nextAlloc->reset(); - } + layoutHash = CRC::Calculate(createInfo.pPushConstantRanges, + sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount, CRC::CRC_32()); + layoutHash = CRC::Calculate(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount, + CRC::CRC_32(), layoutHash); + + if (cachedLayouts.contains(layoutHash)) { + layoutHandle = cachedLayouts[layoutHash]; + return; + } + + VK_CHECK(vkCreatePipelineLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle)); + cachedLayouts[layoutHash] = layoutHandle; } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/Descriptor.h b/src/Engine/Graphics/Vulkan/Descriptor.h index c5bd0c5..cdad028 100644 --- a/src/Engine/Graphics/Vulkan/Descriptor.h +++ b/src/Engine/Graphics/Vulkan/Descriptor.h @@ -1,150 +1,100 @@ #pragma once +#include "Containers/List.h" #include "Enums.h" #include "Graphics/Descriptor.h" -#include "Containers/List.h" #include "Resources.h" -namespace Seele -{ -namespace Vulkan -{ +namespace Seele { +namespace Vulkan { DECLARE_REF(Graphics) -class DescriptorLayout : public Gfx::DescriptorLayout -{ +class DescriptorLayout : public Gfx::DescriptorLayout { public: - DescriptorLayout(PGraphics graphics, const std::string& name); - virtual ~DescriptorLayout(); - virtual void create() override; - constexpr VkDescriptorSetLayout getHandle() const - { - return layoutHandle; - } + DescriptorLayout(PGraphics graphics, const std::string& name); + virtual ~DescriptorLayout(); + virtual void create() override; + constexpr VkDescriptorSetLayout getHandle() const { return layoutHandle; } + private: - uint32 hash; - PGraphics graphics; - Array bindings; - VkDescriptorSetLayout layoutHandle; - friend class DescriptorPool; + PGraphics graphics; + Array bindings; + VkDescriptorSetLayout layoutHandle; + friend class DescriptorPool; }; DEFINE_REF(DescriptorLayout) -class PipelineLayout : public Gfx::PipelineLayout -{ + +DECLARE_REF(DescriptorSet) +class DescriptorPool : public Gfx::DescriptorPool { public: - PipelineLayout(PGraphics graphics, Gfx::PPipelineLayout baseLayout) - : Gfx::PipelineLayout(baseLayout) - , graphics(graphics) - , layoutHandle(VK_NULL_HANDLE) - {} - virtual ~PipelineLayout(); - virtual void create(); - virtual void reset(); - constexpr VkPipelineLayout getHandle() const - { - return layoutHandle; - } + DescriptorPool(PGraphics graphics, PDescriptorLayout layout); + virtual ~DescriptorPool(); + virtual Gfx::PDescriptorSet allocateDescriptorSet() override; + virtual void reset() override; + + constexpr VkDescriptorPool getHandle() const { return poolHandle; } + constexpr PDescriptorLayout getLayout() const { return layout; } private: - Array vulkanDescriptorLayouts; - PGraphics graphics; - VkPipelineLayout layoutHandle; + PGraphics graphics; + PDescriptorLayout layout; + const static int maxSets = 64; + StaticArray cachedHandles; + VkDescriptorPool poolHandle; + DescriptorPool* nextAlloc = nullptr; }; -DEFINE_REF(PipelineLayout) +DEFINE_REF(DescriptorPool) -class DescriptorSet : public Gfx::DescriptorSet -{ +class DescriptorSet : public Gfx::DescriptorSet { public: - DescriptorSet(PGraphics graphics, PDescriptorPool owner) - : setHandle(VK_NULL_HANDLE) - , graphics(graphics) - , owner(owner) - , bindCount(0) - , currentlyInUse(false) - { - } - virtual ~DescriptorSet(); - virtual void writeChanges(); - virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer); - virtual void updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer); - virtual void updateSampler(uint32_t binding, Gfx::PSampler samplerState); - virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler sampler = nullptr); - virtual void updateTextureArray(uint32_t binding, Array texture); - virtual bool operator<(Gfx::PDescriptorSet other); - - constexpr bool isCurrentlyBound() const - { - return bindCount > 0; - } - constexpr bool isCurrentlyInUse() const - { - return currentlyInUse; - } - constexpr void bind() - { - bindCount++; - } - constexpr void unbind() - { - bindCount--; - } - constexpr void allocate() - { - currentlyInUse = true; - } - constexpr void free() - { - currentlyInUse = false; - } - constexpr VkDescriptorSet getHandle() const - { - return setHandle; - } - virtual uint32 getSetIndex() const; + DescriptorSet(PGraphics graphics, PDescriptorPool owner); + virtual ~DescriptorSet(); + virtual void writeChanges() override; + virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) override; + virtual void updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer) override; + virtual void updateSampler(uint32_t binding, Gfx::PSampler samplerState) override; + virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler sampler = nullptr) override; + virtual void updateTextureArray(uint32_t binding, Array texture) override; + + constexpr bool isCurrentlyBound() const { return bindCount > 0; } + constexpr bool isCurrentlyInUse() const { return currentlyInUse; } + constexpr void bind() { bindCount++; } + constexpr void unbind() { bindCount--; } + constexpr void allocate() { currentlyInUse = true; } + constexpr void free() { currentlyInUse = false; } + constexpr VkDescriptorSet getHandle() const { return setHandle; } private: - List imageInfos; - List bufferInfos; - Array writeDescriptors; - // contains the previously bound resources at every binding - // since the layout is fixed, trying to bind a texture to a buffer - // would not work anyways, so casts should be safe - Array cachedData; - VkDescriptorSet setHandle; - PGraphics graphics; - PDescriptorPool owner; - uint32 bindCount; - bool currentlyInUse; - friend class DescriptorPool; - friend class Command; - friend class RenderCommand; - friend class ComputeCommand; + List imageInfos; + List bufferInfos; + Array writeDescriptors; + // contains the previously bound resources at every binding + // since the layout is fixed, trying to bind a texture to a buffer + // would not work anyways, so casts should be safe + Array cachedData; + VkDescriptorSet setHandle; + PGraphics graphics; + PDescriptorPool owner; + uint32 bindCount; + bool currentlyInUse; + friend class DescriptorPool; + friend class Command; + friend class RenderCommand; + friend class ComputeCommand; }; DEFINE_REF(DescriptorSet) -class DescriptorPool : public Gfx::DescriptorPool -{ +class PipelineLayout : public Gfx::PipelineLayout { public: - DescriptorPool(PGraphics graphics, DescriptorLayout &layout); - virtual ~DescriptorPool(); - virtual Gfx::PDescriptorSet allocateDescriptorSet() override; - virtual void reset() override; - - constexpr VkDescriptorPool getHandle() const - { - return poolHandle; - } - constexpr DescriptorLayout& getLayout() const - { - return layout; - } + PipelineLayout(PGraphics graphics, Gfx::PPipelineLayout baseLayout); + virtual ~PipelineLayout(); + virtual void create(); + constexpr VkPipelineLayout getHandle() const { return layoutHandle; } private: - PGraphics graphics; - DescriptorLayout &layout; - const static int maxSets = 64; - StaticArray cachedHandles; - VkDescriptorPool poolHandle; - DescriptorPool* nextAlloc = nullptr; + Array vulkanDescriptorLayouts; + PGraphics graphics; + VkPipelineLayout layoutHandle; }; -DEFINE_REF(DescriptorPool) +DEFINE_REF(PipelineLayout) + } // namespace Vulkan } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/Enums.cpp b/src/Engine/Graphics/Vulkan/Enums.cpp index e7b3d4b..40d9a6a 100644 --- a/src/Engine/Graphics/Vulkan/Enums.cpp +++ b/src/Engine/Graphics/Vulkan/Enums.cpp @@ -1,4 +1,5 @@ #include "Enums.h" +#include using namespace Seele; using namespace Seele::Vulkan; @@ -76,9 +77,8 @@ Seele::Gfx::SeDescriptorType Seele::Vulkan::cast(const VkDescriptorType &descrip return SE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV; #endif default: - break; + throw std::logic_error("Not implemented"); } - return SE_DESCRIPTOR_TYPE_MAX_ENUM; } VkShaderStageFlagBits Seele::Vulkan::cast(const Seele::Gfx::SeShaderStageFlagBits &stage) @@ -120,10 +120,9 @@ VkShaderStageFlagBits Seele::Vulkan::cast(const Seele::Gfx::SeShaderStageFlagBit case SE_SHADER_STAGE_MESH_BIT_NV: return VK_SHADER_STAGE_MESH_BIT_NV; #endif - default: - break; + default: throw std::logic_error("Not implemented"); + } - return VK_SHADER_STAGE_ALL; } Seele::Gfx::SeShaderStageFlagBits Seele::Vulkan::cast(const VkShaderStageFlagBits &stage) @@ -164,10 +163,10 @@ Seele::Gfx::SeShaderStageFlagBits Seele::Vulkan::cast(const VkShaderStageFlagBit case VK_SHADER_STAGE_MESH_BIT_NV: return SE_SHADER_STAGE_MESH_BIT_NV; #endif - default: - break; + default: throw std::logic_error("Not implemented"); + } - return SE_SHADER_STAGE_ALL; + } VkFormat Seele::Vulkan::cast(const Seele::Gfx::SeFormat &format) @@ -1090,8 +1089,8 @@ Seele::Gfx::SeFormat Seele::Vulkan::cast(const VkFormat &format) return SE_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG; case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG: return SE_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG; - default: - return SE_FORMAT_MAX_ENUM; + default: throw std::logic_error("Not implemented"); + } } @@ -1129,8 +1128,8 @@ VkImageLayout Seele::Vulkan::cast(const Gfx::SeImageLayout &imageLayout) return VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV; case SE_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT: return VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; - default: - return VK_IMAGE_LAYOUT_MAX_ENUM; + default: throw std::logic_error("Not implemented"); + } } Gfx::SeImageLayout Seele::Vulkan::cast(const VkImageLayout &imageLayout) @@ -1167,8 +1166,8 @@ Gfx::SeImageLayout Seele::Vulkan::cast(const VkImageLayout &imageLayout) return SE_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV; case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT: return SE_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; - default: - return SE_IMAGE_LAYOUT_MAX_ENUM; + default: throw std::logic_error("Not implemented"); + } } VkAttachmentStoreOp Seele::Vulkan::cast(const Gfx::SeAttachmentStoreOp &storeOp) @@ -1179,8 +1178,8 @@ VkAttachmentStoreOp Seele::Vulkan::cast(const Gfx::SeAttachmentStoreOp &storeOp) return VK_ATTACHMENT_STORE_OP_STORE; case SE_ATTACHMENT_STORE_OP_DONT_CARE: return VK_ATTACHMENT_STORE_OP_DONT_CARE; - default: - return VK_ATTACHMENT_STORE_OP_MAX_ENUM; + default: throw std::logic_error("Not implemented"); + } } Gfx::SeAttachmentStoreOp Seele::Vulkan::cast(const VkAttachmentStoreOp &storeOp) @@ -1191,8 +1190,8 @@ Gfx::SeAttachmentStoreOp Seele::Vulkan::cast(const VkAttachmentStoreOp &storeOp) return SE_ATTACHMENT_STORE_OP_STORE; case VK_ATTACHMENT_STORE_OP_DONT_CARE: return SE_ATTACHMENT_STORE_OP_DONT_CARE; - default: - return SE_ATTACHMENT_STORE_OP_MAX_ENUM; + default: throw std::logic_error("Not implemented"); + } } VkAttachmentLoadOp Seele::Vulkan::cast(const Gfx::SeAttachmentLoadOp &loadOp) @@ -1205,8 +1204,8 @@ VkAttachmentLoadOp Seele::Vulkan::cast(const Gfx::SeAttachmentLoadOp &loadOp) return VK_ATTACHMENT_LOAD_OP_CLEAR; case SE_ATTACHMENT_LOAD_OP_DONT_CARE: return VK_ATTACHMENT_LOAD_OP_DONT_CARE; - default: - return VK_ATTACHMENT_LOAD_OP_MAX_ENUM; + default: throw std::logic_error("Not implemented"); + } } Gfx::SeAttachmentLoadOp Seele::Vulkan::cast(const VkAttachmentLoadOp &loadOp) @@ -1219,8 +1218,8 @@ Gfx::SeAttachmentLoadOp Seele::Vulkan::cast(const VkAttachmentLoadOp &loadOp) return SE_ATTACHMENT_LOAD_OP_CLEAR; case VK_ATTACHMENT_LOAD_OP_DONT_CARE: return SE_ATTACHMENT_LOAD_OP_DONT_CARE; - default: - return SE_ATTACHMENT_LOAD_OP_MAX_ENUM; + default: throw std::logic_error("Not implemented"); + } } @@ -1244,8 +1243,8 @@ Gfx::SeIndexType Seele::Vulkan::cast(const VkIndexType &indexType) return Gfx::SE_INDEX_TYPE_UINT16; case VK_INDEX_TYPE_UINT32: return Gfx::SE_INDEX_TYPE_UINT32; - default: - return Gfx::SE_INDEX_TYPE_MAX_ENUM; + default: throw std::logic_error("Not implemented"); + } } @@ -1305,8 +1304,8 @@ Gfx::SePrimitiveTopology Seele::Vulkan::cast(const VkPrimitiveTopology &topology return SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY; case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: return SE_PRIMITIVE_TOPOLOGY_PATCH_LIST; - default: - return SE_PRIMITIVE_TOPOLOGY_MAX_ENUM; + default: throw std::logic_error("Not implemented"); + } } @@ -1334,8 +1333,8 @@ Gfx::SePolygonMode Seele::Vulkan::cast(const VkPolygonMode &mode) return SE_POLYGON_MODE_LINE; case VK_POLYGON_MODE_POINT: return SE_POLYGON_MODE_POINT; - default: - return SE_POLYGON_MODE_MAX_ENUM; + default: throw std::logic_error("Not implemented"); + } } VkCompareOp Seele::Vulkan::cast(const Gfx::SeCompareOp &op) @@ -1358,8 +1357,8 @@ VkCompareOp Seele::Vulkan::cast(const Gfx::SeCompareOp &op) return VK_COMPARE_OP_GREATER_OR_EQUAL; case SE_COMPARE_OP_ALWAYS: return VK_COMPARE_OP_ALWAYS; - default: - return VK_COMPARE_OP_MAX_ENUM; + default: throw std::logic_error("Not implemented"); + } } Gfx::SeCompareOp Seele::Vulkan::cast(const VkCompareOp &op) @@ -1382,8 +1381,8 @@ Gfx::SeCompareOp Seele::Vulkan::cast(const VkCompareOp &op) return SE_COMPARE_OP_GREATER_OR_EQUAL; case VK_COMPARE_OP_ALWAYS: return SE_COMPARE_OP_ALWAYS; - default: - return SE_COMPARE_OP_MAX_ENUM; + default: throw std::logic_error("Not implemented"); + } } @@ -1455,8 +1454,8 @@ Gfx::SeSamplerAddressMode Seele::Vulkan::cast(const VkSamplerAddressMode &mode) return SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE: return SE_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; - default: - return SE_SAMPLER_ADDRESS_MODE_MAX_ENUM; + default: throw std::logic_error("Not implemented"); + } } VkBorderColor Seele::Vulkan::cast(const Gfx::SeBorderColor &color) @@ -1495,8 +1494,8 @@ Gfx::SeBorderColor Seele::Vulkan::cast(const VkBorderColor &color) return SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE; case VK_BORDER_COLOR_INT_OPAQUE_WHITE: return SE_BORDER_COLOR_INT_OPAQUE_WHITE; - default: - return SE_BORDER_COLOR_MAX_ENUM; + default: throw std::logic_error("Not implemented"); + } } @@ -1510,8 +1509,8 @@ VkFilter Seele::Vulkan::cast(const Gfx::SeFilter &filter) return VK_FILTER_LINEAR; case SE_FILTER_CUBIC_IMG: return VK_FILTER_CUBIC_IMG; - default: - return VK_FILTER_MAX_ENUM; + default: throw std::logic_error("Not implemented"); + } } Gfx::SeFilter Seele::Vulkan::cast(const VkFilter &filter) @@ -1524,8 +1523,8 @@ Gfx::SeFilter Seele::Vulkan::cast(const VkFilter &filter) return SE_FILTER_LINEAR; case VK_FILTER_CUBIC_IMG: return SE_FILTER_CUBIC_IMG; - default: - return SE_FILTER_MAX_ENUM; + default: throw std::logic_error("Not implemented"); + } } @@ -1537,8 +1536,8 @@ VkSamplerMipmapMode Seele::Vulkan::cast(const Gfx::SeSamplerMipmapMode &filter) return VK_SAMPLER_MIPMAP_MODE_NEAREST; case SE_SAMPLER_MIPMAP_MODE_LINEAR: return VK_SAMPLER_MIPMAP_MODE_LINEAR; - default: - return VK_SAMPLER_MIPMAP_MODE_MAX_ENUM; + default: throw std::logic_error("Not implemented"); + } } Gfx::SeSamplerMipmapMode Seele::Vulkan::cast(const VkSamplerMipmapMode &filter) @@ -1549,8 +1548,8 @@ Gfx::SeSamplerMipmapMode Seele::Vulkan::cast(const VkSamplerMipmapMode &filter) return SE_SAMPLER_MIPMAP_MODE_NEAREST; case VK_SAMPLER_MIPMAP_MODE_LINEAR: return SE_SAMPLER_MIPMAP_MODE_LINEAR; - default: - return SE_SAMPLER_MIPMAP_MODE_MAX_ENUM; + default: throw std::logic_error("Not implemented"); + } } VkAccessFlagBits Seele::Vulkan::cast(const Gfx::SeAccessFlagBits &flags) diff --git a/src/Engine/Graphics/Vulkan/PipelineCache.h b/src/Engine/Graphics/Vulkan/PipelineCache.h index 2f2b3e9..e6bbfc0 100644 --- a/src/Engine/Graphics/Vulkan/PipelineCache.h +++ b/src/Engine/Graphics/Vulkan/PipelineCache.h @@ -14,7 +14,7 @@ public: PGraphicsPipeline createPipeline(Gfx::MeshPipelineCreateInfo createInfo); PComputePipeline createPipeline(Gfx::ComputePipelineCreateInfo createInfo); private: - std::map graphicsPipelines; + Map graphicsPipelines; Map computePipelines; std::mutex cacheLock; VkPipelineCache cache; diff --git a/vcpkg.json b/vcpkg.json index d023adf..e07c93c 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -12,6 +12,8 @@ "fmt", "gtest", "vulkan-memory-allocator", - "shader-slang" + "shader-slang", + "spirv-cross", + "glslang" ] } \ No newline at end of file