Basic shader compilation
This commit is contained in:
@@ -171,7 +171,7 @@ public:
|
|||||||
{
|
{
|
||||||
_data = allocateArray(init.size());
|
_data = allocateArray(init.size());
|
||||||
assert(_data != nullptr);
|
assert(_data != nullptr);
|
||||||
std::uninitialized_copy(init.begin(), init.end(), begin());
|
std::uninitialized_move(init.begin(), init.end(), begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr Array(const Array &other)
|
constexpr Array(const Array &other)
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ target_sources(Engine
|
|||||||
Resources.cpp
|
Resources.cpp
|
||||||
Shader.h
|
Shader.h
|
||||||
Shader.cpp
|
Shader.cpp
|
||||||
|
slang-compile.h
|
||||||
|
slang-compile.cpp
|
||||||
StaticMeshVertexData.h
|
StaticMeshVertexData.h
|
||||||
StaticMeshVertexData.cpp
|
StaticMeshVertexData.cpp
|
||||||
Texture.h
|
Texture.h
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ namespace Metal {
|
|||||||
DECLARE_REF(Graphics)
|
DECLARE_REF(Graphics)
|
||||||
class Buffer
|
class Buffer
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
private:
|
||||||
};
|
};
|
||||||
DEFINE_REF(Buffer)
|
DEFINE_REF(Buffer)
|
||||||
class VertexBuffer : public Gfx::VertexBuffer, public Buffer
|
class VertexBuffer : public Gfx::VertexBuffer, public Buffer
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ target_sources(Engine
|
|||||||
RenderPass.mm
|
RenderPass.mm
|
||||||
Resources.h
|
Resources.h
|
||||||
Resources.mm
|
Resources.mm
|
||||||
|
Shader.h
|
||||||
|
Shader.mm
|
||||||
Texture.h
|
Texture.h
|
||||||
Texture.mm
|
Texture.mm
|
||||||
Window.h
|
Window.h
|
||||||
|
|||||||
@@ -1,19 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Graphics/Command.h"
|
#include "Graphics/Command.h"
|
||||||
#include "Metal/MTLComputeCommandEncoder.hpp"
|
|
||||||
#include "Metal/MTLDrawable.hpp"
|
|
||||||
#include "Metal/MTLIOCommandQueue.hpp"
|
|
||||||
#include "Metal/MTLRenderCommandEncoder.hpp"
|
|
||||||
#include "MinimalEngine.h"
|
|
||||||
#include "RenderPass.h"
|
#include "RenderPass.h"
|
||||||
#include "Resources.h"
|
#include "Resources.h"
|
||||||
#include "Graphics.h"
|
|
||||||
|
|
||||||
namespace Seele {
|
namespace Seele {
|
||||||
namespace Metal {
|
namespace Metal {
|
||||||
DECLARE_REF(CommandQueue)
|
DECLARE_REF(CommandQueue)
|
||||||
DECLARE_REF(ComputeCommand)
|
DECLARE_REF(ComputeCommand)
|
||||||
DECLARE_REF(RenderCommand)
|
DECLARE_REF(RenderCommand)
|
||||||
|
DECLARE_REF(Graphics)
|
||||||
class Command
|
class Command
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Graphics/Metal/Command.h"
|
|
||||||
#include "Metal/Metal.hpp"
|
#include "Metal/Metal.hpp"
|
||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
|
|
||||||
@@ -8,6 +7,7 @@ namespace Seele
|
|||||||
namespace Metal
|
namespace Metal
|
||||||
{
|
{
|
||||||
DECLARE_REF(CommandQueue)
|
DECLARE_REF(CommandQueue)
|
||||||
|
DECLARE_REF(IOCommandQueue)
|
||||||
class Graphics : public Gfx::Graphics
|
class Graphics : public Gfx::Graphics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Graphics/Initializer.h"
|
#include "Graphics/Initializer.h"
|
||||||
#include "Graphics/Pipeline.h"
|
#include "Graphics/Pipeline.h"
|
||||||
#include "Metal/MTLComputePipeline.hpp"
|
#include "Resources.h"
|
||||||
#include "Metal/MTLRenderPipeline.hpp"
|
|
||||||
#include "MinimalEngine.h"
|
#include "MinimalEngine.h"
|
||||||
|
|
||||||
namespace Seele {
|
namespace Seele {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Graphics/RenderTarget.h"
|
#include "Graphics/RenderTarget.h"
|
||||||
#include "Graphics.h"
|
#include "Resources.h"
|
||||||
#include "Metal/MTLRenderPass.hpp"
|
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
namespace Metal
|
namespace Metal
|
||||||
{
|
{
|
||||||
|
DECLARE_REF(Graphics)
|
||||||
class RenderPass : public Gfx::RenderPass
|
class RenderPass : public Gfx::RenderPass
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Graphics/Shader.h"
|
||||||
|
#include "Resources.h"
|
||||||
|
|
||||||
|
namespace Seele {
|
||||||
|
namespace Metal {
|
||||||
|
class Shader {
|
||||||
|
public:
|
||||||
|
Shader(PGraphics graphics);
|
||||||
|
virtual ~Shader();
|
||||||
|
|
||||||
|
void create(const ShaderCreateInfo &createInfo);
|
||||||
|
|
||||||
|
constexpr MTL::Function *getFunction() const { return function; }
|
||||||
|
constexpr const char *getEntryPointName() const {
|
||||||
|
// SLang renames all entry points to main, so we dont need that
|
||||||
|
return "main"; // entryPointName.c_str();
|
||||||
|
}
|
||||||
|
uint32 getShaderHash() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
PGraphics graphics;
|
||||||
|
MTL::Library* library;
|
||||||
|
MTL::Function *function;
|
||||||
|
uint32 hash;
|
||||||
|
};
|
||||||
|
DEFINE_REF(Shader)
|
||||||
|
|
||||||
|
template <typename Base> class ShaderBase : public Base, public Shader {
|
||||||
|
public:
|
||||||
|
ShaderBase(PGraphics graphics) : Shader(graphics) {}
|
||||||
|
virtual ~ShaderBase() {}
|
||||||
|
};
|
||||||
|
using VertexShader = ShaderBase<Gfx::VertexShader>;
|
||||||
|
using FragmentShader = ShaderBase<Gfx::FragmentShader>;
|
||||||
|
using ComputeShader = ShaderBase<Gfx::ComputeShader>;
|
||||||
|
using TaskShader = ShaderBase<Gfx::TaskShader>;
|
||||||
|
using MeshShader = ShaderBase<Gfx::MeshShader>;
|
||||||
|
|
||||||
|
DEFINE_REF(VertexShader)
|
||||||
|
DEFINE_REF(FragmentShader)
|
||||||
|
DEFINE_REF(ComputeShader)
|
||||||
|
DEFINE_REF(TaskShader)
|
||||||
|
DEFINE_REF(MeshShader)
|
||||||
|
} // namespace Metal
|
||||||
|
} // namespace Seele
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
#include "Shader.h"
|
||||||
|
#include "Graphics.h"
|
||||||
|
#include "Graphics/slang-compile.h"
|
||||||
|
#include "Metal/MTLLibrary.hpp"
|
||||||
|
#include <slang.h>
|
||||||
|
|
||||||
|
using namespace Seele;
|
||||||
|
using namespace Seele::Metal;
|
||||||
|
|
||||||
|
Shader::Shader(PGraphics graphics) : graphics(graphics) {}
|
||||||
|
Shader::~Shader() {
|
||||||
|
if (function) {
|
||||||
|
function->release();
|
||||||
|
library->release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::create(const ShaderCreateInfo &createInfo) {
|
||||||
|
Slang::ComPtr<slang::IBlob> kernelBlob = generateShader(createInfo, SLANG_DXIL);
|
||||||
|
thread_local IRCompiler* pCompiler = nullptr;
|
||||||
|
if(pCompiler == nullptr)
|
||||||
|
{
|
||||||
|
pCompiler = IRCompilerCreate();
|
||||||
|
}
|
||||||
|
IRCompilerSetEntryPointName(pCompiler, "main");
|
||||||
|
|
||||||
|
IRObject* pDXIL = IRObjectCreateFromDXIL(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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve Metallib:
|
||||||
|
MetaLibBinary* pMetallib = IRMetalLibBinaryCreate();
|
||||||
|
IRObjectGetMetalLibBinary(pOutIR, stage, pMetallib);
|
||||||
|
size_t metallibSize = IRMetalLibGetBytecodeSize(pMetallib);
|
||||||
|
uint8_t* metallib = new uint8_t[metallibSize];
|
||||||
|
IRMetalLibGetBytecode(pMetallib, metallib);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Graphics/Texture.h"
|
#include "Graphics/Texture.h"
|
||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
#include "Metal/MTLTexture.hpp"
|
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -61,10 +61,7 @@ TextureBase::~TextureBase() {
|
|||||||
void TextureBase::executePipelineBarrier(Gfx::SeAccessFlags,
|
void TextureBase::executePipelineBarrier(Gfx::SeAccessFlags,
|
||||||
Gfx::SePipelineStageFlags,
|
Gfx::SePipelineStageFlags,
|
||||||
Gfx::SeAccessFlags,
|
Gfx::SeAccessFlags,
|
||||||
Gfx::SePipelineStageFlags) {
|
Gfx::SePipelineStageFlags) {}
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextureBase::changeLayout(Gfx::SeImageLayout, Gfx::SeAccessFlags,
|
void TextureBase::changeLayout(Gfx::SeImageLayout, Gfx::SeAccessFlags,
|
||||||
Gfx::SePipelineStageFlags, Gfx::SeAccessFlags,
|
Gfx::SePipelineStageFlags, Gfx::SeAccessFlags,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
#include "Graphics/Window.h"
|
#include "Graphics/Window.h"
|
||||||
#include "Metal/MTLRenderCommandEncoder.hpp"
|
|
||||||
#include "Resources.h"
|
#include "Resources.h"
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ void BasePass::render()
|
|||||||
}
|
}
|
||||||
permutation.setFragmentFile("BasePass");
|
permutation.setFragmentFile("BasePass");
|
||||||
graphics->beginRenderPass(renderPass);
|
graphics->beginRenderPass(renderPass);
|
||||||
Array<Gfx::PRenderCommand> commands;
|
Array<Gfx::ORenderCommand> commands;
|
||||||
for (VertexData* vertexData : VertexData::getList())
|
for (VertexData* vertexData : VertexData::getList())
|
||||||
{
|
{
|
||||||
permutation.setVertexData(vertexData->getTypeName());
|
permutation.setVertexData(vertexData->getTypeName());
|
||||||
@@ -98,7 +98,7 @@ void BasePass::render()
|
|||||||
permutation.setMaterial(materialData.material->getName());
|
permutation.setMaterial(materialData.material->getName());
|
||||||
Gfx::PermutationId id(permutation);
|
Gfx::PermutationId id(permutation);
|
||||||
|
|
||||||
Gfx::PRenderCommand command = graphics->createRenderCommand("BaseRender");
|
Gfx::ORenderCommand command = graphics->createRenderCommand("BaseRender");
|
||||||
command->setViewport(viewport);
|
command->setViewport(viewport);
|
||||||
Gfx::OPipelineLayout layout = graphics->createPipelineLayout(basePassLayout);
|
Gfx::OPipelineLayout layout = graphics->createPipelineLayout(basePassLayout);
|
||||||
layout->addDescriptorLayout(INDEX_MATERIAL, materialData.material->getDescriptorLayout());
|
layout->addDescriptorLayout(INDEX_MATERIAL, materialData.material->getDescriptorLayout());
|
||||||
@@ -159,10 +159,10 @@ void BasePass::render()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
commands.add(command);
|
commands.add(std::move(command));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
graphics->executeCommands(commands);
|
graphics->executeCommands(std::move(commands));
|
||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,9 @@ void DebugPass::render()
|
|||||||
renderCommand->bindDescriptor(viewParamsSet);
|
renderCommand->bindDescriptor(viewParamsSet);
|
||||||
renderCommand->bindVertexBuffer({ debugVertices });
|
renderCommand->bindVertexBuffer({ debugVertices });
|
||||||
renderCommand->draw((uint32)gDebugVertices.size(), 1, 0, 0);
|
renderCommand->draw((uint32)gDebugVertices.size(), 1, 0, 0);
|
||||||
graphics->executeCommands(Array{std::move(renderCommand)});
|
Array<Gfx::ORenderCommand> commands;
|
||||||
|
commands.add(std::move(renderCommand));
|
||||||
|
graphics->executeCommands({std::move(commands)});
|
||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
gDebugVertices.clear();
|
gDebugVertices.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,13 +60,14 @@ void LightCullingPass::render()
|
|||||||
cullingDescriptorSet->updateTexture(5, Gfx::PTexture2D(oLightGrid));
|
cullingDescriptorSet->updateTexture(5, Gfx::PTexture2D(oLightGrid));
|
||||||
cullingDescriptorSet->updateTexture(6, Gfx::PTexture2D(tLightGrid));
|
cullingDescriptorSet->updateTexture(6, Gfx::PTexture2D(tLightGrid));
|
||||||
cullingDescriptorSet->writeChanges();
|
cullingDescriptorSet->writeChanges();
|
||||||
Gfx::PComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand");
|
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand");
|
||||||
computeCommand->bindPipeline(cullingPipeline);
|
computeCommand->bindPipeline(cullingPipeline);
|
||||||
computeCommand->bindDescriptor({ viewParamsSet, dispatchParamsSet, cullingDescriptorSet, lightEnv->getDescriptorSet() });
|
computeCommand->bindDescriptor({ viewParamsSet, dispatchParamsSet, cullingDescriptorSet, lightEnv->getDescriptorSet() });
|
||||||
computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z);
|
computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z);
|
||||||
Array<Gfx::PComputeCommand> commands = {computeCommand};
|
Array<Gfx::OComputeCommand> commands;
|
||||||
|
commands.add(std::move(computeCommand));
|
||||||
//std::cout << "Execute" << std::endl;
|
//std::cout << "Execute" << std::endl;
|
||||||
graphics->executeCommands(commands);
|
graphics->executeCommands(std::move(commands));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightCullingPass::endFrame()
|
void LightCullingPass::endFrame()
|
||||||
@@ -246,12 +247,13 @@ void LightCullingPass::setupFrustums()
|
|||||||
dispatchParamsSet->updateBuffer(1, frustumBuffer);
|
dispatchParamsSet->updateBuffer(1, frustumBuffer);
|
||||||
dispatchParamsSet->writeChanges();
|
dispatchParamsSet->writeChanges();
|
||||||
|
|
||||||
Gfx::PComputeCommand command = graphics->createComputeCommand("FrustumCommand");
|
Gfx::OComputeCommand command = graphics->createComputeCommand("FrustumCommand");
|
||||||
command->bindPipeline(frustumPipeline);
|
command->bindPipeline(frustumPipeline);
|
||||||
command->bindDescriptor({ viewParamsSet, dispatchParamsSet });
|
command->bindDescriptor({ viewParamsSet, dispatchParamsSet });
|
||||||
command->dispatch(numThreadGroups.x, numThreadGroups.y, numThreadGroups.z);
|
command->dispatch(numThreadGroups.x, numThreadGroups.y, numThreadGroups.z);
|
||||||
Array<Gfx::PComputeCommand> commands = {command};
|
Array<Gfx::OComputeCommand> commands;
|
||||||
graphics->executeCommands(commands);
|
commands.add(std::move(command));
|
||||||
|
graphics->executeCommands(std::move(commands));
|
||||||
frustumBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
frustumBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
}
|
}
|
||||||
@@ -56,12 +56,14 @@ void SkyboxRenderPass::render()
|
|||||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
|
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
|
||||||
);
|
);
|
||||||
graphics->beginRenderPass(renderPass);
|
graphics->beginRenderPass(renderPass);
|
||||||
Gfx::PRenderCommand renderCommand = graphics->createRenderCommand("SkyboxRender");
|
Gfx::ORenderCommand renderCommand = graphics->createRenderCommand("SkyboxRender");
|
||||||
renderCommand->setViewport(viewport);
|
renderCommand->setViewport(viewport);
|
||||||
renderCommand->bindPipeline(pipeline);
|
renderCommand->bindPipeline(pipeline);
|
||||||
renderCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet});
|
renderCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet});
|
||||||
renderCommand->draw(36, 1, 0, 0);
|
renderCommand->draw(36, 1, 0, 0);
|
||||||
graphics->executeCommands(Array{ renderCommand });
|
Array<Gfx::ORenderCommand> commands;
|
||||||
|
commands.add(std::move(renderCommand));
|
||||||
|
graphics->executeCommands(std::move(commands));
|
||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,10 +73,10 @@ void TextPass::beginFrame(const Component::Camera& cam)
|
|||||||
void TextPass::render()
|
void TextPass::render()
|
||||||
{
|
{
|
||||||
graphics->beginRenderPass(renderPass);
|
graphics->beginRenderPass(renderPass);
|
||||||
Array<Gfx::PRenderCommand> commands;
|
Array<Gfx::ORenderCommand> commands;
|
||||||
for(const auto& [fontAsset, res] : textResources)
|
for(const auto& [fontAsset, res] : textResources)
|
||||||
{
|
{
|
||||||
Gfx::PRenderCommand command = graphics->createRenderCommand("TextPassCommand");
|
Gfx::ORenderCommand command = graphics->createRenderCommand("TextPassCommand");
|
||||||
command->setViewport(viewport);
|
command->setViewport(viewport);
|
||||||
command->bindPipeline(pipeline);
|
command->bindPipeline(pipeline);
|
||||||
for(const auto& resource : res)
|
for(const auto& resource : res)
|
||||||
@@ -87,9 +87,9 @@ void TextPass::render()
|
|||||||
command->pushConstants(layoutRef, Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(TextData), &resource.textData);
|
command->pushConstants(layoutRef, Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(TextData), &resource.textData);
|
||||||
//command->draw(4, static_cast<uint32>(resource.vertexBuffer->getNumVertices()), 0, 0);
|
//command->draw(4, static_cast<uint32>(resource.vertexBuffer->getNumVertices()), 0, 0);
|
||||||
}
|
}
|
||||||
commands.add(command);
|
commands.add(std::move(command));
|
||||||
}
|
}
|
||||||
graphics->executeCommands(commands);
|
graphics->executeCommands(std::move(commands));
|
||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
textResources.clear();
|
textResources.clear();
|
||||||
//co_return;
|
//co_return;
|
||||||
|
|||||||
@@ -48,7 +48,9 @@ void UIPass::render()
|
|||||||
command->bindVertexBuffer({elementBuffer});
|
command->bindVertexBuffer({elementBuffer});
|
||||||
command->bindDescriptor(descriptorSet);
|
command->bindDescriptor(descriptorSet);
|
||||||
command->draw(4, static_cast<uint32>(renderElements.size()), 0, 0);
|
command->draw(4, static_cast<uint32>(renderElements.size()), 0, 0);
|
||||||
graphics->executeCommands(Array{std::move(command)});
|
Array<Gfx::ORenderCommand> commands;
|
||||||
|
commands.add(std::move(command));
|
||||||
|
graphics->executeCommands(std::move(commands));
|
||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
|
|
||||||
//co_return;
|
//co_return;
|
||||||
|
|||||||
@@ -22,16 +22,6 @@ namespace Seele
|
|||||||
{
|
{
|
||||||
namespace Vulkan
|
namespace Vulkan
|
||||||
{
|
{
|
||||||
|
|
||||||
enum class ShaderType
|
|
||||||
{
|
|
||||||
VERTEX = 0,
|
|
||||||
FRAGMENT = 1,
|
|
||||||
COMPUTE = 2,
|
|
||||||
TASK = 3,
|
|
||||||
MESH = 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
VkDescriptorType cast(const Gfx::SeDescriptorType &descriptorType);
|
VkDescriptorType cast(const Gfx::SeDescriptorType &descriptorType);
|
||||||
Gfx::SeDescriptorType cast(const VkDescriptorType &descriptorType);
|
Gfx::SeDescriptorType cast(const VkDescriptorType &descriptorType);
|
||||||
VkShaderStageFlagBits cast(const Gfx::SeShaderStageFlagBits &stage);
|
VkShaderStageFlagBits cast(const Gfx::SeShaderStageFlagBits &stage);
|
||||||
|
|||||||
@@ -8,9 +8,8 @@
|
|||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
using namespace Seele::Vulkan;
|
using namespace Seele::Vulkan;
|
||||||
|
|
||||||
Shader::Shader(PGraphics graphics, ShaderType shaderType, VkShaderStageFlags stage)
|
Shader::Shader(PGraphics graphics, VkShaderStageFlags stage)
|
||||||
: graphics(graphics)
|
: graphics(graphics)
|
||||||
, type(shaderType)
|
|
||||||
, stage(stage)
|
, stage(stage)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -28,91 +27,8 @@ uint32 Seele::Vulkan::Shader::getShaderHash() const
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_RESULT(x) {SlangResult r = x; if(r != 0) {throw std::runtime_error(fmt::format("Error: {0}", r));}}
|
|
||||||
#define CHECK_DIAGNOSTICS() {if(diagnostics) {std::cout << (const char*)diagnostics->getBufferPointer() << std::endl; assert(false);}}
|
|
||||||
|
|
||||||
void Shader::create(const ShaderCreateInfo& createInfo)
|
void Shader::create(const ShaderCreateInfo& createInfo)
|
||||||
{
|
{
|
||||||
entryPointName = createInfo.entryPoint;
|
|
||||||
thread_local Slang::ComPtr<slang::IGlobalSession> globalSession;
|
|
||||||
if(!globalSession)
|
|
||||||
{
|
|
||||||
slang::createGlobalSession(globalSession.writeRef());
|
|
||||||
}
|
|
||||||
slang::SessionDesc sessionDesc;
|
|
||||||
sessionDesc.flags = 0;
|
|
||||||
sessionDesc.defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR;
|
|
||||||
Array<slang::PreprocessorMacroDesc> macros;
|
|
||||||
for(const auto& [key, val] : createInfo.defines)
|
|
||||||
{
|
|
||||||
macros.add(slang::PreprocessorMacroDesc{
|
|
||||||
.name = key,
|
|
||||||
.value = val,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
sessionDesc.preprocessorMacroCount = macros.size();
|
|
||||||
sessionDesc.preprocessorMacros = macros.data();
|
|
||||||
slang::TargetDesc vulkan;
|
|
||||||
vulkan.profile = globalSession->findProfile("sm_6_6");
|
|
||||||
vulkan.format = SLANG_SPIRV;
|
|
||||||
sessionDesc.targetCount = 1;
|
|
||||||
sessionDesc.targets = &vulkan;
|
|
||||||
StaticArray<const char*, 3> searchPaths = {"shaders/", "shaders/lib/", "shaders/generated/"};
|
|
||||||
sessionDesc.searchPaths = searchPaths.data();
|
|
||||||
sessionDesc.searchPathCount = searchPaths.size();
|
|
||||||
|
|
||||||
Slang::ComPtr<slang::ISession> session;
|
|
||||||
CHECK_RESULT(globalSession->createSession(sessionDesc, session.writeRef()));
|
|
||||||
Slang::ComPtr<slang::IBlob> diagnostics;
|
|
||||||
Array<slang::IComponentType*> modules;
|
|
||||||
Slang::ComPtr<slang::IEntryPoint> entrypoint;
|
|
||||||
slang::IModule* mainModule = nullptr;
|
|
||||||
for (const auto& moduleName : createInfo.additionalModules)
|
|
||||||
{
|
|
||||||
modules.add(session->loadModule(moduleName.c_str(), diagnostics.writeRef()));
|
|
||||||
if (moduleName == createInfo.mainModule)
|
|
||||||
{
|
|
||||||
mainModule = (slang::IModule*)modules.back();
|
|
||||||
}
|
|
||||||
CHECK_DIAGNOSTICS();
|
|
||||||
}
|
|
||||||
|
|
||||||
CHECK_DIAGNOSTICS();
|
|
||||||
|
|
||||||
mainModule->findEntryPointByName(createInfo.entryPoint.c_str(), entrypoint.writeRef());
|
|
||||||
modules.add(entrypoint);
|
|
||||||
|
|
||||||
Slang::ComPtr<slang::IComponentType> moduleComposition;
|
|
||||||
session->createCompositeComponentType(modules.data(), modules.size(), moduleComposition.writeRef(), diagnostics.writeRef());
|
|
||||||
|
|
||||||
CHECK_DIAGNOSTICS();
|
|
||||||
|
|
||||||
Slang::ComPtr<slang::IComponentType> linkedProgram;
|
|
||||||
moduleComposition->link(linkedProgram.writeRef(), diagnostics.writeRef());
|
|
||||||
|
|
||||||
CHECK_DIAGNOSTICS();
|
|
||||||
|
|
||||||
slang::ProgramLayout* reflection = linkedProgram->getLayout(0, diagnostics.writeRef());
|
|
||||||
|
|
||||||
CHECK_DIAGNOSTICS();
|
|
||||||
|
|
||||||
Array<slang::SpecializationArg> specialization;
|
|
||||||
for(const auto& [key, value] : createInfo.typeParameter)
|
|
||||||
{
|
|
||||||
specialization.add(slang::SpecializationArg::fromType(reflection->findTypeByName(value)));
|
|
||||||
}
|
|
||||||
Slang::ComPtr<slang::IComponentType> specializedComponent;
|
|
||||||
linkedProgram->specialize(specialization.data(), specialization.size(), specializedComponent.writeRef(), diagnostics.writeRef());
|
|
||||||
CHECK_DIAGNOSTICS();
|
|
||||||
|
|
||||||
Slang::ComPtr<slang::IBlob> kernelBlob;
|
|
||||||
specializedComponent->getEntryPointCode(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
kernelBlob.writeRef(),
|
|
||||||
diagnostics.writeRef()
|
|
||||||
);
|
|
||||||
CHECK_DIAGNOSTICS();
|
|
||||||
|
|
||||||
VkShaderModuleCreateInfo moduleInfo =
|
VkShaderModuleCreateInfo moduleInfo =
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ DECLARE_REF(DescriptorLayout)
|
|||||||
class Shader
|
class Shader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Shader(PGraphics graphics, ShaderType shaderType, VkShaderStageFlags stage);
|
Shader(PGraphics graphics, VkShaderStageFlags stage);
|
||||||
virtual ~Shader();
|
virtual ~Shader();
|
||||||
|
|
||||||
void create(const ShaderCreateInfo& createInfo);
|
void create(const ShaderCreateInfo& createInfo);
|
||||||
@@ -26,44 +26,36 @@ public:
|
|||||||
//SLang renames all entry points to main, so we dont need that
|
//SLang renames all entry points to main, so we dont need that
|
||||||
return "main";//entryPointName.c_str();
|
return "main";//entryPointName.c_str();
|
||||||
}
|
}
|
||||||
constexpr ShaderType getShaderType() const
|
|
||||||
{
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
constexpr VkShaderStageFlags getStage() const
|
constexpr VkShaderStageFlags getStage() const
|
||||||
{
|
{
|
||||||
return stage;
|
return stage;
|
||||||
}
|
}
|
||||||
//Map<uint32, PDescriptorLayout> getDescriptorLayouts();
|
|
||||||
uint32 getShaderHash() const;
|
uint32 getShaderHash() const;
|
||||||
private:
|
private:
|
||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
//Map<uint32, PDescriptorLayout> descriptorSets;
|
|
||||||
VkShaderModule module;
|
VkShaderModule module;
|
||||||
ShaderType type;
|
|
||||||
VkShaderStageFlags stage;
|
VkShaderStageFlags stage;
|
||||||
std::string entryPointName;
|
|
||||||
uint32 hash;
|
uint32 hash;
|
||||||
};
|
};
|
||||||
DEFINE_REF(Shader)
|
DEFINE_REF(Shader)
|
||||||
|
|
||||||
template <typename Base, ShaderType shaderType, VkShaderStageFlags stageFlags>
|
template <typename Base, VkShaderStageFlags stageFlags>
|
||||||
class ShaderBase : public Base, public Shader
|
class ShaderBase : public Base, public Shader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ShaderBase(PGraphics graphics)
|
ShaderBase(PGraphics graphics)
|
||||||
: Shader(graphics, shaderType, stageFlags)
|
: Shader(graphics, stageFlags)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
virtual ~ShaderBase()
|
virtual ~ShaderBase()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
typedef ShaderBase<Gfx::VertexShader, ShaderType::VERTEX, VK_SHADER_STAGE_VERTEX_BIT> VertexShader;
|
using VertexShader = ShaderBase<Gfx::VertexShader, VK_SHADER_STAGE_VERTEX_BIT>;
|
||||||
typedef ShaderBase<Gfx::FragmentShader, ShaderType::FRAGMENT, VK_SHADER_STAGE_FRAGMENT_BIT> FragmentShader;
|
using FragmentShader = ShaderBase<Gfx::FragmentShader, VK_SHADER_STAGE_FRAGMENT_BIT>;
|
||||||
typedef ShaderBase<Gfx::ComputeShader, ShaderType::COMPUTE, VK_SHADER_STAGE_COMPUTE_BIT> ComputeShader;
|
using ComputeShader = ShaderBase<Gfx::ComputeShader, VK_SHADER_STAGE_COMPUTE_BIT>;
|
||||||
typedef ShaderBase<Gfx::TaskShader, ShaderType::TASK, VK_SHADER_STAGE_TASK_BIT_EXT> TaskShader;
|
using TaskShader = ShaderBase<Gfx::TaskShader, VK_SHADER_STAGE_TASK_BIT_EXT>;
|
||||||
typedef ShaderBase<Gfx::MeshShader, ShaderType::MESH, VK_SHADER_STAGE_MESH_BIT_EXT> MeshShader;
|
using MeshShader = ShaderBase<Gfx::MeshShader, VK_SHADER_STAGE_MESH_BIT_EXT>;
|
||||||
|
|
||||||
DEFINE_REF(VertexShader)
|
DEFINE_REF(VertexShader)
|
||||||
DEFINE_REF(FragmentShader)
|
DEFINE_REF(FragmentShader)
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
#include "slang-compile.h"
|
||||||
|
#include <slang-com-ptr.h>
|
||||||
|
#include <slang.h>
|
||||||
|
#include "Containers/Array.h"
|
||||||
|
#include <fmt/core.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#define CHECK_RESULT(x) {SlangResult r = x; if(r != 0) {throw std::runtime_error(fmt::format("Error: {0}", r));}}
|
||||||
|
#define CHECK_DIAGNOSTICS() {if(diagnostics) {std::cout << (const char*)diagnostics->getBufferPointer() << std::endl; assert(false);}}
|
||||||
|
|
||||||
|
Slang::ComPtr<slang::IBlob> Seele::generateShader(const ShaderCreateInfo& createInfo, SlangCompileTarget target)
|
||||||
|
{
|
||||||
|
thread_local Slang::ComPtr<slang::IGlobalSession> globalSession;
|
||||||
|
if(!globalSession)
|
||||||
|
{
|
||||||
|
slang::createGlobalSession(globalSession.writeRef());
|
||||||
|
}
|
||||||
|
slang::SessionDesc sessionDesc;
|
||||||
|
sessionDesc.flags = 0;
|
||||||
|
sessionDesc.defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR;
|
||||||
|
Array<slang::PreprocessorMacroDesc> macros;
|
||||||
|
for(const auto& [key, val] : createInfo.defines)
|
||||||
|
{
|
||||||
|
macros.add(slang::PreprocessorMacroDesc{
|
||||||
|
.name = key,
|
||||||
|
.value = val,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
sessionDesc.preprocessorMacroCount = macros.size();
|
||||||
|
sessionDesc.preprocessorMacros = macros.data();
|
||||||
|
slang::TargetDesc vulkan;
|
||||||
|
vulkan.profile = globalSession->findProfile("sm_6_6");
|
||||||
|
vulkan.format = target;
|
||||||
|
sessionDesc.targetCount = 1;
|
||||||
|
sessionDesc.targets = &vulkan;
|
||||||
|
StaticArray<const char*, 3> searchPaths = {"shaders/", "shaders/lib/", "shaders/generated/"};
|
||||||
|
sessionDesc.searchPaths = searchPaths.data();
|
||||||
|
sessionDesc.searchPathCount = searchPaths.size();
|
||||||
|
|
||||||
|
Slang::ComPtr<slang::ISession> session;
|
||||||
|
CHECK_RESULT(globalSession->createSession(sessionDesc, session.writeRef()));
|
||||||
|
Slang::ComPtr<slang::IBlob> diagnostics;
|
||||||
|
Array<slang::IComponentType*> modules;
|
||||||
|
Slang::ComPtr<slang::IEntryPoint> entrypoint;
|
||||||
|
slang::IModule* mainModule = nullptr;
|
||||||
|
for (const auto& moduleName : createInfo.additionalModules)
|
||||||
|
{
|
||||||
|
modules.add(session->loadModule(moduleName.c_str(), diagnostics.writeRef()));
|
||||||
|
if (moduleName == createInfo.mainModule)
|
||||||
|
{
|
||||||
|
mainModule = (slang::IModule*)modules.back();
|
||||||
|
}
|
||||||
|
CHECK_DIAGNOSTICS();
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_DIAGNOSTICS();
|
||||||
|
|
||||||
|
mainModule->findEntryPointByName(createInfo.entryPoint.c_str(), entrypoint.writeRef());
|
||||||
|
modules.add(entrypoint);
|
||||||
|
|
||||||
|
Slang::ComPtr<slang::IComponentType> moduleComposition;
|
||||||
|
session->createCompositeComponentType(modules.data(), modules.size(), moduleComposition.writeRef(), diagnostics.writeRef());
|
||||||
|
|
||||||
|
CHECK_DIAGNOSTICS();
|
||||||
|
|
||||||
|
Slang::ComPtr<slang::IComponentType> linkedProgram;
|
||||||
|
moduleComposition->link(linkedProgram.writeRef(), diagnostics.writeRef());
|
||||||
|
|
||||||
|
CHECK_DIAGNOSTICS();
|
||||||
|
|
||||||
|
slang::ProgramLayout* reflection = linkedProgram->getLayout(0, diagnostics.writeRef());
|
||||||
|
|
||||||
|
CHECK_DIAGNOSTICS();
|
||||||
|
|
||||||
|
Array<slang::SpecializationArg> specialization;
|
||||||
|
for(const auto& [key, value] : createInfo.typeParameter)
|
||||||
|
{
|
||||||
|
specialization.add(slang::SpecializationArg::fromType(reflection->findTypeByName(value)));
|
||||||
|
}
|
||||||
|
Slang::ComPtr<slang::IComponentType> specializedComponent;
|
||||||
|
linkedProgram->specialize(specialization.data(), specialization.size(), specializedComponent.writeRef(), diagnostics.writeRef());
|
||||||
|
CHECK_DIAGNOSTICS();
|
||||||
|
|
||||||
|
Slang::ComPtr<slang::IBlob> kernelBlob;
|
||||||
|
specializedComponent->getEntryPointCode(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
kernelBlob.writeRef(),
|
||||||
|
diagnostics.writeRef()
|
||||||
|
);
|
||||||
|
CHECK_DIAGNOSTICS();
|
||||||
|
return kernelBlob;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Graphics/Initializer.h"
|
||||||
|
#include <slang-com-ptr.h>
|
||||||
|
#include <slang.h>
|
||||||
|
|
||||||
|
namespace Seele {
|
||||||
|
Slang::ComPtr<slang::IBlob> generateShader(const ShaderCreateInfo& createInfo, SlangCompileTarget target);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user