Fixing some shader stuff
This commit is contained in:
+8
-7
@@ -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
@@ -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)
|
||||||
|
|||||||
Vendored
+1
-1
Submodule external/slang updated: ec0224edc3...ee9d398ebf
@@ -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,8 +2,8 @@ import Common;
|
|||||||
|
|
||||||
struct DebugVertex
|
struct DebugVertex
|
||||||
{
|
{
|
||||||
float3 position;
|
float3 position : POSITION;
|
||||||
float3 color;
|
float3 color : COLOR0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Params
|
struct Params
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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; }
|
||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user