Add vertex and index buffer persistence

This commit is contained in:
tanmaysachan 2024-08-12 00:31:13 +05:30
parent c357779b14
commit 6e8a394d5f
2 changed files with 36 additions and 5 deletions

View File

@ -42,7 +42,7 @@ namespace RT64 {
MTLDepthClipMode depthClipMode = MTLDepthClipModeClip; MTLDepthClipMode depthClipMode = MTLDepthClipModeClip;
MTLWinding winding = MTLWindingClockwise; MTLWinding winding = MTLWindingClockwise;
#endif #endif
} };
struct MetalDescriptorSet : RenderDescriptorSet { struct MetalDescriptorSet : RenderDescriptorSet {
MetalDevice *device = nullptr; MetalDevice *device = nullptr;
@ -107,6 +107,11 @@ namespace RT64 {
MTLIndexType currentIndexType = MTLIndexTypeUInt32; MTLIndexType currentIndexType = MTLIndexTypeUInt32;
id<MTLBuffer> indexBuffer = nil; 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<MTLViewport> viewportVector;
std::vector<MTLScissorRect> scissorVector; std::vector<MTLScissorRect> scissorVector;
#endif #endif
@ -309,6 +314,10 @@ namespace RT64 {
}; };
struct MetalGraphicsPipeline : MetalPipeline { struct MetalGraphicsPipeline : MetalPipeline {
#ifdef __OBJC__
id<MTLRenderPipelineState> state = nil;
#endif
MetalRenderState *renderState; MetalRenderState *renderState;
MetalGraphicsPipeline(MetalDevice *device, const RenderGraphicsPipelineDesc &desc); MetalGraphicsPipeline(MetalDevice *device, const RenderGraphicsPipelineDesc &desc);
~MetalGraphicsPipeline() override; ~MetalGraphicsPipeline() override;

View File

@ -681,6 +681,7 @@ namespace RT64 {
NSError *error = nullptr; NSError *error = nullptr;
this->state = [device->device newRenderPipelineStateWithDescriptor: descriptor error: &error]; this->state = [device->device newRenderPipelineStateWithDescriptor: descriptor error: &error];
renderState->renderPipelineState = state;
if (error != nullptr) { if (error != nullptr) {
fprintf(stderr, "MTLDevice newRenderPipelineStateWithDescriptor: failed with error %s.\n", [error.localizedDescription cStringUsingEncoding: NSUTF8StringEncoding]); fprintf(stderr, "MTLDevice newRenderPipelineStateWithDescriptor: failed with error %s.\n", [error.localizedDescription cStringUsingEncoding: NSUTF8StringEncoding]);
@ -872,6 +873,12 @@ namespace RT64 {
[renderEncoder setViewports: viewportVector.data() count: viewportVector.size()]; [renderEncoder setViewports: viewportVector.data() count: viewportVector.size()];
[renderEncoder setScissorRects: scissorVector.data() count: scissorVector.size()]; [renderEncoder setScissorRects: scissorVector.data() count: scissorVector.size()];
for (uint32_t i = 0; i < viewCount; i++) {
[renderEncoder setVertexBuffer: vertexBuffers[i]
offset: vertexBufferOffsets[i]
atIndex: vertexBufferIndices[i]];
}
} }
} }
@ -958,7 +965,7 @@ namespace RT64 {
guaranteeRenderEncoder(); guaranteeRenderEncoder();
const auto *graphicsPipeline = static_cast<const MetalGraphicsPipeline *>(interfacePipeline); const auto *graphicsPipeline = static_cast<const MetalGraphicsPipeline *>(interfacePipeline);
assert(renderEncoder != nil && "Cannot set pipeline state on nil MTLRenderCommandEncoder!"); assert(renderEncoder != nil && "Cannot set pipeline state on nil MTLRenderCommandEncoder!");
rebindRenderState(graphicsPipeline->state); rebindRenderState(graphicsPipeline->renderState);
break; break;
} }
default: default:
@ -1012,17 +1019,32 @@ namespace RT64 {
} }
void MetalCommandList::setIndexBuffer(const RenderIndexBufferView *view) { void MetalCommandList::setIndexBuffer(const RenderIndexBufferView *view) {
// TODO: Argument Buffer Creation & Binding
if (view != nullptr) { if (view != nullptr) {
const auto *interfaceBuffer = static_cast<const MetalBuffer *>(view->buffer.ref); const auto *interfaceBuffer = static_cast<const MetalBuffer *>(view->buffer.ref);
indexBuffer = interfaceBuffer->buffer;
} }
} }
void MetalCommandList::setVertexBuffers(uint32_t startSlot, const RenderVertexBufferView *views, uint32_t viewCount, const RenderInputSlot *inputSlots) { void MetalCommandList::setVertexBuffers(uint32_t startSlot, const RenderVertexBufferView *views, uint32_t viewCount, const RenderInputSlot *inputSlots) {
// TODO: Argument Buffer Creation & Binding
if ((views != nullptr) && (viewCount > 0)) { if ((views != nullptr) && (viewCount > 0)) {
guaranteeRenderEncoder();
assert(inputSlots != nullptr); assert(inputSlots != nullptr);
this->viewCount = viewCount;
vertexBuffers.clear();
vertexBufferOffsets.clear();
vertexBufferIndices.clear();
for (uint32_t i = 0; i < viewCount; i++) {
const MetalBuffer *interfaceBuffer = static_cast<const MetalBuffer *>(views[i].buffer.ref);
vertexBuffers.emplace_back(interfaceBuffer->buffer);
vertexBufferOffsets.emplace_back(views[i].buffer.offset);
vertexBufferIndices.emplace_back(startSlot + i);
[renderEncoder setVertexBuffer: interfaceBuffer->buffer
offset: views[i].buffer.offset
atIndex: startSlot + i];
}
} }
} }