mirror of
https://github.com/rt64/rt64.git
synced 2025-03-14 04:19:02 +00:00
Merge pull request #74 from tanmaysachan/tsachan/metal
WIP Metal backend
This commit is contained in:
commit
7d8867a3ee
@ -847,12 +847,7 @@ namespace RT64 {
|
||||
auto *metalInterface = dynamic_cast<RT64::MetalInterface *>(renderInterface);
|
||||
metalInterface->assignDeviceToLayer(view);
|
||||
|
||||
// SDL_Window's handle can be used directly if needed
|
||||
SDL_SysWMinfo wmInfo;
|
||||
SDL_VERSION(&wmInfo.version);
|
||||
SDL_GetWindowWMInfo(window, &wmInfo);
|
||||
|
||||
TestInitialize(renderInterface, { wmInfo.info.cocoa.window });
|
||||
TestInitialize(renderInterface, { window });
|
||||
TestResize();
|
||||
|
||||
bool running = true;
|
||||
|
4
src/hle/rt64_application_window.cpp
Normal file → Executable file
4
src/hle/rt64_application_window.cpp
Normal file → Executable file
@ -135,7 +135,7 @@ namespace RT64 {
|
||||
windowHandle.display = wmInfo.info.x11.display;
|
||||
windowHandle.window = wmInfo.info.x11.window;
|
||||
# elif defined(__APPLE__)
|
||||
windowHandle.window = wmInfo.info.cocoa.window;
|
||||
windowHandle.window = sdlWindow;
|
||||
# else
|
||||
static_assert(false && "Unimplemented");
|
||||
# endif
|
||||
@ -380,4 +380,4 @@ namespace RT64 {
|
||||
#else
|
||||
static_assert(false && "Unimplemented");
|
||||
#endif
|
||||
};
|
||||
};
|
114
src/metal/rt64_metal.h
Normal file → Executable file
114
src/metal/rt64_metal.h
Normal file → Executable file
@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "rhi/rt64_render_interface.h"
|
||||
#include <map>
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Metal/Metal.h>
|
||||
@ -33,9 +34,35 @@ namespace RT64 {
|
||||
struct MetalPool;
|
||||
struct MetalPipelineLayout;
|
||||
struct MetalTexture;
|
||||
struct MetalSampler;
|
||||
|
||||
struct MetalRenderState {
|
||||
#ifdef __OBJC__
|
||||
id<MTLRenderPipelineState> renderPipelineState = nil;
|
||||
id<MTLDepthStencilState> depthStencilState = nil;
|
||||
MTLCullMode cullMode = MTLCullModeNone;
|
||||
MTLDepthClipMode depthClipMode = MTLDepthClipModeClip;
|
||||
MTLWinding winding = MTLWindingClockwise;
|
||||
MTLSamplePosition *samplePositions = nullptr;
|
||||
#endif
|
||||
uint32_t sampleCount = 0;
|
||||
};
|
||||
|
||||
struct MetalDescriptorSet : RenderDescriptorSet {
|
||||
#ifdef __OBJC__
|
||||
id<MTLBuffer> descriptorBuffer;
|
||||
std::vector<id<MTLBuffer>> residentBuffers;
|
||||
std::unordered_map<uint32_t, id<MTLTexture>> indicesToTextures;
|
||||
std::vector<id<MTLSamplerState>> staticSamplers;
|
||||
std::vector<MTLArgumentDescriptor *> argumentDescriptors;
|
||||
#endif
|
||||
|
||||
MetalDevice *device = nullptr;
|
||||
uint32_t bufferOffset = 0;
|
||||
uint32_t entryCount = 0;
|
||||
uint32_t descriptorTypeMaxIndex = 0;
|
||||
std::vector<RenderDescriptorRangeType> descriptorTypes;
|
||||
std::vector<uint32_t> samplerIndices;
|
||||
|
||||
MetalDescriptorSet(MetalDevice *device, const RenderDescriptorSetDesc &desc);
|
||||
MetalDescriptorSet(MetalDevice *device, uint32_t entryCount);
|
||||
@ -45,12 +72,38 @@ namespace RT64 {
|
||||
void setAccelerationStructure(uint32_t descriptorIndex, const RenderAccelerationStructure *accelerationStructure) override;
|
||||
};
|
||||
|
||||
struct MetalDescriptorSetLayout {
|
||||
#ifdef __OBJC__
|
||||
std::vector<id<MTLSamplerState>> staticSamplers;
|
||||
NSMutableArray* argumentDescriptors = nil;
|
||||
id<MTLArgumentEncoder> argumentEncoder = nil;
|
||||
id<MTLBuffer> descriptorBuffer = nil;
|
||||
#endif
|
||||
|
||||
MetalDevice *device = nullptr;
|
||||
std::vector<RenderDescriptorRangeType> descriptorTypes;
|
||||
std::vector<uint32_t> descriptorToRangeIndex;
|
||||
std::vector<uint32_t> descriptorIndexBases;
|
||||
std::vector<uint32_t> descriptorRangeBinding;
|
||||
std::vector<uint32_t> samplerIndices;
|
||||
uint32_t bufferOffset = 0;
|
||||
uint32_t entryCount = 0;
|
||||
uint32_t descriptorTypeMaxIndex = 0;
|
||||
uint32_t initialIndexOffset = 0;
|
||||
|
||||
MetalDescriptorSetLayout(MetalDevice *device, const RenderDescriptorSetDesc &desc);
|
||||
~MetalDescriptorSetLayout();
|
||||
};
|
||||
|
||||
struct MetalSwapChain : RenderSwapChain {
|
||||
#ifdef __OBJC__
|
||||
id<CAMetalDrawable> drawable = nil;
|
||||
#endif
|
||||
CAMetalLayer *layer = nullptr;
|
||||
MetalCommandQueue *commandQueue = nullptr;
|
||||
RenderWindow renderWindow = {};
|
||||
std::vector<MetalTexture> textures;
|
||||
uint32_t textureCount = 0;
|
||||
MetalTexture *proxyTexture;
|
||||
RenderFormat format = RenderFormat::UNKNOWN;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
@ -70,7 +123,6 @@ namespace RT64 {
|
||||
bool isEmpty() const override;
|
||||
uint32_t getRefreshRate() const override;
|
||||
void getWindowSize(uint32_t &dstWidth, uint32_t &dstHeight) const;
|
||||
void setTextures();
|
||||
};
|
||||
|
||||
struct MetalFramebuffer : RenderFramebuffer {
|
||||
@ -92,13 +144,46 @@ namespace RT64 {
|
||||
id<MTLRenderCommandEncoder> renderEncoder = nil;
|
||||
id<MTLComputeCommandEncoder> computeEncoder = nil;
|
||||
id<MTLBlitCommandEncoder> blitEncoder = nil;
|
||||
MTLCaptureManager *captureManager = nil;
|
||||
|
||||
MTLRenderPassDescriptor *renderDescriptor = nil;
|
||||
|
||||
MTLPrimitiveType currentPrimitiveType = MTLPrimitiveTypeTriangle;
|
||||
MTLIndexType currentIndexType = MTLIndexTypeUInt32;
|
||||
id<MTLBuffer> indexBuffer = nil;
|
||||
|
||||
uint32_t viewCount = 0;
|
||||
std::vector<id<MTLBuffer>> vertexBuffers;
|
||||
std::vector<uint32_t> vertexBufferOffsets;
|
||||
std::vector<uint32_t> vertexBufferIndices;
|
||||
|
||||
std::vector<MTLViewport> viewportVector;
|
||||
std::vector<MTLScissorRect> scissorVector;
|
||||
|
||||
id<MTLBuffer> graphicsPushConstantsBuffer = nil;
|
||||
id<MTLBuffer> computePushConstantsBuffer = nil;
|
||||
|
||||
std::map<id<MTLTexture>, id<MTLTexture>> resolveTo;
|
||||
|
||||
struct DrawCall {
|
||||
enum class Type {
|
||||
Draw,
|
||||
DrawIndexed
|
||||
};
|
||||
Type type;
|
||||
MTLPrimitiveType primitiveType = MTLPrimitiveTypeTriangle;
|
||||
uint32_t startVertexLocation = 0;
|
||||
uint32_t vertexCountPerInstance = 0;
|
||||
uint32_t instanceCount = 0;
|
||||
uint32_t startInstanceLocation = 0;
|
||||
|
||||
uint32_t indexCountPerInstance = 0;
|
||||
MTLIndexType indexType = MTLIndexTypeUInt32;
|
||||
id<MTLBuffer> indexBuffer = nil;
|
||||
int32_t baseVertexLocation = 0;
|
||||
uint32_t startIndexLocation = 0;
|
||||
};
|
||||
std::vector<DrawCall> deferredDrawCalls;
|
||||
#endif
|
||||
|
||||
MetalDevice *device = nullptr;
|
||||
@ -108,15 +193,26 @@ namespace RT64 {
|
||||
const MetalPipelineLayout *activeComputePipelineLayout = nullptr;
|
||||
const MetalPipelineLayout *activeGraphicsPipelineLayout = nullptr;
|
||||
const MetalGraphicsPipeline *activeGraphicsPipeline = nullptr;
|
||||
const MetalRenderState *activeRenderState = nullptr;
|
||||
|
||||
std::unordered_map<uint32_t, MetalDescriptorSet *> indicesToRenderDescriptorSets;
|
||||
std::unordered_map<uint32_t, MetalDescriptorSet *> indicesToComputeDescriptorSets;
|
||||
|
||||
std::unordered_map<uint32_t, RenderColor> attachmentsToClear;
|
||||
float depthClearValue = -1.0f;
|
||||
|
||||
uint32_t colorAttachmentsCount = 0;
|
||||
|
||||
MetalCommandList(MetalCommandQueue *queue, RenderCommandListType type);
|
||||
~MetalCommandList() override;
|
||||
void begin() override;
|
||||
void end() override;
|
||||
void endEncoder();
|
||||
void endEncoder(bool clearDescs);
|
||||
void guaranteeRenderDescriptor();
|
||||
void guaranteeRenderEncoder();
|
||||
void guaranteeComputeEncoder();
|
||||
void guaranteeBlitEncoder();
|
||||
void clearDrawCalls();
|
||||
void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) override;
|
||||
void dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) override;
|
||||
void traceRays(uint32_t width, uint32_t height, uint32_t depth, RenderBufferReference shaderBindingTable, const RenderShaderBindingGroupsInfo &shaderBindingGroupsInfo) override;
|
||||
@ -147,7 +243,7 @@ namespace RT64 {
|
||||
void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect) override;
|
||||
void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) override;
|
||||
void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) override;
|
||||
void setDescriptorSet(const MetalPipelineLayout *activePipelineLayout, RenderDescriptorSet *descriptorSet, uint32_t setIndex, bool setCompute);
|
||||
void setDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex, bool setCompute);
|
||||
};
|
||||
|
||||
struct MetalCommandFence : RenderCommandFence {
|
||||
@ -207,6 +303,7 @@ namespace RT64 {
|
||||
MetalDevice *device = nullptr;
|
||||
MetalPool *pool = nullptr;
|
||||
RenderTextureDesc desc;
|
||||
MetalSwapChain *parentSwapChain = nullptr;
|
||||
|
||||
MetalTexture() = default;
|
||||
MetalTexture(MetalDevice *device, MetalPool *pool, const RenderTextureDesc &desc);
|
||||
@ -219,7 +316,6 @@ namespace RT64 {
|
||||
#ifdef __OBJC__
|
||||
id<MTLTexture> mtlTexture = nil;
|
||||
#endif
|
||||
MetalTexture *texture = nullptr;
|
||||
|
||||
MetalTextureView(MetalTexture *texture, const RenderTextureViewDesc &desc);
|
||||
~MetalTextureView() override;
|
||||
@ -302,15 +398,21 @@ namespace RT64 {
|
||||
id<MTLRenderPipelineState> state = nil;
|
||||
#endif
|
||||
|
||||
MetalRenderState *renderState;
|
||||
MetalGraphicsPipeline(MetalDevice *device, const RenderGraphicsPipelineDesc &desc);
|
||||
~MetalGraphicsPipeline() override;
|
||||
RenderPipelineProgram getProgram(const std::string &name) const override;
|
||||
};
|
||||
|
||||
struct MetalPipelineLayout : RenderPipelineLayout {
|
||||
#ifdef __OBJC__
|
||||
id<MTLBuffer> pushConstantsBuffer = nil;
|
||||
#endif
|
||||
|
||||
MetalDevice *device = nullptr;
|
||||
std::vector<RenderPushConstantRange> pushConstantRanges;
|
||||
uint32_t setCount = 0;
|
||||
std::vector<MetalDescriptorSetLayout *> setLayoutHandles;
|
||||
|
||||
MetalPipelineLayout(MetalDevice *device, const RenderPipelineLayoutDesc &desc);
|
||||
~MetalPipelineLayout() override;
|
||||
@ -377,4 +479,4 @@ namespace RT64 {
|
||||
|
||||
void assignDeviceToLayer(void* layer);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
821
src/metal/rt64_metal.mm
Normal file → Executable file
821
src/metal/rt64_metal.mm
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
5
src/rhi/rt64_render_interface_types.h
Normal file → Executable file
5
src/rhi/rt64_render_interface_types.h
Normal file → Executable file
@ -23,7 +23,8 @@
|
||||
#undef ControlMask
|
||||
#undef Success
|
||||
#elif defined(__APPLE__)
|
||||
typedef struct _NSWindow NSWindow;
|
||||
//typedef struct _NSWindow NSWindow;
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
namespace RT64 {
|
||||
@ -43,7 +44,7 @@ namespace RT64 {
|
||||
};
|
||||
#elif defined(__APPLE__)
|
||||
struct RenderWindow {
|
||||
NSWindow* window;
|
||||
SDL_Window* window;
|
||||
bool operator==(const struct RenderWindow& rhs) const {
|
||||
return window == rhs.window;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user