Skip to content

Commit

Permalink
First Metal cleanup & formatting pass
Browse files Browse the repository at this point in the history
  • Loading branch information
wheremyfoodat committed Nov 9, 2024
1 parent 4cc62d4 commit e1e5f39
Show file tree
Hide file tree
Showing 13 changed files with 1,068 additions and 1,086 deletions.
2 changes: 0 additions & 2 deletions include/renderer_gl/surface_cache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ template <typename SurfaceType, size_t capacity, bool evictOnOverflow = false>
class SurfaceCache {
// Vanilla std::optional can't hold actual references
using OptionalRef = std::optional<std::reference_wrapper<SurfaceType>>;
//static_assert(std::is_same<SurfaceType, ColourBuffer>() || std::is_same<SurfaceType, DepthBuffer>() ||
// std::is_same<SurfaceType, Texture>(), "Invalid surface type");

size_t size;
size_t evictionIndex;
Expand Down
130 changes: 64 additions & 66 deletions include/renderer_mtl/mtl_blit_pipeline_cache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,69 +7,67 @@
using namespace PICA;

namespace Metal {

struct BlitPipelineHash {
// Formats
ColorFmt colorFmt;
DepthFmt depthFmt;
};

// This pipeline only caches the pipeline with all of its color and depth attachment variations
class BlitPipelineCache {
public:
BlitPipelineCache() = default;

~BlitPipelineCache() {
reset();
vertexFunction->release();
fragmentFunction->release();
}

void set(MTL::Device* dev, MTL::Function* vert, MTL::Function* frag) {
device = dev;
vertexFunction = vert;
fragmentFunction = frag;
}

MTL::RenderPipelineState* get(BlitPipelineHash hash) {
u8 intHash = ((u8)hash.colorFmt << 3) | (u8)hash.depthFmt;
auto& pipeline = pipelineCache[intHash];
if (!pipeline) {
MTL::RenderPipelineDescriptor* desc = MTL::RenderPipelineDescriptor::alloc()->init();
desc->setVertexFunction(vertexFunction);
desc->setFragmentFunction(fragmentFunction);

auto colorAttachment = desc->colorAttachments()->object(0);
colorAttachment->setPixelFormat(toMTLPixelFormatColor(hash.colorFmt));

desc->setDepthAttachmentPixelFormat(toMTLPixelFormatDepth(hash.depthFmt));

NS::Error* error = nullptr;
desc->setLabel(toNSString("Blit pipeline"));
pipeline = device->newRenderPipelineState(desc, &error);
if (error) {
Helpers::panic("Error creating blit pipeline state: %s", error->description()->cString(NS::ASCIIStringEncoding));
}

desc->release();
}

return pipeline;
}

void reset() {
for (auto& pair : pipelineCache) {
pair.second->release();
}
pipelineCache.clear();
}

private:
std::map<u8, MTL::RenderPipelineState*> pipelineCache;

MTL::Device* device;
MTL::Function* vertexFunction;
MTL::Function* fragmentFunction;
};

} // namespace Metal
struct BlitPipelineHash {
// Formats
ColorFmt colorFmt;
DepthFmt depthFmt;
};

// This pipeline only caches the pipeline with all of its color and depth attachment variations
class BlitPipelineCache {
public:
BlitPipelineCache() = default;

~BlitPipelineCache() {
reset();
vertexFunction->release();
fragmentFunction->release();
}

void set(MTL::Device* dev, MTL::Function* vert, MTL::Function* frag) {
device = dev;
vertexFunction = vert;
fragmentFunction = frag;
}

MTL::RenderPipelineState* get(BlitPipelineHash hash) {
u8 intHash = ((u8)hash.colorFmt << 3) | (u8)hash.depthFmt;
auto& pipeline = pipelineCache[intHash];
if (!pipeline) {
MTL::RenderPipelineDescriptor* desc = MTL::RenderPipelineDescriptor::alloc()->init();
desc->setVertexFunction(vertexFunction);
desc->setFragmentFunction(fragmentFunction);

auto colorAttachment = desc->colorAttachments()->object(0);
colorAttachment->setPixelFormat(toMTLPixelFormatColor(hash.colorFmt));

desc->setDepthAttachmentPixelFormat(toMTLPixelFormatDepth(hash.depthFmt));

NS::Error* error = nullptr;
desc->setLabel(toNSString("Blit pipeline"));
pipeline = device->newRenderPipelineState(desc, &error);
if (error) {
Helpers::panic("Error creating blit pipeline state: %s", error->description()->cString(NS::ASCIIStringEncoding));
}

desc->release();
}

return pipeline;
}

void reset() {
for (auto& pair : pipelineCache) {
pair.second->release();
}
pipelineCache.clear();
}

private:
std::map<u8, MTL::RenderPipelineState*> pipelineCache;

MTL::Device* device;
MTL::Function* vertexFunction;
MTL::Function* fragmentFunction;
};
} // namespace Metal
104 changes: 51 additions & 53 deletions include/renderer_mtl/mtl_command_encoder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,54 @@
#include <Metal/Metal.hpp>

namespace Metal {

struct RenderState {
MTL::RenderPipelineState* renderPipelineState = nullptr;
MTL::DepthStencilState* depthStencilState = nullptr;
MTL::Texture* textures[3] = {nullptr};
MTL::SamplerState* samplerStates[3] = {nullptr};
};

class CommandEncoder {
public:
void newRenderCommandEncoder(MTL::RenderCommandEncoder* rce) {
renderCommandEncoder = rce;

// Reset the render state
renderState = RenderState{};
}

// Resource binding
void setRenderPipelineState(MTL::RenderPipelineState* renderPipelineState) {
if (renderPipelineState != renderState.renderPipelineState) {
renderCommandEncoder->setRenderPipelineState(renderPipelineState);
renderState.renderPipelineState = renderPipelineState;
}
}

void setDepthStencilState(MTL::DepthStencilState* depthStencilState) {
if (depthStencilState != renderState.depthStencilState) {
renderCommandEncoder->setDepthStencilState(depthStencilState);
renderState.depthStencilState = depthStencilState;
}
}

void setFragmentTexture(MTL::Texture* texture, u32 index) {
if (texture != renderState.textures[index]) {
renderCommandEncoder->setFragmentTexture(texture, index);
renderState.textures[index] = texture;
}
}

void setFragmentSamplerState(MTL::SamplerState* samplerState, u32 index) {
if (samplerState != renderState.samplerStates[index]) {
renderCommandEncoder->setFragmentSamplerState(samplerState, index);
renderState.samplerStates[index] = samplerState;
}
}

private:
MTL::RenderCommandEncoder* renderCommandEncoder = nullptr;

RenderState renderState;
};

} // namespace Metal
struct RenderState {
MTL::RenderPipelineState* renderPipelineState = nullptr;
MTL::DepthStencilState* depthStencilState = nullptr;
MTL::Texture* textures[3] = {nullptr};
MTL::SamplerState* samplerStates[3] = {nullptr};
};

class CommandEncoder {
public:
void newRenderCommandEncoder(MTL::RenderCommandEncoder* rce) {
renderCommandEncoder = rce;

// Reset the render state
renderState = RenderState{};
}

// Resource binding
void setRenderPipelineState(MTL::RenderPipelineState* renderPipelineState) {
if (renderPipelineState != renderState.renderPipelineState) {
renderCommandEncoder->setRenderPipelineState(renderPipelineState);
renderState.renderPipelineState = renderPipelineState;
}
}

void setDepthStencilState(MTL::DepthStencilState* depthStencilState) {
if (depthStencilState != renderState.depthStencilState) {
renderCommandEncoder->setDepthStencilState(depthStencilState);
renderState.depthStencilState = depthStencilState;
}
}

void setFragmentTexture(MTL::Texture* texture, u32 index) {
if (texture != renderState.textures[index]) {
renderCommandEncoder->setFragmentTexture(texture, index);
renderState.textures[index] = texture;
}
}

void setFragmentSamplerState(MTL::SamplerState* samplerState, u32 index) {
if (samplerState != renderState.samplerStates[index]) {
renderCommandEncoder->setFragmentSamplerState(samplerState, index);
renderState.samplerStates[index] = samplerState;
}
}

private:
MTL::RenderCommandEncoder* renderCommandEncoder = nullptr;

RenderState renderState;
};
} // namespace Metal
Loading

0 comments on commit e1e5f39

Please sign in to comment.