Fixing some shader stuff

This commit is contained in:
Dynamitos
2024-04-17 14:33:06 +02:00
parent d67c8ebffe
commit a72e92ee37
17 changed files with 292 additions and 225 deletions
+8 -7
View File
@@ -77,15 +77,15 @@ target_link_libraries(Engine PUBLIC nlohmann_json::nlohmann_json)
target_link_libraries(Engine PUBLIC crcpp) target_link_libraries(Engine PUBLIC crcpp)
target_link_libraries(Engine PUBLIC fmt::fmt) target_link_libraries(Engine PUBLIC fmt::fmt)
target_link_libraries(Engine PUBLIC GPUOpen::VulkanMemoryAllocator) target_link_libraries(Engine PUBLIC GPUOpen::VulkanMemoryAllocator)
target_link_libraries(Engine PUBLIC shader-slang) target_link_libraries(Engine PUBLIC slang)
target_link_libraries(Engine PUBLIC spirv-cross-glsl spirv-cross-msl) target_link_libraries(Engine PUBLIC spirv-cross-glsl spirv-cross-msl)
target_link_libraries(Engine PUBLIC glslang::glslang) target_link_libraries(Engine PUBLIC glslang::glslang)
if(APPLE) if(APPLE)
target_include_directories(Engine PUBLIC /usr/local/include)
target_link_directories(Engine PUBLIC /usr/local/lib)
target_link_libraries(Engine PUBLIC metalirconverter)
target_link_libraries(Engine PUBLIC metal) target_link_libraries(Engine PUBLIC metal)
SET(CMAKE_OSX_DEPLOYMENT_TARGET 14.3) SET(CMAKE_OSX_DEPLOYMENT_TARGET 14.3)
install(FILES
${EXTERNAL_ROOT}/dxc
DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
endif() endif()
if(UNIX) if(UNIX)
target_link_libraries(Engine PUBLIC Threads::Threads) target_link_libraries(Engine PUBLIC Threads::Threads)
@@ -121,8 +121,8 @@ else()
endif() endif()
if(APPLE) if(APPLE)
#Metal lib throws that internally for some reason #Metal lib throws that internally for some reason
target_compile_options(Engine PUBLIC -Wno-gnu-anonymous-struct) target_compile_options(Engine PUBLIC -Wno-gnu-anonymous-struct -Wno-nested-anon-types)
target_compile_options(Editor PUBLIC -Wno-gnu-anonymous-struct) target_compile_options(Editor PUBLIC -Wno-gnu-anonymous-struct -Wno-nested-anon-types)
endif() endif()
target_compile_options(Engine PUBLIC "$<$<CONFIG:DEBUG>:-DENABLE_VALIDATION>") target_compile_options(Engine PUBLIC "$<$<CONFIG:DEBUG>:-DENABLE_VALIDATION>")
target_compile_options(Engine PUBLIC "$<$<CONFIG:DEBUG>:-DSEELE_DEBUG>") target_compile_options(Engine PUBLIC "$<$<CONFIG:DEBUG>:-DSEELE_DEBUG>")
@@ -137,7 +137,7 @@ if(WIN32)
DEPENDS Editor) DEPENDS Editor)
elseif(APPLE) elseif(APPLE)
add_custom_target(dll_copy ALL add_custom_target(dll_copy ALL
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SLANG_ROOT}bin/libslang.dylib $<TARGET_FILE_DIR:Editor> COMMAND ${CMAKE_COMMAND} -E true
COMMAND_EXPAND_LISTS COMMAND_EXPAND_LISTS
DEPENDS Editor) DEPENDS Editor)
else() else()
@@ -157,6 +157,7 @@ install(
Engine Engine
crcpp crcpp
metal metal
slang
EXPORT EXPORT
EngineTargets EngineTargets
FILE_SET HEADERS FILE_SET HEADERS
+31 -30
View File
@@ -2,36 +2,37 @@ include (ExternalProject)
#--------------SLang------------------------------ #--------------SLang------------------------------
add_library(shader-slang-glslang SHARED IMPORTED) set(SLANG_ROOT ${EXTERNAL_ROOT}/slang)
add_library(shader-slang SHARED IMPORTED) #add_library(shader-slang SHARED IMPORTED)
if(WIN32) #if(WIN32)
set(SLANG_ROOT ${EXTERNAL_ROOT}/vcpkg/packages/shader-slang_x64-windows/) # add_library(shader-slang-glslang SHARED IMPORTED)
set_target_properties(shader-slang-glslang PROPERTIES IMPORTED_LOCATION ${SLANG_ROOT}/bin/slang-glslang.dll) # set(SLANG_ROOT ${EXTERNAL_ROOT}/slang/bin/windows-x64/release/)
set_target_properties(shader-slang-glslang PROPERTIES IMPORTED_IMPLIB ${SLANG_ROOT}/lib/slang.lib) # set_target_properties(shader-slang-glslang PROPERTIES IMPORTED_LOCATION ${SLANG_ROOT}/bin/slang-glslang.dll)
set_target_properties(shader-slang PROPERTIES IMPORTED_LOCATION ${SLANG_ROOT}/bin/slang.dll) # set_target_properties(shader-slang-glslang PROPERTIES IMPORTED_IMPLIB ${SLANG_ROOT}/lib/slang.lib)
set_target_properties(shader-slang PROPERTIES IMPORTED_IMPLIB ${SLANG_ROOT}/lib/slang.lib) # set_target_properties(shader-slang PROPERTIES IMPORTED_LOCATION ${SLANG_ROOT}/bin/slang.dll)
target_link_libraries(shader-slang INTERFACE shader-slang-glslang) # set_target_properties(shader-slang PROPERTIES IMPORTED_IMPLIB ${SLANG_ROOT}/lib/slang.lib)
install(FILES # target_link_libraries(shader-slang INTERFACE shader-slang-glslang)
${SLANG_ROOT}/bin/slang-glslang.dll # install(FILES
${SLANG_ROOT}/bin/slang.dll # ${SLANG_ROOT}/bin/slang-glslang.dll
DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) # ${SLANG_ROOT}/bin/slang.dll
install(FILES # DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
${SLANG_ROOT}/lib/slang.lib # install(FILES
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) # ${SLANG_ROOT}/lib/slang.lib
elseif(APPLE) # DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
set(SLANG_ROOT ${EXTERNAL_ROOT}/vcpkg/packages/shader-slang_arm64-osx/) #elseif(APPLE)
set_target_properties(shader-slang-glslang PROPERTIES IMPORTED_LOCATION ${SLANG_ROOT}/bin/libslang-glslang.dylib) # set(BINARY_ROOT ${SLANG_ROOT}/bin/macosx-aarch64/release/)
set_target_properties(shader-slang PROPERTIES IMPORTED_LOCATION ${SLANG_ROOT}/bin/libslang.dylib) # set_target_properties(shader-slang PROPERTIES IMPORTED_LOCATION ${BINARY_ROOT}/libslang.dylib)
target_link_libraries(shader-slang INTERFACE shader-slang-glslang) # install(FILES
install(FILES # ${BINARY_ROOT}/libslang.dylib
${SLANG_ROOT}/bin/libslang.dylib # DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
${SLANG_ROOT}/bin/libslang-glslang.dylib #endif()
DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) #target_include_directories(shader-slang INTERFACE
endif() # $<BUILD_INTERFACE:${SLANG_ROOT}/>
target_include_directories(shader-slang INTERFACE # $<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${SLANG_ROOT}/include/> #)
$<INSTALL_INTERFACE:include>
) add_subdirectory(${SLANG_ROOT})
target_compile_definitions(compiler-core PUBLIC SLANG_ENABLE_DXIL_SUPPORT=1)
#--------------CRC++------------------------------ #--------------CRC++------------------------------
add_library(crcpp INTERFACE) add_library(crcpp INTERFACE)
+1 -1
Submodule external/slang updated: ec0224edc3...ee9d398ebf
+3 -3
View File
@@ -26,10 +26,10 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
{ {
result += pLightEnv.directionalLights[i].illuminate(lightingParams, brdf); result += pLightEnv.directionalLights[i].illuminate(lightingParams, brdf);
} }
for(uint i = 0; i < lightCount; ++i) for(uint i = 0; i < pLightEnv.numPointLights; ++i)
{ {
uint lightIndex = pLightCullingData.lightIndexList[startOffset + i]; //uint lightIndex = pLightCullingData.lightIndexList[startOffset + i];
result += pLightEnv.pointLights[lightIndex].illuminate(lightingParams, brdf); result += pLightEnv.pointLights[i].illuminate(lightingParams, brdf);
} }
return float4(params.vertexColor, 1.0f); return float4(params.vertexColor, 1.0f);
} }
+2 -2
View File
@@ -2,8 +2,8 @@ import Common;
struct DebugVertex struct DebugVertex
{ {
float3 position; float3 position : POSITION;
float3 color; float3 color : COLOR0;
}; };
struct Params struct Params
+9 -3
View File
@@ -65,6 +65,12 @@ struct PrimitiveAttributes
uint cull: SV_CullPrimitive; uint cull: SV_CullPrimitive;
}; };
uint unpackPrimitiveIndices(uint index)
{
uint32_t packed = pScene.primitiveIndices[index / 4];
return (packed >> (index % 4)) & 0xff;
}
[numthreads(MESH_GROUP_SIZE, 1, 1)] [numthreads(MESH_GROUP_SIZE, 1, 1)]
[outputtopology("triangle")] [outputtopology("triangle")]
[shader("mesh")] [shader("mesh")]
@@ -84,9 +90,9 @@ void meshMain(
{ {
uint p = min(i, m.primitiveCount - 1); uint p = min(i, m.primitiveCount - 1);
{ {
uint local_idx0 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 0]; uint local_idx0 = unpackPrimitiveIndices(m.primitiveOffset + (p * 3) + 0);
uint local_idx1 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 1]; uint local_idx1 = unpackPrimitiveIndices(m.primitiveOffset + (p * 3) + 1);
uint local_idx2 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 2]; uint local_idx2 = unpackPrimitiveIndices(m.primitiveOffset + (p * 3) + 2);
indices[p] = uint3(local_idx0, local_idx1, local_idx2); indices[p] = uint3(local_idx0, local_idx1, local_idx2);
} }
} }
+8 -7
View File
@@ -14,12 +14,12 @@ struct MeshletDescription
struct MeshData struct MeshData
{ {
BoundingSphere bounding; BoundingSphere bounding;
uint32_t numMeshlets; uint32_t numMeshlets;
uint32_t meshletOffset; uint32_t meshletOffset;
uint32_t firstIndex; uint32_t firstIndex;
uint32_t numIndices; uint32_t numIndices;
uint32_t indicesOffset; uint32_t indicesOffset;
uint32_t pad0[3]; uint32_t pad0[3];
}; };
static const uint MAX_VERTICES = 64; static const uint MAX_VERTICES = 64;
@@ -38,7 +38,8 @@ struct Scene
StructuredBuffer<InstanceData> instances; StructuredBuffer<InstanceData> instances;
StructuredBuffer<MeshData> meshData; StructuredBuffer<MeshData> meshData;
StructuredBuffer<MeshletDescription> meshletInfos; StructuredBuffer<MeshletDescription> meshletInfos;
StructuredBuffer<uint8_t> primitiveIndices; // uint8_t is not valid in DXIL
StructuredBuffer<uint32_t> primitiveIndices;
StructuredBuffer<uint32_t> vertexIndices; StructuredBuffer<uint32_t> vertexIndices;
}; };
+10 -9
View File
@@ -1596,15 +1596,16 @@ typedef enum SeShaderStageFlagBits
SE_SHADER_STAGE_COMPUTE_BIT = 0x00000020, SE_SHADER_STAGE_COMPUTE_BIT = 0x00000020,
SE_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F, SE_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F,
SE_SHADER_STAGE_ALL = 0x7FFFFFFF, SE_SHADER_STAGE_ALL = 0x7FFFFFFF,
SE_SHADER_STAGE_RAYGEN_BIT_NV = 0x00000100, SE_SHADER_STAGE_RAYGEN_BIT_KHR = 0x00000100,
SE_SHADER_STAGE_ANY_HIT_BIT_NV = 0x00000200, SE_SHADER_STAGE_ANY_HIT_BIT_KHR = 0x00000200,
SE_SHADER_STAGE_CLOSEST_HIT_BIT_NV = 0x00000400, SE_SHADER_STAGE_CLOSEST_HIT_BIT_KHR = 0x00000400,
SE_SHADER_STAGE_MISS_BIT_NV = 0x00000800, SE_SHADER_STAGE_MISS_BIT_KHR = 0x00000800,
SE_SHADER_STAGE_INTERSECTION_BIT_NV = 0x00001000, SE_SHADER_STAGE_INTERSECTION_BIT_KHR = 0x00001000,
SE_SHADER_STAGE_CALLABLE_BIT_NV = 0x00002000, SE_SHADER_STAGE_CALLABLE_BIT_KHR = 0x00002000,
SE_SHADER_STAGE_TASK_BIT_NV = 0x00000040, SE_SHADER_STAGE_TASK_BIT_EXT = 0x00000040,
SE_SHADER_STAGE_MESH_BIT_NV = 0x00000080, SE_SHADER_STAGE_MESH_BIT_EXT = 0x00000080,
SE_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF SE_SHADER_STAGE_SUBPASS_SHADING_BIT_HUAWEI = 0x00004000,
SE_SHADER_STAGE_CLUSTER_CULLING_BIT_HUAWEI = 0x00080000,
} SeShaderStageFlagBits; } SeShaderStageFlagBits;
typedef SeFlags SePipelineVertexInputStateCreateFlags; typedef SeFlags SePipelineVertexInputStateCreateFlags;
typedef SeFlags SePipelineInputAssemblyStateCreateFlags; typedef SeFlags SePipelineInputAssemblyStateCreateFlags;
+3 -1
View File
@@ -54,7 +54,9 @@ void VertexBuffer::download(Array<uint8>& buffer) {
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; } void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; }
void VertexBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, void VertexBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {} Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {
}
IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo& createInfo) IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo& createInfo)
: Gfx::IndexBuffer(graphics->getFamilyMapping(), createInfo.sourceData.size, createInfo.indexType, : Gfx::IndexBuffer(graphics->getFamilyMapping(), createInfo.sourceData.size, createInfo.indexType,
+86 -77
View File
@@ -1,6 +1,10 @@
#pragma once #pragma once
#include "Graphics/Command.h"
#include "Buffer.h" #include "Buffer.h"
#include "Graphics/Command.h"
#include "Metal/MTLBlitCommandEncoder.hpp"
#include "Metal/MTLCommandBuffer.hpp"
#include "Metal/MTLComputeCommandEncoder.hpp"
#include "Metal/MTLRenderCommandEncoder.hpp"
#include "RenderPass.h" #include "RenderPass.h"
#include "Resources.h" #include "Resources.h"
@@ -12,106 +16,111 @@ DECLARE_REF(RenderCommand)
DECLARE_REF(Graphics) DECLARE_REF(Graphics)
DECLARE_REF(IndexBuffer) DECLARE_REF(IndexBuffer)
DECLARE_REF(GraphicsPipeline) DECLARE_REF(GraphicsPipeline)
class Command class Command {
{
public: public:
Command(PGraphics graphics, MTL::CommandBuffer* cmdBuffer); Command(PGraphics graphics, MTL::CommandBuffer* cmdBuffer);
~Command(); ~Command();
void beginRenderPass(PRenderPass renderPass); void beginRenderPass(PRenderPass renderPass);
void endRenderPass(); void endRenderPass();
void present(MTL::Drawable* drawable); void present(MTL::Drawable* drawable);
void end(PEvent signal); void end(PEvent signal);
void executeCommands(Array<Gfx::ORenderCommand> commands); void waitDeviceIdle();
void executeCommands(Array<Gfx::OComputeCommand> commands); void signalEvent(PEvent event);
void waitDeviceIdle(); void waitForEvent(PEvent event);
void signalEvent(PEvent event); MTL::RenderCommandEncoder* createRenderEncoder() { return parallelEncoder->renderCommandEncoder(); }
void waitForEvent(PEvent event); MTL::BlitCommandEncoder* getBlitEncoder() {
MTL::RenderCommandEncoder* createRenderEncoder() { return renderEncoder->renderCommandEncoder(); } assert(!parallelEncoder);
MTL::ComputeCommandEncoder* createComputeEncoder() { return cmdBuffer->computeCommandEncoder(); } if(blitEncoder == nullptr)
PEvent getCompletedEvent() const { return completed; }
constexpr MTL::CommandBuffer* getHandle() const
{ {
return cmdBuffer; blitEncoder = cmdBuffer->blitCommandEncoder();
} }
return blitEncoder;
}
PEvent getCompletedEvent() const { return completed; }
constexpr MTL::CommandBuffer* getHandle() const { return cmdBuffer; }
private: private:
PGraphics graphics; PGraphics graphics;
OEvent completed; OEvent completed;
MTL::CommandBuffer* cmdBuffer; MTL::CommandBuffer* cmdBuffer;
MTL::ParallelRenderCommandEncoder* renderEncoder; MTL::ParallelRenderCommandEncoder* parallelEncoder = nullptr;
MTL::BlitCommandEncoder* blitEncoder = nullptr;
}; };
DEFINE_REF(Command) DEFINE_REF(Command)
class RenderCommand : public Gfx::RenderCommand class RenderCommand : public Gfx::RenderCommand {
{
public: public:
RenderCommand(MTL::RenderCommandEncoder* encoder); RenderCommand(MTL::RenderCommandEncoder* encode, const std::string& name);
virtual ~RenderCommand(); virtual ~RenderCommand();
void end(); void end();
virtual void setViewport(Gfx::PViewport viewport) override; virtual void setViewport(Gfx::PViewport viewport) override;
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override; virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet) override; virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet) override;
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) override; virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) override;
virtual void bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) override; virtual void bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) override;
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override; 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 pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override; const void* data) override;
virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) override; virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override;
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override; virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset,
uint32 firstInstance) override;
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override;
private: private:
MTL::RenderCommandEncoder* encoder; MTL::RenderCommandEncoder* encoder;
PIndexBuffer boundIndexBuffer; PIndexBuffer boundIndexBuffer;
PGraphicsPipeline boundPipeline; PGraphicsPipeline boundPipeline;
std::string name;
}; };
DEFINE_REF(RenderCommand) DEFINE_REF(RenderCommand)
class ComputeCommand : public Gfx::ComputeCommand class ComputeCommand : public Gfx::ComputeCommand {
{
public: public:
ComputeCommand(MTL::ComputeCommandEncoder* encoder); ComputeCommand(MTL::CommandBuffer* cmdBuffer, const std::string& name);
virtual ~ComputeCommand(); virtual ~ComputeCommand();
void end(); void end();
virtual void bindPipeline(Gfx::PComputePipeline pipeline) override; virtual void bindPipeline(Gfx::PComputePipeline pipeline) override;
virtual void bindDescriptor(Gfx::PDescriptorSet set) override; virtual void bindDescriptor(Gfx::PDescriptorSet set) override;
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) override; virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) override;
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override; virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override; const void* data) override;
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override;
private: private:
MTL::ComputeCommandEncoder* encoder; MTL::CommandBuffer* commandBuffer;
MTL::ComputeCommandEncoder* encoder;
std::string name;
}; };
DEFINE_REF(ComputeCommand) DEFINE_REF(ComputeCommand)
class CommandQueue class CommandQueue {
{
public: public:
CommandQueue(PGraphics graphics); CommandQueue(PGraphics graphics);
~CommandQueue(); ~CommandQueue();
constexpr MTL::CommandQueue* getHandle() constexpr MTL::CommandQueue* getHandle() { return queue; }
{ PCommand getCommands() { return activeCommand; }
return queue; ORenderCommand getRenderCommand(const std::string& name);
} OComputeCommand getComputeCommand(const std::string& name);
PCommand getCommands() {return activeCommand;} //TODO void executeCommands(Array<Gfx::ORenderCommand> commands);
ORenderCommand getRenderCommand(const std::string& name); void executeCommands(Array<Gfx::OComputeCommand> commands);
OComputeCommand getComputeCommand(const std::string& name); void submitCommands(PEvent signal = nullptr);
void submitCommands(PEvent signal = nullptr);
private: private:
PGraphics graphics; PGraphics graphics;
MTL::CommandQueue* queue; MTL::CommandQueue* queue;
OCommand activeCommand; OCommand activeCommand;
Array<OCommand> pendingCommands; Array<OCommand> pendingCommands;
}; };
class IOCommandQueue class IOCommandQueue {
{
public: public:
IOCommandQueue(PGraphics graphics); IOCommandQueue(PGraphics graphics);
~IOCommandQueue(); ~IOCommandQueue();
constexpr MTL::IOCommandQueue* getHandle() constexpr MTL::IOCommandQueue* getHandle() { return queue; }
{ PCommand getCommands() { return activeCommand; } // TODO
return queue;
}
PCommand getCommands() {return activeCommand;} // TODO
void submitCommands(PEvent signal = nullptr); void submitCommands(PEvent signal = nullptr);
private: private:
PGraphics graphics; PGraphics graphics;
MTL::IOCommandQueue* queue; MTL::IOCommandQueue* queue;
OCommand activeCommand; OCommand activeCommand;
}; };
DEFINE_REF(IOCommandQueue) DEFINE_REF(IOCommandQueue)
} } // namespace Metal
} } // namespace Seele
+54 -34
View File
@@ -1,31 +1,43 @@
#include "Command.h" #include "Command.h"
#include "Buffer.h" #include "Buffer.h"
#include "Containers/Array.h"
#include "Descriptor.h" #include "Descriptor.h"
#include "Enums.h" #include "Enums.h"
#include "Graphics/Command.h"
#include "Graphics/Enums.h" #include "Graphics/Enums.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "Metal/MTLCommandBuffer.hpp" #include "Graphics/Resources.h"
#include "Pipeline.h" #include "Pipeline.h"
#include "Resources.h" #include "Resources.h"
#include "Window.h" #include "Window.h"
#include <Metal/Metal.h>
using namespace Seele; using namespace Seele;
using namespace Seele::Metal; using namespace Seele::Metal;
Command::Command(PGraphics graphics, MTL::CommandBuffer* cmdBuffer) Command::Command(PGraphics graphics, MTL::CommandBuffer* cmdBuffer)
: graphics(graphics), completed(new Event(graphics)), cmdBuffer(cmdBuffer), renderEncoder(nullptr) {} : graphics(graphics), completed(new Event(graphics)), cmdBuffer(cmdBuffer) {}
Command::~Command() { cmdBuffer->release(); } Command::~Command() {}
void Command::beginRenderPass(PRenderPass renderPass) { void Command::beginRenderPass(PRenderPass renderPass) {
renderEncoder = cmdBuffer->parallelRenderCommandEncoder(renderPass->getDescriptor()); if (blitEncoder) {
blitEncoder->endEncoding();
blitEncoder = nullptr;
}
parallelEncoder = cmdBuffer->parallelRenderCommandEncoder(renderPass->getDescriptor());
} }
void Command::endRenderPass() { renderEncoder->endEncoding(); } void Command::endRenderPass() {
parallelEncoder->endEncoding();
parallelEncoder = nullptr;
}
void Command::present(MTL::Drawable* drawable) { cmdBuffer->presentDrawable(drawable); } void Command::present(MTL::Drawable* drawable) { cmdBuffer->presentDrawable(drawable); }
void Command::end(PEvent signal) { void Command::end(PEvent signal) {
assert(!parallelEncoder);
blitEncoder->endEncoding();
if (signal != nullptr) { if (signal != nullptr) {
cmdBuffer->encodeSignalEvent(signal->getHandle(), 1); cmdBuffer->encodeSignalEvent(signal->getHandle(), 1);
} }
@@ -33,29 +45,16 @@ void Command::end(PEvent signal) {
cmdBuffer->commit(); cmdBuffer->commit();
} }
void Command::executeCommands(Array<Gfx::ORenderCommand> commands) {
for (auto& command : commands) {
auto cmd = Gfx::PRenderCommand(command).cast<RenderCommand>();
cmd->end();
}
}
void Command::executeCommands(Array<Gfx::OComputeCommand> commands) {
for (auto& command : commands) {
auto cmd = Gfx::PComputeCommand(command).cast<ComputeCommand>();
cmd->end();
}
}
void Command::waitDeviceIdle() { cmdBuffer->waitUntilCompleted(); } void Command::waitDeviceIdle() { cmdBuffer->waitUntilCompleted(); }
void Command::signalEvent(PEvent event) { cmdBuffer->encodeSignalEvent(event->getHandle(), 1); } void Command::signalEvent(PEvent event) { cmdBuffer->encodeSignalEvent(event->getHandle(), 1); }
void Command::waitForEvent(PEvent event) { cmdBuffer->encodeWait(event->getHandle(), 1); } void Command::waitForEvent(PEvent event) { cmdBuffer->encodeWait(event->getHandle(), 1); }
RenderCommand::RenderCommand(MTL::RenderCommandEncoder* encoder) : encoder(encoder) {} RenderCommand::RenderCommand(MTL::RenderCommandEncoder* encoder, const std::string& name)
: encoder(encoder), name(name) {}
RenderCommand::~RenderCommand() { encoder->release(); } RenderCommand::~RenderCommand() {}
void RenderCommand::end() { encoder->endEncoding(); } void RenderCommand::end() { encoder->endEncoding(); }
@@ -88,11 +87,10 @@ void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorS
bindDescriptor(set); bindDescriptor(set);
} }
} }
void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) { void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) {
uint32 i = 0; uint32 i = 0;
for (auto buffer : buffers) { for (auto buffer : buffers) {
encoder->setVertexBuffer(buffer.cast<VertexBuffer>()->getHandle(), 0, i++); encoder->setVertexBuffer(buffer.cast<VertexBuffer>()->getHandle(), 0, METAL_VERTEXBUFFER_OFFSET + i++);
} }
} }
@@ -125,11 +123,15 @@ void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) {
encoder->drawMeshThreadgroups(MTL::Size(groupX, groupY, groupZ), MTL::Size(128, 128, 128), MTL::Size(32, 32, 32)); encoder->drawMeshThreadgroups(MTL::Size(groupX, groupY, groupZ), MTL::Size(128, 128, 128), MTL::Size(32, 32, 32));
} }
ComputeCommand::ComputeCommand(MTL::ComputeCommandEncoder* encoder) : encoder(encoder) {} ComputeCommand::ComputeCommand(MTL::CommandBuffer* cmdBuffer, const std::string& name)
: commandBuffer(cmdBuffer), encoder(cmdBuffer->computeCommandEncoder()), name(name) {}
ComputeCommand::~ComputeCommand() { encoder->release(); } ComputeCommand::~ComputeCommand() {}
void ComputeCommand::end() { encoder->endEncoding(); } void ComputeCommand::end() {
encoder->endEncoding();
commandBuffer->commit();
}
void ComputeCommand::bindPipeline(Gfx::PComputePipeline pipeline) { void ComputeCommand::bindPipeline(Gfx::PComputePipeline pipeline) {
encoder->setComputePipelineState(pipeline.cast<ComputePipeline>()->getHandle()); encoder->setComputePipelineState(pipeline.cast<ComputePipeline>()->getHandle());
@@ -159,34 +161,52 @@ void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) {
CommandQueue::CommandQueue(PGraphics graphics) : graphics(graphics) { CommandQueue::CommandQueue(PGraphics graphics) : graphics(graphics) {
queue = graphics->getDevice()->newCommandQueue(); queue = graphics->getDevice()->newCommandQueue();
activeCommand = new Command(graphics, queue->commandBuffer()); MTL::CommandBufferDescriptor* descriptor = MTL::CommandBufferDescriptor::alloc()->init();
descriptor->setErrorOptions(MTL::CommandBufferErrorOptionEncoderExecutionStatus);
activeCommand = new Command(graphics, queue->commandBuffer(descriptor));
} }
CommandQueue::~CommandQueue() { queue->release(); } CommandQueue::~CommandQueue() { queue->release(); }
ORenderCommand CommandQueue::getRenderCommand(const std::string& name) { ORenderCommand CommandQueue::getRenderCommand(const std::string& name) {
return new RenderCommand(activeCommand->createRenderEncoder()); return new RenderCommand(activeCommand->createRenderEncoder(), name);
} }
OComputeCommand CommandQueue::getComputeCommand(const std::string& name) { OComputeCommand CommandQueue::getComputeCommand(const std::string& name) {
return new ComputeCommand(activeCommand->createComputeEncoder()); return new ComputeCommand(queue->commandBuffer(), name);
}
void CommandQueue::executeCommands(Array<Gfx::ORenderCommand> commands) {
for (auto& command : commands) {
auto metalCmd = Gfx::PRenderCommand(command).cast<RenderCommand>();
metalCmd->end();
}
}
void CommandQueue::executeCommands(Array<Gfx::OComputeCommand> commands) {
submitCommands();
for (auto& command : commands) {
auto metalCmd = Gfx::PComputeCommand(command).cast<ComputeCommand>();
metalCmd->end();
}
} }
void CommandQueue::submitCommands(PEvent signalSemaphore) { void CommandQueue::submitCommands(PEvent signalSemaphore) {
activeCommand->getHandle()->addCompletedHandler(MTL::CommandBufferHandler([&](MTL::CommandBuffer* cmdBuffer) { activeCommand->getHandle()->addCompletedHandler(MTL::CommandBufferHandler([&](MTL::CommandBuffer* cmdBuffer) {
for(auto it = pendingCommands.begin(); it != pendingCommands.end(); it++) for (auto it = pendingCommands.begin(); it != pendingCommands.end(); it++) {
{ if ((*it)->getHandle() == cmdBuffer) {
if((*it)->getHandle() == cmdBuffer)
{
pendingCommands.remove(it); pendingCommands.remove(it);
return; return;
} }
} }
})); }));
activeCommand->end(signalSemaphore); activeCommand->end(signalSemaphore);
activeCommand->waitDeviceIdle();
PEvent prevCmdEvent = activeCommand->getCompletedEvent(); PEvent prevCmdEvent = activeCommand->getCompletedEvent();
pendingCommands.add(std::move(activeCommand)); pendingCommands.add(std::move(activeCommand));
activeCommand = new Command(graphics, queue->commandBuffer()); MTL::CommandBufferDescriptor* descriptor = MTL::CommandBufferDescriptor::alloc()->init();
descriptor->setErrorOptions(MTL::CommandBufferErrorOptionEncoderExecutionStatus);
activeCommand = new Command(graphics, queue->commandBuffer(descriptor));
activeCommand->waitForEvent(prevCmdEvent); activeCommand->waitForEvent(prevCmdEvent);
} }
+3
View File
@@ -7,6 +7,9 @@ namespace Seele
{ {
namespace Metal namespace Metal
{ {
constexpr uint64 METAL_VERTEXBUFFER_OFFSET = 6;// something about metal vertex fetch
constexpr uint64 METAL_VERTEXATTRIBUTE_OFFSET = 11;
MTL::PixelFormat cast(Gfx::SeFormat format); MTL::PixelFormat cast(Gfx::SeFormat format);
Gfx::SeFormat cast(MTL::PixelFormat format); Gfx::SeFormat cast(MTL::PixelFormat format);
MTL::LoadAction cast(Gfx::SeAttachmentLoadOp loadOp); MTL::LoadAction cast(Gfx::SeAttachmentLoadOp loadOp);
+3 -2
View File
@@ -31,6 +31,7 @@ void Graphics::init(GraphicsInitializer)
queue = new CommandQueue(this); queue = new CommandQueue(this);
ioQueue = new IOCommandQueue(this); ioQueue = new IOCommandQueue(this);
cache = new PipelineCache(this, "pipelines.metal"); cache = new PipelineCache(this, "pipelines.metal");
meshShadingEnabled = true;
} }
Gfx::OWindow Graphics::createWindow(const WindowCreateInfo &createInfo) Gfx::OWindow Graphics::createWindow(const WindowCreateInfo &createInfo)
@@ -65,12 +66,12 @@ void Graphics::waitDeviceIdle()
void Graphics::executeCommands(Array<Gfx::ORenderCommand> commands) void Graphics::executeCommands(Array<Gfx::ORenderCommand> commands)
{ {
queue->getCommands()->executeCommands(std::move(commands)); queue->executeCommands(std::move(commands));
} }
void Graphics::executeCommands(Array<Gfx::OComputeCommand> commands) void Graphics::executeCommands(Array<Gfx::OComputeCommand> commands)
{ {
queue->getCommands()->executeCommands(std::move(commands)); queue->executeCommands(std::move(commands));
} }
Gfx::OTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo) Gfx::OTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo)
+20 -22
View File
@@ -2,6 +2,7 @@
#include "Descriptor.h" #include "Descriptor.h"
#include "Enums.h" #include "Enums.h"
#include "Foundation/NSError.hpp" #include "Foundation/NSError.hpp"
#include "Foundation/NSString.hpp"
#include "Graphics.h" #include "Graphics.h"
#include "Graphics/Descriptor.h" #include "Graphics/Descriptor.h"
#include "Graphics/Enums.h" #include "Graphics/Enums.h"
@@ -13,6 +14,7 @@
#include "Metal/MTLVertexDescriptor.hpp" #include "Metal/MTLVertexDescriptor.hpp"
#include "Shader.h" #include "Shader.h"
#include "Texture.h" #include "Texture.h"
#include <iostream>
using namespace Seele; using namespace Seele;
using namespace Seele::Metal; using namespace Seele::Metal;
@@ -26,14 +28,13 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
MTL::RenderPipelineDescriptor* pipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init(); MTL::RenderPipelineDescriptor* pipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init();
MTL::VertexDescriptor* vertexDescriptor = MTL::VertexDescriptor::alloc()->init(); MTL::VertexDescriptor* vertexDescriptor = pipelineDescriptor->vertexDescriptor()->init();
MTL::VertexAttributeDescriptorArray* attributes = vertexDescriptor->attributes(); MTL::VertexAttributeDescriptorArray* attributes = vertexDescriptor->attributes()->init();
if(createInfo.vertexInput != nullptr) if (createInfo.vertexInput != nullptr) {
{
const auto& vertexInfo = createInfo.vertexInput->getInfo(); const auto& vertexInfo = createInfo.vertexInput->getInfo();
for (size_t attr = 0; attr < vertexInfo.attributes.size(); ++attr) { for (size_t attr = 0; attr < vertexInfo.attributes.size(); ++attr) {
MTL::VertexAttributeDescriptor* attribute = MTL::VertexAttributeDescriptor::alloc()->init(); MTL::VertexAttributeDescriptor* attribute = attributes->object(attr + METAL_VERTEXATTRIBUTE_OFFSET)->init();
attribute->setBufferIndex(vertexInfo.attributes[attr].binding); attribute->setBufferIndex(vertexInfo.attributes[attr].binding + METAL_VERTEXBUFFER_OFFSET);
switch (vertexInfo.attributes[attr].format) { switch (vertexInfo.attributes[attr].format) {
case Gfx::SE_FORMAT_R32G32B32_SFLOAT: case Gfx::SE_FORMAT_R32G32B32_SFLOAT:
attribute->setFormat(MTL::VertexFormatFloat3); attribute->setFormat(MTL::VertexFormatFloat3);
@@ -42,12 +43,11 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
throw std::logic_error("TODO"); throw std::logic_error("TODO");
} }
attribute->setOffset(vertexInfo.attributes[attr].offset); attribute->setOffset(vertexInfo.attributes[attr].offset);
attributes->setObject(attribute, attr);
} }
MTL::VertexBufferLayoutDescriptorArray* bufferLayout = vertexDescriptor->layouts(); MTL::VertexBufferLayoutDescriptorArray* bufferLayout = vertexDescriptor->layouts()->init();
for (size_t binding = 0; binding < vertexInfo.bindings.size(); ++binding) { for (size_t binding = 0; binding < vertexInfo.bindings.size(); ++binding) {
MTL::VertexBufferLayoutDescriptor* buffer = MTL::VertexBufferLayoutDescriptor::alloc()->init(); MTL::VertexBufferLayoutDescriptor* buffer = bufferLayout->object(binding + METAL_VERTEXBUFFER_OFFSET)->init();
buffer->setStride(vertexInfo.bindings[binding].stride); buffer->setStride(vertexInfo.bindings[binding].stride);
buffer->setStepRate(1); buffer->setStepRate(1);
switch (vertexInfo.bindings[binding].inputRate) { switch (vertexInfo.bindings[binding].inputRate) {
@@ -58,7 +58,6 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
buffer->setStepFunction(MTL::VertexStepFunctionPerInstance); buffer->setStepFunction(MTL::VertexStepFunctionPerInstance);
break; break;
} }
bufferLayout->setObject(buffer, binding);
} }
} }
pipelineDescriptor->setVertexDescriptor(vertexDescriptor); pipelineDescriptor->setVertexDescriptor(vertexDescriptor);
@@ -118,14 +117,15 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
type = MTL::PrimitiveTypeTriangle; type = MTL::PrimitiveTypeTriangle;
break; break;
} }
NS::Error* error; NS::Error* error;
graphicsPipelines[hash] = graphicsPipelines[hash] =
new GraphicsPipeline(graphics, type, graphics->getDevice()->newRenderPipelineState(pipelineDescriptor, &error), new GraphicsPipeline(graphics, type, graphics->getDevice()->newRenderPipelineState(pipelineDescriptor, &error),
std::move(createInfo.pipelineLayout)); std::move(createInfo.pipelineLayout));
assert(!error); if (error) {
std::cout << error->localizedDescription()->cString(NS::ASCIIStringEncoding) << std::endl;
assert(false);
}
vertexDescriptor->release();
pipelineDescriptor->release(); pipelineDescriptor->release();
return graphicsPipelines[hash]; return graphicsPipelines[hash];
} }
@@ -133,7 +133,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo createInfo) { PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo createInfo) {
MTL::MeshRenderPipelineDescriptor* pipelineDescriptor = MTL::MeshRenderPipelineDescriptor::alloc()->init(); MTL::MeshRenderPipelineDescriptor* pipelineDescriptor = MTL::MeshRenderPipelineDescriptor::alloc()->init();
pipelineDescriptor->setMeshFunction(createInfo.meshShader.cast<VertexShader>()->getFunction()); pipelineDescriptor->setMeshFunction(createInfo.meshShader.cast<MeshShader>()->getFunction());
if (createInfo.taskShader != nullptr) { if (createInfo.taskShader != nullptr) {
pipelineDescriptor->setObjectFunction(createInfo.taskShader.cast<TaskShader>()->getFunction()); pipelineDescriptor->setObjectFunction(createInfo.taskShader.cast<TaskShader>()->getFunction());
} }
@@ -154,14 +154,12 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo crea
if (graphicsPipelines.contains(hash)) { if (graphicsPipelines.contains(hash)) {
return graphicsPipelines[hash]; return graphicsPipelines[hash];
} }
NS::Error* error = nullptr;
graphics->getDevice()->newRenderPipelineState( MTL::AutoreleasedRenderPipelineReflection reflection;
pipelineDescriptor, MTL::PipelineOptionNone, graphicsPipelines[hash] = new GraphicsPipeline(
[&](MTL::RenderPipelineState* state, MTL::RenderPipelineReflection*, NS::Error* error) { graphics, MTL::PrimitiveTypeTriangle,
assert(!error); graphics->getDevice()->newRenderPipelineState(pipelineDescriptor, MTL::PipelineOptionNone, &reflection, &error),
graphicsPipelines[hash] = std::move(createInfo.pipelineLayout));
new GraphicsPipeline(graphics, MTL::PrimitiveTypeLine, state, std::move(createInfo.pipelineLayout));
});
pipelineDescriptor->release(); pipelineDescriptor->release();
return graphicsPipelines[hash]; return graphicsPipelines[hash];
+2 -2
View File
@@ -37,8 +37,8 @@ public:
using VertexShader = ShaderBase<Gfx::VertexShader, Gfx::SE_SHADER_STAGE_VERTEX_BIT>; using VertexShader = ShaderBase<Gfx::VertexShader, Gfx::SE_SHADER_STAGE_VERTEX_BIT>;
using FragmentShader = ShaderBase<Gfx::FragmentShader, Gfx::SE_SHADER_STAGE_FRAGMENT_BIT>; using FragmentShader = ShaderBase<Gfx::FragmentShader, Gfx::SE_SHADER_STAGE_FRAGMENT_BIT>;
using ComputeShader = ShaderBase<Gfx::ComputeShader, Gfx::SE_SHADER_STAGE_COMPUTE_BIT>; using ComputeShader = ShaderBase<Gfx::ComputeShader, Gfx::SE_SHADER_STAGE_COMPUTE_BIT>;
using TaskShader = ShaderBase<Gfx::TaskShader, Gfx::SE_SHADER_STAGE_TASK_BIT_NV>; using TaskShader = ShaderBase<Gfx::TaskShader, Gfx::SE_SHADER_STAGE_TASK_BIT_EXT>;
using MeshShader = ShaderBase<Gfx::MeshShader, Gfx::SE_SHADER_STAGE_MESH_BIT_NV>; using MeshShader = ShaderBase<Gfx::MeshShader, Gfx::SE_SHADER_STAGE_MESH_BIT_EXT>;
DEFINE_REF(VertexShader) DEFINE_REF(VertexShader)
DEFINE_REF(FragmentShader) DEFINE_REF(FragmentShader)
+48 -24
View File
@@ -8,9 +8,8 @@
#include "Metal/MTLLibrary.hpp" #include "Metal/MTLLibrary.hpp"
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <metal_irconverter/metal_irconverter.h>
#include <slang.h> #include <slang.h>
#include <spirv_cross.hpp>
#include <spirv_cross/spirv_msl.hpp>
using namespace Seele; using namespace Seele;
using namespace Seele::Metal; using namespace Seele::Metal;
@@ -25,33 +24,58 @@ Shader::~Shader() {
} }
void Shader::create(const ShaderCreateInfo& createInfo) { void Shader::create(const ShaderCreateInfo& createInfo) {
Slang::ComPtr<slang::IBlob> kernelBlob = generateShader(createInfo, SLANG_SPIRV); Slang::ComPtr<slang::IBlob> kernelBlob = generateShader(createInfo, SLANG_DXIL);
hash = CRC::Calculate(kernelBlob->getBufferPointer(), kernelBlob->getBufferSize(), CRC::CRC_32());
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), hash = CRC::Calculate(kernelBlob->getBufferPointer(), kernelBlob->getBufferSize(), CRC::CRC_32());
mtlOptions, &error); IRCompiler* pCompiler = IRCompilerCreate();
if (error) { IRCompilerSetEntryPointName(pCompiler, "main");
std::cout << error->debugDescription() << std::endl;
assert(false); 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);
} }
function = library->newFunction(NS::String::string("main0", NS::ASCIIStringEncoding)); IRShaderStage irStage;
switch (stage) {
case Gfx::SE_SHADER_STAGE_VERTEX_BIT:
irStage = IRShaderStageVertex;
break;
case Gfx::SE_SHADER_STAGE_FRAGMENT_BIT:
irStage = IRShaderStageFragment;
break;
case Gfx::SE_SHADER_STAGE_COMPUTE_BIT:
irStage = IRShaderStageCompute;
break;
case Gfx::SE_SHADER_STAGE_TASK_BIT_EXT:
irStage = IRShaderStageAmplification;
break;
case Gfx::SE_SHADER_STAGE_MESH_BIT_EXT:
irStage = IRShaderStageMesh;
break;
}
// Retrieve Metallib:
IRMetalLibBinary* pMetallib = IRMetalLibBinaryCreate();
IRObjectGetMetalLibBinary(pOutIR, irStage, pMetallib);
dispatch_data_t data = IRMetalLibGetBytecodeData(pMetallib);
// Store the metallib to custom format or disk, or use to create a MTLLibrary.
NS::Error* error;
library = graphics->getDevice()->newLibrary(data, &error);
function = library->newFunction(NS::String::string("main", NS::ASCIIStringEncoding));
if(!function) if(!function)
{ {
std::ofstream shaderFile("error.metal"); assert(false);
shaderFile << metalCode;
shaderFile.close();
assert(!function);
} }
mtlOptions->release(); IRMetalLibBinaryDestroy(pMetallib);
IRObjectDestroy(pDXIL);
IRObjectDestroy(pOutIR);
IRCompilerDestroy(pCompiler);
} }
uint32 Shader::getShaderHash() const { return hash; } uint32 Shader::getShaderHash() const { return hash; }
+1 -1
View File
@@ -99,7 +99,7 @@ protected:
Map<MeshId, uint64> meshOffsets; Map<MeshId, uint64> meshOffsets;
Map<MeshId, uint64> meshVertexCounts; Map<MeshId, uint64> meshVertexCounts;
Array<MeshletDescription> meshlets; Array<MeshletDescription> meshlets;
Array<uint8> primitiveIndices; Array<uint32> primitiveIndices;
Array<uint32> vertexIndices; Array<uint32> vertexIndices;
Array<uint32> indices; Array<uint32> indices;
Gfx::PGraphics graphics; Gfx::PGraphics graphics;