mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-16 18:59:48 +12:00
store vertices in 1 big buffer
This commit is contained in:
parent
ea56f45fc2
commit
720882efeb
3 changed files with 81 additions and 3 deletions
71
include/renderer_mtl/mtl_vertex_buffer_cache.hpp
Normal file
71
include/renderer_mtl/mtl_vertex_buffer_cache.hpp
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include "pica_to_mtl.hpp"
|
||||||
|
|
||||||
|
using namespace PICA;
|
||||||
|
|
||||||
|
namespace Metal {
|
||||||
|
|
||||||
|
struct BufferHandle {
|
||||||
|
MTL::Buffer* buffer;
|
||||||
|
size_t offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 64MB buffer for caching vertex data
|
||||||
|
#define CACHE_BUFFER_SIZE 64 * 1024 * 1024
|
||||||
|
|
||||||
|
class VertexBufferCache {
|
||||||
|
public:
|
||||||
|
VertexBufferCache() = default;
|
||||||
|
|
||||||
|
~VertexBufferCache() {
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(MTL::Device* dev) {
|
||||||
|
device = dev;
|
||||||
|
buffer = device->newBuffer(CACHE_BUFFER_SIZE, MTL::ResourceStorageModeShared);
|
||||||
|
}
|
||||||
|
|
||||||
|
void endFrame() {
|
||||||
|
ptr = 0;
|
||||||
|
for (auto buffer : additionalAllocations) {
|
||||||
|
buffer->release();
|
||||||
|
}
|
||||||
|
additionalAllocations.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferHandle get(const std::span<const PICA::Vertex>& vertices) {
|
||||||
|
// If the vertex buffer is too large, just create a new one
|
||||||
|
if (ptr + vertices.size_bytes() > CACHE_BUFFER_SIZE) {
|
||||||
|
MTL::Buffer* newBuffer = device->newBuffer(vertices.data(), vertices.size_bytes(), MTL::ResourceStorageModeShared);
|
||||||
|
additionalAllocations.push_back(newBuffer);
|
||||||
|
Helpers::warn("Vertex buffer doesn't have enough space, creating a new buffer");
|
||||||
|
|
||||||
|
return BufferHandle{newBuffer, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the data into the buffer
|
||||||
|
memcpy((char*)buffer->contents() + ptr, vertices.data(), vertices.size_bytes());
|
||||||
|
|
||||||
|
size_t oldPtr = ptr;
|
||||||
|
ptr += vertices.size_bytes();
|
||||||
|
|
||||||
|
return BufferHandle{buffer, oldPtr};
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
endFrame();
|
||||||
|
buffer->release();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MTL::Buffer* buffer;
|
||||||
|
size_t ptr = 0;
|
||||||
|
std::vector<MTL::Buffer*> additionalAllocations;
|
||||||
|
|
||||||
|
MTL::Device* device;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Metal
|
|
@ -6,6 +6,7 @@
|
||||||
#include "render_target.hpp"
|
#include "render_target.hpp"
|
||||||
#include "mtl_pipeline_cache.hpp"
|
#include "mtl_pipeline_cache.hpp"
|
||||||
#include "mtl_depth_stencil_cache.hpp"
|
#include "mtl_depth_stencil_cache.hpp"
|
||||||
|
#include "mtl_vertex_buffer_cache.hpp"
|
||||||
// HACK: use the OpenGL cache
|
// HACK: use the OpenGL cache
|
||||||
#include "../renderer_gl/surface_cache.hpp"
|
#include "../renderer_gl/surface_cache.hpp"
|
||||||
|
|
||||||
|
@ -43,6 +44,7 @@ class RendererMTL final : public Renderer {
|
||||||
Metal::PipelineCache blitPipelineCache;
|
Metal::PipelineCache blitPipelineCache;
|
||||||
Metal::PipelineCache drawPipelineCache;
|
Metal::PipelineCache drawPipelineCache;
|
||||||
Metal::DepthStencilCache depthStencilCache;
|
Metal::DepthStencilCache depthStencilCache;
|
||||||
|
Metal::VertexBufferCache vertexBufferCache;
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
MTL::SamplerState* basicSampler;
|
MTL::SamplerState* basicSampler;
|
||||||
|
|
|
@ -78,6 +78,9 @@ void RendererMTL::display() {
|
||||||
|
|
||||||
commandBuffer->presentDrawable(drawable);
|
commandBuffer->presentDrawable(drawable);
|
||||||
commitCommandBuffer();
|
commitCommandBuffer();
|
||||||
|
|
||||||
|
// Inform the vertex buffer cache that the frame ended
|
||||||
|
vertexBufferCache.endFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererMTL::initGraphicsContext(SDL_Window* window) {
|
void RendererMTL::initGraphicsContext(SDL_Window* window) {
|
||||||
|
@ -191,6 +194,9 @@ void RendererMTL::initGraphicsContext(SDL_Window* window) {
|
||||||
|
|
||||||
// Depth stencil cache
|
// Depth stencil cache
|
||||||
depthStencilCache.set(device);
|
depthStencilCache.set(device);
|
||||||
|
|
||||||
|
// Vertex buffer cache
|
||||||
|
vertexBufferCache.set(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererMTL::clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control) {
|
void RendererMTL::clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control) {
|
||||||
|
@ -382,9 +388,8 @@ void RendererMTL::drawVertices(PICA::PrimType primType, std::span<const PICA::Ve
|
||||||
if (vertices.size_bytes() < 4 * 1024) {
|
if (vertices.size_bytes() < 4 * 1024) {
|
||||||
renderCommandEncoder->setVertexBytes(vertices.data(), vertices.size_bytes(), VERTEX_BUFFER_BINDING_INDEX);
|
renderCommandEncoder->setVertexBytes(vertices.data(), vertices.size_bytes(), VERTEX_BUFFER_BINDING_INDEX);
|
||||||
} else {
|
} else {
|
||||||
// TODO: cache this buffer
|
Metal::BufferHandle buffer = vertexBufferCache.get(vertices);
|
||||||
MTL::Buffer* vertexBuffer = device->newBuffer(vertices.data(), vertices.size_bytes(), MTL::ResourceStorageModeShared);
|
renderCommandEncoder->setVertexBuffer(buffer.buffer, buffer.offset, VERTEX_BUFFER_BINDING_INDEX);
|
||||||
renderCommandEncoder->setVertexBuffer(vertexBuffer, 0, VERTEX_BUFFER_BINDING_INDEX);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind resources
|
// Bind resources
|
||||||
|
|
Loading…
Add table
Reference in a new issue