diff --git a/cmake/SuperBuild.cmake b/cmake/SuperBuild.cmake index eb8e56c..226df12 100644 --- a/cmake/SuperBuild.cmake +++ b/cmake/SuperBuild.cmake @@ -80,7 +80,7 @@ set(SLANG_BINARY_DIR ${SLANG_ROOT}/bin/linux-x64/release) ExternalProject_Add(slang-build SOURCE_DIR ${SLANG_ROOT} BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} - CONFIGURE_COMMAND premake5 --file=${CMAKE_SOURCE_DIR}/external/slang/premake5.lua gmake2 --arch=x64 --deps=true --build-location=build/linux + CONFIGURE_COMMAND ${CMAKE_SOURCE_DIR}/premake5 --file=${CMAKE_SOURCE_DIR}/external/slang/premake5.lua gmake2 --arch=x64 --deps=true --build-location=build/linux BUILD_COMMAND make -C ${CMAKE_SOURCE_DIR}/external/slang/build/linux config=${SLANG_CONFIG} INSTALL_COMMAND "" ) diff --git a/external/slang b/external/slang index cc22270..4547125 160000 --- a/external/slang +++ b/external/slang @@ -1 +1 @@ -Subproject commit cc222702a8d7a1fccf8ad14b256570bcec1554ae +Subproject commit 4547125ce945140dc10542e9606b225dd06159b8 diff --git a/src/Editor/Asset/MeshLoader.cpp b/src/Editor/Asset/MeshLoader.cpp index 7459c5a..da46245 100644 --- a/src/Editor/Asset/MeshLoader.cpp +++ b/src/Editor/Asset/MeshLoader.cpp @@ -177,71 +177,64 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array meshlets; - if (Gfx::useMeshShading) + meshlets.reserve(indices.size() / (3ull * Gfx::numPrimitivesPerMeshlet)); + std::set uniqueVertices; + Meshlet current = { + .numVertices = 0, + .numPrimitives = 0, + }; + auto insertAndGetIndex = [&uniqueVertices, ¤t](uint32 index) -> int8_t { - meshlets.reserve(indices.size() / (3ull * Gfx::numPrimitivesPerMeshlet)); - std::set uniqueVertices; - Meshlet current = { + auto [it, inserted] = uniqueVertices.insert(index); + if (inserted) + { + if (current.numVertices == Gfx::numVerticesPerMeshlet) + { + return -1; + } + current.uniqueVertices[current.numVertices] = index; + return current.numVertices++; + } + else + { + for (uint32 i = 0; i < current.numVertices; ++i) + { + if (current.uniqueVertices[i] == index) + { + return i; + } + } + assert(false); + } + }; + auto completeMeshlet = [&meshlets, ¤t, &uniqueVertices]() { + meshlets.add(current); + current = { .numVertices = 0, .numPrimitives = 0, }; - auto insertAndGetIndex = [&uniqueVertices, ¤t](uint32 index) -> int8_t - { - auto [it, inserted] = uniqueVertices.insert(index); - if (inserted) - { - if (current.numVertices == Gfx::numVerticesPerMeshlet) - { - return -1; - } - current.uniqueVertices[current.numVertices] = index; - return current.numVertices++; - } - else - { - for (uint32 i = 0; i < current.numVertices; ++i) - { - if (current.uniqueVertices[i] == index) - { - return i; - } - } - assert(false); - } - }; - auto completeMeshlet = [&meshlets, ¤t, &uniqueVertices]() { - meshlets.add(current); - current = { - .numVertices = 0, - .numPrimitives = 0, - }; - uniqueVertices.clear(); - }; - for (size_t faceIndex = 0; faceIndex < mesh->mNumFaces; ++faceIndex) - { - auto i1 = insertAndGetIndex(mesh->mFaces[faceIndex].mIndices[0]); - auto i2 = insertAndGetIndex(mesh->mFaces[faceIndex].mIndices[1]); - auto i3 = insertAndGetIndex(mesh->mFaces[faceIndex].mIndices[2]); - if (i1 == -1 || i2 == -1 || i3 == -1) - { - completeMeshlet(); - } - current.primitiveLayout[current.numPrimitives * 3 + 0] = i1; - current.primitiveLayout[current.numPrimitives * 3 + 1] = i2; - current.primitiveLayout[current.numPrimitives * 3 + 2] = i3; - current.numPrimitives++; - if (current.numPrimitives == Gfx::numPrimitivesPerMeshlet) - { - completeMeshlet(); - } - } - vertexData->loadMesh(id, meshlets); - } - else + uniqueVertices.clear(); + }; + for (size_t faceIndex = 0; faceIndex < mesh->mNumFaces; ++faceIndex) { - // \! todo + auto i1 = insertAndGetIndex(mesh->mFaces[faceIndex].mIndices[0]); + auto i2 = insertAndGetIndex(mesh->mFaces[faceIndex].mIndices[1]); + auto i3 = insertAndGetIndex(mesh->mFaces[faceIndex].mIndices[2]); + if (i1 == -1 || i2 == -1 || i3 == -1) + { + completeMeshlet(); + } + current.primitiveLayout[current.numPrimitives * 3 + 0] = i1; + current.primitiveLayout[current.numPrimitives * 3 + 1] = i2; + current.primitiveLayout[current.numPrimitives * 3 + 2] = i3; + current.numPrimitives++; + if (current.numPrimitives == Gfx::numPrimitivesPerMeshlet) + { + completeMeshlet(); + } } - + vertexData->loadMesh(id, meshlets); + collider.physicsMesh.addCollider(positions, indices, Matrix4(1.0f)); @@ -262,6 +255,7 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Arraymeshlets = std::move(meshlets); globalMeshes[meshIndex]->vertexCount = mesh->mNumVertices; + globalMeshes[meshIndex]->indexBuffer = std::move(indexBuffer); } } diff --git a/src/Engine/Graphics/Enums.h b/src/Engine/Graphics/Enums.h index cabc738..ec3af48 100644 --- a/src/Engine/Graphics/Enums.h +++ b/src/Engine/Graphics/Enums.h @@ -165,7 +165,7 @@ namespace Gfx { static constexpr bool useAsyncCompute = true; static constexpr bool waitIdleOnSubmit = true; -static constexpr bool useMeshShading = true; +extern bool useMeshShading = false; // enable if supported static constexpr uint32 numFramesBuffered = 3; // meshlet dimensions curated by NVIDIA diff --git a/src/Engine/Graphics/Mesh.h b/src/Engine/Graphics/Mesh.h index 469e8d8..26816f0 100644 --- a/src/Engine/Graphics/Mesh.h +++ b/src/Engine/Graphics/Mesh.h @@ -1,6 +1,7 @@ #pragma once #include "Asset/MaterialInstanceAsset.h" #include "VertexData.h" +#include "Graphics/Buffer.h" namespace Seele { @@ -13,6 +14,7 @@ public: VertexData* vertexData; MeshId id; uint64 vertexCount; + Gfx::OIndexBuffer indexBuffer; PMaterialInstanceAsset referencedMaterial; Array meshlets; void save(ArchiveBuffer& buffer) const; diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index b875617..effa471 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -1,5 +1,7 @@ #include "BasePass.h" +#include "Graphics/Enums.h" #include "Graphics/Graphics.h" +#include "Graphics/Initializer.h" #include "Graphics/Shader.h" #include "Window/Window.h" #include "Component/Camera.h" @@ -73,10 +75,18 @@ void BasePass::render() graphics->beginRenderPass(renderPass); Gfx::ShaderPermutation permutation; permutation.hasFragment = true; - permutation.useMeshShading = true; - permutation.hasTaskShader = true; - std::memcpy(permutation.taskFile, "MeshletBasePass", std::strlen("MeshletBasePass")); - std::memcpy(permutation.vertexMeshFile, "MeshletBasePass", std::strlen("MeshletBasePass")); + if(Gfx::useMeshShading) + { + permutation.useMeshShading = true; + permutation.hasTaskShader = true; + std::memcpy(permutation.taskFile, "MeshletBasePass", sizeof("MeshletBasePass")); + std::memcpy(permutation.vertexMeshFile, "MeshletBasePass", sizeof("MeshletBasePass")); + } + else + { + permutation.useMeshShading = false; + std::memcpy(permutation.vertexMeshFile, "LegacyBasePass", sizeof("LegacyBasePass")); + } std::memcpy(permutation.fragmentFile, "BasePass", std::strlen("BasePass")); for (VertexData* vertexData : VertexData::getList()) { @@ -105,15 +115,30 @@ void BasePass::render() const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id); assert(collection != nullptr); - Gfx::MeshPipelineCreateInfo pipelineInfo; - pipelineInfo.taskShader = collection->taskShader; - pipelineInfo.meshShader = collection->meshShader; - pipelineInfo.fragmentShader = collection->fragmentShader; - pipelineInfo.pipelineLayout = layout; - pipelineInfo.renderPass = renderPass; - pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL; - Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInfo); - command->bindPipeline(pipeline); + if(Gfx::useMeshShading) + { + Gfx::MeshPipelineCreateInfo pipelineInfo; + pipelineInfo.taskShader = collection->taskShader; + pipelineInfo.meshShader = collection->meshShader; + pipelineInfo.fragmentShader = collection->fragmentShader; + pipelineInfo.pipelineLayout = layout; + pipelineInfo.renderPass = renderPass; + pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL; + Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInfo); + command->bindPipeline(pipeline); + } + else + { + Gfx::LegacyPipelineCreateInfo pipelineInfo; + pipelineInfo.vertexDeclaration = collection->vertexDeclaration; + pipelineInfo.vertexShader = collection->vertexShader; + pipelineInfo.fragmentShader = collection->fragmentShader; + pipelineInfo.pipelineLayout = layout; + pipelineInfo.renderPass = renderPass; + pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL; + Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInfo); + command->bindPipeline(pipeline); + } descriptorSets[INDEX_VERTEX_DATA] = vertexData->getVertexDataSet(); for (const auto& [_, instance] : materialData.instances) @@ -121,7 +146,20 @@ void BasePass::render() descriptorSets[INDEX_MATERIAL] = instance.materialInstance->getDescriptorSet(); descriptorSets[INDEX_SCENE_DATA] = instance.descriptorSet; command->bindDescriptor(descriptorSets); - command->dispatch(instance.numMeshes, 1, 1); + if(Gfx::useMeshShading) + { + command->dispatch(instance.numMeshes, 1, 1); + } + else + { + uint32 instanceOffset = 0; + for(const auto& mesh : instance.meshes) + { + uint32 vertexOffset = vertexData->getMeshOffset(mesh.id); + command->bindIndexBuffer(mesh.indexBuffer); + command->drawIndexed(mesh.indexBuffer->getNumIndices(), 1, 0, vertexOffset, instanceOffset); + } + } } } } diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index 4a73e80..d09db3b 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp @@ -1,4 +1,5 @@ #include "DepthPrepass.h" +#include "Graphics/Enums.h" #include "Graphics/Graphics.h" #include "Graphics/Shader.h" #include "Window/Window.h" @@ -38,10 +39,18 @@ void DepthPrepass::render() depthAttachment->getTexture()->transferOwnership(Gfx::QueueType::GRAPHICS); Gfx::ShaderPermutation permutation; permutation.hasFragment = false; - permutation.useMeshShading = true; - permutation.hasTaskShader = true; - std::memcpy(permutation.taskFile, "MeshletBasePass", sizeof("MeshletBasePass")); - std::memcpy(permutation.vertexMeshFile, "MeshletBasePass", sizeof("MeshletBasePass")); + if(Gfx::useMeshShading) + { + permutation.useMeshShading = true; + permutation.hasTaskShader = true; + std::memcpy(permutation.taskFile, "MeshletBasePass", sizeof("MeshletBasePass")); + std::memcpy(permutation.vertexMeshFile, "MeshletBasePass", sizeof("MeshletBasePass")); + } + else + { + permutation.useMeshShading = false; + std::memcpy(permutation.vertexMeshFile, "LegacyBasePass", sizeof("LegacyBasePass")); + } graphics->beginRenderPass(renderPass); for (VertexData* vertexData : VertexData::getList()) { @@ -65,17 +74,53 @@ void DepthPrepass::render() layout->addDescriptorLayout(INDEX_SCENE_DATA, vertexData->getInstanceDataLayout()); layout->create(); - Gfx::MeshPipelineCreateInfo pipelineInfo; - Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInfo); - command->bindPipeline(pipeline); + const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id); + assert(collection != nullptr); + if(Gfx::useMeshShading) + { + Gfx::MeshPipelineCreateInfo pipelineInfo; + pipelineInfo.taskShader = collection->taskShader; + pipelineInfo.meshShader = collection->meshShader; + pipelineInfo.fragmentShader = collection->fragmentShader; + pipelineInfo.pipelineLayout = layout; + pipelineInfo.renderPass = renderPass; + pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL; + Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInfo); + command->bindPipeline(pipeline); + } + else + { + Gfx::LegacyPipelineCreateInfo pipelineInfo; + pipelineInfo.vertexDeclaration = collection->vertexDeclaration; + pipelineInfo.vertexShader = collection->vertexShader; + pipelineInfo.fragmentShader = collection->fragmentShader; + pipelineInfo.pipelineLayout = layout; + pipelineInfo.renderPass = renderPass; + pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL; + Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInfo); + command->bindPipeline(pipeline); + } descriptorSets[INDEX_VERTEX_DATA] = vertexData->getVertexDataSet(); - for (const auto&[_, instance]: materialData.instances) + for (const auto& [_, instance] : materialData.instances) { descriptorSets[INDEX_MATERIAL] = instance.materialInstance->getDescriptorSet(); descriptorSets[INDEX_SCENE_DATA] = instance.descriptorSet; command->bindDescriptor(descriptorSets); - command->dispatch(instance.numMeshes, 1, 1); + if(Gfx::useMeshShading) + { + command->dispatch(instance.numMeshes, 1, 1); + } + else + { + uint32 instanceOffset = 0; + for(const auto& mesh : instance.meshes) + { + uint32 vertexOffset = vertexData->getMeshOffset(mesh.id); + command->bindIndexBuffer(mesh.indexBuffer); + command->drawIndexed(mesh.indexBuffer->getNumIndices(), 1, 0, vertexOffset, instanceOffset); + } + } } } } diff --git a/src/Engine/Graphics/Resources.h b/src/Engine/Graphics/Resources.h index a8d69a7..6bcff4c 100644 --- a/src/Engine/Graphics/Resources.h +++ b/src/Engine/Graphics/Resources.h @@ -126,6 +126,7 @@ public: virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0; virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0; virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) = 0; + virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) = 0; virtual void dispatch(uint32 groupX, uint32 groupY, uint32 groupZ) = 0; std::string name; }; diff --git a/src/Engine/Graphics/Shader.cpp b/src/Engine/Graphics/Shader.cpp index 9e5dd8d..059f9ad 100644 --- a/src/Engine/Graphics/Shader.cpp +++ b/src/Engine/Graphics/Shader.cpp @@ -1,4 +1,5 @@ #include "Shader.h" +#include "Graphics/Initializer.h" #include "Graphics/RenderPass/DepthPrepass.h" #include "Graphics/RenderPass/BasePass.h" #include @@ -121,6 +122,7 @@ ShaderCollection& ShaderCompiler::createShaders(ShaderPermutation permutation) createInfo.entryPoint = "fragmentMain"; collection.fragmentShader = graphics->createFragmentShader(createInfo); } + collection.vertexDeclaration = graphics->createVertexDeclaration(Array()); PermutationId perm = PermutationId(permutation); shaders[perm] = std::move(collection); diff --git a/src/Engine/Graphics/StaticMeshVertexData.h b/src/Engine/Graphics/StaticMeshVertexData.h index 491236e..6c4d4ca 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.h +++ b/src/Engine/Graphics/StaticMeshVertexData.h @@ -1,4 +1,5 @@ #pragma once +#include "Graphics/Initializer.h" #include "Math/Vector.h" #include "VertexData.h" @@ -15,6 +16,7 @@ public: void loadNormals(MeshId id, const Array& data); void loadTangents(MeshId id, const Array& data); void loadBiTangents(MeshId id, const Array& data); + virtual Gfx::PVertexDeclaration getDeclaration() override; virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) override; virtual void deserializeMesh(MeshId id, ArchiveBuffer& buffer) override; virtual void init(Gfx::PGraphics graphics) override; diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index be1e86e..6922171 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -28,7 +28,8 @@ void VertexData::updateMesh(const Component::Transform& transform, PMesh mesh) .id = mesh->id, .instance = InstanceData { .transformMatrix = transform.toMatrix(), - } + }, + .indexBuffer = mesh->indexBuffer, }); } @@ -150,6 +151,11 @@ MeshId VertexData::allocateVertexData(uint64 numVertices) return res; } +uint32 VertexData::getMeshOffset(MeshId id) +{ + return meshOffsets[id]; +} + List vertexDataList; List VertexData::getList() diff --git a/src/Engine/Graphics/VertexData.h b/src/Engine/Graphics/VertexData.h index 3513cc8..34b3045 100644 --- a/src/Engine/Graphics/VertexData.h +++ b/src/Engine/Graphics/VertexData.h @@ -1,4 +1,5 @@ #pragma once +#include "Graphics/Initializer.h" #include "Material/MaterialInstance.h" #include "Component/Transform.h" #include "Containers/List.h" @@ -37,12 +38,13 @@ public: { MeshId id; InstanceData instance; + Gfx::PIndexBuffer indexBuffer; }; struct MaterialInstanceData { PMaterialInstance materialInstance; Gfx::PDescriptorSet descriptorSet; - uint32_t numMeshes; // not necessarily equal to meshes.size() if a MeshId has multiple meshes + uint32 numMeshes; // not necessarily equal to meshes.size() if a MeshId has multiple meshes Array meshes; }; struct MaterialData @@ -61,6 +63,7 @@ public: void loadMesh(MeshId id, Array meshlets); void createDescriptors(); MeshId allocateVertexData(uint64 numVertices); + uint32 getMeshOffset(MeshId id); virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) = 0; virtual void deserializeMesh(MeshId id, ArchiveBuffer& buffer) = 0; virtual void bindBuffers(Gfx::PRenderCommand command) = 0; diff --git a/src/Engine/Graphics/Vulkan/CommandBuffer.cpp b/src/Engine/Graphics/Vulkan/CommandBuffer.cpp index c8ec381..a8ef35e 100644 --- a/src/Engine/Graphics/Vulkan/CommandBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/CommandBuffer.cpp @@ -8,6 +8,7 @@ #include "Pipeline.h" #include "DescriptorSets.h" #include "RenderTarget.h" +#include using namespace Seele; using namespace Seele::Vulkan; @@ -310,6 +311,11 @@ void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount, int32 firstVe vkCmdDraw(handle, vertexCount, instanceCount, firstVertex, firstInstance); } +void RenderCommand::drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) +{ + assert(threadId == std::this_thread::get_id()); + vkCmdDrawIndexed(handle, indexCount, instanceCount, firstIndex, vertexOffset, firstIndex); +} void RenderCommand::dispatch(uint32 groupX, uint32 groupY, uint32 groupZ) { assert(threadId == std::this_thread::get_id()); diff --git a/src/Engine/Graphics/Vulkan/CommandBuffer.h b/src/Engine/Graphics/Vulkan/CommandBuffer.h index b9340a6..dbb263b 100644 --- a/src/Engine/Graphics/Vulkan/CommandBuffer.h +++ b/src/Engine/Graphics/Vulkan/CommandBuffer.h @@ -88,6 +88,7 @@ public: virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override; virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override; virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override; + virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) override; virtual void dispatch(uint32 groupX, uint32 groupY, uint32 groupZ) override; private: PGraphicsPipeline pipeline; diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index edda4f0..d2a9d9b 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -2,6 +2,7 @@ #include "Graphics.h" #include "Allocator.h" #include "Buffer.h" +#include "Graphics/Enums.h" #include "PipelineCache.h" #include "CommandBuffer.h" #include "Initializer.h" @@ -10,6 +11,8 @@ #include "Framebuffer.h" #include "Shader.h" #include +#include +#include using namespace Seele; using namespace Seele::Vulkan; @@ -466,6 +469,18 @@ void Graphics::pickPhysicalDevice() physicalDevice = bestDevice; vkGetPhysicalDeviceProperties(physicalDevice, &props); vkGetPhysicalDeviceFeatures(physicalDevice, &features); + uint32 count = 0; + vkEnumerateDeviceExtensionProperties(physicalDevice, "VK_EXT_mesh_shader", &count, nullptr); + Array extensionProps(count); + vkEnumerateDeviceExtensionProperties(physicalDevice, "VK_EXT_mesh_shader", &count, extensionProps.data()); + for(size_t i = 0; i < count; ++i) + { + if(std::strcmp("VK_EXT_mesh_shader", extensionProps[i].extensionName) == 0) + { + Gfx::useMeshShading = true; + break; + } + } } void Graphics::createDevice(GraphicsInitializer initializer) diff --git a/src/Engine/Graphics/Vulkan/RenderTarget.cpp b/src/Engine/Graphics/Vulkan/RenderTarget.cpp index 7c19c35..8ec9e80 100644 --- a/src/Engine/Graphics/Vulkan/RenderTarget.cpp +++ b/src/Engine/Graphics/Vulkan/RenderTarget.cpp @@ -9,6 +9,7 @@ using namespace Seele; using namespace Seele::Vulkan; +double useMeshShading = false; double currentFrameDelta = 0; double Gfx::getCurrentFrameDelta() {