diff --git a/.gitignore b/.gitignore index ef35f6b..42f0944 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# apple +.DS_Store + # cmake CMakeFiles/ .cmake/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f7197b..17c650f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,8 @@ option (NRI_STATIC_LIBRARY "Build static library" OFF) # Options: backends option (NRI_ENABLE_NONE_SUPPORT "Enable NONE backend" ON) +option (NRI_ENABLE_VK_SUPPORT "Enable VULKAN backend" ON) +option (NRI_ENABLE_METAL_SUPPORT "Enable METAL backend" ON) option (NRI_ENABLE_D3D11_SUPPORT "Enable D3D11 backend" ON) option (NRI_ENABLE_D3D12_SUPPORT "Enable D3D12 backend" ON) option (NRI_ENABLE_VK_SUPPORT "Enable VULKAN backend" ON) @@ -226,6 +228,24 @@ if (WIN32 AND NRI_ENABLE_D3D12_SUPPORT) endif () endif () +# METAL +if (NRI_ENABLE_METAL_SUPPORT AND APPLE) + message ("NRI adding backend: METAL") + set (COMPILE_DEFINITIONS ${COMPILE_DEFINITIONS} NRI_USE_MTL=1) + file (GLOB MTL_SOURCE "Source/Metal/*.cpp" "Source/Metal/*.mm" "Source/Metal/*.h" "Source/Metal/*.hpp" ) + source_group ("" FILES ${MTL_SOURCE}) + add_library (NRI_MTL STATIC ${MTL_SOURCE}) + target_link_libraries(NRI_MTL + "-framework Metal" + "-framework MetalKit" + "-framework AppKit" + "-framework Foundation" + "-framework QuartzCore" + ) + target_include_directories (NRI_MTL PRIVATE "Include" "Source/Shared" "External") + target_compile_definitions (NRI_MTL PRIVATE ${COMPILE_DEFINITIONS}) +endif() + # VK if (NRI_ENABLE_VK_SUPPORT) message ("NRI adding backend: VK") @@ -335,6 +355,9 @@ endif () if (NRI_ENABLE_VK_SUPPORT) target_link_libraries (${PROJECT_NAME} PRIVATE NRI_VK) endif () +if (NRI_ENABLE_METAL_SUPPORT) + target_link_libraries (${PROJECT_NAME} PRIVATE NRI_MTL) +endif () set_property (TARGET ${PROJECT_NAME} PROPERTY FOLDER ${PROJECT_FOLDER}) diff --git a/Include/Extensions/NRIWrapperMTL.h b/Include/Extensions/NRIWrapperMTL.h new file mode 100644 index 0000000..277be62 --- /dev/null +++ b/Include/Extensions/NRIWrapperMTL.h @@ -0,0 +1,52 @@ +// © 2021 NVIDIA Corporation + +#pragma once + +#include "NRIMacro.h" +#include "NRIDeviceCreation.h" + + +NriNamespaceBegin + + +typedef void* MTLHeap; +typedef void* MTLDeviceHandle; // id +typedef void* MTLBufferHandle; // id +typedef void* MTLTextureHandle; + +NriStruct(DeviceCreationMTLDesc) +{ + bool enableNRIValidation; + MTLDeviceHandle MtlDevice; +}; + +NriStruct(CommandBufferMTLDesc) +{ + +}; + +NriStruct(BufferMTLDesc) +{ + MTLBufferHandle buffer; + void* mappedMemory; + //MTLResourceOptions options; +}; + +NriStruct(TextureMTLDesc) +{ + //MTLTextureHandle mtlTexture; + //MTLTextureDescriptor* descriptor; +}; + +NriStruct(MemoryMTLDesc) +{ + uint64_t size; + // MTLStorageMode storage; + + //MTLResourceOptions options; +}; + +NRI_API Nri(Result) NRI_CALL nriCreateDeviceFromMtlDevice(const NriRef(DeviceCreationMTLDesc) deviceDesc, NriRef(Device*) device); + +NriNamespaceEnd + diff --git a/Include/NRIDescs.h b/Include/NRIDescs.h index 14a49be..04227ee 100644 --- a/Include/NRIDescs.h +++ b/Include/NRIDescs.h @@ -1,4 +1,4 @@ -// © 2021 NVIDIA Corporation +// © 2021 NVIDIA Corporation #pragma once @@ -75,7 +75,8 @@ NriEnum(GraphicsAPI, uint8_t, NONE, // Supports everything, does nothing, returns dummy non-NULL objects and ~0-filled descs, available if "NRI_ENABLE_NONE_SUPPORT = ON" in CMake D3D11, // Direct3D 11 (feature set 11.1), available if "NRI_ENABLE_D3D11_SUPPORT = ON" in CMake D3D12, // Direct3D 12 (feature set 11.1+), available if "NRI_ENABLE_D3D12_SUPPORT = ON" in CMake - VK // Vulkan 1.3 or 1.2+ (can be used on MacOS via MoltenVK), available if "NRI_ENABLE_VK_SUPPORT = ON" in CMake + VK, // Vulkan 1.3 or 1.2+ (can be used on MacOS via MoltenVK), available if "NRI_ENABLE_VK_SUPPORT = ON" in CMake + MTL ); NriEnum(Result, uint8_t, @@ -684,9 +685,14 @@ NriStruct(VertexAttributeVK) { uint32_t location; }; +NriStruct(VertexAttributeMTL) { + uint32_t location; +}; + NriStruct(VertexAttributeDesc) { Nri(VertexAttributeD3D) d3d; Nri(VertexAttributeVK) vk; + Nri(VertexAttributeMTL) mtl; uint32_t offset; Nri(Format) format; uint16_t streamIndex; @@ -1283,12 +1289,17 @@ NriStruct(PipelineStatisticsDesc) { #pragma region [ Device desc ] //============================================================================================================================================================================================ +// defined in apple framework +#undef INTEL +#undef AMD + NriEnum(Vendor, uint8_t, UNKNOWN, NVIDIA, AMD, - INTEL -); + INTEL, + APPLE +); NriStruct(AdapterDesc) { char name[256]; diff --git a/Source/Creation/Creation.cpp b/Source/Creation/Creation.cpp index f294a7c..68e704c 100644 --- a/Source/Creation/Creation.cpp +++ b/Source/Creation/Creation.cpp @@ -18,6 +18,11 @@ Result CreateDeviceD3D12(const DeviceCreationDesc& deviceCreationDesc, DeviceBas Result CreateDeviceD3D12(const DeviceCreationD3D12Desc& deviceCreationDesc, DeviceBase*& device); #endif +#if NRI_USE_MTL +Result CreateDeviceMTL(const DeviceCreationDesc& deviceCreationDesc, DeviceBase*& device); +Result CreateDeviceMTL(const DeviceCreationMTLDesc& deviceCreationDesc, DeviceBase*& device); +#endif + #if NRI_USE_VK Result CreateDeviceVK(const DeviceCreationDesc& deviceCreationDesc, DeviceBase*& device); Result CreateDeviceVK(const DeviceCreationVKDesc& deviceDesc, DeviceBase*& device); @@ -209,6 +214,24 @@ NRI_API Result NRI_CALL nriCreateDeviceFromD3D12Device(const DeviceCreationD3D12 return FinalizeDeviceCreation(deviceCreationDesc, *deviceImpl, device); } +NRI_API Result NRI_CALL nriCreateDeviceFromMtlDevice(const DeviceCreationMTLDesc& deviceCreationMtlDesc, Device*& device) { + DeviceCreationDesc deviceCreationDesc = {}; + deviceCreationDesc.graphicsAPI = GraphicsAPI::MTL; + deviceCreationDesc.enableNRIValidation = deviceCreationMtlDesc.enableNRIValidation; + + Result result = Result::UNSUPPORTED; + DeviceBase* deviceImpl = nullptr; + +#if NRI_USE_MTL + //result = CreateDeviceD3D12(tempDeviceCreationD3D12Desc, deviceImpl); +#endif + + if (result != Result::SUCCESS) + return result; + + return FinalizeDeviceCreation(deviceCreationDesc, *deviceImpl, device); +} + NRI_API Result NRI_CALL nriCreateDeviceFromVkDevice(const DeviceCreationVKDesc& deviceCreationVKDesc, Device*& device) { DeviceCreationDesc deviceCreationDesc = {}; deviceCreationDesc.callbackInterface = deviceCreationVKDesc.callbackInterface; @@ -250,6 +273,17 @@ NRI_API Format NRI_CALL nriConvertDXGIFormatToNRI(uint32_t dxgiFormat) { return DXGIFormatToNRIFormat(dxgiFormat); } +NRI_API uint32_t NRI_CALL nriConvertNRIFormatToMTL(Format format) { + MaybeUnused(format); + +#if NRI_USE_VK + return NRIFormatToMTLFormat(format); +#else + return 0; +#endif +} + + NRI_API uint32_t NRI_CALL nriConvertNRIFormatToVK(Format format) { MaybeUnused(format); @@ -368,6 +402,8 @@ NRI_API void NRI_CALL nriReportLiveObjects() { pDebug->ReportLiveObjects(DXGI_DEBUG_ALL, (DXGI_DEBUG_RLO_FLAGS)((uint32_t)DXGI_DEBUG_RLO_DETAIL | (uint32_t)DXGI_DEBUG_RLO_IGNORE_INTERNAL)); } +#elif __APPLE__ + #else # include # define GET_VK_FUNCTION(instance, name) \ diff --git a/Source/Metal/BufferMTL.h b/Source/Metal/BufferMTL.h new file mode 100644 index 0000000..9604cef --- /dev/null +++ b/Source/Metal/BufferMTL.h @@ -0,0 +1,58 @@ +// © 2021 NVIDIA Corporation +#pragma once + +#import + +namespace nri { + +struct DeviceMTL; +struct MemoryMTL; + +struct BufferMTL { + + inline BufferMTL(DeviceMTL& device) + : m_Device(device) { + } + + ~BufferMTL(); + + inline id GetHandle() const { + return m_Handle; + } + + inline DeviceMTL& GetDevice() const { + return m_Device; + } + + inline const BufferDesc& GetDesc() const { + return m_Desc; + } + + void* Map(uint64_t offset, uint64_t size); + void Unmap(); + + void FinishMemoryBinding(MemoryMTL& memory, uint64_t memoryOffset); + Result Create(const BufferDesc& bufferDesc); + + //================================================================================================================ + // NRI + //================================================================================================================ + + void SetDebugName(const char* name); + +private: + void UpdateLabel(); + + NSString* m_Label = nullptr; + DeviceMTL& m_Device; + id m_Handle; + uint8_t* m_MappedMemory = nullptr; + uint64_t m_MappedMemoryOffset = 0; + uint64_t m_MappedMemoryRangeSize = 0; + uint64_t m_MappedMemoryRangeOffset = 0; + BufferDesc m_Desc = {}; + bool m_OwnsNativeObjects = true; +}; + + +}; diff --git a/Source/Metal/BufferMTL.mm b/Source/Metal/BufferMTL.mm new file mode 100644 index 0000000..2d7ae57 --- /dev/null +++ b/Source/Metal/BufferMTL.mm @@ -0,0 +1,44 @@ +#include "SharedMTL.h" + +#include "BufferMTL.h" +#include "MemoryMTL.h" + +using namespace nri; + +void* BufferMTL::Map(uint64_t offset, uint64_t size) { + return (uint8_t*)[m_Handle contents] + offset; +} + +BufferMTL::~BufferMTL() { + [m_Label release]; +} + +void BufferMTL::Unmap() { + +} + +void BufferMTL::FinishMemoryBinding(MemoryMTL& memory, uint64_t memoryOffset) { + m_Handle = [memory.GetHandle() + newBufferWithLength: m_Desc.size + options: MTLResourceCPUCacheModeDefaultCache + offset: memoryOffset]; + UpdateLabel(); +} + +void BufferMTL::UpdateLabel() { + if(m_Handle && m_Label) { + [m_Handle setLabel: m_Label]; + } +} + + + +Result BufferMTL::Create(const BufferDesc& bufferDesc) { + m_Desc = bufferDesc; +} + +void BufferMTL::SetDebugName(const char* name) { + m_Label = [NSString stringWithUTF8String:name]; + [m_Label retain]; + UpdateLabel(); +} diff --git a/Source/Metal/CommandAllocatorMTL.h b/Source/Metal/CommandAllocatorMTL.h new file mode 100644 index 0000000..127c7ad --- /dev/null +++ b/Source/Metal/CommandAllocatorMTL.h @@ -0,0 +1,38 @@ +// © 2021 NVIDIA Corporation + +#pragma once + +namespace nri { + +struct DeviceMTL; +struct CommandQueueMTL; + +struct CommandAllocatorMTL { + inline CommandAllocatorMTL(DeviceMTL& device) + : m_Device(device) { + } + + inline DeviceMTL& GetDevice() const { + return m_Device; + } + + ~CommandAllocatorMTL(); + + + Result Create(const CommandQueue& commandQueue); + + //================================================================================================================ + // NRI + //================================================================================================================ + + void SetDebugName(const char* name); + Result CreateCommandBuffer(CommandBuffer*& commandBuffer); + void Reset(); + +private: + DeviceMTL& m_Device; + struct CommandQueueMTL* m_CommandQueue; +}; + +} + diff --git a/Source/Metal/CommandAllocatorMTL.hpp b/Source/Metal/CommandAllocatorMTL.hpp new file mode 100644 index 0000000..0239d98 --- /dev/null +++ b/Source/Metal/CommandAllocatorMTL.hpp @@ -0,0 +1,19 @@ +// © 2021 NVIDIA Corporation + +#pragma region[ Core ] + +static void NRI_CALL SetCommandAllocatorDebugName(CommandAllocator& commandAllocator, const char* name) { + //((CommandAllocatorVK&)commandAllocator).SetDebugName(name); +} + +static Result NRI_CALL CreateCommandBuffer(CommandAllocator& commandAllocator, CommandBuffer*& commandBuffer) { + return ((CommandAllocatorMTL&)commandAllocator).CreateCommandBuffer(commandBuffer); +} + +static void NRI_CALL ResetCommandAllocator(CommandAllocator& commandAllocator) { + //((CommandAllocatorVK&)commandAllocator).Reset(); +} + +#pragma endregion + + diff --git a/Source/Metal/CommandAllocatorMTL.mm b/Source/Metal/CommandAllocatorMTL.mm new file mode 100644 index 0000000..9fc54bd --- /dev/null +++ b/Source/Metal/CommandAllocatorMTL.mm @@ -0,0 +1,29 @@ +#include "SharedMTL.h" + +#include "CommandAllocatorMTL.h" +#include "CommandBufferMTL.h" +#include "CommandQueueMTL.h" + +using namespace nri; + +CommandAllocatorMTL::~CommandAllocatorMTL() { + +} + +Result CommandAllocatorMTL::Create(const CommandQueue& commandQueue) { + m_CommandQueue = &(CommandQueueMTL&)commandQueue; + return Result::SUCCESS; +} + +//================================================================================================================ +// NRI +//================================================================================================================ + +Result CommandAllocatorMTL::CreateCommandBuffer(CommandBuffer*& commandBuffer) { + + CommandBufferMTL* commandBufferImpl = Allocate(m_Device.GetStdAllocator(), m_Device); + commandBuffer = (CommandBuffer*)commandBufferImpl; + return Result::SUCCESS; +} + +#include "CommandAllocatorMTL.hpp" diff --git a/Source/Metal/CommandBufferMTL.h b/Source/Metal/CommandBufferMTL.h new file mode 100644 index 0000000..f4f0349 --- /dev/null +++ b/Source/Metal/CommandBufferMTL.h @@ -0,0 +1,114 @@ +// © 2021 NVIDIA Corporation + +#pragma once + +#include +#import + +namespace nri { + +struct DeviceMTL; +struct PipelineMTL; +struct BufferMTL; +struct PipelineLayoutMTL; +struct TextureMTL; +struct DescriptorMTL; + + +NriBits(CommandBufferDirtyBits, uint8_t, + NONE = 0, + CMD_DIRTY_STENCIL = NriBit(0) +); + +struct CommandBufferMTL { + + inline CommandBufferMTL(DeviceMTL& device) + : m_Device(device) { + } + + inline DeviceMTL& GetDevice() const { + return m_Device; + } + + inline operator id() const { + return m_Handle; + } + + + void SetDebugName(const char* name); + Result Begin(const DescriptorPool* descriptorPool); + Result End(); + void SetPipeline(const Pipeline& pipeline); + void SetPipelineLayout(const PipelineLayout& pipelineLayout); + void SetDescriptorSet(uint32_t setIndexInPipelineLayout, const DescriptorSet& descriptorSet, const uint32_t* dynamicConstantBufferOffsets); + void SetConstants(uint32_t pushConstantIndex, const void* data, uint32_t size); + void SetDescriptorPool(const DescriptorPool& descriptorPool); + void Barrier(const BarrierGroupDesc& barrierGroupDesc); + void BeginRendering(const AttachmentsDesc& attachmentsDesc); + void EndRendering(); + void SetViewports(const Viewport* viewports, uint32_t viewportNum); + void SetScissors(const Rect* rects, uint32_t rectNum); + void SetDepthBounds(float boundsMin, float boundsMax); + void SetStencilReference(uint8_t frontRef, uint8_t backRef); + // void SetSamplePositions(const SamplePosition* positions, Sample_t positionNum, Sample_t sampleNum); + void SetBlendConstants(const Color32f& color); + void SetShadingRate(const ShadingRateDesc& shadingRateDesc); + void ClearAttachments(const ClearDesc* clearDescs, uint32_t clearDescNum, const Rect* rects, uint32_t rectNum); + void SetIndexBuffer(const Buffer& buffer, uint64_t offset, IndexType indexType); + void SetVertexBuffers(uint32_t baseSlot, uint32_t bufferNum, const Buffer* const* buffers, const uint64_t* offsets); + void Draw(const DrawDesc& drawDesc); + void DrawIndexed(const DrawIndexedDesc& drawIndexedDesc); + void DrawIndirect(const Buffer& buffer, uint64_t offset, uint32_t drawNum, uint32_t stride, const Buffer* countBuffer, uint64_t countBufferOffset); + void DrawIndexedIndirect(const Buffer& buffer, uint64_t offset, uint32_t drawNum, uint32_t stride, const Buffer* countBuffer, uint64_t countBufferOffset); + void Dispatch(const DispatchDesc& dispatchDesc); + void DispatchIndirect(const Buffer& buffer, uint64_t offset); + void BeginQuery(const QueryPool& queryPool, uint32_t offset); + void EndQuery(const QueryPool& queryPool, uint32_t offset); + void BeginAnnotation(const char* name); + void EndAnnotation(); + void ClearStorageBuffer(const ClearStorageBufferDesc& clearDesc); + void ClearStorageTexture(const ClearStorageTextureDesc& clearDesc); + void CopyBuffer(Buffer& dstBuffer, uint64_t dstOffset, const Buffer& srcBuffer, uint64_t srcOffset, uint64_t size); + void CopyTexture(Texture& dstTexture, const TextureRegionDesc* dstRegionDesc, const Texture& srcTexture, const TextureRegionDesc* srcRegionDesc); + void UploadBufferToTexture(Texture& dstTexture, const TextureRegionDesc& dstRegionDesc, const Buffer& srcBuffer, const TextureDataLayoutDesc& srcDataLayoutDesc); + void ReadbackTextureToBuffer(Buffer& dstBuffer, TextureDataLayoutDesc& dstDataLayoutDesc, const Texture& srcTexture, const TextureRegionDesc& srcRegionDesc); + void CopyQueries(const QueryPool& queryPool, uint32_t offset, uint32_t num, Buffer& dstBuffer, uint64_t dstOffset); + void ResetQueries(const QueryPool& queryPool, uint32_t offset, uint32_t num); + void BuildTopLevelAccelerationStructure(uint32_t instanceNum, const Buffer& buffer, uint64_t bufferOffset, AccelerationStructureBuildBits flags, AccelerationStructure& dst, Buffer& scratch, uint64_t scratchOffset); + void BuildBottomLevelAccelerationStructure(uint32_t geometryObjectNum, const GeometryObject* geometryObjects, AccelerationStructureBuildBits flags, AccelerationStructure& dst, Buffer& scratch, uint64_t scratchOffset); + void UpdateTopLevelAccelerationStructure(uint32_t instanceNum, const Buffer& buffer, uint64_t bufferOffset, AccelerationStructureBuildBits flags, AccelerationStructure& dst, AccelerationStructure& src, Buffer& scratch, uint64_t scratchOffset); + void UpdateBottomLevelAccelerationStructure(uint32_t geometryObjectNum, const GeometryObject* geometryObjects, AccelerationStructureBuildBits flags, AccelerationStructure& dst, AccelerationStructure& src, Buffer& scratch, uint64_t scratchOffset); + void CopyAccelerationStructure(AccelerationStructure& dst, AccelerationStructure& src, CopyMode copyMode); + void WriteAccelerationStructureSize(const AccelerationStructure* const* accelerationStructures, uint32_t accelerationStructureNum, QueryPool& queryPool, uint32_t queryPoolOffset); + void DispatchRays(const DispatchRaysDesc& dispatchRaysDesc); + void DispatchRaysIndirect(const Buffer& buffer, uint64_t offset); + void DrawMeshTasks(const DrawMeshTasksDesc& drawMeshTasksDesc); + void DrawMeshTasksIndirect(const Buffer& buffer, uint64_t offset, uint32_t drawNum, uint32_t stride); + + ~CommandBufferMTL(); + + void Create(id cmd); + + struct CmdIndexBuffer { + size_t m_Offset; + MTLIndexType m_Type; + struct BufferMTL* m_Buffer; + }; + +private: + + void updateCommandBufferState(); + + DeviceMTL& m_Device; + struct PipelineMTL* m_CurrentPipeline = nullptr; + struct CmdIndexBuffer m_CurrentIndexCmd; + id m_Handle; + id m_RendererEncoder = nil; + id m_ComputeEncoder = nil; + + //id + + CommandBufferDirtyBits m_DirtyBits = CommandBufferDirtyBits::NONE; +}; +}; + diff --git a/Source/Metal/CommandBufferMTL.hpp b/Source/Metal/CommandBufferMTL.hpp new file mode 100644 index 0000000..17f4af4 --- /dev/null +++ b/Source/Metal/CommandBufferMTL.hpp @@ -0,0 +1,179 @@ + +//#pragma region[ Core ] +// +//static void NRI_CALL SetCommandBufferDebugName(CommandBuffer& commandBuffer, const char* name) { +// ((CommandBufferMTL&)commandBuffer).SetDebugName(name); +//} +// +//static Result NRI_CALL BeginCommandBuffer(CommandBuffer& commandBuffer, const DescriptorPool* descriptorPool) { +// return ((CommandBufferMTL&)commandBuffer).Begin(descriptorPool); +//} +// +//static Result NRI_CALL EndCommandBuffer(CommandBuffer& commandBuffer) { +// return ((CommandBufferMTL&)commandBuffer).End(); +//} +// +//static void NRI_CALL CmdSetPipelineLayout(CommandBuffer& commandBuffer, const PipelineLayout& pipelineLayout) { +// ((CommandBufferMTL&)commandBuffer).SetPipelineLayout(pipelineLayout); +//} +// +//static void NRI_CALL CmdSetPipeline(CommandBuffer& commandBuffer, const Pipeline& pipeline) { +// ((CommandBufferMTL&)commandBuffer).SetPipeline(pipeline); +//} +// +//static void NRI_CALL CmdBarrier(CommandBuffer& commandBuffer, const BarrierGroupDesc& barrierGroupDesc) { +// ((CommandBufferMTL&)commandBuffer).Barrier(barrierGroupDesc); +//} +// +//static void NRI_CALL CmdSetDescriptorPool(CommandBuffer& commandBuffer, const DescriptorPool& descriptorPool) { +// ((CommandBufferMTL&)commandBuffer).SetDescriptorPool(descriptorPool); +//} +// +//static void NRI_CALL CmdSetDescriptorSet(CommandBuffer& commandBuffer, uint32_t setIndexInPipelineLayout, const DescriptorSet& descriptorSet, const uint32_t* dynamicConstantBufferOffsets) { +// ((CommandBufferMTL&)commandBuffer).SetDescriptorSet(setIndexInPipelineLayout, descriptorSet, dynamicConstantBufferOffsets); +//} +// +//static void NRI_CALL CmdSetConstants(CommandBuffer& commandBuffer, uint32_t pushConstantIndex, const void* data, uint32_t size) { +// ((CommandBufferMTL&)commandBuffer).SetConstants(pushConstantIndex, data, size); +//} +// +//static void NRI_CALL CmdBeginRendering(CommandBuffer& commandBuffer, const AttachmentsDesc& attachmentsDesc) { +// ((CommandBufferMTL&)commandBuffer).BeginRendering(attachmentsDesc); +//} +// +//static void NRI_CALL CmdEndRendering(CommandBuffer& commandBuffer) { +// ((CommandBufferMTL&)commandBuffer).EndRendering(); +//} +// +//static void NRI_CALL CmdSetViewports(CommandBuffer& commandBuffer, const Viewport* viewports, uint32_t viewportNum) { +// ((CommandBufferMTL&)commandBuffer).SetViewports(viewports, viewportNum); +//} +// +//static void NRI_CALL CmdSetScissors(CommandBuffer& commandBuffer, const nri::Rect* rects, uint32_t rectNum) { +// ((CommandBufferMTL&)commandBuffer).SetScissors(rects, rectNum); +//} +// +//static void NRI_CALL CmdSetDepthBounds(CommandBuffer& commandBuffer, float boundsMin, float boundsMax) { +// ((CommandBufferMTL&)commandBuffer).SetDepthBounds(boundsMin, boundsMax); +//} +// +//static void NRI_CALL CmdSetStencilReference(CommandBuffer& commandBuffer, uint8_t frontRef, uint8_t backRef) { +// ((CommandBufferMTL&)commandBuffer).SetStencilReference(frontRef, backRef); +//} +// +//static void NRI_CALL CmdSetSamplePositions(CommandBuffer& commandBuffer, const SamplePosition* positions, Sample_t positionNum, Sample_t sampleNum) { +// ((CommandBufferMTL&)commandBuffer).SetSamplePositions(positions, positionNum, sampleNum); +//} +// +//static void NRI_CALL CmdSetBlendConstants(CommandBuffer& commandBuffer, const Color32f& color) { +// ((CommandBufferMTL&)commandBuffer).SetBlendConstants(color); +//} +// +//static void NRI_CALL CmdSetShadingRate(CommandBuffer& commandBuffer, const ShadingRateDesc& shadingRateDesc) { +// ((CommandBufferMTL&)commandBuffer).SetShadingRate(shadingRateDesc); +//} +// +//static void NRI_CALL CmdSetDepthBias(CommandBuffer& commandBuffer, const DepthBiasDesc& depthBiasDesc) { +// //((CommandBufferMTL&)commandBuffer).SetDepthBias(depthBiasDesc); +//} +// +//static void NRI_CALL CmdClearAttachments(CommandBuffer& commandBuffer, const ClearDesc* clearDescs, uint32_t clearDescNum, const nri::Rect* rects, uint32_t rectNum) { +// ((CommandBufferMTL&)commandBuffer).ClearAttachments(clearDescs, clearDescNum, rects, rectNum); +//} +// +//static void NRI_CALL CmdSetIndexBuffer(CommandBuffer& commandBuffer, const Buffer& buffer, uint64_t offset, IndexType indexType) { +// ((CommandBufferMTL&)commandBuffer).SetIndexBuffer(buffer, offset, indexType); +//} +// +//static void NRI_CALL CmdSetVertexBuffers(CommandBuffer& commandBuffer, uint32_t baseSlot, uint32_t bufferNum, const Buffer* const* buffers, const uint64_t* offsets) { +// ((CommandBufferMTL&)commandBuffer).SetVertexBuffers(baseSlot, bufferNum, buffers, offsets); +//} +// +//static void NRI_CALL CmdDraw(CommandBuffer& commandBuffer, const DrawDesc& drawDesc) { +// ((CommandBufferMTL&)commandBuffer).Draw(drawDesc); +//} +// +//static void NRI_CALL CmdDrawIndexed(CommandBuffer& commandBuffer, const DrawIndexedDesc& drawIndexedDesc) { +// ((CommandBufferMTL&)commandBuffer).DrawIndexed(drawIndexedDesc); +//} +// +//static void NRI_CALL CmdDrawIndirect(CommandBuffer& commandBuffer, const Buffer& buffer, uint64_t offset, uint32_t drawNum, uint32_t stride, const Buffer* countBuffer, uint64_t countBufferOffset) { +// ((CommandBufferMTL&)commandBuffer).DrawIndirect(buffer, offset, drawNum, stride, countBuffer, countBufferOffset); +//} +// +//static void NRI_CALL CmdDrawIndexedIndirect(CommandBuffer& commandBuffer, const Buffer& buffer, uint64_t offset, uint32_t drawNum, uint32_t stride, const Buffer* countBuffer, uint64_t countBufferOffset) { +// ((CommandBufferMTL&)commandBuffer).DrawIndexedIndirect(buffer, offset, drawNum, stride, countBuffer, countBufferOffset); +//} +// +//static void NRI_CALL CmdDispatch(CommandBuffer& commandBuffer, const DispatchDesc& dispatchDesc) { +// ((CommandBufferMTL&)commandBuffer).Dispatch(dispatchDesc); +//} +// +//static void NRI_CALL CmdDispatchIndirect(CommandBuffer& commandBuffer, const Buffer& buffer, uint64_t offset) { +// ((CommandBufferMTL&)commandBuffer).DispatchIndirect(buffer, offset); +//} +// +//static void NRI_CALL CmdBeginQuery(CommandBuffer& commandBuffer, const QueryPool& queryPool, uint32_t offset) { +// ((CommandBufferMTL&)commandBuffer).BeginQuery(queryPool, offset); +//} +// +//static void NRI_CALL CmdEndQuery(CommandBuffer& commandBuffer, const QueryPool& queryPool, uint32_t offset) { +// ((CommandBufferMTL&)commandBuffer).EndQuery(queryPool, offset); +//} +// +//static void NRI_CALL CmdBeginAnnotation(CommandBuffer& commandBuffer, const char* name) { +// ((CommandBufferMTL&)commandBuffer).BeginAnnotation(name); +//} +// +//static void NRI_CALL CmdEndAnnotation(CommandBuffer& commandBuffer) { +// ((CommandBufferMTL&)commandBuffer).EndAnnotation(); +//} +// +//static void NRI_CALL CmdClearStorageBuffer(CommandBuffer& commandBuffer, const ClearStorageBufferDesc& clearDesc) { +// ((CommandBufferMTL&)commandBuffer).ClearStorageBuffer(clearDesc); +//} +// +//static void NRI_CALL CmdClearStorageTexture(CommandBuffer& commandBuffer, const ClearStorageTextureDesc& clearDesc) { +// ((CommandBufferMTL&)commandBuffer).ClearStorageTexture(clearDesc); +//} +// +//static void NRI_CALL CmdCopyBuffer(CommandBuffer& commandBuffer, Buffer& dstBuffer, uint64_t dstOffset, const Buffer& srcBuffer, uint64_t srcOffset, uint64_t size) { +// ((CommandBufferMTL&)commandBuffer).CopyBuffer(dstBuffer, dstOffset, srcBuffer, srcOffset, size); +//} +// +//static void NRI_CALL CmdCopyTexture( +// CommandBuffer& commandBuffer, Texture& dstTexture, const TextureRegionDesc* dstRegionDesc, const Texture& srcTexture, const TextureRegionDesc* srcRegionDesc) { +// ((CommandBufferMTL&)commandBuffer).CopyTexture(dstTexture, dstRegionDesc, srcTexture, srcRegionDesc); +//} +// +//static void NRI_CALL CmdUploadBufferToTexture(CommandBuffer& commandBuffer, Texture& dstTexture, const TextureRegionDesc& dstRegionDesc, const Buffer& srcBuffer, const TextureDataLayoutDesc& srcDataLayoutDesc) { +// ((CommandBufferMTL&)commandBuffer).UploadBufferToTexture(dstTexture, dstRegionDesc, srcBuffer, srcDataLayoutDesc); +//} +// +//static void NRI_CALL CmdReadbackTextureToBuffer(CommandBuffer& commandBuffer, Buffer& dstBuffer, const TextureDataLayoutDesc& dstDataLayoutDesc, const Texture& srcTexture, const TextureRegionDesc& srcRegionDesc) { +// //((CommandBufferMTL&)commandBuffer).ReadbackTextureToBuffer(dstBuffer, dstDataLayoutDesc, srcTexture, srcRegionDesc); +//} +// +//static void NRI_CALL CmdCopyQueries(CommandBuffer& commandBuffer, const QueryPool& queryPool, uint32_t offset, uint32_t num, Buffer& dstBuffer, uint64_t dstOffset) { +// ((CommandBufferMTL&)commandBuffer).CopyQueries(queryPool, offset, num, dstBuffer, dstOffset); +//} +// +//static void NRI_CALL CmdResetQueries(CommandBuffer& commandBuffer, const QueryPool& queryPool, uint32_t offset, uint32_t num) { +// ((CommandBufferMTL&)commandBuffer).ResetQueries(queryPool, offset, num); +//} +// +//static void* NRI_CALL GetCommandBufferNativeObject(const CommandBuffer& commandBuffer) { +// if (!(&commandBuffer)) +// return nullptr; +// +// return nullptr; +// // return (CommandBufferMTL)((CommandBufferMTL&)commandBuffer); +//} +// +//#pragma endregion +// +// +// +// +//Define_Core_CommandBuffer_PartiallyFillFunctionTable(VK); + diff --git a/Source/Metal/CommandBufferMTL.mm b/Source/Metal/CommandBufferMTL.mm new file mode 100644 index 0000000..66bd664 --- /dev/null +++ b/Source/Metal/CommandBufferMTL.mm @@ -0,0 +1,266 @@ +#include "SharedMTL.h" + +#include "CommandBufferMTL.h" + +#include "BufferMTL.h" +#include "CommandBufferMTL.h" +#include "CommandQueueMTL.h" +#include "DescriptorMTL.h" +#include "PipelineLayoutMTL.h" +#include "PipelineMTL.h" +#include "TextureMTL.h" + +#include + +using namespace nri; + +CommandBufferMTL::~CommandBufferMTL() { + +} + +void CommandBufferMTL::SetDebugName(const char* name) { + [m_Handle setLabel:[NSString stringWithUTF8String:name]]; +} + +Result CommandBufferMTL::Begin(const DescriptorPool* descriptorPool) { + m_ComputeEncoder = [m_Handle computeCommandEncoderWithDescriptor: NULL]; +} + +Result CommandBufferMTL::End() { + m_ComputeEncoder = nil; + m_RendererEncoder = nil; + +} + +void CommandBufferMTL::SetPipeline(const Pipeline& pipeline) { + if (m_CurrentPipeline == (PipelineMTL*)&pipeline) + return; + PipelineMTL& pipelineImpl = (PipelineMTL&)pipeline; + m_CurrentPipeline = &pipelineImpl; + +// if(m_CurrentPipeline->m_pipelineType == nri::PipelineMTL::Compute) { + // m_ComputeEncoder = [m_Handle computeCommandEncoderWithDescriptor: NULL]; + // } + +} +void CommandBufferMTL::SetPipelineLayout(const PipelineLayout& pipelineLayout) { + +} +void CommandBufferMTL::SetDescriptorSet(uint32_t setIndexInPipelineLayout, const DescriptorSet& descriptorSet, const uint32_t* dynamicConstantBufferOffsets) { + +} +void CommandBufferMTL::SetConstants(uint32_t pushConstantIndex, const void* data, uint32_t size) { + //if (pDesc->mUsedStages & SHADER_STAGE_VERT) + //{ + // [m_RendererEncoder setVertexBytes:data length:size atIndex:pushConstantIndex]; + //} + + //if (pDesc->mUsedStages & SHADER_STAGE_FRAG) + //{ + // [m_RendererEncoder setFragmentBytes:data length:size atIndex:pushConstantIndex]; + //} + + //if (pDesc->mUsedStages & SHADER_STAGE_COMP) + //{ + // [m_RendererEncoder setBytes:data length:size atIndex:pushConstantIndex]; + //} + +} +void CommandBufferMTL::SetDescriptorPool(const DescriptorPool& descriptorPool) {} +void CommandBufferMTL::Barrier(const BarrierGroupDesc& barrierGroupDesc) { + //if (pCmd->pQueue->mBarrierFlags & BARRIER_FLAG_BUFFERS) + { + [m_RendererEncoder memoryBarrierWithScope:MTLBarrierScopeBuffers + afterStages:MTLRenderStageFragment + beforeStages:MTLRenderStageVertex]; + } + + //if (pCmd->pQueue->mBarrierFlags & BARRIER_FLAG_TEXTURES) + { + [m_RendererEncoder memoryBarrierWithScope:MTLBarrierScopeTextures + afterStages:MTLRenderStageFragment + beforeStages:MTLRenderStageVertex]; + } + + //if (pCmd->pQueue->mBarrierFlags & BARRIER_FLAG_RENDERTARGETS) + { + [m_RendererEncoder memoryBarrierWithScope:MTLBarrierScopeRenderTargets + afterStages:MTLRenderStageFragment + beforeStages:MTLRenderStageVertex]; + } + + +} +void CommandBufferMTL::BeginRendering(const AttachmentsDesc& attachmentsDesc) { + MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]; + + for(uint32_t i = 0; i < attachmentsDesc.colorNum; i++) { + DescriptorMTL& descriptorMTL = *(DescriptorMTL*)attachmentsDesc.colors[i]; + + renderPassDescriptor.colorAttachments[i].texture = descriptorMTL.GetTextureHandle(); + renderPassDescriptor.colorAttachments[i].clearColor = MTLClearColorMake(0, 0, 0, 1); + renderPassDescriptor.colorAttachments[i].loadAction = MTLLoadActionClear; + renderPassDescriptor.colorAttachments[i].storeAction = MTLStoreActionStore; + + } + + if(attachmentsDesc.depthStencil) { + + DescriptorMTL& descriptorMTL = *(DescriptorMTL*)attachmentsDesc.depthStencil; + renderPassDescriptor.depthAttachment.texture = descriptorMTL.GetTextureHandle(); + // renderPassDescriptor.depthAttachment.clearColor = MTLClearColorMake(0, 0, 0, 1); + renderPassDescriptor.depthAttachment.loadAction = MTLLoadActionClear; + renderPassDescriptor.depthAttachment.storeAction = MTLStoreActionStore; + + } + + m_RendererEncoder = [m_Handle renderCommandEncoderWithDescriptor: renderPassDescriptor]; +} +void CommandBufferMTL::EndRendering() { + NSCAssert(m_RendererEncoder, @"Renderer Encoderer Not Set"); + [m_RendererEncoder endEncoding]; + m_RendererEncoder = nil; + m_ComputeEncoder = nil; +} +void CommandBufferMTL::SetViewports(const Viewport* viewports, uint32_t viewportNum) { + Scratch mtlViewports = AllocateScratch(m_Device, MTLViewport, viewportNum); + for(size_t i = 0; i < viewportNum; i++) { + mtlViewports[i].originX = viewports[i].x; + mtlViewports[i].originY = viewports[i].y; + mtlViewports[i].width = viewports[i].width; + mtlViewports[i].height = viewports[i].height; + mtlViewports[i].znear = viewports[i].depthMin; + mtlViewports[i].zfar = viewports[i].depthMax; + } + [m_RendererEncoder setViewports: mtlViewports count: viewportNum]; +} +void CommandBufferMTL::SetScissors(const Rect* rects, uint32_t rectNum) { + NSCAssert(m_RendererEncoder, @"encoder set"); + MTLScissorRect rect; + rect.x = rects[rectNum].x; + rect.y = rects[rectNum].y; + rect.width = rects[rectNum].width; + rect.height = rects[rectNum].height; + [m_RendererEncoder setScissorRect: rect]; +} +void CommandBufferMTL::SetDepthBounds(float boundsMin, float boundsMax) { + +} +void CommandBufferMTL::SetStencilReference(uint8_t frontRef, uint8_t backRef) { + [m_RendererEncoder setStencilFrontReferenceValue: frontRef backReferenceValue:backRef]; +} +//void CommandBufferMTL::SetSamplePositions(const SamplePosition* positions, Sample_t positionNum, Sample_t sampleNum) { +//} +void CommandBufferMTL::SetBlendConstants(const Color32f& color) { + [m_RendererEncoder + setBlendColorRed:color.x + green:color.y + blue:color.z + alpha:color.w + ]; +} +void CommandBufferMTL::SetShadingRate(const ShadingRateDesc& shadingRateDesc) { + +} + +void CommandBufferMTL::ClearAttachments(const ClearDesc* clearDescs, uint32_t clearDescNum, const Rect* rects, uint32_t rectNum) { +} + +void CommandBufferMTL::SetIndexBuffer(const Buffer& buffer, uint64_t offset, IndexType indexType) { + m_CurrentIndexCmd.m_Buffer = &(BufferMTL&)buffer; + switch(indexType) { + case IndexType::UINT16: + m_CurrentIndexCmd.m_Type = MTLIndexType::MTLIndexTypeUInt16; + break; + default: + case IndexType::UINT32: + m_CurrentIndexCmd.m_Type = MTLIndexType::MTLIndexTypeUInt32; + break; + } + m_CurrentIndexCmd.m_Offset = offset; +} + +void CommandBufferMTL::SetVertexBuffers(uint32_t baseSlot, uint32_t bufferNum, const Buffer* const* buffers, const uint64_t* offsets) { + for(size_t i = 0; i < bufferNum; i++) { + BufferMTL* mtlBuffer = (BufferMTL*)buffers[i]; + [m_RendererEncoder setVertexBuffer: mtlBuffer->GetHandle() + offset: offsets[i] + atIndex: i + baseSlot]; + } + +} + +void CommandBufferMTL::Draw(const DrawDesc& drawDesc) { + [m_RendererEncoder drawPrimitives: m_CurrentPipeline->m_primitiveType + vertexStart:drawDesc.baseVertex + vertexCount:drawDesc.vertexNum + instanceCount:drawDesc.instanceNum + baseInstance:0]; +} + +void CommandBufferMTL::DrawIndexed(const DrawIndexedDesc& drawIndexedDesc) { + id indexBuffer = m_CurrentIndexCmd.m_Buffer->GetHandle(); + [m_RendererEncoder drawIndexedPrimitives: m_CurrentPipeline->m_primitiveType + indexCount: drawIndexedDesc.indexNum + indexType: m_CurrentIndexCmd.m_Type + indexBuffer: indexBuffer + indexBufferOffset: m_CurrentIndexCmd.m_Offset]; +} + +void CommandBufferMTL::DrawIndirect(const Buffer& buffer, uint64_t offset, uint32_t drawNum, uint32_t stride, const Buffer* countBuffer, uint64_t countBufferOffset) { + // TODO: implement count Buffer + NSCAssert(!countBuffer, @"count buffer not supported"); + + [m_RendererEncoder + drawPrimitives: m_CurrentPipeline->m_primitiveType + indirectBuffer:((BufferMTL&)buffer).GetHandle() + indirectBufferOffset: offset]; +} +void CommandBufferMTL::DrawIndexedIndirect(const Buffer& buffer, uint64_t offset, uint32_t drawNum, uint32_t stride, const Buffer* countBuffer, uint64_t countBufferOffset) { + // m_CurrentPipeline-> + + id indexBuffer = m_CurrentIndexCmd.m_Buffer->GetHandle(); + const BufferMTL& bufferImpl = (const BufferMTL&)buffer; + //const BufferMTL& bufferImpl = (const BufferMTL&)buffer; +// [m_RendererEncoder drawIndexedPrimitives: m_CurrentPipeline->m_primitiveType +// indexCount: drawIndexedDesc.indexNum +// indexType: m_CurrentIndexCmd.m_Type +// indexBuffer: indexBuffer +// indexBufferOffset: m_CurrentIndexCmd.m_Offset +// ]; +} +void CommandBufferMTL::Dispatch(const DispatchDesc& dispatchDesc) { + +} +void CommandBufferMTL::DispatchIndirect(const Buffer& buffer, uint64_t offset) {} +void CommandBufferMTL::BeginQuery(const QueryPool& queryPool, uint32_t offset) {} +void CommandBufferMTL::EndQuery(const QueryPool& queryPool, uint32_t offset) {} +void CommandBufferMTL::BeginAnnotation(const char* name) {} +void CommandBufferMTL::EndAnnotation() {} +void CommandBufferMTL::ClearStorageBuffer(const ClearStorageBufferDesc& clearDesc) {} +void CommandBufferMTL::ClearStorageTexture(const ClearStorageTextureDesc& clearDesc) {} +void CommandBufferMTL::CopyBuffer(Buffer& dstBuffer, uint64_t dstOffset, const Buffer& srcBuffer, uint64_t srcOffset, uint64_t size) {} +void CommandBufferMTL::CopyTexture(Texture& dstTexture, const TextureRegionDesc* dstRegionDesc, const Texture& srcTexture, const TextureRegionDesc* srcRegionDesc) {} +void CommandBufferMTL::UploadBufferToTexture(Texture& dstTexture, const TextureRegionDesc& dstRegionDesc, const Buffer& srcBuffer, const TextureDataLayoutDesc& srcDataLayoutDesc) {} +void CommandBufferMTL::ReadbackTextureToBuffer(Buffer& dstBuffer, TextureDataLayoutDesc& dstDataLayoutDesc, const Texture& srcTexture, const TextureRegionDesc& srcRegionDesc) {} +void CommandBufferMTL::CopyQueries(const QueryPool& queryPool, uint32_t offset, uint32_t num, Buffer& dstBuffer, uint64_t dstOffset) {} +void CommandBufferMTL::ResetQueries(const QueryPool& queryPool, uint32_t offset, uint32_t num) {} +void CommandBufferMTL::BuildTopLevelAccelerationStructure(uint32_t instanceNum, const Buffer& buffer, uint64_t bufferOffset, AccelerationStructureBuildBits flags, AccelerationStructure& dst, Buffer& scratch, uint64_t scratchOffset) {} +void CommandBufferMTL::BuildBottomLevelAccelerationStructure(uint32_t geometryObjectNum, const GeometryObject* geometryObjects, AccelerationStructureBuildBits flags, AccelerationStructure& dst, Buffer& scratch, uint64_t scratchOffset) {} +void CommandBufferMTL::UpdateTopLevelAccelerationStructure(uint32_t instanceNum, const Buffer& buffer, uint64_t bufferOffset, AccelerationStructureBuildBits flags, AccelerationStructure& dst, AccelerationStructure& src, Buffer& scratch, uint64_t scratchOffset) {} +void CommandBufferMTL::UpdateBottomLevelAccelerationStructure(uint32_t geometryObjectNum, const GeometryObject* geometryObjects, AccelerationStructureBuildBits flags, AccelerationStructure& dst, AccelerationStructure& src, Buffer& scratch, uint64_t scratchOffset) {} +void CommandBufferMTL::CopyAccelerationStructure(AccelerationStructure& dst, AccelerationStructure& src, CopyMode copyMode) {} +void CommandBufferMTL::WriteAccelerationStructureSize(const AccelerationStructure* const* accelerationStructures, uint32_t accelerationStructureNum, QueryPool& queryPool, uint32_t queryPoolOffset) {} +void CommandBufferMTL::DispatchRays(const DispatchRaysDesc& dispatchRaysDesc) {} +void CommandBufferMTL::DispatchRaysIndirect(const Buffer& buffer, uint64_t offset) {} +void CommandBufferMTL::DrawMeshTasks(const DrawMeshTasksDesc& drawMeshTasksDesc) {} +void CommandBufferMTL::DrawMeshTasksIndirect(const Buffer& buffer, uint64_t offset, uint32_t drawNum, uint32_t stride) { + +} + +void Create(id cmd); + + + +#include "CommandBufferMTL.hpp" + diff --git a/Source/Metal/CommandQueueMTL.h b/Source/Metal/CommandQueueMTL.h new file mode 100644 index 0000000..0486e73 --- /dev/null +++ b/Source/Metal/CommandQueueMTL.h @@ -0,0 +1,59 @@ +// © 2021 NVIDIA Corporation +#pragma once + +#import + +namespace nri { + +struct DeviceMTL; + +NriBits(QueueBarrierBits, uint8_t, + NONE = 0, + BARRIER_FLAG_BUFFERS = NriBit(0), + BARRIER_FLAG_TEXTURES = NriBit(1), + BARRIER_FLAG_RENDERTARGETS = NriBit(2), + BARRIER_FLAG_FENCE = NriBit(3)); + +struct CommandQueueMTL { + + inline CommandQueueMTL(DeviceMTL& device) + : m_Device(device) { + } + + ~CommandQueueMTL(); + + inline operator id() const { + return m_Handle; + } + + inline DeviceMTL& GetDevice() const { + return m_Device; + } + + inline CommandQueueType GetType() const { + return m_Type; + } + + inline Lock& GetLock() { + return m_Lock; + } + + + void SetDebugName(const char* name); + void Submit(const QueueSubmitDesc& queueSubmitDesc, const SwapChain* swapChain); + Result WaitForIdle(); + + Result Create(CommandQueueType type); + QueueBarrierBits m_BarrierBits = QueueBarrierBits::NONE; + +private: + DeviceMTL& m_Device; + CommandQueueType m_Type = CommandQueueType(-1); + id m_Handle; + Lock m_Lock; + +}; + +} + + diff --git a/Source/Metal/CommandQueueMTL.mm b/Source/Metal/CommandQueueMTL.mm new file mode 100644 index 0000000..6ad2415 --- /dev/null +++ b/Source/Metal/CommandQueueMTL.mm @@ -0,0 +1,53 @@ +// © 2021 NVIDIA Corporation + +#include "SharedMTL.h" + +#include "CommandQueueMTL.h" +#include "CommandBufferMTL.h" + +using namespace nri; + +CommandQueueMTL::~CommandQueueMTL() { + m_Handle = nil; +} + +Result CommandQueueMTL::Create(CommandQueueType type) { + m_Type = type; + const char* queueNames[] = { + "GRAPHICS_QUEUE", // GRAPHICS + "TRANSFER_QUEUE", // TRANSFER + "COMPUTE_QUEUE" // COMPUTE + }; + + m_Handle = [m_Device newCommandQueueWithMaxCommandBufferCount:512]; + SetDebugName(queueNames[(uint32_t)type]); + + return Result::SUCCESS; +} + + +void CommandQueueMTL::Submit(const QueueSubmitDesc& queueSubmitDesc, const SwapChain* swapChain) { + + for(uint32_t i = 0; i < queueSubmitDesc.commandBufferNum; i++) { + id cmd = *(struct CommandBufferMTL*)queueSubmitDesc.commandBuffers[i]; + [cmd commit]; + + } + + +} + + +void CommandQueueMTL::SetDebugName(const char* name) { + [m_Handle setLabel:[NSString stringWithUTF8String:name]]; +} + +Result CommandQueueMTL::WaitForIdle() { + + id waitCmdBuf = [m_Handle commandBufferWithUnretainedReferences]; + + [waitCmdBuf commit]; + [waitCmdBuf waitUntilCompleted]; + + waitCmdBuf = nil; +} diff --git a/Source/Metal/ConversionMTL.h b/Source/Metal/ConversionMTL.h new file mode 100644 index 0000000..f8d1e8b --- /dev/null +++ b/Source/Metal/ConversionMTL.h @@ -0,0 +1,277 @@ +#pragma once + +#include + +namespace nri { + +constexpr std::array DEFAULT_MEMORY_RESOURCE_OPTION_MEMORY_LOCATION ={ + MTLResourceStorageModePrivate, // DEVICE + MTLResourceStorageModeShared | MTLResourceCPUCacheModeWriteCombined, // DEVICE_UPLOAD + MTLResourceStorageModeShared | MTLResourceCPUCacheModeWriteCombined, // HOST_UPLOAD + MTLResourceStorageModeShared | MTLResourceCPUCacheModeDefaultCache // HOST_READBACK +}; + +constexpr std::array DEFAULT_CACHE_MODE_MEMORY_LOCATION ={ + MTLCPUCacheModeDefaultCache, // DEVICE + MTLCPUCacheModeWriteCombined, // DEVICE_UPLOAD + MTLCPUCacheModeWriteCombined, // HOST_UPLOAD + MTLCPUCacheModeDefaultCache // HOST_READBACK +}; + +constexpr std::array DEFAULT_STORAGE_MODE_MEMORY_LOCATION ={ + MTLStorageModePrivate, // DEVICE + MTLStorageModeShared, // DEVICE_UPLOAD + MTLStorageModeShared, // HOST_UPLOAD + MTLStorageModeShared // HOST_READBACK +}; + + +constexpr std::array MTL_NRI_FORMAT_TO_VERTEX_FORMAT = { + MTLVertexFormatInvalid, // UNKNOWN + MTLVertexFormatUCharNormalized, // R8_UNORM + MTLVertexFormatCharNormalized, // R8_SNORM + MTLVertexFormatUChar, // R8_UINT + MTLVertexFormatChar, // R8_SINT + MTLVertexFormatUChar2Normalized, // RG8_UNORM + MTLVertexFormatChar2Normalized, // RG8_SNORM + MTLVertexFormatUChar2, // RG8_UINT + MTLVertexFormatChar2, // RG8_SINT + MTLVertexFormatUChar4Normalized, // BGRA8_UNORM + MTLVertexFormatInvalid, // BGRA8_SRGB + MTLVertexFormatUChar4Normalized, // RGBA8_UNORM + MTLVertexFormatInvalid, // RGBA8_SRGB + MTLVertexFormatChar4Normalized, // RGBA8_SNORM + MTLVertexFormatUChar4, // RGBA8_UINT + MTLVertexFormatChar4, // RGBA8_SINT + MTLVertexFormatUShortNormalized, // R16_UNORM + MTLVertexFormatShortNormalized, // R16_SNORM + MTLVertexFormatUShort, // R16_UINT + MTLVertexFormatShort, // R16_SINT + MTLVertexFormatHalf, // R16_SFLOAT + MTLVertexFormatUShort2Normalized, // RG16_UNORM + MTLVertexFormatShort2Normalized, // RG16_SNORM + MTLVertexFormatUShort2, // RG16_UINT + MTLVertexFormatShort2, // RG16_SINT + MTLVertexFormatHalf2, // RG16_SFLOAT + MTLVertexFormatUShort4Normalized, // RGBA16_UNORM + MTLVertexFormatShort4Normalized, // RGBA16_SNORM + MTLVertexFormatUShort4, // RGBA16_UINT + MTLVertexFormatShort4, // RGBA16_SINT + MTLVertexFormatHalf4, // RGBA16_SFLOAT + MTLVertexFormatUInt, // R32_UINT + MTLVertexFormatInt, // R32_SINT + MTLVertexFormatFloat, // R32_SFLOAT + MTLVertexFormatUInt2, // RG32_UINT + MTLVertexFormatInt2, // RG32_SINT + MTLVertexFormatFloat2, // RG32_SFLOAT + MTLVertexFormatInvalid, // RGB32_UINT //TODO: lookup correct values + MTLVertexFormatInvalid, // RGB32_SINT //TODO: lookup correct values + MTLVertexFormatInvalid, // RGB32_SFLOAT //TODO: lookup correct values + MTLVertexFormatUInt4, // RGBA32_UINT + MTLVertexFormatInt4, // RGBA32_SINT + MTLVertexFormatFloat4, // RGBA32_SFLOAT + MTLVertexFormatInvalid, // B5_G6_R5_UNORM + MTLVertexFormatInvalid, // B5_G5_R5_A1_UNORM + MTLVertexFormatInvalid, // B4_G4_R4_A4_UNORM + MTLVertexFormatInvalid, // R10_G10_B10_A2_UNORM + MTLVertexFormatInvalid, // R10_G10_B10_A2_UINT + MTLVertexFormatInvalid, // R11_G11_B10_UFLOAT + MTLVertexFormatInvalid, // R9_G9_B9_E5_UFLOAT + MTLVertexFormatInvalid, // BC1_RGBA_UNORM + MTLVertexFormatInvalid, // BC1_RGBA_SRGB + MTLVertexFormatInvalid, // BC2_RGBA_UNORM + MTLVertexFormatInvalid, // BC2_RGBA_SRGB + MTLVertexFormatInvalid, // BC3_RGBA_UNORM + MTLVertexFormatInvalid, // BC3_RGBA_SRGB + MTLVertexFormatInvalid, // BC4_R_UNORM + MTLVertexFormatInvalid, // BC4_R_SNORM + MTLVertexFormatInvalid, // BC5_RG_UNORM + MTLVertexFormatInvalid, // BC5_RG_SNORM + MTLVertexFormatInvalid, // BC6H_RGB_UFLOAT + MTLVertexFormatInvalid, // BC6H_RGB_SFLOAT + MTLVertexFormatInvalid, // BC7_RGBA_UNORM + MTLVertexFormatInvalid, // BC7_RGBA_SRGB + MTLVertexFormatInvalid, // D16_UNORM + MTLVertexFormatInvalid, // D24_UNORM_S8_UINT + MTLVertexFormatInvalid, // D32_SFLOAT + MTLVertexFormatInvalid, // D32_SFLOAT_S8_UINT_X24 + MTLVertexFormatInvalid, // R24_UNORM_X8 + MTLVertexFormatInvalid, // X24_G8_UINT + MTLVertexFormatInvalid, // R32_SFLOAT_X8_X24 + MTLVertexFormatInvalid, // X32_G8_UINT_X24 +}; + +constexpr std::array BLEND_OP = { + MTLBlendOperationAdd, // ADD + MTLBlendOperationSubtract, // SUBTRACT + MTLBlendOperationReverseSubtract, // REVERSE_SUBTRACT + MTLBlendOperationMin, // MIN + MTLBlendOperationMax // MAX +}; +constexpr MTLBlendOperation GetBlendOp(BlendFunc blendFunc) { + return BLEND_OP[(size_t)blendFunc]; +} + +constexpr std::array IMAGE_TYPES = { + MTLTextureType1D, // TEXTURE_1D + MTLTextureType2D, // TEXTURE_2D + MTLTextureType3D, // TEXTURE_3D +}; + +constexpr MTLTextureType GetImageTypeMTL(TextureType type) { + return IMAGE_TYPES[(size_t)type]; +} + +constexpr std::array BLEND_FACTOR = { + MTLBlendFactorZero, // ZERO + MTLBlendFactorOne, // ONE + MTLBlendFactorSourceColor, // SRC_COLOR + MTLBlendFactorOneMinusSourceColor, // ONE_MINUS_SRC_COLOR + MTLBlendFactorDestinationColor, // DST_COLOR + MTLBlendFactorOneMinusDestinationColor, // ONE_MINUS_DST_COLOR + MTLBlendFactorSourceAlpha, // SRC_ALPHA + MTLBlendFactorOneMinusSourceAlpha, // ONE_MINUS_SRC_ALPHA + MTLBlendFactorDestinationAlpha, // DST_ALPHA + MTLBlendFactorOneMinusDestinationAlpha, // ONE_MINUS_DST_ALPHA + MTLBlendFactorBlendColor, // CONSTANT_COLOR + MTLBlendFactorOneMinusBlendColor, // ONE_MINUS_CONSTANT_COLOR + MTLBlendFactorBlendAlpha, // CONSTANT_ALPHA + MTLBlendFactorOneMinusBlendAlpha, // ONE_MINUS_CONSTANT_ALPHA + MTLBlendFactorSourceAlphaSaturated, // SRC_ALPHA_SATURATE + MTLBlendFactorSource1Color, // SRC1_COLOR + MTLBlendFactorOneMinusSource1Color, // ONE_MINUS_SRC1_COLOR + MTLBlendFactorSource1Alpha, // SRC1_ALPHA + MTLBlendFactorOneMinusSource1Alpha, // ONE_MINUS_SRC1_ALPHA +}; + +constexpr MTLBlendFactor GetBlendFactor(BlendFactor blendFactor) { + return BLEND_FACTOR[(size_t)blendFactor]; +} + +constexpr MTLColorWriteMask GetColorComponent(ColorWriteBits colorWriteMask) { + return MTLColorWriteMask(colorWriteMask) & MTLColorWriteMaskAll; +} + +constexpr std::array DESCRIPTOR_TYPES = { + MTLDataTypeSampler, // SAMPLER + MTLDataTypeNone, // CONSTANT_BUFFER + MTLDataTypeTexture, // TEXTURE + MTLDataTypeNone, // STORAGE_TEXTURE + MTLDataTypeStruct, // BUFFER + MTLDataTypeStruct, // STORAGE_BUFFER + MTLDataTypeArray, // STRUCTURED_BUFFER + MTLDataTypeStruct, // STORAGE_STRUCTURED_BUFFER + MTLDataTypePrimitiveAccelerationStructure // ACCELERATION_STRUCTURE +}; + +constexpr MTLDataType GetDescriptorType(DescriptorType type) { + return DESCRIPTOR_TYPES[(size_t)type]; +} + +constexpr std::array COMPARE_OP = { + MTLCompareFunctionNever, // NONE + MTLCompareFunctionAlways, // ALWAYS + MTLCompareFunctionNever, // NEVER + MTLCompareFunctionEqual, // EQUAL + MTLCompareFunctionNotEqual, // NOT_EQUAL + MTLCompareFunctionLess, // LESS + MTLCompareFunctionLessEqual, // LESS_EQUAL + MTLCompareFunctionGreater, // GREATER + MTLCompareFunctionGreaterEqual, // GREATER_EQUAL +}; + +constexpr MTLCompareFunction GetCompareOp(CompareFunc compareFunc) { + return COMPARE_OP[(size_t)compareFunc]; +} + +constexpr std::array STENCIL_OP = { + MTLStencilOperationKeep, // KEEP + MTLStencilOperationZero, // ZERO + MTLStencilOperationReplace, // REPLACE + MTLStencilOperationIncrementClamp, // INCREMENT_AND_CLAMP + MTLStencilOperationDecrementClamp, // DECREMENT_AND_CLAMP + MTLStencilOperationInvert, // INVERT + MTLStencilOperationIncrementWrap, // INCREMENT_AND_WRAP + MTLStencilOperationDecrementWrap // DECREMENT_AND_WRAP +}; + +constexpr MTLStencilOperation GetStencilOp(StencilFunc stencilFunc) { + return STENCIL_OP[(size_t)stencilFunc]; +} + + +constexpr std::array CULL_MODES = { + MTLCullModeNone, // NONE + MTLCullModeFront, // FRONT + MTLCullModeBack // BACK +}; + +constexpr MTLCullMode GetCullMode(CullMode cullMode) { + return CULL_MODES[(size_t)cullMode]; +} + +constexpr std::array POLYGON_MODES = { + MTLTriangleFillModeFill, // SOLID + MTLTriangleFillModeLines // WIREFRAME +}; + +constexpr MTLTriangleFillMode GetPolygonMode(FillMode fillMode) { + return POLYGON_MODES[(size_t)fillMode]; +} + +constexpr std::array SAMPLER_ADDRESS_MODE = { + MTLSamplerAddressModeRepeat, // REPEAT, + MTLSamplerAddressModeMirrorRepeat, // MIRRORED_REPEAT, + MTLSamplerAddressModeClampToEdge, // CLAMP_TO_EDGE, + MTLSamplerAddressModeClampToBorderColor, // CLAMP_TO_BORDER, + MTLSamplerAddressModeClampToEdge // MIRROR_CLAMP_TO_EDGE +}; + +constexpr std::array MIN_MAG_FILTER = { + MTLSamplerMinMagFilterNearest, // NEAREST + MTLSamplerMinMagFilterLinear // LINEAR +}; + +constexpr MTLSamplerMinMagFilter GetFilter(Filter filter) { + return MIN_MAG_FILTER[(size_t)filter]; +} + +constexpr MTLSamplerAddressMode GetSamplerAddressMode(AddressMode addressMode) { + return SAMPLER_ADDRESS_MODE[(size_t)addressMode]; +} + +constexpr std::array TOPOLOGIES_CLASSES = { + MTLPrimitiveTopologyClassPoint, // POINT_LIST + MTLPrimitiveTopologyClassLine, // LINE_LIST + MTLPrimitiveTopologyClassLine, // LINE_STRIP + MTLPrimitiveTopologyClassTriangle, // TRIANGLE_LIST + MTLPrimitiveTopologyClassTriangle, // TRIANGLE_STRIP + MTLPrimitiveTopologyClassLine, // LINE_LIST_WITH_ADJACENCY + MTLPrimitiveTopologyClassLine, // LINE_STRIP_WITH_ADJACENCY + MTLPrimitiveTopologyClassTriangle, // TRIANGLE_LIST_WITH_ADJACENCY + MTLPrimitiveTopologyClassTriangle, // TRIANGLE_STRIP_WITH_ADJACENCY + MTLPrimitiveTopologyClassTriangle // PATCH_LIST TODO: not sure +}; + + +constexpr MTLPrimitiveTopologyClass GetTopologyMTL(Topology topology) { + return TOPOLOGIES_CLASSES [(size_t)topology]; +} + + +inline MTLVertexFormat GetVertexFormatMTL(Format format) { + return (MTLVertexFormat)MTL_NRI_FORMAT_TO_VERTEX_FORMAT[(size_t)format]; +} + +inline MTLPixelFormat GetFormatMTL(Format format, bool demoteSrgb = false) { + if (demoteSrgb) { + const FormatProps& formatProps = GetFormatProps(format); + if (formatProps.isSrgb) + format = (Format)((uint32_t)format - 1); + } + + return (MTLPixelFormat)NRIFormatToMTLFormat(format); +} + +}; + diff --git a/Source/Metal/ConversionMTL.mm b/Source/Metal/ConversionMTL.mm new file mode 100644 index 0000000..ef20071 --- /dev/null +++ b/Source/Metal/ConversionMTL.mm @@ -0,0 +1,87 @@ +#include "SharedMTL.h" + +#include "ConversionMTL.h" + +using namespace nri; + +// Each depth/stencil format is only compatible with itself in VK +constexpr std::array MTL_PIXEL_FORMAT = { + MTLPixelFormatInvalid, // UNKNOWN + MTLPixelFormatR8Unorm, // R8_UNORM + MTLPixelFormatR8Snorm, // R8_SNORM + MTLPixelFormatR8Uint, // R8_UINT + MTLPixelFormatR8Sint, // R8_SINT + MTLPixelFormatRG8Unorm, // RG8_UNORM + MTLPixelFormatRG8Snorm, // RG8_SNORM + MTLPixelFormatRG8Uint, // RG8_UINT + MTLPixelFormatRG8Sint, // RG8_SINT + MTLPixelFormatBGRA8Unorm, // BGRA8_UNORM + MTLPixelFormatBGRA8Unorm_sRGB, // BGRA8_SRGB + MTLPixelFormatRGBA8Unorm, // RGBA8_UNORM + MTLPixelFormatRGBA8Unorm_sRGB, // RGBA8_SRGB + MTLPixelFormatRGBA8Snorm, // RGBA8_SNORM + MTLPixelFormatRGBA8Uint, // RGBA8_UINT + MTLPixelFormatRGBA8Sint, // RGBA8_SINT + MTLPixelFormatR16Unorm, // R16_UNORM + MTLPixelFormatR16Snorm, // R16_SNORM + MTLPixelFormatR16Uint, // R16_UINT + MTLPixelFormatR16Sint, // R16_SINT + MTLPixelFormatR16Float, // R16_SFLOAT + MTLPixelFormatRG16Unorm, // RG16_UNORM + MTLPixelFormatRG16Snorm, // RG16_SNORM + MTLPixelFormatRG16Uint, // RG16_UINT + MTLPixelFormatRG16Sint, // RG16_SINT + MTLPixelFormatRG16Float, // RG16_SFLOAT + MTLPixelFormatRGBA16Unorm, // RGBA16_UNORM + MTLPixelFormatRGBA16Snorm, // RGBA16_SNORM + MTLPixelFormatRGBA16Uint, // RGBA16_UINT + MTLPixelFormatRGBA16Sint, // RGBA16_SINT + MTLPixelFormatRGBA16Float, // RGBA16_SFLOAT + MTLPixelFormatR32Uint, // R32_UINT + MTLPixelFormatR32Sint, // R32_SINT + MTLPixelFormatR32Float, // R32_SFLOAT + MTLPixelFormatRG32Uint, // RG32_UINT + MTLPixelFormatRG32Sint, // RG32_SINT + MTLPixelFormatRG32Float, // RG32_SFLOAT + MTLPixelFormatInvalid, // RGB32_UINT //TODO: lookup correct values + MTLPixelFormatInvalid, // RGB32_SINT //TODO: lookup correct values + MTLPixelFormatInvalid, // RGB32_SFLOAT //TODO: lookup correct values + MTLPixelFormatRGBA32Uint, // RGB32_UINT + MTLPixelFormatRGBA32Sint, // RGB32_SINT + MTLPixelFormatRGBA32Float, // RGB32_SFLOAT + MTLPixelFormatB5G6R5Unorm, // B5_G6_R5_UNORM + MTLPixelFormatA1BGR5Unorm, // B5_G5_R5_A1_UNORM + MTLPixelFormatABGR4Unorm, // B4_G4_R4_A4_UNORM + MTLPixelFormatRGB10A2Unorm, // R10_G10_B10_A2_UNORM + MTLPixelFormatRGB10A2Uint, // R10_G10_B10_A2_UINT + MTLPixelFormatRG11B10Float, // R11_G11_B10_UFLOAT + MTLPixelFormatRGB9E5Float, // R9_G9_B9_E5_UFLOAT + MTLPixelFormatBC1_RGBA, // BC1_RGBA_UNORM + MTLPixelFormatBC1_RGBA_sRGB, // BC1_RGBA_SRGB + MTLPixelFormatBC2_RGBA, // BC2_RGBA_UNORM + MTLPixelFormatBC2_RGBA_sRGB, // BC2_RGBA_SRGB + MTLPixelFormatBC3_RGBA, // BC3_RGBA_UNORM + MTLPixelFormatBC3_RGBA_sRGB, // BC3_RGBA_SRGB + MTLPixelFormatBC4_RUnorm, // BC4_R_UNORM + MTLPixelFormatBC4_RSnorm, // BC4_R_SNORM + MTLPixelFormatBC5_RGUnorm, // BC5_RG_UNORM + MTLPixelFormatBC5_RGSnorm, // BC5_RG_SNORM + MTLPixelFormatBC6H_RGBUfloat, // BC6H_RGB_UFLOAT + MTLPixelFormatBC6H_RGBFloat, // BC6H_RGB_SFLOAT + MTLPixelFormatBC7_RGBAUnorm, // BC7_RGBA_UNORM + MTLPixelFormatBC7_RGBAUnorm_sRGB, // BC7_RGBA_SRGB + MTLPixelFormatDepth16Unorm, // D16_UNORM + MTLPixelFormatDepth24Unorm_Stencil8, // D24_UNORM_S8_UINT + MTLPixelFormatDepth32Float, // D32_SFLOAT + MTLPixelFormatDepth32Float_Stencil8, // D32_SFLOAT_S8_UINT_X24 + MTLPixelFormatDepth24Unorm_Stencil8, // R24_UNORM_X8 + MTLPixelFormatDepth24Unorm_Stencil8, // X24_G8_UINT + MTLPixelFormatDepth32Float_Stencil8, // R32_SFLOAT_X8_X24 + MTLPixelFormatDepth32Float_Stencil8, // X32_G8_UINT_X24 +}; + + +uint32_t NRIFormatToMTLFormat(Format format) { + return (uint32_t)MTL_PIXEL_FORMAT[(uint32_t)format]; +} + diff --git a/Source/Metal/DescriptorMTL.h b/Source/Metal/DescriptorMTL.h new file mode 100644 index 0000000..903fb9c --- /dev/null +++ b/Source/Metal/DescriptorMTL.h @@ -0,0 +1,69 @@ +// © 2021 NVIDIA Corporation + +#pragma once + +namespace nri { + +struct DeviceMTL; + + +struct DescriptorView { +}; + +enum class DescriptorTypeMTL { + NONE, + IMAGE_VIEW_1D, + IMAGE_VIEW_2D, + IMAGE_VIEW_3D, + SAMPLER, + BUFFER_VIEW +}; + + +struct DescriptorMTL { +public: + inline DescriptorMTL (DeviceMTL& device) + : m_Device(device) { + } + + ~DescriptorMTL(); + inline DescriptorTypeMTL GetType() { + return m_Type; + } + inline id GetTextureHandle() { + return m_Texture; + } + inline id GetBufferHandle() { + return m_Buffer; + } + inline id GetSamplerStateHandler() { + return m_SamplerState; + } + + inline struct BufferViewDesc& BufferView() { + return m_BufferViewDesc; + } + + Result Create(const BufferViewDesc& bufferViewDesc); + Result Create(const Texture1DViewDesc& textureViewDesc); + Result Create(const Texture2DViewDesc& textureViewDesc); + Result Create(const Texture3DViewDesc& textureViewDesc); + Result Create(const SamplerDesc& samplerDesc); + +private: + + DeviceMTL& m_Device; + DescriptorTypeMTL m_Type = DescriptorTypeMTL::NONE; + id m_Texture; + id m_Buffer; + id m_SamplerState; + + union { + BufferViewDesc m_BufferViewDesc; + SamplerDesc m_SamplerViewDesc; + }; + + +}; + +} // namespace nri diff --git a/Source/Metal/DescriptorMTL.mm b/Source/Metal/DescriptorMTL.mm new file mode 100644 index 0000000..fe9c189 --- /dev/null +++ b/Source/Metal/DescriptorMTL.mm @@ -0,0 +1,101 @@ +#include "SharedMTL.h" + +#include "DescriptorMTL.h" + +#include "BufferMTL.h" +#include "TextureMTL.h" + +#include "ConversionMTL.h" + +namespace nri { + +DescriptorMTL::~DescriptorMTL() { + +} + + +Result DescriptorMTL::Create(const BufferViewDesc& bufferViewDesc) { + m_Type = DescriptorTypeMTL::BUFFER_VIEW; + const BufferMTL& buffer = *(const BufferMTL*)bufferViewDesc.buffer; + + return Result::SUCCESS; + +} + + +Result DescriptorMTL::Create(const Texture1DViewDesc& textureViewDesc) { + TextureMTL& texture = *(TextureMTL*)textureViewDesc.texture; + const Mip_t remainingMips = textureViewDesc.mipNum - textureViewDesc.mipOffset; + const Dim_t remainingLayers = textureViewDesc.layerNum - textureViewDesc.layerOffset; + + NSRange level; + level.location = textureViewDesc.mipOffset; + level.length = textureViewDesc.mipNum == REMAINING_MIPS ? remainingMips: textureViewDesc.mipNum; + NSRange slices; + slices.location = textureViewDesc.layerNum; + slices.length = textureViewDesc.layerNum == REMAINING_LAYERS ? remainingLayers : textureViewDesc.layerNum; + m_Texture = [texture.GetHandle() + newTextureViewWithPixelFormat: GetFormatMTL(textureViewDesc.format) + textureType: MTLTextureType1D + levels:level + slices:slices]; + + return Result::SUCCESS; + +} +Result DescriptorMTL::Create(const Texture2DViewDesc& textureViewDesc) { + TextureMTL& texture = *(TextureMTL*)textureViewDesc.texture; + const Mip_t remainingMips = textureViewDesc.mipNum - textureViewDesc.mipOffset; + const Dim_t remainingLayers = textureViewDesc.layerNum - textureViewDesc.layerOffset; + + NSRange level; + level.location = textureViewDesc.mipOffset; + level.length = textureViewDesc.mipNum == REMAINING_MIPS ? remainingMips: textureViewDesc.mipNum; + NSRange slices; + slices.location = textureViewDesc.layerNum; + slices.length = textureViewDesc.layerNum == REMAINING_LAYERS ? remainingLayers : textureViewDesc.layerNum; + m_Texture = [texture.GetHandle() + newTextureViewWithPixelFormat: GetFormatMTL(textureViewDesc.format) + textureType: MTLTextureType2D + levels:level + slices:slices]; + + return Result::SUCCESS; +} +Result DescriptorMTL::Create(const Texture3DViewDesc& textureViewDesc){ + TextureMTL& texture = *(TextureMTL*)textureViewDesc.texture; + const Mip_t remainingMips = textureViewDesc.mipNum - textureViewDesc.mipOffset; + const Dim_t remainingLayers = textureViewDesc.sliceNum - textureViewDesc.sliceOffset; + + NSRange level; + level.location = textureViewDesc.mipOffset; + level.length = textureViewDesc.mipNum == REMAINING_MIPS ? remainingMips: textureViewDesc.mipNum; + NSRange slices; + slices.location = textureViewDesc.sliceOffset; + slices.length = textureViewDesc.sliceNum == REMAINING_LAYERS ? remainingLayers : textureViewDesc.sliceOffset; + m_Texture = [texture.GetHandle() + newTextureViewWithPixelFormat: GetFormatMTL(textureViewDesc.format) + textureType: MTLTextureType3D + levels:level + slices:slices]; + + return Result::SUCCESS; +} + +Result DescriptorMTL::Create(const SamplerDesc& samplerDesc){ + MTLSamplerDescriptor* mtlDesc = [[MTLSamplerDescriptor alloc] init]; + [mtlDesc setMagFilter: GetFilter(samplerDesc.filters.mag)]; + [mtlDesc setMinFilter: GetFilter(samplerDesc.filters.min)]; + [mtlDesc setRAddressMode: GetSamplerAddressMode(samplerDesc.addressModes.w)]; + [mtlDesc setSAddressMode: GetSamplerAddressMode(samplerDesc.addressModes.u)]; + [mtlDesc setTAddressMode: GetSamplerAddressMode(samplerDesc.addressModes.v)]; + [mtlDesc setMaxAnisotropy: samplerDesc.anisotropy]; + [mtlDesc setCompareFunction: GetCompareOp(samplerDesc.compareFunc)]; + [mtlDesc setLodMinClamp: samplerDesc.mipMin]; + [mtlDesc setLodMaxClamp: samplerDesc.mipMax]; + m_SamplerState = [m_Device newSamplerStateWithDescriptor: mtlDesc]; + + return Result::SUCCESS; +} + +} diff --git a/Source/Metal/DescriptorPoolMTL.h b/Source/Metal/DescriptorPoolMTL.h new file mode 100644 index 0000000..c21b0fb --- /dev/null +++ b/Source/Metal/DescriptorPoolMTL.h @@ -0,0 +1,45 @@ +// © 2021 NVIDIA Corporation + +#pragma once + +#import + +namespace nri { + +struct DeviceMTL; +struct DescriptorSetMTL; + +struct DescriptorPoolMTL { + inline DescriptorPoolMTL(DeviceMTL& device) + : m_Device(device) + , m_AllocatedSets(device.GetStdAllocator()) { + m_AllocatedSets.reserve(64); + } + + inline DeviceMTL& GetDevice() const { + return m_Device; + } + + ~DescriptorPoolMTL(); + Result Create(const DescriptorPoolDesc& descriptorPoolDesc); + + //================================================================================================================ + // NRI + //================================================================================================================ + +// size_t GetNumberOfArugmentsAlloc(); + void SetDebugName(const char* name); + void Reset(); + Result AllocateDescriptorSets(const PipelineLayout& pipelineLayout, uint32_t setIndex, DescriptorSet** descriptorSets, uint32_t instanceNum, uint32_t variableDescriptorNum); + +private: + DeviceMTL& m_Device; + size_t m_ArgumentOffset = 0; + Vector m_AllocatedSets; + id m_ArgumentBuffer; + + uint32_t m_UsedSets = 0; + bool m_OwnsNativeObjects = true; +}; + +} // namespace nri diff --git a/Source/Metal/DescriptorPoolMTL.mm b/Source/Metal/DescriptorPoolMTL.mm new file mode 100644 index 0000000..adb6488 --- /dev/null +++ b/Source/Metal/DescriptorPoolMTL.mm @@ -0,0 +1,72 @@ + +#include "SharedMTL.h" +#include "DescriptorPoolMTL.h" +#include "DescriptorSetMTL.h" +#include "PipelineLayoutMTL.h" + +using namespace nri; + + +DescriptorPoolMTL::~DescriptorPoolMTL() { + +} + +Result DescriptorPoolMTL::Create(const DescriptorPoolDesc& descriptorPoolDesc) { + size_t numArgs = descriptorPoolDesc.samplerMaxNum + + descriptorPoolDesc.constantBufferMaxNum + + descriptorPoolDesc.dynamicConstantBufferMaxNum + + descriptorPoolDesc.textureMaxNum + + descriptorPoolDesc.storageTextureMaxNum + + descriptorPoolDesc.bufferMaxNum + + descriptorPoolDesc.storageBufferMaxNum + + descriptorPoolDesc.structuredBufferMaxNum + + descriptorPoolDesc.accelerationStructureMaxNum; + + m_ArgumentBuffer = [m_Device + newBufferWithLength: numArgs * sizeof(uint32_t) options:MTLResourceStorageModeShared]; +} + + +//size_t DescriptorPoolMTL::GetNumberOfArugmentsAlloc() { +// return [m_ArgumentBuffer length] / sizeof(uint32_t); +//} + +//================================================================================================================ +// NRI +//================================================================================================================ + +void DescriptorPoolMTL::SetDebugName(const char* name) { + +} +void DescriptorPoolMTL::Reset() { + +} + +Result DescriptorPoolMTL::AllocateDescriptorSets(const PipelineLayout& pipelineLayout, uint32_t setIndex, DescriptorSet** descriptorSets, uint32_t instanceNum, uint32_t variableDescriptorNum) { + PipelineLayoutMTL* pipelineLayoutMTL = (PipelineLayoutMTL*)&pipelineLayout; + + uint32_t freeSetNum = (uint32_t)m_AllocatedSets.size() - m_UsedSets; + if (freeSetNum < instanceNum) { + uint32_t newSetNum = instanceNum - freeSetNum; + uint32_t prevSetNum = (uint32_t)m_AllocatedSets.size(); + m_AllocatedSets.resize(prevSetNum + newSetNum); + for (size_t i = 0; i < newSetNum; i++) { + Construct(m_AllocatedSets[prevSetNum + i], 1, m_Device); + } + } + + struct DescriptorSetLayout* setLayoutMTL = pipelineLayoutMTL->GetDescriptorSetLayout(setIndex); + for(uint32_t i = 0; i < instanceNum; i++) { + descriptorSets[i] = (DescriptorSet*)m_AllocatedSets[m_UsedSets++]; + ((DescriptorSetMTL*)descriptorSets[i])->Create( + m_ArgumentOffset, + m_ArgumentBuffer, + setLayoutMTL->m_ArgumentDescriptors, + &setLayoutMTL->m_DescriptorSetDesc); + m_ArgumentOffset += ((DescriptorSetMTL*)descriptorSets[i])->getDescriptorLength(); + } + + + return Result::SUCCESS; +} + diff --git a/Source/Metal/DescriptorSetMTL.h b/Source/Metal/DescriptorSetMTL.h new file mode 100644 index 0000000..dfb520d --- /dev/null +++ b/Source/Metal/DescriptorSetMTL.h @@ -0,0 +1,31 @@ +// © 2021 NVIDIA Corporation + +#pragma once + +namespace nri { + +struct DeviceVK; +struct DescriptorSetMTL { +public: + inline DescriptorSetMTL (DeviceMTL& device) + : m_Device(device) { + } + + void Create(size_t argumentBufferOffset, id argumentBuffer, NSArray* argDesc, const struct DescriptorSetDesc* desc); + void UpdateDescriptorRanges(uint32_t rangeOffset, uint32_t rangeNum, const DescriptorRangeUpdateDesc* rangeUpdateDescs); + inline id GetArgumentHandle() { + return m_ArgumentEncoder; + } + size_t getDescriptorLength(); + +private: + DeviceMTL& m_Device; + id m_ArgumentEncoder; + id m_ArgumentBuffer; + size_t m_ArgumentBufferOffset; + NSArray* m_ArgumentDescriptor; + const DescriptorSetDesc* m_Desc = nullptr; +}; + +} // namespace nri + diff --git a/Source/Metal/DescriptorSetMTL.mm b/Source/Metal/DescriptorSetMTL.mm new file mode 100644 index 0000000..9ae3d47 --- /dev/null +++ b/Source/Metal/DescriptorSetMTL.mm @@ -0,0 +1,51 @@ + +#include "SharedMTL.h" + +#include "DescriptorSetMTL.h" +#include "DescriptorMTL.h" + +using namespace nri; + + +void DescriptorSetMTL::Create(size_t argumentBufferOffset, id argumentBuffer, NSArray* argDesc, const struct DescriptorSetDesc* desc) { + m_ArgumentDescriptor = argDesc; + m_ArgumentBuffer = argumentBuffer; + m_ArgumentBufferOffset = argumentBufferOffset; + m_Desc = desc; + m_ArgumentEncoder = [m_Device newArgumentEncoderWithArguments: argDesc]; + [m_ArgumentEncoder setArgumentBuffer:m_ArgumentBuffer offset:argumentBufferOffset]; +} + +size_t DescriptorSetMTL::getDescriptorLength() { + return [m_ArgumentEncoder encodedLength]; +} + +void DescriptorSetMTL::UpdateDescriptorRanges(uint32_t rangeOffset, uint32_t rangeNum, const DescriptorRangeUpdateDesc* rangeUpdateDescs) { + + for(size_t j = 0; j < rangeNum; j++) { + const DescriptorRangeUpdateDesc& update = rangeUpdateDescs[j]; + for(size_t descIdx = 0; descIdx < update.descriptorNum; descIdx++) { + DescriptorMTL* descriptorImpl = (DescriptorMTL*)&update.descriptors[descIdx]; + const DescriptorRangeDesc& rangeDesc = m_Desc->ranges[rangeOffset + j]; + + switch(descriptorImpl->GetType()) { + case DescriptorTypeMTL::IMAGE_VIEW_1D: + case DescriptorTypeMTL::IMAGE_VIEW_2D: + case DescriptorTypeMTL::IMAGE_VIEW_3D: + [m_ArgumentEncoder setTexture: descriptorImpl->GetTextureHandle() atIndex: rangeDesc.baseRegisterIndex + descIdx]; + break; + case DescriptorTypeMTL::SAMPLER: + [m_ArgumentEncoder setSamplerState: descriptorImpl->GetSamplerStateHandler() atIndex:rangeDesc.baseRegisterIndex + descIdx]; // not sure if this is correct + break; + case DescriptorTypeMTL::BUFFER_VIEW: { + BufferViewDesc* view = &descriptorImpl->BufferView(); + [m_ArgumentEncoder setBuffer: descriptorImpl->GetBufferHandle() offset: view->offset atIndex: rangeDesc.baseRegisterIndex + descIdx]; + break; + } + default: + break; + } + + } + } +} diff --git a/Source/Metal/DeviceMTL.h b/Source/Metal/DeviceMTL.h new file mode 100644 index 0000000..6839d00 --- /dev/null +++ b/Source/Metal/DeviceMTL.h @@ -0,0 +1,70 @@ +#pragma once + +#import + +namespace nri { + +struct CommandQueueMTL; + +struct DeviceMTL final : public DeviceBase { +public: + DeviceMTL(const CallbackInterface& callbacks, const StdAllocator& stdAllocator); + ~DeviceMTL(); + + + Result GetCommandQueue(CommandQueueType commandQueueType, CommandQueue*& commandQueue); + + inline operator id() const { + return m_Device; + } + + inline id GetHandle() const { + return m_Device; + } + + template + inline Result CreateImplementation(Interface*& entity, const Args&... args) { + Implementation* impl = Allocate(GetStdAllocator(), *this); + Result result = impl->Create(args...); + + if (result != Result::SUCCESS) { + Destroy(GetStdAllocator(), impl); + entity = nullptr; + } else + entity = (Interface*)impl; + + return result; + } + + //void GetMemoryTypeInfo(MemoryLocation memoryLocation, MemoryDesc& memoryDesc) const; + void GetMemoryDesc(const BufferDesc& bufferDesc, MemoryLocation memoryLocation, MemoryDesc& memoryDesc) const; + void GetMemoryDesc(const TextureDesc& textureDesc, MemoryLocation memoryLocation, MemoryDesc& memoryDesc) const; + void GetMemoryDesc(const AccelerationStructureDesc& accelerationStructureDesc, MemoryLocation memoryLocation, MemoryDesc& memoryDesc) const; + //bool GetMemoryTypeInfo(MemoryLocation memoryLocation, MemoryTypeInfo& memoryTypeInfo) const; + + const DeviceDesc& GetDesc() const override { + return m_Desc; + } + + + void Destruct() override; + Result FillFunctionTable(CoreInterface& table) const override; + Result FillFunctionTable(HelperInterface& table) const override; + Result FillFunctionTable(LowLatencyInterface& table) const override; + Result FillFunctionTable(MeshShaderInterface& table) const override; + Result FillFunctionTable(RayTracingInterface& table) const override; + Result FillFunctionTable(StreamerInterface& table) const override; + Result FillFunctionTable(SwapChainInterface& table) const override; + Result FillFunctionTable(ResourceAllocatorInterface& table) const override; + + Result Create(const DeviceCreationDesc& deviceCreationDesc, const DeviceCreationMTLDesc& deviceCreationVKDesc, bool isWrapper); +private: + //Lock m_Lock; + id m_Device; + std::array m_CommandQueues = {}; + DeviceDesc m_Desc = {}; + MTLGPUFamily m_Family; + bool m_OwnsNativeObjects = true; + Lock m_Lock; +}; +}; // namespace nri diff --git a/Source/Metal/DeviceMTL.hpp b/Source/Metal/DeviceMTL.hpp new file mode 100644 index 0000000..c6dd5d9 --- /dev/null +++ b/Source/Metal/DeviceMTL.hpp @@ -0,0 +1,260 @@ +// © 2021 NVIDIA Corporation + +//Declare_PartiallyFillFunctionTable_Functions(MTL); +// +//#pragma region[ Core ] +// +//static const DeviceDesc& NRI_CALL GetDeviceDesc(const Device& device) { +// return ((const DeviceMTL&)device).GetDesc(); +//} +// +//static const BufferDesc& NRI_CALL GetBufferDesc(const Buffer& buffer) { +// return ((const BufferMTL&)buffer).GetDesc(); +//} +// +//static const TextureDesc& NRI_CALL GetTextureDesc(const Texture& texture) { +// return ((const TextureMTL&)texture).GetDesc(); +//} +// +//static FormatSupportBits NRI_CALL GetFormatSupport(const Device& device, Format format) { +// return (FormatSupportBits)0; +// //return ((const DeviceDesc&)device).GetFormatSupport(format); +//} +// +//static void NRI_CALL GetBufferMemoryDesc(const Device& device, const BufferDesc& bufferDesc, MemoryLocation memoryLocation, MemoryDesc& memoryDesc) { +// //D3D12_RESOURCE_DESC desc = {}; +// //GetResourceDesc(&desc, bufferDesc); +// +// //((const DeviceD3D12&)device).GetMemoryDesc(memoryLocation, desc, memoryDesc); +//} +// +//static void NRI_CALL GetTextureMemoryDesc(const Device& device, const TextureDesc& textureDesc, MemoryLocation memoryLocation, MemoryDesc& memoryDesc) { +// //return ((const DeviceMTL&)device).GetMemoryDesc(textureDesc, memoryLocation, memoryDesc); +// +//} +// +//static Result NRI_CALL GetCommandQueue(Device& device, CommandQueueType commandQueueType, CommandQueue*& commandQueue) { +// return ((DeviceMTL&)device).GetCommandQueue(commandQueueType, commandQueue); +//} +// +//static Result NRI_CALL CreateCommandAllocator(const CommandQueue& commandQueue, CommandAllocator*& commandAllocator) { +// //DeviceMTL& device = ((CommandQueueD3D12&)commandQueue).GetDevice(); +// //return device.CreateImplementation(commandAllocator, commandQueue); +// return Result::SUCCESS; +//} +// +//static Result NRI_CALL CreateDescriptorPool(Device& device, const DescriptorPoolDesc& descriptorPoolDesc, DescriptorPool*& descriptorPool) { +// //return ((DeviceMTL&)device).CreateImplementation(descriptorPool, descriptorPoolDesc); +// return Result::SUCCESS; +//} +// +//static Result NRI_CALL CreateBuffer(Device& device, const BufferDesc& bufferDesc, Buffer*& buffer) { +// return ((DeviceMTL&)device).CreateImplementation(buffer, bufferDesc); +//} +// +//static Result NRI_CALL CreateTexture(Device& device, const TextureDesc& textureDesc, Texture*& texture) { +// return ((DeviceMTL&)device).CreateImplementation(texture, textureDesc); +//} +// +//static Result NRI_CALL CreateBufferView(const BufferViewDesc& bufferViewDesc, Descriptor*& bufferView) { +// //DeviceMTL& device = ((const BufferD3D12*)bufferViewDesc.buffer)->GetDevice(); +// //return device.CreateImplementation(bufferView, bufferViewDesc); +// return Result::SUCCESS; +//} +// +// +//static Result NRI_CALL CreateTexture1DView(const Texture1DViewDesc& textureViewDesc, Descriptor*& textureView) { +// //DeviceMTL& device = ((const TextureMTL*)textureViewDesc.texture)->GetDevice(); +// //return device.CreateImplementation(textureView, textureViewDesc); +// +// +// //DeviceMTL& device = ((const TextureD3D12*)textureViewDesc.texture)->GetDevice(); +// //return device.CreateImplementation(textureView, textureViewDesc); +// return Result::SUCCESS; +//} +// +//static Result NRI_CALL CreateTexture2DView(const Texture2DViewDesc& textureViewDesc, Descriptor*& textureView) { +// //DeviceMTL& device = ((const TextureD3D12*)textureViewDesc.texture)->GetDevice(); +// //return device.CreateImplementation(textureView, textureViewDesc); +// return Result::SUCCESS; +//} +// +//static Result NRI_CALL CreateTexture3DView(const Texture3DViewDesc& textureViewDesc, Descriptor*& textureView) { +// //DeviceMTL& device = ((const TextureD3D12*)textureViewDesc.texture)->GetDevice(); +// //return device.CreateImplementation(textureView, textureViewDesc); +// return Result::SUCCESS; +//} +// +//static Result NRI_CALL CreateSampler(Device& device, const SamplerDesc& samplerDesc, Descriptor*& sampler) { +// //return ((DeviceMTL&)device).CreateImplementation(sampler, samplerDesc); +// return Result::SUCCESS; +//} +// +//static Result NRI_CALL CreatePipelineLayout(Device& device, const PipelineLayoutDesc& pipelineLayoutDesc, PipelineLayout*& pipelineLayout) { +// //return ((DeviceMTL&)device).CreateImplementation(pipelineLayout, pipelineLayoutDesc); +// return Result::SUCCESS; +//} +// +//static Result NRI_CALL CreateGraphicsPipeline(Device& device, const GraphicsPipelineDesc& graphicsPipelineDesc, Pipeline*& pipeline) { +// //return ((DeviceMTL&)device).CreateImplementation(pipeline, graphicsPipelineDesc); +// return Result::SUCCESS; +//} +// +//static Result NRI_CALL CreateComputePipeline(Device& device, const ComputePipelineDesc& computePipelineDesc, Pipeline*& pipeline) { +// //return ((DeviceMTL&)device).CreateImplementation(pipeline, computePipelineDesc); +// return Result::SUCCESS; +//} +// +//static Result NRI_CALL CreateFence(Device& device, uint64_t initialValue, Fence*& fence) { +// //return ((DeviceMTL&)device).CreateImplementation(fence, initialValue); +// return Result::SUCCESS; +//} +// +//static Result NRI_CALL CreateQueryPool(Device& device, const QueryPoolDesc& queryPoolDesc, QueryPool*& queryPool) { +// //return ((DeviceMTL&)device).CreateImplementation(queryPool, queryPoolDesc); +// return Result::SUCCESS; +//} +// +//static void NRI_CALL DestroyCommandBuffer(CommandBuffer& commandBuffer) { +// //Destroy((CommandBufferD3D12*)&commandBuffer); +//} +// +//static void NRI_CALL DestroyCommandAllocator(CommandAllocator& commandAllocator) { +// //Destroy((CommandAllocatorD3D12*)&commandAllocator); +//} +// +//static void NRI_CALL DestroyDescriptorPool(DescriptorPool& descriptorPool) { +// //Destroy((DescriptorPoolD3D12*)&descriptorPool); +//} +// +//static void NRI_CALL DestroyBuffer(Buffer& buffer) { +// //Destroy((BufferD3D12*)&buffer); +//} +// +//static void NRI_CALL DestroyTexture(Texture& texture) { +// //Destroy((TextureD3D12*)&texture); +//} +// +//static void NRI_CALL DestroyDescriptor(Descriptor& descriptor) { +// //Destroy((DescriptorD3D12*)&descriptor); +//} +// +//static void NRI_CALL DestroyPipelineLayout(PipelineLayout& pipelineLayout) { +// //Destroy((PipelineLayoutD3D12*)&pipelineLayout); +//} +// +//static void NRI_CALL DestroyPipeline(Pipeline& pipeline) { +// //Destroy((PipelineD3D12*)&pipeline); +//} +// +//static void NRI_CALL DestroyQueryPool(QueryPool& queryPool) { +// //Destroy((QueryPoolD3D12*)&queryPool); +//} +// +//static void NRI_CALL DestroyFence(Fence& fence) { +// Destroy((FenceMTL*)&fence); +//} +// +//static Result NRI_CALL AllocateMemory(Device& device, const AllocateMemoryDesc& allocateMemoryDesc, Memory*& memory) { +// return Result::SUCCESS; +// //return ((DeviceMTL&)device).CreateImplementation(memory, allocateMemoryDesc); +//} +// +//static Result NRI_CALL BindBufferMemory(Device& device, const BufferMemoryBindingDesc* memoryBindingDescs, uint32_t memoryBindingDescNum) { +// //return ((DeviceMTL&)device).BindBufferMemory(memoryBindingDescs, memoryBindingDescNum); +// return Result::SUCCESS; +//} +// +//static Result NRI_CALL BindTextureMemory(Device& device, const TextureMemoryBindingDesc* memoryBindingDescs, uint32_t memoryBindingDescNum) { +// //return ((DeviceMTL&)device).BindTextureMemory(memoryBindingDescs, memoryBindingDescNum); +// return Result::SUCCESS; +//} +// +//static void NRI_CALL FreeMemory(Memory& memory) { +//// Destroy((MemoryD3D12*)&memory); +//} +// +//static void NRI_CALL SetDeviceDebugName(Device& device, const char* name) { +//// ((DeviceMTL&)device).SetDebugName(name); +//} +// +//static void NRI_CALL SetPipelineDebugName(Pipeline& pipeline, const char* name) { +//// ((PipelineD3D12&)pipeline).SetDebugName(name); +//} +// +//static void NRI_CALL SetPipelineLayoutDebugName(PipelineLayout& pipelineLayout, const char* name) { +//// ((PipelineLayoutD3D12&)pipelineLayout).SetDebugName(name); +//} +// +//static void NRI_CALL SetMemoryDebugName(Memory& memory, const char* name) { +//// ((MemoryMetal&)memory).SetDebugName(name); +//} +// +//static void* NRI_CALL GetDeviceNativeObject(const Device& device) { +// if (!(&device)) +// return nullptr; +// return (DeviceMTL*)&((DeviceMTL&)device); +// +// //return ((DeviceMetal&)device).GetNativeObject(); +//} +// +////Result DeviceMTL::FillFunctionTable(CoreInterface& table) const { +//// table = {}; +//// // Core_Device_PartiallyFillFunctionTableMTL(table); +//// // Core_Buffer_PartiallyFillFunctionTableMTL(table); +//// // Core_CommandAllocator_PartiallyFillFunctionTableMTL(table); +//// // Core_CommandBuffer_PartiallyFillFunctionTableMTL(table); +//// // Core_CommandQueue_PartiallyFillFunctionTableMTL(table); +//// // Core_Descriptor_PartiallyFillFunctionTableMTL(table); +//// // Core_DescriptorPool_PartiallyFillFunctionTableMTL(table); +//// // Core_DescriptorSet_PartiallyFillFunctionTableMTL(table); +//// // Core_Fence_PartiallyFillFunctionTableMTL(table); +//// // Core_QueryPool_PartiallyFillFunctionTableMTL(table); +//// // Core_Texture_PartiallyFillFunctionTableMTL(table); +//// // return ValidateFunctionTable(table); +//// return Result::UNSUPPORTED; +////} +// +//#pragma endregion +// +////Result DeviceMTL::FillFunctionTable(HelperInterface& table) const { +//// table = {}; +//// return Result::UNSUPPORTED; +////} +//// +////Result DeviceMTL::FillFunctionTable(LowLatencyInterface& table) const { +//// table = {}; +//// return Result::UNSUPPORTED; +////} +// +////Result DeviceMTL::FillFunctionTable(MeshShaderInterface& table) const { +//// table = {}; +//// return Result::UNSUPPORTED; +////} +// +////Result DeviceMTL::FillFunctionTable(RayTracingInterface& table) const { +//// table = {}; +//// return Result::UNSUPPORTED; +////} +//// +////Result DeviceMTL::FillFunctionTable(StreamerInterface& table) const { +//// table = {}; +//// return Result::UNSUPPORTED; +////} +//// +////Result DeviceMTL::FillFunctionTable(SwapChainInterface& table) const { +//// table = {}; +//// return Result::UNSUPPORTED; +////} +//// +////Result DeviceMTL::FillFunctionTable(ResourceAllocatorInterface& table) const { +//// table = {}; +//// return Result::UNSUPPORTED; +////} +// +////Dfine_Core_Device_PartiallyFillFunctionTable(MTL); +////Define_Helper_Device_PartiallyFillFunctionTable(MTL); +////Define_RayTracing_Device_PartiallyFillFunctionTable(MTL); +////Define_Streamer_Device_PartiallyFillFunctionTable(MTL); +////Define_SwapChain_Device_PartiallyFillFunctionTable(MTL); +////Define_ResourceAllocator_Device_PartiallyFillFunctionTable(MTL); diff --git a/Source/Metal/DeviceMTL.mm b/Source/Metal/DeviceMTL.mm new file mode 100644 index 0000000..244faea --- /dev/null +++ b/Source/Metal/DeviceMTL.mm @@ -0,0 +1,361 @@ + + +#include "SharedMTL.h" + +#include "CommandQueueMTL.h" +#include "DeviceMTL.h" +#include "BufferMTL.h" +#include "CommandQueueMTL.h" +#include "TextureMTL.h" +#include "FenceMTL.h" +#include "MemoryMTL.h" +#include "PipelineLayoutMTL.h" +#include "PipelineMTL.h" + +using namespace nri; + + +static bool FindMTLGpuFamily(id device, + const MTLGPUFamily *families, size_t len, + MTLGPUFamily* current) { + for(size_t i = 0; i < len; i++) { + if( [device supportsFamily: families[i]]) { + *current = families[i]; + return true; + } + } + return false; +} + +// referenced from Molten VK +static uint32_t GetEntryProperty(io_registry_entry_t entry, CFStringRef propertyName) { + + uint32_t value = 0; + + CFTypeRef cfProp = IORegistryEntrySearchCFProperty(entry, + kIOServicePlane, + propertyName, + kCFAllocatorDefault, + kIORegistryIterateRecursively | + kIORegistryIterateParents); + if (cfProp) { + const uint32_t* pValue = reinterpret_cast(CFDataGetBytePtr((CFDataRef)cfProp)); + if (pValue) { value = *pValue; } + CFRelease(cfProp); + } + + return value; +} + + + + +DeviceMTL::DeviceMTL(const CallbackInterface& callbacks, const StdAllocator& stdAllocator) + : DeviceBase(callbacks, stdAllocator) { + + for (uint32_t i = 0; i < m_CommandQueues.size(); i++) + Destroy(GetStdAllocator(), m_CommandQueues[i]); + + m_Desc.graphicsAPI = GraphicsAPI::MTL; + m_Desc.nriVersionMajor = NRI_VERSION_MAJOR; + m_Desc.nriVersionMinor = NRI_VERSION_MINOR; +} + + +void DeviceMTL::Destruct() { + Destroy(GetStdAllocator(), this); +} + +DeviceMTL::~DeviceMTL() { + +} + + +//FormatSupportBits DeviceMTL::GetFormatSupport(const Device& device, Format format) { +// int currentFamily = HIGHEST_GPU_FAMILY; +// for (; currentFamily >= (int)MTLGPUFamilyApple1; currentFamily--) { +// if ([m_Device supportsFamily:(MTLGPUFamily)currentFamily]) { +// highestAppleFamily = (MTLGPUFamily)currentFamily; +// break; +// } +// } +//} + + +void DeviceMTL::GetMemoryDesc(const BufferDesc& bufferDesc, MemoryLocation memoryLocation, MemoryDesc& memoryDesc) const { + MemoryTypeInfo memoryTypeInfo; + memoryTypeInfo.options = DEFAULT_MEMORY_RESOURCE_OPTION_MEMORY_LOCATION[(size_t)memoryLocation]; + memoryTypeInfo.cacheMode = DEFAULT_CACHE_MODE_MEMORY_LOCATION[(size_t)memoryLocation]; + memoryTypeInfo.storageMode = DEFAULT_STORAGE_MODE_MEMORY_LOCATION[(size_t)memoryLocation]; + MTLTextureDescriptor* mtlTextureDesc = [[MTLTextureDescriptor alloc] init]; + MTLSizeAndAlign sizeAlign = [m_Device heapBufferSizeAndAlignWithLength: bufferDesc.size options: (MTLResourceOptions)memoryTypeInfo.options]; + + memoryDesc.size = sizeAlign.size; + memoryDesc.alignment = sizeAlign.align; + memoryDesc.type = memoryTypeInfo.value; + +} + +void DeviceMTL::GetMemoryDesc(const TextureDesc& textureDesc, MemoryLocation memoryLocation, MemoryDesc& memoryDesc) const { + MTLTextureDescriptor* mtlTextureDesc = [[MTLTextureDescriptor alloc] init]; + + MemoryTypeInfo memoryTypeInfo; + memoryTypeInfo.options = DEFAULT_MEMORY_RESOURCE_OPTION_MEMORY_LOCATION[(size_t)memoryLocation]; + memoryTypeInfo.cacheMode = DEFAULT_CACHE_MODE_MEMORY_LOCATION[(size_t)memoryLocation]; + memoryTypeInfo.storageMode = DEFAULT_STORAGE_MODE_MEMORY_LOCATION[(size_t)memoryLocation]; + nri::fillMTLTextureDescriptor(textureDesc, mtlTextureDesc); + const MTLSizeAndAlign sizeAlign = [m_Device heapTextureSizeAndAlignWithDescriptor: mtlTextureDesc]; + + memoryDesc.size = sizeAlign.size; + memoryDesc.alignment = sizeAlign.align; + memoryDesc.type = memoryTypeInfo.value; +} + +void DeviceMTL::GetMemoryDesc(const AccelerationStructureDesc& accelerationStructureDesc, MemoryLocation memoryLocation, MemoryDesc& memoryDesc) const { +// MTLAccelerationStructureDescriptor* mtlAcceleration = [[MTLAccelerationStructureDescriptor alloc] init]; +// [mtlAcceleration set] + + // [m_Device heapAccelerationStructureSizeAndAlignWithSize: accelerationStructureDesc.geometryObjects] + // TODO: need to add ray traced +} + + +Result DeviceMTL::GetCommandQueue(CommandQueueType commandQueueType, CommandQueue*& commandQueue) { + ExclusiveScope lock(m_Lock); + + // Check if already created (or wrapped) + uint32_t index = (uint32_t)commandQueueType; + if (m_CommandQueues[index]) { + commandQueue = (CommandQueue*)m_CommandQueues[index]; + return Result::SUCCESS; + } + Result result = CreateImplementation(commandQueue, commandQueueType); + if (result == Result::SUCCESS) + m_CommandQueues[index] = (CommandQueueMTL*)commandQueue; + + return result; +} + + +Result DeviceMTL::Create(const DeviceCreationDesc& deviceCreationDesc, const DeviceCreationMTLDesc& deviceCreationMTLDesc, bool isWrapper) { + m_OwnsNativeObjects = !isWrapper; + if(isWrapper) { + m_Device = *(id*)&deviceCreationMTLDesc.MtlDevice; + } + + strncpy(m_Desc.adapterDesc.name, [m_Device.name UTF8String], sizeof(m_Desc.adapterDesc.name)); + // No vendor id, device id for Apple GPUs + if (strstr(m_Desc.adapterDesc.name, "Apple")) { + m_Desc.adapterDesc.vendor = nri::Vendor::APPLE; + } + + const uint64_t regID = [m_Device registryID]; + if (regID) + { + io_registry_entry_t entry = IOServiceGetMatchingService(MACH_PORT_NULL, IORegistryEntryIDMatching(regID)); + if (entry) + { + // That returned the IOGraphicsAccelerator nub. Its parent, then, is the actual PCI device. + io_registry_entry_t deviceEntry; + if (IORegistryEntryGetParentEntry(entry, kIOServicePlane, &deviceEntry) == kIOReturnSuccess) + { + m_Desc.adapterDesc.vendor = GetVendorFromID(GetEntryProperty(deviceEntry, CFSTR("vendor-id"))) ; + m_Desc.adapterDesc.deviceId = GetEntryProperty(deviceEntry, CFSTR("device-id")); + } + } + } else { + m_Desc.adapterDesc.vendor = nri::Vendor::APPLE; + } + + + MTLArgumentBuffersTier argumentBufferTier = MTLArgumentBuffersTier1; + if ([m_Device respondsToSelector: @selector(argumentBuffersSupport)]) { + argumentBufferTier = [m_Device argumentBuffersSupport]; + } + + for (uint32_t sc = 1; sc <= 64; sc <<= 1) { + if([m_Device supportsTextureSampleCount: sc]) { + m_Desc.colorSampleMaxNum |= sc; + m_Desc.depthSampleMaxNum |= sc; + m_Desc.stencilSampleMaxNum |= sc; + m_Desc.zeroAttachmentsSampleMaxNum |= sc; + m_Desc.textureColorSampleMaxNum |= sc; + m_Desc.textureIntegerSampleMaxNum |= sc; + m_Desc.textureDepthSampleMaxNum |= sc; + m_Desc.textureStencilSampleMaxNum |= sc; + m_Desc.storageTextureSampleMaxNum |= sc; + } + } + + + m_Desc.viewportMaxNum = 16; + m_Desc.viewportBoundsRange[0] = -32768; + m_Desc.viewportBoundsRange[1] = 32767; + + m_Desc.attachmentMaxDim = 16384; + m_Desc.attachmentLayerMaxNum = 2048; + m_Desc.colorAttachmentMaxNum = 8; + + m_Desc.colorSampleMaxNum = 32; + m_Desc.depthSampleMaxNum = 32; + m_Desc.stencilSampleMaxNum = 32; + m_Desc.zeroAttachmentsSampleMaxNum = 32; + m_Desc.textureColorSampleMaxNum = 32; + m_Desc.textureIntegerSampleMaxNum = 32; + m_Desc.textureDepthSampleMaxNum = 32; + m_Desc.textureStencilSampleMaxNum = 32; + m_Desc.storageTextureSampleMaxNum = 32; + + m_Desc.textureArrayLayerMaxNum = 16384; + m_Desc.typedBufferMaxDim = uint32_t(-1); + + m_Desc.deviceUploadHeapSize = 256 * 1024 * 1024; + m_Desc.memoryAllocationMaxNum = uint32_t(-1); + m_Desc.samplerAllocationMaxNum = 4096; + m_Desc.constantBufferMaxRange = 64 * 1024; + m_Desc.storageBufferMaxRange = uint32_t(-1); + m_Desc.bufferTextureGranularity = 1; + m_Desc.bufferMaxSize = [m_Device maxBufferLength]; + + m_Desc.uploadBufferTextureRowAlignment = 1; + m_Desc.uploadBufferTextureSliceAlignment = 1; + m_Desc.bufferShaderResourceOffsetAlignment = 1; + m_Desc.constantBufferOffsetAlignment = 1; + m_Desc.shaderBindingTableAlignment = 1; + m_Desc.scratchBufferOffsetAlignment = 1; + + m_Desc.pipelineLayoutDescriptorSetMaxNum = 64; + m_Desc.pipelineLayoutRootConstantMaxSize = 256; + m_Desc.pipelineLayoutRootDescriptorMaxNum = 64; + + m_Desc.perStageDescriptorSamplerMaxNum = 1000000; + m_Desc.perStageDescriptorConstantBufferMaxNum = 1000000; + m_Desc.perStageDescriptorStorageBufferMaxNum = 1000000; + m_Desc.perStageDescriptorTextureMaxNum = 1000000; + m_Desc.perStageDescriptorStorageTextureMaxNum = 1000000; + m_Desc.perStageResourceMaxNum = 1000000; + + m_Desc.descriptorSetSamplerMaxNum = m_Desc.perStageDescriptorSamplerMaxNum; + m_Desc.descriptorSetConstantBufferMaxNum = m_Desc.perStageDescriptorConstantBufferMaxNum; + m_Desc.descriptorSetStorageBufferMaxNum = m_Desc.perStageDescriptorStorageBufferMaxNum; + m_Desc.descriptorSetTextureMaxNum = m_Desc.perStageDescriptorTextureMaxNum; + m_Desc.descriptorSetStorageTextureMaxNum = m_Desc.perStageDescriptorStorageTextureMaxNum; + + m_Desc.vertexShaderAttributeMaxNum = 32; + m_Desc.vertexShaderStreamMaxNum = 32; + m_Desc.vertexShaderOutputComponentMaxNum = 128; + + m_Desc.tessControlShaderGenerationMaxLevel = 64.0f; + m_Desc.tessControlShaderPatchPointMaxNum = 32; + m_Desc.tessControlShaderPerVertexInputComponentMaxNum = 128; + m_Desc.tessControlShaderPerVertexOutputComponentMaxNum = 128; + m_Desc.tessControlShaderPerPatchOutputComponentMaxNum = 128; + m_Desc.tessControlShaderTotalOutputComponentMaxNum = m_Desc.tessControlShaderPatchPointMaxNum * m_Desc.tessControlShaderPerVertexOutputComponentMaxNum + m_Desc.tessControlShaderPerPatchOutputComponentMaxNum; + + m_Desc.tessEvaluationShaderInputComponentMaxNum = 128; + m_Desc.tessEvaluationShaderOutputComponentMaxNum = 128; + + m_Desc.geometryShaderInvocationMaxNum = 32; + m_Desc.geometryShaderInputComponentMaxNum = 128; + m_Desc.geometryShaderOutputComponentMaxNum = 128; + m_Desc.geometryShaderOutputVertexMaxNum = 1024; + m_Desc.geometryShaderTotalOutputComponentMaxNum = 1024; + + m_Desc.fragmentShaderInputComponentMaxNum = 128; + m_Desc.fragmentShaderOutputAttachmentMaxNum = 8; + m_Desc.fragmentShaderDualSourceAttachmentMaxNum = 1; + + +// m_Desc.computeShaderSharedMemoryMaxSize = [m_Device maxThreadgroupMemoryLength]; +// const MTLSize threadGroupSize = [m_Device maxThreadsPerThreadgroup]; +// //familiesm_Desc.computeShaderWorkGroupMaxNum = threadGroupSize.width; +// m_Desc.computeShaderWorkGroupMaxNum[0] = threadGroupSize.width; +// m_Desc.computeShaderWorkGroupMaxNum[1] = threadGroupSize.height; +// m_Desc.computeShaderWorkGroupMaxNum[2] = threadGroupSize.depth; + m_Desc.computeShaderSharedMemoryMaxSize = 64 * 1024; + m_Desc.computeShaderWorkGroupMaxNum[0] = 64 * 1024; + m_Desc.computeShaderWorkGroupMaxNum[1] = 64 * 1024; + m_Desc.computeShaderWorkGroupMaxNum[2] = 64 * 1024; + m_Desc.computeShaderWorkGroupInvocationMaxNum = 64 * 1024; + m_Desc.computeShaderWorkGroupMaxDim[0] = 64 * 1024; + m_Desc.computeShaderWorkGroupMaxDim[1] = 64 * 1024; + m_Desc.computeShaderWorkGroupMaxDim[2] = 64 * 1024; + + m_Desc.rayTracingShaderGroupIdentifierSize = 32; + m_Desc.rayTracingShaderTableMaxStride = (uint32_t)(-1); + m_Desc.rayTracingShaderRecursionMaxDepth = 31; + m_Desc.rayTracingGeometryObjectMaxNum = (uint32_t)(-1); + + m_Desc.meshControlSharedMemoryMaxSize = 64 * 1024; + m_Desc.meshControlWorkGroupInvocationMaxNum = 128; + m_Desc.meshControlPayloadMaxSize = 64 * 1024; + m_Desc.meshEvaluationOutputVerticesMaxNum = 256; + m_Desc.meshEvaluationOutputPrimitiveMaxNum = 256; + m_Desc.meshEvaluationOutputComponentMaxNum = 128; + m_Desc.meshEvaluationSharedMemoryMaxSize = 64 * 1024; + m_Desc.meshEvaluationWorkGroupInvocationMaxNum = 128; + + m_Desc.viewportPrecisionBits = 8; + m_Desc.subPixelPrecisionBits = 8; + m_Desc.subTexelPrecisionBits = 8; + m_Desc.mipmapPrecisionBits = 8; + + m_Desc.drawIndirectMaxNum = uint32_t(-1); + m_Desc.samplerLodBiasMin = -16.0f; + m_Desc.samplerLodBiasMax = 16.0f; + m_Desc.samplerAnisotropyMax = 16; + m_Desc.texelOffsetMin = -8; + m_Desc.texelOffsetMax = 7; + m_Desc.texelGatherOffsetMin = -8; + m_Desc.texelGatherOffsetMax = 7; + m_Desc.clipDistanceMaxNum = 8; + m_Desc.cullDistanceMaxNum = 8; + m_Desc.combinedClipAndCullDistanceMaxNum = 8; + m_Desc.shadingRateAttachmentTileSize = 16; + m_Desc.shaderModel = 69; + + m_Desc.conservativeRasterTier = 3; + m_Desc.sampleLocationsTier = 2; + m_Desc.shadingRateTier = 2; + m_Desc.bindlessTier = 2; + m_Desc.bindlessTier = 2; + + m_Desc.isRayTracingSupported = [m_Device supportsRaytracing]; + + const MTLGPUFamily appleFamilyGPUs[] = { + MTLGPUFamilyApple9, + MTLGPUFamilyApple8, + MTLGPUFamilyApple7, + MTLGPUFamilyApple6, + MTLGPUFamilyApple5, + MTLGPUFamilyApple4, + MTLGPUFamilyApple3, + MTLGPUFamilyApple2, + MTLGPUFamilyApple1 + }; + + const MTLGPUFamily macFamilyGPUs[] = { + MTLGPUFamilyMac2 + }; + + // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf + MTLGPUFamily maxSelectedGPU; + m_Desc.texture3DMaxDim = 2048; + if(FindMTLGpuFamily(m_Device, appleFamilyGPUs, GetCountOf(appleFamilyGPUs), &maxSelectedGPU)) { + m_Desc.texture2DMaxDim = (maxSelectedGPU >= MTLGPUFamilyApple3) ? 16384 : 8192; + m_Desc.texture1DMaxDim = (maxSelectedGPU >= MTLGPUFamilyApple3) ? 16384 : 8192; + + } else if(FindMTLGpuFamily(m_Device, macFamilyGPUs, GetCountOf(macFamilyGPUs), &maxSelectedGPU)) { + m_Desc.texture2DMaxDim = 16384; + m_Desc.texture1DMaxDim = 16384; + } else { + return Result::UNSUPPORTED; + } + + + return Result::SUCCESS; + +} + +#include "DeviceMTL.hpp" + diff --git a/Source/Metal/FencMTL.mm b/Source/Metal/FencMTL.mm new file mode 100644 index 0000000..d0ee5d5 --- /dev/null +++ b/Source/Metal/FencMTL.mm @@ -0,0 +1,13 @@ +#include "SharedMTL.h" + +#include "FenceMTL.h" + +using namespace nri; + +FenceMTL::~FenceMTL() { + +} + +Result FenceMTL::Create(uint64_t initialValue) { + m_Handle = dispatch_semaphore_create(initialValue); +} diff --git a/Source/Metal/FenceMTL.h b/Source/Metal/FenceMTL.h new file mode 100644 index 0000000..0531e63 --- /dev/null +++ b/Source/Metal/FenceMTL.h @@ -0,0 +1,31 @@ +// © 2021 NVIDIA Corporation + +#pragma once + +#import + +namespace nri { + +struct DeviceMTL; + +struct FenceMTL { + inline FenceMTL(DeviceMTL& device) + : m_Device(device) { + } + ~FenceMTL(); + + inline DeviceMTL& GetDevice() const { + return m_Device; + } + + Result Create(uint64_t initialValue); + + //void SetDebugName(const char* name); + //uint64_t GetFenceValue() const; + //void Wait(uint64_t value); +private: + dispatch_semaphore_t m_Handle; + DeviceMTL& m_Device; +}; + +} // namespace nri diff --git a/Source/Metal/ImplMTL.mm b/Source/Metal/ImplMTL.mm new file mode 100644 index 0000000..bca2a33 --- /dev/null +++ b/Source/Metal/ImplMTL.mm @@ -0,0 +1,483 @@ +// © 2021 NVIDIA Corporation + +#include "SharedMTL.h" + +using namespace nri; + +#include "BufferMTL.h" +#include "CommandAllocatorMTL.h" +#include "CommandBufferMTL.h" +#include "DeviceMTL.h" +#include "DescriptorMTL.h" +#include "TextureMTL.h" +#include "PipelineLayoutMTL.h" +#include "PipelineMTL.h" +#include "DescriptorMTL.h" +#include "MemoryMTL.h" + +Result CreateDeviceMTL(const DeviceCreationDesc& desc, DeviceBase*& device) { + StdAllocator allocator(desc.allocationCallbacks); + DeviceMTL* impl = Allocate(allocator, desc.callbackInterface, allocator); + Result result = impl->Create(desc, {}, false); + + + MTLPurgeableState a; + MTLStorageMode mode; + if (result != Result::SUCCESS) { + Destroy(allocator, impl); + device = nullptr; + } else + device = (DeviceBase*)impl; + return result; +} + + +Result CreateDeviceMTL(const DeviceCreationMTLDesc& desc, DeviceBase*& device) { + return Result::SUCCESS; +} +//============================================================================================================================================================================================ +#pragma region[ Core ] + + +static void NRI_CALL SetBufferDebugName(Buffer& buffer, const char* name) { + ((BufferMTL&)buffer).SetDebugName(name); +} + +static uint64_t NRI_CALL GetBufferNativeObject(const Buffer& buffer) { + if (!(&buffer)) + return 0; + return uint64_t(((BufferMTL&)buffer).GetHandle()); +} + + +static void* NRI_CALL MapBuffer(Buffer& buffer, uint64_t offset, uint64_t size) { + return ((BufferMTL&)buffer).Map(offset, size); +} + +static void NRI_CALL UnmapBuffer(Buffer& buffer) { + ((BufferMTL&)buffer).Unmap(); +} + +static void NRI_CALL SetCommandAllocatorDebugName(CommandAllocator& commandAllocator, const char* name) { + // ((CommandAllocatorVK&)commandAllocator).SetDebugName(name); +} + +static Result NRI_CALL CreateCommandBuffer(CommandAllocator& commandAllocator, CommandBuffer*& commandBuffer) { + return ((CommandAllocatorMTL&)commandAllocator).CreateCommandBuffer(commandBuffer); +} + +static void NRI_CALL ResetCommandAllocator(CommandAllocator& commandAllocator) { + // ((CommandAllocatorVK&)commandAllocator).Reset(); +} + +static void NRI_CALL SetCommandBufferDebugName(CommandBuffer& commandBuffer, const char* name) { + ((CommandBufferMTL&)commandBuffer).SetDebugName(name); +} + +static Result NRI_CALL BeginCommandBuffer(CommandBuffer& commandBuffer, const DescriptorPool* descriptorPool) { + return ((CommandBufferMTL&)commandBuffer).Begin(descriptorPool); +} + +static Result NRI_CALL EndCommandBuffer(CommandBuffer& commandBuffer) { + return ((CommandBufferMTL&)commandBuffer).End(); +} + +static void NRI_CALL CmdSetPipelineLayout(CommandBuffer& commandBuffer, const PipelineLayout& pipelineLayout) { + ((CommandBufferMTL&)commandBuffer).SetPipelineLayout(pipelineLayout); +} + +static void NRI_CALL CmdSetPipeline(CommandBuffer& commandBuffer, const Pipeline& pipeline) { + ((CommandBufferMTL&)commandBuffer).SetPipeline(pipeline); +} + +static void NRI_CALL CmdBarrier(CommandBuffer& commandBuffer, const BarrierGroupDesc& barrierGroupDesc) { + ((CommandBufferMTL&)commandBuffer).Barrier(barrierGroupDesc); +} + +static void NRI_CALL CmdSetDescriptorPool(CommandBuffer& commandBuffer, const DescriptorPool& descriptorPool) { + ((CommandBufferMTL&)commandBuffer).SetDescriptorPool(descriptorPool); +} + +static void NRI_CALL CmdSetDescriptorSet(CommandBuffer& commandBuffer, uint32_t setIndex, const DescriptorSet& descriptorSet, const uint32_t* dynamicConstantBufferOffsets) { + ((CommandBufferMTL&)commandBuffer).SetDescriptorSet(setIndex, descriptorSet, dynamicConstantBufferOffsets); +} + +static void NRI_CALL CmdSetRootConstants(CommandBuffer& commandBuffer, uint32_t rootConstantIndex, const void* data, uint32_t size) { + //((CommandBufferMTL&)commandBuffer).SetRootConstants(rootConstantIndex, data, size); +} + +static void NRI_CALL CmdSetRootDescriptor(CommandBuffer& commandBuffer, uint32_t rootDescriptorIndex, Descriptor& descriptor) { + //((CommandBufferMTL&)commandBuffer).SetRootDescriptor(rootDescriptorIndex, descriptor); +} + +static void NRI_CALL CmdBeginRendering(CommandBuffer& commandBuffer, const AttachmentsDesc& attachmentsDesc) { + ((CommandBufferMTL&)commandBuffer).BeginRendering(attachmentsDesc); +} + +static void NRI_CALL CmdEndRendering(CommandBuffer& commandBuffer) { + ((CommandBufferMTL&)commandBuffer).EndRendering(); +} + +static void NRI_CALL CmdSetViewports(CommandBuffer& commandBuffer, const Viewport* viewports, uint32_t viewportNum) { + ((CommandBufferMTL&)commandBuffer).SetViewports(viewports, viewportNum); +} + +static void NRI_CALL CmdSetScissors(CommandBuffer& commandBuffer, const nri::Rect* rects, uint32_t rectNum) { + ((CommandBufferMTL&)commandBuffer).SetScissors(rects, rectNum); +} + +static void NRI_CALL CmdSetDepthBounds(CommandBuffer& commandBuffer, float boundsMin, float boundsMax) { + ((CommandBufferMTL&)commandBuffer).SetDepthBounds(boundsMin, boundsMax); +} + +static void NRI_CALL CmdSetStencilReference(CommandBuffer& commandBuffer, uint8_t frontRef, uint8_t backRef) { + ((CommandBufferMTL&)commandBuffer).SetStencilReference(frontRef, backRef); +} + +static void NRI_CALL CmdSetSampleLocations(CommandBuffer& commandBuffer, const SampleLocation* locations, Sample_t locationNum, Sample_t sampleNum) { + //((CommandBufferMTL&)commandBuffer).SetSampleLocations(locations, locationNum, sampleNum); +} + +static void NRI_CALL CmdSetBlendConstants(CommandBuffer& commandBuffer, const Color32f& color) { + ((CommandBufferMTL&)commandBuffer).SetBlendConstants(color); +} + +static void NRI_CALL CmdSetShadingRate(CommandBuffer& commandBuffer, const ShadingRateDesc& shadingRateDesc) { + ((CommandBufferMTL&)commandBuffer).SetShadingRate(shadingRateDesc); +} + +static void NRI_CALL CmdSetDepthBias(CommandBuffer& commandBuffer, const DepthBiasDesc& depthBiasDesc) { + // ((CommandBufferMTL&)commandBuffer).SetDepthBias(depthBiasDesc); +} + +static void NRI_CALL CmdClearAttachments(CommandBuffer& commandBuffer, const ClearDesc* clearDescs, uint32_t clearDescNum, const nri::Rect* rects, uint32_t rectNum) { + //((CommandBufferMTL&)commandBuffer).ClearAttachments(clearDescs, clearDescNum, rects, rectNum); +} + +static void NRI_CALL CmdSetIndexBuffer(CommandBuffer& commandBuffer, const Buffer& buffer, uint64_t offset, IndexType indexType) { + ((CommandBufferMTL&)commandBuffer).SetIndexBuffer(buffer, offset, indexType); +} + +static void NRI_CALL CmdSetVertexBuffers(CommandBuffer& commandBuffer, uint32_t baseSlot, uint32_t bufferNum, const Buffer* const* buffers, const uint64_t* offsets) { + ((CommandBufferMTL&)commandBuffer).SetVertexBuffers(baseSlot, bufferNum, buffers, offsets); +} + +static void NRI_CALL CmdDraw(CommandBuffer& commandBuffer, const DrawDesc& drawDesc) { + ((CommandBufferMTL&)commandBuffer).Draw(drawDesc); +} + +static void NRI_CALL CmdDrawIndexed(CommandBuffer& commandBuffer, const DrawIndexedDesc& drawIndexedDesc) { + ((CommandBufferMTL&)commandBuffer).DrawIndexed(drawIndexedDesc); +} + +static void NRI_CALL CmdDrawIndirect(CommandBuffer& commandBuffer, const Buffer& buffer, uint64_t offset, uint32_t drawNum, uint32_t stride, const Buffer* countBuffer, uint64_t countBufferOffset) { + ((CommandBufferMTL&)commandBuffer).DrawIndirect(buffer, offset, drawNum, stride, countBuffer, countBufferOffset); +} + +static void NRI_CALL CmdDrawIndexedIndirect(CommandBuffer& commandBuffer, const Buffer& buffer, uint64_t offset, uint32_t drawNum, uint32_t stride, const Buffer* countBuffer, uint64_t countBufferOffset) { + ((CommandBufferMTL&)commandBuffer).DrawIndexedIndirect(buffer, offset, drawNum, stride, countBuffer, countBufferOffset); +} + +static void NRI_CALL CmdDispatch(CommandBuffer& commandBuffer, const DispatchDesc& dispatchDesc) { + ((CommandBufferMTL&)commandBuffer).Dispatch(dispatchDesc); +} + +static void NRI_CALL CmdDispatchIndirect(CommandBuffer& commandBuffer, const Buffer& buffer, uint64_t offset) { + ((CommandBufferMTL&)commandBuffer).DispatchIndirect(buffer, offset); +} + +static void NRI_CALL CmdBeginQuery(CommandBuffer& commandBuffer, const QueryPool& queryPool, uint32_t offset) { + ((CommandBufferMTL&)commandBuffer).BeginQuery(queryPool, offset); +} + +static void NRI_CALL CmdEndQuery(CommandBuffer& commandBuffer, const QueryPool& queryPool, uint32_t offset) { + ((CommandBufferMTL&)commandBuffer).EndQuery(queryPool, offset); +} + +static void NRI_CALL CmdBeginAnnotation(CommandBuffer& commandBuffer, const char* name) { + ((CommandBufferMTL&)commandBuffer).BeginAnnotation(name); +} + +static void NRI_CALL CmdEndAnnotation(CommandBuffer& commandBuffer) { + ((CommandBufferMTL&)commandBuffer).EndAnnotation(); +} + +static void NRI_CALL CmdClearStorageBuffer(CommandBuffer& commandBuffer, const ClearStorageBufferDesc& clearDesc) { + ((CommandBufferMTL&)commandBuffer).ClearStorageBuffer(clearDesc); +} + +static void NRI_CALL CmdClearStorageTexture(CommandBuffer& commandBuffer, const ClearStorageTextureDesc& clearDesc) { + ((CommandBufferMTL&)commandBuffer).ClearStorageTexture(clearDesc); +} + +static void NRI_CALL CmdResolveTexture(CommandBuffer& commandBuffer, Texture& dstTexture, const TextureRegionDesc* dstRegionDesc, const Texture& srcTexture, const TextureRegionDesc* srcRegionDesc) { + //((CommandBufferMTL&)commandBuffer).ResolveTexture(dstTexture, dstRegionDesc, srcTexture, srcRegionDesc); +} + +static void NRI_CALL CmdCopyBuffer(CommandBuffer& commandBuffer, Buffer& dstBuffer, uint64_t dstOffset, const Buffer& srcBuffer, uint64_t srcOffset, uint64_t size) { + ((CommandBufferMTL&)commandBuffer).CopyBuffer(dstBuffer, dstOffset, srcBuffer, srcOffset, size); +} + +static void NRI_CALL CmdCopyTexture( + CommandBuffer& commandBuffer, Texture& dstTexture, const TextureRegionDesc* dstRegionDesc, const Texture& srcTexture, const TextureRegionDesc* srcRegionDesc) { + ((CommandBufferMTL&)commandBuffer).CopyTexture(dstTexture, dstRegionDesc, srcTexture, srcRegionDesc); +} + +static void NRI_CALL CmdUploadBufferToTexture(CommandBuffer& commandBuffer, Texture& dstTexture, const TextureRegionDesc& dstRegionDesc, const Buffer& srcBuffer, const TextureDataLayoutDesc& srcDataLayoutDesc) { + ((CommandBufferMTL&)commandBuffer).UploadBufferToTexture(dstTexture, dstRegionDesc, srcBuffer, srcDataLayoutDesc); +} + +static void NRI_CALL CmdReadbackTextureToBuffer(CommandBuffer& commandBuffer, Buffer& dstBuffer, const TextureDataLayoutDesc& dstDataLayoutDesc, const Texture& srcTexture, const TextureRegionDesc& srcRegionDesc) { + //((CommandBufferMTL&)commandBuffer).ReadbackTextureToBuffer(dstBuffer, dstDataLayoutDesc, srcTexture, srcRegionDesc); +} + +static void NRI_CALL CmdCopyQueries(CommandBuffer& commandBuffer, const QueryPool& queryPool, uint32_t offset, uint32_t num, Buffer& dstBuffer, uint64_t dstOffset) { + ((CommandBufferMTL&)commandBuffer).CopyQueries(queryPool, offset, num, dstBuffer, dstOffset); +} + +static void NRI_CALL CmdResetQueries(CommandBuffer& commandBuffer, const QueryPool& queryPool, uint32_t offset, uint32_t num) { + ((CommandBufferMTL&)commandBuffer).ResetQueries(queryPool, offset, num); +} + +static const DeviceDesc& NRI_CALL GetDeviceDesc(const Device& device) { + return ((DeviceMTL&)device).GetDesc(); +} + +//static Result NRI_CALL CreateBufferView(const BufferViewDesc& bufferViewDesc, Descriptor*& bufferView) { +// DeviceMTL& device = ((const BufferMTL*)bufferViewDesc.buffer)->GetDevice(); +// return device.CreateImplementation(bufferView, bufferViewDesc); +//} +// +//static Result NRI_CALL CreateTexture1DView(const Texture1DViewDesc& textureViewDesc, Descriptor*& textureView) { +// DeviceMTL& device = ((const TextureMTL*)textureViewDesc.texture)->GetDevice(); +// return device.CreateImplementation(textureView, textureViewDesc); +//} +// +//static Result NRI_CALL CreateTexture2DView(const Texture2DViewDesc& textureViewDesc, Descriptor*& textureView) { +// DeviceMTL& device = ((const TextureMTL*)textureViewDesc.texture)->GetDevice(); +// return device.CreateImplementation(textureView, textureViewDesc); +//} +// +//static Result NRI_CALL CreateTexture3DView(const Texture3DViewDesc& textureViewDesc, Descriptor*& textureView) { +// DeviceMTL& device = ((const TextureMTL*)textureViewDesc.texture)->GetDevice(); +// return device.CreateImplementation(textureView, textureViewDesc); +//} + + +//static void NRI_CALL QueueSubmit(CommandQueue& commandQueue, const QueueSubmitDesc& workSubmissionDesc) { +// ((CommandQueueMTL&)commandQueue).Submit(workSubmissionDesc, nullptr); +//} + + +static void NRI_CALL DestroyCommandBuffer(CommandBuffer& commandBuffer) { + Destroy((CommandBufferMTL*)&commandBuffer); +} + +static void NRI_CALL DestroyCommandAllocator(CommandAllocator& commandAllocator) { + Destroy((CommandAllocatorMTL*)&commandAllocator); +} + +static void NRI_CALL DestroyDescriptorPool(DescriptorPool& descriptorPool) { + //Destroy((DescriptorPoolM*)&descriptorPool); +} + +static void NRI_CALL DestroyBuffer(Buffer& buffer) { + Destroy((BufferMTL*)&buffer); +} + +static void NRI_CALL DestroyTexture(Texture& texture) { + Destroy((TextureMTL*)&texture); +} + +static void NRI_CALL DestroyDescriptor(Descriptor& descriptor) { + // Destroy((DescriptorMTL*)&descriptor); +} + +static void NRI_CALL DestroyPipelineLayout(PipelineLayout& pipelineLayout) { + // Destroy((PipelineLayoutMTL*)&pipelineLayout); +} + +static void NRI_CALL DestroyPipeline(Pipeline& pipeline) { + //Destroy((PipelineMTL*)&pipeline); +} + +static void NRI_CALL DestroyQueryPool(QueryPool& queryPool) { + //Destroy((QueryPoolVK*)&queryPool); +} + +static void NRI_CALL DestroyFence(Fence& fence) { + // Destroy((Fenc*)&fence); +} + +static void NRI_CALL FreeMemory(Memory& memory) { + Destroy((MemoryMTL*)&memory); +} + +static const BufferDesc& NRI_CALL GetBufferDesc(const Buffer& buffer) { + return ((const BufferMTL&)buffer).GetDesc(); +} + +static const TextureDesc& NRI_CALL GetTextureDesc(const Texture& texture) { + return ((const TextureMTL&)texture).GetDesc(); +} + + +static void NRI_CALL GetBufferMemoryDesc(const Device& device, const BufferDesc& bufferDesc, MemoryLocation memoryLocation, MemoryDesc& memoryDesc) { + ((const DeviceMTL&)device).GetMemoryDesc(bufferDesc, memoryLocation, memoryDesc); +} + +static void NRI_CALL GetTextureMemoryDesc(const Device& device, const TextureDesc& textureDesc, MemoryLocation memoryLocation, MemoryDesc& memoryDesc) { + ((const DeviceMTL&)device).GetMemoryDesc(textureDesc, memoryLocation, memoryDesc); +} + +static Result NRI_CALL CreateGraphicsPipeline(Device& device, const GraphicsPipelineDesc& graphicsPipelineDesc, Pipeline*& pipeline) { + return ((DeviceMTL&)device).CreateImplementation(pipeline, graphicsPipelineDesc); +} + +static Result NRI_CALL AllocateDescriptorSets(DescriptorPool& descriptorPool, const PipelineLayout& pipelineLayout, uint32_t setIndex, DescriptorSet** descriptorSets, uint32_t instanceNum, uint32_t variableDescriptorNum) { + return Result::SUCCESS; + //return ((DescriptorPoolMTL&)descriptorPool).AllocateDescriptorSets(pipelineLayout, setIndex, descriptorSets, instanceNum, variableDescriptorNum); +} + + + +Result DeviceMTL::FillFunctionTable(CoreInterface& table) const { + table.GetDeviceDesc = ::GetDeviceDesc; + table.GetBufferDesc = ::GetBufferDesc; + table.GetTextureDesc = ::GetTextureDesc; + //table.GetFormatSupport = ::GetFormatSupport; + //table.GetQuerySize = ::GetQuerySize; + table.GetBufferMemoryDesc = ::GetBufferMemoryDesc; + table.GetTextureMemoryDesc = ::GetTextureMemoryDesc; + //table.GetCommandQueue = ::GetCommandQueue; + //table.CreateCommandAllocator = ::CreateCommandAllocator; + //table.CreateCommandBuffer = ::CreateCommandBuffer; + //table.CreateDescriptorPool = ::CreateDescriptorPool; + //table.CreateBuffer = ::CreateBuffer; + //table.CreateTexture = ::CreateTexture; + //table.CreateBufferView = ::CreateBufferView; + //table.CreateTexture1DView = ::CreateTexture1DView; + //table.CreateTexture2DView = ::CreateTexture2DView; + //table.CreateTexture3DView = ::CreateTexture3DView; + //table.CreateSampler = ::CreateSampler; + //table.CreatePipelineLayout = ::CreatePipelineLayout; + table.CreateGraphicsPipeline = ::CreateGraphicsPipeline; +// table.CreateComputePipeline = ::CreateComputePipeline; +// table.CreateQueryPool = ::CreateQueryPool; +// table.CreateFence = ::CreateFence; + table.DestroyCommandAllocator = ::DestroyCommandAllocator; + table.DestroyCommandBuffer = ::DestroyCommandBuffer; + table.DestroyDescriptorPool = ::DestroyDescriptorPool; + table.DestroyBuffer = ::DestroyBuffer; + table.DestroyTexture = ::DestroyTexture; + table.DestroyDescriptor = ::DestroyDescriptor; + table.DestroyPipelineLayout = ::DestroyPipelineLayout; + table.DestroyPipeline = ::DestroyPipeline; + table.DestroyQueryPool = ::DestroyQueryPool; + table.DestroyFence = ::DestroyFence; +// table.AllocateMemory = ::AllocateMemory; +// table.BindBufferMemory = ::BindBufferMemory; +// table.BindTextureMemory = ::BindTextureMemory; + table.FreeMemory = ::FreeMemory; + table.BeginCommandBuffer = ::BeginCommandBuffer; + table.CmdSetDescriptorPool = ::CmdSetDescriptorPool; + table.CmdSetDescriptorSet = ::CmdSetDescriptorSet; + table.CmdSetPipelineLayout = ::CmdSetPipelineLayout; + table.CmdSetPipeline = ::CmdSetPipeline; + table.CmdSetRootConstants = ::CmdSetRootConstants; + table.CmdSetRootDescriptor = ::CmdSetRootDescriptor; + table.CmdBarrier = ::CmdBarrier; + table.CmdSetIndexBuffer = ::CmdSetIndexBuffer; + table.CmdSetVertexBuffers = ::CmdSetVertexBuffers; + table.CmdSetViewports = ::CmdSetViewports; + table.CmdSetScissors = ::CmdSetScissors; + table.CmdSetStencilReference = ::CmdSetStencilReference; + table.CmdSetDepthBounds = ::CmdSetDepthBounds; + table.CmdSetBlendConstants = ::CmdSetBlendConstants; + table.CmdSetSampleLocations = ::CmdSetSampleLocations; + table.CmdSetShadingRate = ::CmdSetShadingRate; + table.CmdSetDepthBias = ::CmdSetDepthBias; + table.CmdBeginRendering = ::CmdBeginRendering; + table.CmdClearAttachments = ::CmdClearAttachments; + table.CmdDraw = ::CmdDraw; + table.CmdDrawIndexed = ::CmdDrawIndexed; + table.CmdDrawIndirect = ::CmdDrawIndirect; + table.CmdDrawIndexedIndirect = ::CmdDrawIndexedIndirect; + table.CmdEndRendering = ::CmdEndRendering; + table.CmdDispatch = ::CmdDispatch; + table.CmdDispatchIndirect = ::CmdDispatchIndirect; + table.CmdCopyBuffer = ::CmdCopyBuffer; + table.CmdCopyTexture = ::CmdCopyTexture; + table.CmdUploadBufferToTexture = ::CmdUploadBufferToTexture; + table.CmdReadbackTextureToBuffer = ::CmdReadbackTextureToBuffer; + table.CmdClearStorageBuffer = ::CmdClearStorageBuffer; + table.CmdClearStorageTexture = ::CmdClearStorageTexture; + table.CmdResolveTexture = ::CmdResolveTexture; + table.CmdResetQueries = ::CmdResetQueries; + table.CmdBeginQuery = ::CmdBeginQuery; + table.CmdEndQuery = ::CmdEndQuery; + table.CmdCopyQueries = ::CmdCopyQueries; + table.CmdBeginAnnotation = ::CmdBeginAnnotation; + table.CmdEndAnnotation = ::CmdEndAnnotation; + table.EndCommandBuffer = ::EndCommandBuffer; +// table.QueueSubmit = ::QueueSubmit; +// table.Wait = ::Wait; +// table.GetFenceValue = ::GetFenceValue; +// table.UpdateDescriptorRanges = ::UpdateDescriptorRanges; +// table.UpdateDynamicConstantBuffers = ::UpdateDynamicConstantBuffers; +// table.CopyDescriptorSet = ::CopyDescriptorSet; + table.AllocateDescriptorSets = ::AllocateDescriptorSets; +// table.ResetDescriptorPool = ::ResetDescriptorPool; + table.ResetCommandAllocator = ::ResetCommandAllocator; + table.MapBuffer = ::MapBuffer; + table.UnmapBuffer = ::UnmapBuffer; +// table.SetDeviceDebugName = ::SetDeviceDebugName; +// table.SetFenceDebugName = ::SetFenceDebugName; +// table.SetDescriptorDebugName = ::SetDescriptorDebugName; +// table.SetPipelineDebugName = ::SetPipelineDebugName; + table.SetCommandBufferDebugName = ::SetCommandBufferDebugName; + table.SetBufferDebugName = ::SetBufferDebugName; +// table.SetTextureDebugName = ::SetTextureDebugName; +// table.SetCommandQueueDebugName = ::SetCommandQueueDebugName; + table.SetCommandAllocatorDebugName = ::SetCommandAllocatorDebugName; +// table.SetDescriptorPoolDebugName = ::SetDescriptorPoolDebugName; +// table.SetPipelineLayoutDebugName = ::SetPipelineLayoutDebugName; +// table.SetQueryPoolDebugName = ::SetQueryPoolDebugName; +// table.SetDescriptorSetDebugName = ::SetDescriptorSetDebugName; +// table.SetMemoryDebugName = ::SetMemoryDebugName; +// table.GetDeviceNativeObject = ::GetDeviceNativeObject; +// table.GetCommandBufferNativeObject = ::GetCommandBufferNativeObject; + table.GetBufferNativeObject = ::GetBufferNativeObject; +// table.GetTextureNativeObject = ::GetTextureNativeObject; +// table.GetDescriptorNativeObject = ::GetDescriptorNativeObject; + + return Result::SUCCESS; +} + + +#pragma endregion + +Result DeviceMTL::FillFunctionTable(HelperInterface& table) const { + return Result::SUCCESS; +} +Result DeviceMTL::FillFunctionTable(LowLatencyInterface& table) const { + + return Result::SUCCESS; +} +Result DeviceMTL::FillFunctionTable(MeshShaderInterface& table) const { + + return Result::SUCCESS; +} +Result DeviceMTL::FillFunctionTable(RayTracingInterface& table) const { + return Result::SUCCESS; +} +Result DeviceMTL::FillFunctionTable(StreamerInterface& table) const { + return Result::SUCCESS; +} +Result DeviceMTL::FillFunctionTable(SwapChainInterface& table) const { + return Result::SUCCESS; +} +Result DeviceMTL::FillFunctionTable(ResourceAllocatorInterface& table) const { + + return Result::SUCCESS; +} diff --git a/Source/Metal/MemoryMTL.h b/Source/Metal/MemoryMTL.h new file mode 100644 index 0000000..db196a9 --- /dev/null +++ b/Source/Metal/MemoryMTL.h @@ -0,0 +1,57 @@ +// © 2021 NVIDIA Corporation + +#pragma once + +#include + +#import + +namespace nri { + +struct DeviceMTL; + +struct MemoryMTL { + + inline MemoryMTL (DeviceMTL& device) + : m_Device(device) { + } + + inline id GetHandle() const { + return m_Handle; + } + + inline DeviceMTL& GetDevice() const { + return m_Device; + } + + inline MemoryType GetType() const { + return m_Type; + } + +// inline uint8_t* GetMappedMemory() const { +// return m_MappedMemory; +// } + + ~MemoryMTL(); + + // Result Create(const MemoryMTLDesc& memoryDesc); + Result Create(const AllocateMemoryDesc& allocateMemoryDesc); + // Result CreateDedicated(const BufferVK& buffer); + // Result CreateDedicated(const TextureVK& texture); + + //================================================================================================================ + // NRI + //================================================================================================================ + void SetDebugName(const char* name); + +private: + DeviceMTL& m_Device; + id m_Handle; + MemoryType m_Type; + float m_Priority = 0.0f; + bool m_OwnsNativeObjects = true; +}; + + +} + diff --git a/Source/Metal/MemoryMTL.mm b/Source/Metal/MemoryMTL.mm new file mode 100644 index 0000000..00accab --- /dev/null +++ b/Source/Metal/MemoryMTL.mm @@ -0,0 +1,62 @@ +// © 2021 NVIDIA Corporation +#include "SharedMTL.h" + +#include "MemoryMTL.h" + +using namespace nri; + +MemoryMTL::~MemoryMTL() { + //if (m_OwnsNativeObjects) { + // const auto& vk = m_Device.GetDispatchTable(); + // vk.FreeMemory(m_Device, m_Handle, m_Device.GetAllocationCallbacks()); + //} +} + +Result MemoryMTL::Create(const AllocateMemoryDesc& allocateMemoryDesc) { + MTLHeapDescriptor* heapDescriptor = [[MTLHeapDescriptor alloc] init]; + MemoryTypeInfo typeInfo; + typeInfo.value = allocateMemoryDesc.type; + [heapDescriptor setCpuCacheMode: (MTLCPUCacheMode)typeInfo.cacheMode]; + [heapDescriptor setStorageMode: (MTLStorageMode)typeInfo.storageMode]; + [heapDescriptor setResourceOptions: (MTLResourceOptions)typeInfo.options]; + [heapDescriptor setSize: allocateMemoryDesc.size]; + m_Handle = [m_Device newHeapWithDescriptor: heapDescriptor]; + m_Type = allocateMemoryDesc.type; + m_Priority = allocateMemoryDesc.priority; +} + +void MemoryMTL::SetDebugName(const char* name) { + NSString* str = [NSString stringWithUTF8String:name]; + [m_Handle setLabel: str]; +} + + +//Result MemoryMTL::Create(const MemoryMTLDesc& memoryDesc) { +// MTLHeapDescriptor* heapDescriptor = [[MTLHeapDescriptor alloc] init]; +// +// [heapDescriptor setSize:memoryDesc.size]; +// +// // [heapDescriptor setStorageMode:memoryDesc.storage]; +// +// // if (!memoryDesc.vkDeviceMemory) +// // return Result::INVALID_ARGUMENT; +// +// // MemoryTypeInfo memoryTypeInfo = {}; +// +// //bool found = m_Device.GetMemoryTypeByIndex(memoryDesc.memoryTypeIndex, memoryTypeInfo); +// //RETURN_ON_FAILURE(&m_Device, found, Result::INVALID_ARGUMENT, "Can't find memory by index"); +// +//// m_OwnsNativeObjects = false; +// // m_Buffer = memoryDesc.buffer; +//// m_MappedMemory = (uint8_t*)memoryDesc.mappedMemory; +// // m_Type = memoryDesc.options; +// +// // const auto& mtl = m_Device.GetDispatchTable(); +// //if (!m_MappedMemory && IsHostVisibleMemory(memoryTypeInfo.location)) { +// // VkResult result = mtl.MapMemory(m_Device, m_Handle, 0, memoryDesc.size, 0, (void**)&m_MappedMemory); +// // RETURN_ON_FAILURE(&m_Device, result == VK_SUCCESS, GetReturnCode(result), "vkMapMemory returned %d", (int32_t)result); +// //} +// +// return Result::SUCCESS; +//} + diff --git a/Source/Metal/PipelineLayoutMTL.h b/Source/Metal/PipelineLayoutMTL.h new file mode 100644 index 0000000..436549d --- /dev/null +++ b/Source/Metal/PipelineLayoutMTL.h @@ -0,0 +1,62 @@ +#pragma once + +#import + +namespace nri { + +struct DeviceMTL; + + +// +//struct BindingInfo { +// BindingInfo(StdAllocator& allocator); +//// Vector pushConstantBindings; +//// Vector pushDescriptorBindings; +//}; + +struct DescriptorSetLayout { + DescriptorSetDesc m_DescriptorSetDesc; + NSMutableArray* m_ArgumentDescriptors; +}; + +struct PipelineLayoutMTL { + + inline PipelineLayoutMTL (DeviceMTL& device) + : m_Device(device) + , m_HasVariableDescriptorNum(device.GetStdAllocator()) + , m_DescriptorSetRangeDescs(device.GetStdAllocator()) + , m_DynamicConstantBufferDescs(device.GetStdAllocator()) + , m_DescriptorSets(device.GetStdAllocator()) + { + } + + ~PipelineLayoutMTL(); + + inline DeviceMTL& GetDevice() const { + return m_Device; + } + + inline struct DescriptorSetLayout* GetDescriptorSetLayout(uint32_t setIndex) { + return &m_DescriptorSets[setIndex]; + } + +// inline struct DescriptorSetDesc* GetDescriptorSetDesc(uint32_t setIndex) { +// return &m_DescriptorSetDesc[setIndex]; +// } + + Result Create(const PipelineLayoutDesc& pipelineLayoutDesc); + + +private: + DeviceMTL& m_Device; + + Vector m_HasVariableDescriptorNum; + Vector m_DescriptorSetRangeDescs; + Vector m_DynamicConstantBufferDescs; +// Vector m_DescriptorSetDesc; + Vector m_DescriptorSets; + +// BindingInfo m_BindingInfo; +}; + +} diff --git a/Source/Metal/PipelineLayoutMTL.mm b/Source/Metal/PipelineLayoutMTL.mm new file mode 100644 index 0000000..aefa22c --- /dev/null +++ b/Source/Metal/PipelineLayoutMTL.mm @@ -0,0 +1,82 @@ +#include "SharedMTL.h" + +#include "PipelineLayoutMTL.h" + +using namespace nri; + +// +//BindingInfo::BindingInfo(StdAllocator& allocator) +// : hasVariableDescriptorNum(allocator) +// , descriptorSetRangeDescs(allocator) +// , dynamicConstantBufferDescs(allocator) +// , descriptorSetDescs(allocator) { +// +//} +// + +PipelineLayoutMTL::~PipelineLayoutMTL() { + +} + +Result PipelineLayoutMTL::Create(const PipelineLayoutDesc& pipelineLayoutDesc) { + + + size_t rangeNum = 0; + size_t dynamicConstantBufferNum = 0; + for (uint32_t i = 0; i < pipelineLayoutDesc.descriptorSetNum; i++) { + rangeNum += pipelineLayoutDesc.descriptorSets[i].rangeNum; + dynamicConstantBufferNum += pipelineLayoutDesc.descriptorSets[i].dynamicConstantBufferNum; + } + + m_DescriptorSets.resize(pipelineLayoutDesc.descriptorSetNum); + m_HasVariableDescriptorNum.resize(pipelineLayoutDesc.descriptorSetNum); + m_DescriptorSetRangeDescs.reserve(rangeNum); + m_DynamicConstantBufferDescs.reserve(dynamicConstantBufferNum); + + for (uint32_t i = 0; i < pipelineLayoutDesc.descriptorSetNum; i++) { + const DescriptorSetDesc& descriptorSetDesc = pipelineLayoutDesc.descriptorSets[i]; + + // Binding info + m_HasVariableDescriptorNum[i] = false; + m_DescriptorSets[i].m_DescriptorSetDesc = descriptorSetDesc; + m_DescriptorSets[i].m_DescriptorSetDesc.ranges = m_DescriptorSetRangeDescs.data() +m_DescriptorSetRangeDescs.size(); + m_DescriptorSets[i].m_DescriptorSetDesc.dynamicConstantBuffers = m_DynamicConstantBufferDescs.data() + m_DynamicConstantBufferDescs.size(); + m_DescriptorSetRangeDescs.insert(m_DescriptorSetRangeDescs.end(), descriptorSetDesc.ranges, descriptorSetDesc.ranges + descriptorSetDesc.rangeNum); + m_DynamicConstantBufferDescs.insert(m_DynamicConstantBufferDescs.end(), descriptorSetDesc.dynamicConstantBuffers, descriptorSetDesc.dynamicConstantBuffers + descriptorSetDesc.dynamicConstantBufferNum); + + NSMutableArray* argumentDescriptors = [[NSMutableArray alloc] init]; + for(size_t r = 0; r < descriptorSetDesc.rangeNum; r++) { + MTLArgumentDescriptor* argDescriptor = [MTLArgumentDescriptor argumentDescriptor]; + const DescriptorRangeDesc* range = &descriptorSetDesc.ranges[r]; + argDescriptor.arrayLength = range->descriptorNum; + argDescriptor.access = MTLBindingAccessReadWrite; + argDescriptor.index = range->baseRegisterIndex; + switch(range->descriptorType) { + case DescriptorType::TEXTURE: + argDescriptor.dataType = MTLDataTypeTexture; + argDescriptor.textureType = MTLTextureType2D; // descriptor type does not have this + break; + case DescriptorType::SAMPLER: + argDescriptor.dataType = MTLDataTypeSampler; + break; + case DescriptorType::CONSTANT_BUFFER: + case DescriptorType::STORAGE_TEXTURE: + case DescriptorType::BUFFER: + case DescriptorType::STORAGE_BUFFER: + case DescriptorType::STRUCTURED_BUFFER: + case DescriptorType::STORAGE_STRUCTURED_BUFFER: + argDescriptor.dataType = MTLDataTypeStruct; + break; + case DescriptorType::ACCELERATION_STRUCTURE: + argDescriptor.dataType = MTLDataTypePrimitiveAccelerationStructure; + break; + default: + break; + } + } + m_DescriptorSets[i].m_ArgumentDescriptors = argumentDescriptors; + + } + return Result::SUCCESS; +} + diff --git a/Source/Metal/PipelineMTL.h b/Source/Metal/PipelineMTL.h new file mode 100644 index 0000000..4351886 --- /dev/null +++ b/Source/Metal/PipelineMTL.h @@ -0,0 +1,45 @@ +#pragma once + +#import + +namespace nri { + +struct DeviceMTL; +struct PipelineLayoutMTL; + +NriEnum(PipelineType, uint8_t, + Compute, + Graphics, + Raytracing +); + +struct PipelineMTL { +public: + inline PipelineMTL(DeviceMTL& device) + : m_Device(device) { + } + ~PipelineMTL(); + + inline PipelineType GetPipelineType() { + return m_PipelineType; + } + + Result Create(const GraphicsPipelineDesc& graphicsPipelineDesc); + Result Create(const ComputePipelineDesc& computePipelineDesc); + Result Create(const RayTracingPipelineDesc& rayTracingPipelineDesc); + + MTLPrimitiveTopologyClass m_topologyClass; + MTLPrimitiveType m_primitiveType; + StageBits m_usedBits; + +private: + PipelineType m_PipelineType; + union{ + id m_ComputePipeline = nil; + id m_GraphicsPipeline; + }; + DeviceMTL& m_Device; +}; + +} + diff --git a/Source/Metal/PipelineMTL.mm b/Source/Metal/PipelineMTL.mm new file mode 100644 index 0000000..61d72f4 --- /dev/null +++ b/Source/Metal/PipelineMTL.mm @@ -0,0 +1,168 @@ +#include "SharedMTL.h" + +#include "PipelineMTL.h" +#include "PipelineLayoutMTL.h" + +using namespace nri; + +PipelineMTL::~PipelineMTL() { + switch(m_PipelineType) { + case PipelineType::Graphics: + m_GraphicsPipeline = nil; + break; + case PipelineType::Compute: + m_ComputePipeline = nil; + break; + case PipelineType::Raytracing: + break; + default: + break; + } + +} + +Result PipelineMTL::Create(const ComputePipelineDesc& computePipelineDesc) { + MTLComputePipelineDescriptor* pipelineDesc = [[MTLComputePipelineDescriptor alloc] init]; + NSError* error = nil; + + dispatch_data_t byteCode = dispatch_data_create( + computePipelineDesc.shader.bytecode, + computePipelineDesc.shader.size, nil, DISPATCH_DATA_DESTRUCTOR_DEFAULT); + + id lib = [m_Device newLibraryWithData: byteCode error:&error]; + NSCAssert(lib, @"Failed to load Metal shader library %@", error); // not sure how to correctly report this + RETURN_ON_FAILURE(&m_Device, lib, Result::FAILURE, "Failed to Load Metal shader library"); + // Create a MTLFunction from the loaded MTLLibrary. + NSString *entryPointNStr = [lib functionNames][0]; + if (computePipelineDesc.shader.entryPointName) { + entryPointNStr = [[NSString alloc] initWithUTF8String:computePipelineDesc.shader.entryPointName]; + } + id entryPointFunc = [lib newFunctionWithName:entryPointNStr]; + + m_PipelineType = PipelineType::Compute; + pipelineDesc.computeFunction = entryPointFunc; + NSCAssert(pipelineDesc.computeFunction, @"Failed to create Metal kernel function %@: %@", entryPointNStr, error); + + + m_ComputePipeline = [m_Device newComputePipelineStateWithDescriptor: pipelineDesc + options: MTLPipelineOptionNone + reflection: nil + error:&error]; + NSCAssert(m_ComputePipeline, @"Failed to create pipeline state: %@", error); + return Result::SUCCESS; +} + +Result PipelineMTL::Create(const RayTracingPipelineDesc& rayTracingPipelineDesc) { + return Result::SUCCESS; +} + +Result PipelineMTL::Create(const GraphicsPipelineDesc& graphicsPipelineDesc) { + MTLRenderPipelineDescriptor *renderPipelineDesc = [[MTLRenderPipelineDescriptor alloc] init]; + + //m_type = PipelineMTL::Graphics; + const InputAssemblyDesc& ia = graphicsPipelineDesc.inputAssembly; + switch (ia.topology) { + case Topology::POINT_LIST: + m_primitiveType = MTLPrimitiveType::MTLPrimitiveTypePoint; + break; + case Topology::LINE_LIST: + case Topology::LINE_STRIP: + case Topology::LINE_LIST_WITH_ADJACENCY: + case Topology::LINE_STRIP_WITH_ADJACENCY: + m_primitiveType = MTLPrimitiveType::MTLPrimitiveTypeLine; + break; + case Topology::TRIANGLE_LIST: + case Topology::TRIANGLE_STRIP: + case Topology::TRIANGLE_LIST_WITH_ADJACENCY: + case Topology::TRIANGLE_STRIP_WITH_ADJACENCY: + m_primitiveType = MTLPrimitiveType::MTLPrimitiveTypeTriangle; + break; + case Topology::PATCH_LIST: + default: + break; + } + + for (uint32_t i = 0; i < graphicsPipelineDesc.shaderNum; i++) { + const ShaderDesc& shader = graphicsPipelineDesc.shaders[i]; + m_usedBits |= shader.stage; + + dispatch_data_t byteCode = dispatch_data_create(shader.bytecode, shader.size, nil, DISPATCH_DATA_DESTRUCTOR_DEFAULT); + NSError *error; + id lib = [m_Device newLibraryWithData:byteCode error:&error]; + NSCAssert(lib, @"Failed to load Metal shader library %@", error); // not sure how to correctly report this + RETURN_ON_FAILURE(&m_Device, lib, Result::FAILURE, "Failed to Load Metal shader library"); + + // Create a MTLFunction from the loaded MTLLibrary. + NSString *entryPointNStr = [lib functionNames][0]; + if (shader.entryPointName) { + entryPointNStr = [[NSString alloc] initWithUTF8String:shader.entryPointName]; + } + id entryPointFunc = [lib newFunctionWithName:entryPointNStr]; + if(shader.stage & nri::StageBits::VERTEX_SHADER) { + renderPipelineDesc.vertexFunction = entryPointFunc; + } else if(shader.stage & nri::StageBits::FRAGMENT_SHADER) { + renderPipelineDesc.fragmentFunction = entryPointFunc; + } + } + // Depth-stencil + const DepthAttachmentDesc& da = graphicsPipelineDesc.outputMerger.depth; + const StencilAttachmentDesc& sa = graphicsPipelineDesc.outputMerger.stencil; + + const PipelineLayout *pl = graphicsPipelineDesc.pipelineLayout; + const VertexInputDesc *vi = graphicsPipelineDesc.vertexInput; + if (vi) { + MTLVertexDescriptor *vertexDescriptor = [MTLVertexDescriptor new]; + for(size_t attIdx = 0; attIdx < vi->attributeNum; attIdx++) { + const nri::VertexAttributeDesc* attrib = &vi->attributes[attIdx]; + vertexDescriptor.attributes[attrib->mtl.location].offset = attrib->offset; + vertexDescriptor.attributes[attrib->mtl.location].format = GetVertexFormatMTL(attrib->format); + vertexDescriptor.attributes[attrib->mtl.location].bufferIndex = attrib->streamIndex; + } + + for(size_t layoutIdx = 0; layoutIdx < vi->streamNum; layoutIdx++) { + const nri::VertexStreamDesc* stream = &vi->streams[layoutIdx]; + vertexDescriptor.layouts[stream->bindingSlot].stride = stream->stride; + vertexDescriptor.layouts[stream->bindingSlot].stepRate = static_cast(stream->stepRate); + } + renderPipelineDesc.vertexDescriptor = vertexDescriptor; + } + + renderPipelineDesc.inputPrimitiveTopology = GetTopologyMTL(ia.topology); + + if (graphicsPipelineDesc.multisample) { + // TODO: multisampling + // + } + + // renderPipelineDesc.rasterSampleCount = pCreateInfo->pMultisampleState->pSampleMask[0]; + + + // Blending + + // assign render target pixel format for all attachments + const OutputMergerDesc& om = graphicsPipelineDesc.outputMerger; + for (uint32_t i = 0; i < om.colorNum; i++) { + + const ColorAttachmentDesc& attachmentDesc = om.colors[i]; + renderPipelineDesc.colorAttachments[i].pixelFormat = GetFormatMTL(attachmentDesc.format, false); + + renderPipelineDesc.colorAttachments[i].blendingEnabled = attachmentDesc.blendEnabled; + renderPipelineDesc.colorAttachments[i].rgbBlendOperation = GetBlendOp(attachmentDesc.colorBlend.func); + renderPipelineDesc.colorAttachments[i].alphaBlendOperation = GetBlendOp(attachmentDesc.alphaBlend.func); + + renderPipelineDesc.colorAttachments[i].sourceRGBBlendFactor = GetBlendFactor(attachmentDesc.colorBlend.srcFactor); + renderPipelineDesc.colorAttachments[i].destinationRGBBlendFactor = GetBlendFactor(attachmentDesc.colorBlend.dstFactor); + renderPipelineDesc.colorAttachments[i].sourceAlphaBlendFactor = GetBlendFactor(attachmentDesc.alphaBlend.srcFactor); + renderPipelineDesc.colorAttachments[i].destinationAlphaBlendFactor = GetBlendFactor(attachmentDesc.alphaBlend.dstFactor); + + renderPipelineDesc.colorAttachments[i].writeMask = GetColorComponent(attachmentDesc.colorWriteMask); + + } + NSError* error = nil; + m_GraphicsPipeline = [m_Device newRenderPipelineStateWithDescriptor:renderPipelineDesc error: &error]; + NSCAssert(m_GraphicsPipeline, @"Failed to create pipeline state: %@", error); + + + return Result::SUCCESS; + +} diff --git a/Source/Metal/QueryMTL.h b/Source/Metal/QueryMTL.h new file mode 100644 index 0000000..e69de29 diff --git a/Source/Metal/QueryMTL.mm b/Source/Metal/QueryMTL.mm new file mode 100644 index 0000000..e69de29 diff --git a/Source/Metal/SharedMTL.h b/Source/Metal/SharedMTL.h new file mode 100644 index 0000000..4c23611 --- /dev/null +++ b/Source/Metal/SharedMTL.h @@ -0,0 +1,17 @@ +#import + +#include "SharedExternal.h" + +#include "ConversionMTL.h" +#include "DeviceMTL.h" + +struct MemoryTypeInfo { + union { + uint32_t value; + struct { + uint32_t options: 16; // MTLResourceOptions + uint32_t storageMode: 4; // MTLStorageMode + uint32_t cacheMode: 2; // MTLCPUCacheMode + }; + }; +}; diff --git a/Source/Metal/SwapChainMTL.h b/Source/Metal/SwapChainMTL.h new file mode 100644 index 0000000..567d03b --- /dev/null +++ b/Source/Metal/SwapChainMTL.h @@ -0,0 +1,26 @@ +#pragma once + +namespace nri { + +// Let's keep things simple and hide it under the hood +constexpr uint32_t MAX_NUMBER_OF_FRAMES_IN_FLIGHT = 8; + +struct SwapChainMTL: public DisplayDescHelper { + SwapChainMTL(DeviceMTL& device) + : m_Device(device) { + + } + ~SwapChainMTL(); + + Result Create(const SwapChainDesc& swapChainDesc); + +private: + CAMetalLayer* m_MetalLayer; + + DeviceMTL& m_Device; + uint64_t m_PresentId = 0; + uint32_t m_TextureIndex = 0; + uint8_t m_FrameIndex = 0; // in flight, not global +}; + +}; diff --git a/Source/Metal/SwapChainMTL.mm b/Source/Metal/SwapChainMTL.mm new file mode 100644 index 0000000..f2bad95 --- /dev/null +++ b/Source/Metal/SwapChainMTL.mm @@ -0,0 +1,15 @@ +#include "SharedMTL.h" + +#include "SwapChainMTL.h" + +using namespace nri; + + +SwapChainMTL::~SwapChainMTL() { + +} + +Result SwapChainMTL::Create(const SwapChainDesc& swapChainDesc) { + m_MetalLayer = (CAMetalLayer*)swapChainDesc.window.metal.caMetalLayer; + +} diff --git a/Source/Metal/TextureMTL.h b/Source/Metal/TextureMTL.h new file mode 100644 index 0000000..834c258 --- /dev/null +++ b/Source/Metal/TextureMTL.h @@ -0,0 +1,52 @@ +// © 2021 NVIDIA Corporation +#pragma once + +#import + +namespace nri { + +struct DeviceMTL; + +class MemoryMTL; + +void fillMTLTextureDescriptor(const TextureDesc& textureDesc, MTLTextureDescriptor* mtlDescriptor); + +struct TextureMTL { +public: + inline TextureMTL(DeviceMTL& device) + : m_Device(device) { + } + ~TextureMTL(); + + inline id GetHandle() const { + return m_Handle; + } + + inline DeviceMTL& GetDevice() const { + return m_Device; + } + + inline const TextureDesc& GetDesc() const { + return m_Desc; + } + + Result Create(const TextureDesc& textureDesc); + void FinishMemoryBinding(MemoryMTL& memory, uint64_t memoryOffset); + + //================================================================================================================ + // NRI + //================================================================================================================ + + void SetDebugName(const char* name); + +private: + + void UpdateLabel(); + NSString* m_Label = nullptr; + DeviceMTL& m_Device; + TextureDesc m_Desc = {}; + id m_Handle; + NSString* m_label; +}; + +} // namespace nri diff --git a/Source/Metal/TextureMTL.mm b/Source/Metal/TextureMTL.mm new file mode 100644 index 0000000..b6f7fe1 --- /dev/null +++ b/Source/Metal/TextureMTL.mm @@ -0,0 +1,48 @@ +#include "SharedMTL.h" + +#include "TextureMTL.h" +#include "MemoryMTL.h" + +using namespace nri; + +TextureMTL::~TextureMTL() { + m_Handle = nil; + [m_label release]; +} + +void nri::fillMTLTextureDescriptor(const TextureDesc& textureDesc, MTLTextureDescriptor* info) { + info.textureType = ::GetImageTypeMTL(textureDesc.type); + info.pixelFormat = ::GetFormatMTL(textureDesc.format, true); + info.width = textureDesc.width; + info.height = textureDesc.height; + info.depth = textureDesc.depth; + info.mipmapLevelCount = textureDesc.mipNum; + info.sampleCount = textureDesc.sampleNum; + info.arrayLength = textureDesc.layerNum; +} + +Result TextureMTL::Create(const TextureDesc& textureDesc) { + m_Desc = textureDesc; + + return Result::SUCCESS; +} + + +void TextureMTL::FinishMemoryBinding(MemoryMTL& memory, uint64_t memoryOffset) { + MTLTextureDescriptor* info = [[MTLTextureDescriptor alloc] init]; + fillMTLTextureDescriptor(m_Desc, info); + m_Handle = [memory.GetHandle() newTextureWithDescriptor:info offset:memoryOffset]; + UpdateLabel(); +} + +void TextureMTL::UpdateLabel() { + if(m_Handle && m_Label) { + [m_Handle setLabel: m_Label]; + } +} + +void TextureMTL::SetDebugName(const char* name) { + m_label = [NSString stringWithUTF8String:name]; + [m_label retain]; + UpdateLabel(); +} diff --git a/Source/Shared/SharedExternal.h b/Source/Shared/SharedExternal.h index 6d0bc4d..8cbb3c9 100644 --- a/Source/Shared/SharedExternal.h +++ b/Source/Shared/SharedExternal.h @@ -1,4 +1,4 @@ -// © 2021 NVIDIA Corporation +// © 2021 NVIDIA Corporation #pragma once @@ -29,6 +29,7 @@ typedef uint32_t DXGI_FORMAT; #include "Extensions/NRIWrapperD3D11.h" #include "Extensions/NRIWrapperD3D12.h" #include "Extensions/NRIWrapperVK.h" +#include "Extensions/NRIWrapperMTL.h" #include "NRICompatibility.hlsli" @@ -164,6 +165,7 @@ nri::Format VKFormatToNRIFormat(uint32_t vkFormat); uint32_t NRIFormatToDXGIFormat(nri::Format format); uint32_t NRIFormatToVKFormat(nri::Format format); +uint32_t NRIFormatToMTLFormat(nri::Format format); // Misc inline nri::Vendor GetVendorFromID(uint32_t vendorID) { @@ -174,6 +176,8 @@ inline nri::Vendor GetVendorFromID(uint32_t vendorID) { return nri::Vendor::AMD; case 0x8086: return nri::Vendor::INTEL; + case 0x106b: + return nri::Vendor::APPLE; } return nri::Vendor::UNKNOWN;