mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-16 18:59:48 +12:00
use depth stencil render target
This commit is contained in:
parent
9241306d4d
commit
d977f7ef85
4 changed files with 224 additions and 94 deletions
55
include/renderer_mtl/mtl_depth_stencil_cache.hpp
Normal file
55
include/renderer_mtl/mtl_depth_stencil_cache.hpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
#pragma once
|
||||
|
||||
#include "pica_to_mtl.hpp"
|
||||
|
||||
using namespace PICA;
|
||||
|
||||
namespace Metal {
|
||||
|
||||
struct DepthStencilHash {
|
||||
bool depthWrite;
|
||||
u8 depthFunc;
|
||||
};
|
||||
|
||||
class DepthStencilCache {
|
||||
public:
|
||||
DepthStencilCache() = default;
|
||||
|
||||
~DepthStencilCache() {
|
||||
clear();
|
||||
}
|
||||
|
||||
void set(MTL::Device* dev) {
|
||||
device = dev;
|
||||
}
|
||||
|
||||
MTL::DepthStencilState* get(DepthStencilHash hash) {
|
||||
u8 intHash = hash.depthWrite | (hash.depthFunc << 1);
|
||||
auto& depthStencilState = depthStencilCache[intHash];
|
||||
if (!depthStencilState) {
|
||||
MTL::DepthStencilDescriptor* desc = MTL::DepthStencilDescriptor::alloc()->init();
|
||||
desc->setDepthWriteEnabled(hash.depthWrite);
|
||||
desc->setDepthCompareFunction(toMTLCompareFunc(hash.depthFunc));
|
||||
|
||||
depthStencilState = device->newDepthStencilState(desc);
|
||||
|
||||
desc->release();
|
||||
}
|
||||
|
||||
return depthStencilState;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
for (auto& pair : depthStencilCache) {
|
||||
pair.second->release();
|
||||
}
|
||||
depthStencilCache.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<u8, MTL::DepthStencilState*> depthStencilCache;
|
||||
|
||||
MTL::Device* device;
|
||||
};
|
||||
|
||||
} // namespace Metal
|
|
@ -20,8 +20,25 @@ inline MTL::PixelFormat toMTLPixelFormatDepth(DepthFmt format) {
|
|||
case DepthFmt::Depth16: return MTL::PixelFormatDepth16Unorm;
|
||||
case DepthFmt::Unknown1: return MTL::PixelFormatInvalid;
|
||||
case DepthFmt::Depth24: return MTL::PixelFormatDepth32Float; // TODO: is this okay?
|
||||
case DepthFmt::Depth24Stencil8: return MTL::PixelFormatDepth24Unorm_Stencil8;
|
||||
// Apple sillicon doesn't support 24-bit depth buffers, so we use 32-bit instead
|
||||
case DepthFmt::Depth24Stencil8: return MTL::PixelFormatDepth32Float_Stencil8;
|
||||
}
|
||||
}
|
||||
|
||||
inline MTL::CompareFunction toMTLCompareFunc(u8 func) {
|
||||
switch (func) {
|
||||
case 0: return MTL::CompareFunctionNever;
|
||||
case 1: return MTL::CompareFunctionAlways;
|
||||
case 2: return MTL::CompareFunctionEqual;
|
||||
case 3: return MTL::CompareFunctionNotEqual;
|
||||
case 4: return MTL::CompareFunctionLess;
|
||||
case 5: return MTL::CompareFunctionLessEqual;
|
||||
case 6: return MTL::CompareFunctionGreater;
|
||||
case 7: return MTL::CompareFunctionGreaterEqual;
|
||||
default: panic("Unknown compare function %u", func);
|
||||
}
|
||||
|
||||
return MTL::CompareFunctionAlways;
|
||||
}
|
||||
|
||||
} // namespace PICA
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "texture.hpp"
|
||||
#include "render_target.hpp"
|
||||
#include "mtl_pipeline_cache.hpp"
|
||||
#include "mtl_depth_stencil_cache.hpp"
|
||||
// HACK: use the OpenGL cache
|
||||
#include "../renderer_gl/surface_cache.hpp"
|
||||
|
||||
|
@ -41,6 +42,7 @@ class RendererMTL final : public Renderer {
|
|||
SurfaceCache<Metal::Texture, 256, true> textureCache;
|
||||
Metal::PipelineCache blitPipelineCache;
|
||||
Metal::PipelineCache drawPipelineCache;
|
||||
Metal::DepthStencilCache depthStencilCache;
|
||||
|
||||
// Helpers
|
||||
MTL::SamplerState* basicSampler;
|
||||
|
@ -58,6 +60,7 @@ class RendererMTL final : public Renderer {
|
|||
}
|
||||
|
||||
std::optional<Metal::ColorRenderTarget> getColorRenderTarget(u32 addr, PICA::ColorFmt format, u32 width, u32 height, bool createIfnotFound = true);
|
||||
Metal::DepthStencilRenderTarget& getDepthRenderTarget();
|
||||
MTL::Texture* getTexture(Metal::Texture& tex);
|
||||
void setupTextureEnvState(MTL::RenderCommandEncoder* encoder);
|
||||
void bindTexturesToSlots(MTL::RenderCommandEncoder* encoder);
|
||||
|
|
|
@ -24,9 +24,9 @@ RendererMTL::RendererMTL(GPU& gpu, const std::array<u32, regNum>& internalRegs,
|
|||
RendererMTL::~RendererMTL() {}
|
||||
|
||||
void RendererMTL::reset() {
|
||||
colorRenderTargetCache.reset();
|
||||
depthStencilRenderTargetCache.reset();
|
||||
textureCache.reset();
|
||||
colorRenderTargetCache.reset();
|
||||
depthStencilRenderTargetCache.reset();
|
||||
textureCache.reset();
|
||||
|
||||
// TODO: implement
|
||||
Helpers::warn("RendererMTL::reset not implemented");
|
||||
|
@ -38,45 +38,45 @@ void RendererMTL::display() {
|
|||
CA::MetalDrawable* drawable = metalLayer->nextDrawable();
|
||||
|
||||
MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
||||
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = renderPassDescriptor->colorAttachments()->object(0);
|
||||
colorAttachment->setTexture(drawable->texture());
|
||||
colorAttachment->setLoadAction(MTL::LoadActionClear);
|
||||
colorAttachment->setClearColor(MTL::ClearColor{0.0f, 0.0f, 0.0f, 1.0f});
|
||||
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
||||
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = renderPassDescriptor->colorAttachments()->object(0);
|
||||
colorAttachment->setTexture(drawable->texture());
|
||||
colorAttachment->setLoadAction(MTL::LoadActionClear);
|
||||
colorAttachment->setClearColor(MTL::ClearColor{0.0f, 0.0f, 0.0f, 1.0f});
|
||||
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
||||
|
||||
MTL::RenderCommandEncoder* renderCommandEncoder = commandBuffer->renderCommandEncoder(renderPassDescriptor);
|
||||
renderCommandEncoder->setRenderPipelineState(displayPipeline);
|
||||
renderCommandEncoder->setFragmentSamplerState(basicSampler, 0);
|
||||
MTL::RenderCommandEncoder* renderCommandEncoder = commandBuffer->renderCommandEncoder(renderPassDescriptor);
|
||||
renderCommandEncoder->setRenderPipelineState(displayPipeline);
|
||||
renderCommandEncoder->setFragmentSamplerState(basicSampler, 0);
|
||||
|
||||
using namespace PICA::ExternalRegs;
|
||||
|
||||
// Top screen
|
||||
{
|
||||
const u32 topActiveFb = externalRegs[Framebuffer0Select] & 1;
|
||||
const u32 topScreenAddr = externalRegs[topActiveFb == 0 ? Framebuffer0AFirstAddr : Framebuffer0ASecondAddr];
|
||||
auto topScreen = colorRenderTargetCache.findFromAddress(topScreenAddr);
|
||||
const u32 topActiveFb = externalRegs[Framebuffer0Select] & 1;
|
||||
const u32 topScreenAddr = externalRegs[topActiveFb == 0 ? Framebuffer0AFirstAddr : Framebuffer0ASecondAddr];
|
||||
auto topScreen = colorRenderTargetCache.findFromAddress(topScreenAddr);
|
||||
|
||||
if (topScreen) {
|
||||
renderCommandEncoder->setViewport(MTL::Viewport{0, 0, 400, 240, 0.0f, 1.0f});
|
||||
renderCommandEncoder->setFragmentTexture(topScreen->get().texture, 0);
|
||||
renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangleStrip, NS::UInteger(0), NS::UInteger(4));
|
||||
}
|
||||
if (topScreen) {
|
||||
renderCommandEncoder->setViewport(MTL::Viewport{0, 0, 400, 240, 0.0f, 1.0f});
|
||||
renderCommandEncoder->setFragmentTexture(topScreen->get().texture, 0);
|
||||
renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangleStrip, NS::UInteger(0), NS::UInteger(4));
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom screen
|
||||
{
|
||||
const u32 bottomActiveFb = externalRegs[Framebuffer1Select] & 1;
|
||||
const u32 bottomScreenAddr = externalRegs[bottomActiveFb == 0 ? Framebuffer1AFirstAddr : Framebuffer1ASecondAddr];
|
||||
auto bottomScreen = colorRenderTargetCache.findFromAddress(bottomScreenAddr);
|
||||
const u32 bottomActiveFb = externalRegs[Framebuffer1Select] & 1;
|
||||
const u32 bottomScreenAddr = externalRegs[bottomActiveFb == 0 ? Framebuffer1AFirstAddr : Framebuffer1ASecondAddr];
|
||||
auto bottomScreen = colorRenderTargetCache.findFromAddress(bottomScreenAddr);
|
||||
|
||||
if (bottomScreen) {
|
||||
renderCommandEncoder->setViewport(MTL::Viewport{40, 240, 320, 240, 0.0f, 1.0f});
|
||||
renderCommandEncoder->setFragmentTexture(bottomScreen->get().texture, 0);
|
||||
renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangleStrip, NS::UInteger(0), NS::UInteger(4));
|
||||
}
|
||||
if (bottomScreen) {
|
||||
renderCommandEncoder->setViewport(MTL::Viewport{40, 240, 320, 240, 0.0f, 1.0f});
|
||||
renderCommandEncoder->setFragmentTexture(bottomScreen->get().texture, 0);
|
||||
renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangleStrip, NS::UInteger(0), NS::UInteger(4));
|
||||
}
|
||||
}
|
||||
|
||||
renderCommandEncoder->endEncoding();
|
||||
renderCommandEncoder->endEncoding();
|
||||
|
||||
commandBuffer->presentDrawable(drawable);
|
||||
commandBuffer->commit();
|
||||
|
@ -135,68 +135,71 @@ void RendererMTL::initGraphicsContext(SDL_Window* window) {
|
|||
MTL::Function* fragmentDrawFunction = library->newFunction(NS::String::string("fragmentDraw", NS::ASCIIStringEncoding));
|
||||
|
||||
// -------- Vertex descriptor --------
|
||||
MTL::VertexDescriptor* vertexDescriptor = MTL::VertexDescriptor::alloc()->init();
|
||||
MTL::VertexDescriptor* vertexDescriptor = MTL::VertexDescriptor::alloc()->init();
|
||||
|
||||
// Position
|
||||
MTL::VertexAttributeDescriptor* positionAttribute = vertexDescriptor->attributes()->object(0);
|
||||
positionAttribute->setFormat(MTL::VertexFormatFloat4);
|
||||
positionAttribute->setOffset(offsetof(Vertex, s.positions));
|
||||
positionAttribute->setBufferIndex(VERTEX_BUFFER_BINDING_INDEX);
|
||||
// Position
|
||||
MTL::VertexAttributeDescriptor* positionAttribute = vertexDescriptor->attributes()->object(0);
|
||||
positionAttribute->setFormat(MTL::VertexFormatFloat4);
|
||||
positionAttribute->setOffset(offsetof(Vertex, s.positions));
|
||||
positionAttribute->setBufferIndex(VERTEX_BUFFER_BINDING_INDEX);
|
||||
|
||||
// Quaternion
|
||||
MTL::VertexAttributeDescriptor* quaternionAttribute = vertexDescriptor->attributes()->object(1);
|
||||
quaternionAttribute->setFormat(MTL::VertexFormatFloat4);
|
||||
quaternionAttribute->setOffset(offsetof(Vertex, s.quaternion));
|
||||
quaternionAttribute->setBufferIndex(VERTEX_BUFFER_BINDING_INDEX);
|
||||
// Quaternion
|
||||
MTL::VertexAttributeDescriptor* quaternionAttribute = vertexDescriptor->attributes()->object(1);
|
||||
quaternionAttribute->setFormat(MTL::VertexFormatFloat4);
|
||||
quaternionAttribute->setOffset(offsetof(Vertex, s.quaternion));
|
||||
quaternionAttribute->setBufferIndex(VERTEX_BUFFER_BINDING_INDEX);
|
||||
|
||||
// Color
|
||||
MTL::VertexAttributeDescriptor* colorAttribute = vertexDescriptor->attributes()->object(2);
|
||||
colorAttribute->setFormat(MTL::VertexFormatFloat4);
|
||||
colorAttribute->setOffset(offsetof(Vertex, s.colour));
|
||||
colorAttribute->setBufferIndex(VERTEX_BUFFER_BINDING_INDEX);
|
||||
// Color
|
||||
MTL::VertexAttributeDescriptor* colorAttribute = vertexDescriptor->attributes()->object(2);
|
||||
colorAttribute->setFormat(MTL::VertexFormatFloat4);
|
||||
colorAttribute->setOffset(offsetof(Vertex, s.colour));
|
||||
colorAttribute->setBufferIndex(VERTEX_BUFFER_BINDING_INDEX);
|
||||
|
||||
// Texture coordinate 0
|
||||
MTL::VertexAttributeDescriptor* texCoord0Attribute = vertexDescriptor->attributes()->object(3);
|
||||
texCoord0Attribute->setFormat(MTL::VertexFormatFloat2);
|
||||
texCoord0Attribute->setOffset(offsetof(Vertex, s.texcoord0));
|
||||
texCoord0Attribute->setBufferIndex(VERTEX_BUFFER_BINDING_INDEX);
|
||||
// Texture coordinate 0
|
||||
MTL::VertexAttributeDescriptor* texCoord0Attribute = vertexDescriptor->attributes()->object(3);
|
||||
texCoord0Attribute->setFormat(MTL::VertexFormatFloat2);
|
||||
texCoord0Attribute->setOffset(offsetof(Vertex, s.texcoord0));
|
||||
texCoord0Attribute->setBufferIndex(VERTEX_BUFFER_BINDING_INDEX);
|
||||
|
||||
// Texture coordinate 1
|
||||
MTL::VertexAttributeDescriptor* texCoord1Attribute = vertexDescriptor->attributes()->object(4);
|
||||
texCoord1Attribute->setFormat(MTL::VertexFormatFloat2);
|
||||
texCoord1Attribute->setOffset(offsetof(Vertex, s.texcoord1));
|
||||
texCoord1Attribute->setBufferIndex(VERTEX_BUFFER_BINDING_INDEX);
|
||||
// Texture coordinate 1
|
||||
MTL::VertexAttributeDescriptor* texCoord1Attribute = vertexDescriptor->attributes()->object(4);
|
||||
texCoord1Attribute->setFormat(MTL::VertexFormatFloat2);
|
||||
texCoord1Attribute->setOffset(offsetof(Vertex, s.texcoord1));
|
||||
texCoord1Attribute->setBufferIndex(VERTEX_BUFFER_BINDING_INDEX);
|
||||
|
||||
// Texture coordinate 0 W
|
||||
MTL::VertexAttributeDescriptor* texCoord0WAttribute = vertexDescriptor->attributes()->object(5);
|
||||
texCoord0WAttribute->setFormat(MTL::VertexFormatFloat);
|
||||
texCoord0WAttribute->setOffset(offsetof(Vertex, s.texcoord0_w));
|
||||
texCoord0WAttribute->setBufferIndex(VERTEX_BUFFER_BINDING_INDEX);
|
||||
// Texture coordinate 0 W
|
||||
MTL::VertexAttributeDescriptor* texCoord0WAttribute = vertexDescriptor->attributes()->object(5);
|
||||
texCoord0WAttribute->setFormat(MTL::VertexFormatFloat);
|
||||
texCoord0WAttribute->setOffset(offsetof(Vertex, s.texcoord0_w));
|
||||
texCoord0WAttribute->setBufferIndex(VERTEX_BUFFER_BINDING_INDEX);
|
||||
|
||||
// View
|
||||
MTL::VertexAttributeDescriptor* viewAttribute = vertexDescriptor->attributes()->object(6);
|
||||
viewAttribute->setFormat(MTL::VertexFormatFloat3);
|
||||
viewAttribute->setOffset(offsetof(Vertex, s.view));
|
||||
viewAttribute->setBufferIndex(VERTEX_BUFFER_BINDING_INDEX);
|
||||
// View
|
||||
MTL::VertexAttributeDescriptor* viewAttribute = vertexDescriptor->attributes()->object(6);
|
||||
viewAttribute->setFormat(MTL::VertexFormatFloat3);
|
||||
viewAttribute->setOffset(offsetof(Vertex, s.view));
|
||||
viewAttribute->setBufferIndex(VERTEX_BUFFER_BINDING_INDEX);
|
||||
|
||||
// Texture coordinate 2
|
||||
MTL::VertexAttributeDescriptor* texCoord2Attribute = vertexDescriptor->attributes()->object(7);
|
||||
texCoord2Attribute->setFormat(MTL::VertexFormatFloat2);
|
||||
texCoord2Attribute->setOffset(offsetof(Vertex, s.texcoord2));
|
||||
texCoord2Attribute->setBufferIndex(VERTEX_BUFFER_BINDING_INDEX);
|
||||
// Texture coordinate 2
|
||||
MTL::VertexAttributeDescriptor* texCoord2Attribute = vertexDescriptor->attributes()->object(7);
|
||||
texCoord2Attribute->setFormat(MTL::VertexFormatFloat2);
|
||||
texCoord2Attribute->setOffset(offsetof(Vertex, s.texcoord2));
|
||||
texCoord2Attribute->setBufferIndex(VERTEX_BUFFER_BINDING_INDEX);
|
||||
|
||||
MTL::VertexBufferLayoutDescriptor* vertexBufferLayout = vertexDescriptor->layouts()->object(VERTEX_BUFFER_BINDING_INDEX);
|
||||
vertexBufferLayout->setStride(sizeof(Vertex));
|
||||
vertexBufferLayout->setStepFunction(MTL::VertexStepFunctionPerVertex);
|
||||
vertexBufferLayout->setStepRate(1);
|
||||
MTL::VertexBufferLayoutDescriptor* vertexBufferLayout = vertexDescriptor->layouts()->object(VERTEX_BUFFER_BINDING_INDEX);
|
||||
vertexBufferLayout->setStride(sizeof(Vertex));
|
||||
vertexBufferLayout->setStepFunction(MTL::VertexStepFunctionPerVertex);
|
||||
vertexBufferLayout->setStepRate(1);
|
||||
|
||||
drawPipelineCache.set(device, vertexDrawFunction, fragmentDrawFunction, vertexDescriptor);
|
||||
|
||||
// Depth stencil cache
|
||||
depthStencilCache.set(device);
|
||||
}
|
||||
|
||||
void RendererMTL::clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control) {
|
||||
createCommandBufferIfNeeded();
|
||||
createCommandBufferIfNeeded();
|
||||
|
||||
const auto color = colorRenderTargetCache.findFromAddress(startAddress);
|
||||
const auto color = colorRenderTargetCache.findFromAddress(startAddress);
|
||||
if (color) {
|
||||
const float r = Helpers::getBits<24, 8>(value) / 255.0f;
|
||||
const float g = Helpers::getBits<16, 8>(value) / 255.0f;
|
||||
|
@ -222,9 +225,9 @@ void RendererMTL::clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 c
|
|||
}
|
||||
|
||||
void RendererMTL::displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, u32 outputSize, u32 flags) {
|
||||
createCommandBufferIfNeeded();
|
||||
createCommandBufferIfNeeded();
|
||||
|
||||
const u32 inputWidth = inputSize & 0xffff;
|
||||
const u32 inputWidth = inputSize & 0xffff;
|
||||
const u32 inputHeight = inputSize >> 16;
|
||||
const auto inputFormat = ToColorFormat(Helpers::getBits<8, 3>(flags));
|
||||
const auto outputFormat = ToColorFormat(Helpers::getBits<12, 3>(flags));
|
||||
|
@ -287,28 +290,67 @@ void RendererMTL::textureCopy(u32 inputAddr, u32 outputAddr, u32 totalBytes, u32
|
|||
void RendererMTL::drawVertices(PICA::PrimType primType, std::span<const PICA::Vertex> vertices) {
|
||||
createCommandBufferIfNeeded();
|
||||
|
||||
auto renderTarget = getColorRenderTarget(colourBufferLoc, colourBufferFormat, fbSize[0], fbSize[1]);
|
||||
// Color
|
||||
auto colorRenderTarget = getColorRenderTarget(colourBufferLoc, colourBufferFormat, fbSize[0], fbSize[1]);
|
||||
|
||||
// Depth stencil
|
||||
const u32 depthControl = regs[PICA::InternalRegs::DepthAndColorMask];
|
||||
const bool depthWrite = regs[PICA::InternalRegs::DepthBufferWrite];
|
||||
const bool depthTestEnable = depthControl & 0x1;
|
||||
const bool depthWriteEnable = Helpers::getBit<12>(depthControl);
|
||||
const u8 depthFunc = Helpers::getBits<4, 3>(depthControl);
|
||||
const u8 colorMask = Helpers::getBits<8, 4>(depthControl);
|
||||
// gl.setColourMask(colorMask & 0x1, colorMask & 0x2, colorMask & 0x4, colorMask & 0x8);
|
||||
|
||||
const u32 stencilConfig = regs[PICA::InternalRegs::StencilTest];
|
||||
const bool stencilEnable = Helpers::getBit<0>(stencilConfig);
|
||||
|
||||
std::optional<Metal::DepthStencilRenderTarget> depthStencilRenderTarget = std::nullopt;
|
||||
Metal::DepthStencilHash depthStencilHash{false, 1};
|
||||
if (depthTestEnable) {
|
||||
depthStencilHash.depthWrite = depthWriteEnable && depthWrite;
|
||||
depthStencilHash.depthFunc = depthFunc;
|
||||
depthStencilRenderTarget = getDepthRenderTarget();
|
||||
} else {
|
||||
if (depthWriteEnable) {
|
||||
depthStencilHash.depthWrite = true;
|
||||
depthStencilRenderTarget = getDepthRenderTarget();
|
||||
} else if (stencilEnable) {
|
||||
depthStencilRenderTarget = getDepthRenderTarget();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: stencil tests
|
||||
|
||||
// TODO: don't begin a new render pass every time
|
||||
MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
||||
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = renderPassDescriptor->colorAttachments()->object(0);
|
||||
colorAttachment->setTexture(renderTarget->texture);
|
||||
colorAttachment->setTexture(colorRenderTarget->texture);
|
||||
colorAttachment->setLoadAction(MTL::LoadActionLoad);
|
||||
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
||||
if (depthStencilRenderTarget) {
|
||||
MTL::RenderPassDepthAttachmentDescriptor* depthAttachment = renderPassDescriptor->depthAttachment();
|
||||
depthAttachment->setTexture(depthStencilRenderTarget->texture);
|
||||
depthAttachment->setLoadAction(MTL::LoadActionLoad);
|
||||
depthAttachment->setStoreAction(MTL::StoreActionStore);
|
||||
}
|
||||
|
||||
// Pipeline
|
||||
Metal::PipelineHash hash{renderTarget->format, PICA::DepthFmt::Unknown1};
|
||||
Metal::PipelineHash hash{colorRenderTarget->format, DepthFmt::Unknown1};
|
||||
if (depthStencilRenderTarget) {
|
||||
hash.depthFmt = depthStencilRenderTarget->format;
|
||||
}
|
||||
MTL::RenderPipelineState* pipeline = drawPipelineCache.get(hash);
|
||||
|
||||
MTL::RenderCommandEncoder* renderCommandEncoder = commandBuffer->renderCommandEncoder(renderPassDescriptor);
|
||||
renderCommandEncoder->setRenderPipelineState(pipeline);
|
||||
// If size is < 4KB, use inline vertex data, otherwise use a buffer
|
||||
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 {
|
||||
// TODO: cache this buffer
|
||||
MTL::Buffer* vertexBuffer = device->newBuffer(vertices.data(), vertices.size_bytes(), MTL::ResourceStorageModeShared);
|
||||
renderCommandEncoder->setVertexBuffer(vertexBuffer, 0, VERTEX_BUFFER_BINDING_INDEX);
|
||||
// TODO: cache this buffer
|
||||
MTL::Buffer* vertexBuffer = device->newBuffer(vertices.data(), vertices.size_bytes(), MTL::ResourceStorageModeShared);
|
||||
renderCommandEncoder->setVertexBuffer(vertexBuffer, 0, VERTEX_BUFFER_BINDING_INDEX);
|
||||
}
|
||||
|
||||
// Bind resources
|
||||
|
@ -329,15 +371,17 @@ void RendererMTL::screenshot(const std::string& name) {
|
|||
}
|
||||
|
||||
void RendererMTL::deinitGraphicsContext() {
|
||||
colorRenderTargetCache.reset();
|
||||
depthStencilRenderTargetCache.reset();
|
||||
textureCache.reset();
|
||||
colorRenderTargetCache.reset();
|
||||
depthStencilRenderTargetCache.reset();
|
||||
textureCache.reset();
|
||||
|
||||
// TODO: implement
|
||||
Helpers::warn("RendererMTL::deinitGraphicsContext not implemented");
|
||||
}
|
||||
|
||||
std::optional<Metal::ColorRenderTarget> RendererMTL::getColorRenderTarget(u32 addr, PICA::ColorFmt format, u32 width, u32 height, bool createIfnotFound) {
|
||||
std::optional<Metal::ColorRenderTarget> RendererMTL::getColorRenderTarget(
|
||||
u32 addr, PICA::ColorFmt format, u32 width, u32 height, bool createIfnotFound
|
||||
) {
|
||||
// Try to find an already existing buffer that contains the provided address
|
||||
// This is a more relaxed check compared to getColourFBO as display transfer/texcopy may refer to
|
||||
// subrect of a surface and in case of texcopy we don't know the format of the surface.
|
||||
|
@ -356,6 +400,17 @@ std::optional<Metal::ColorRenderTarget> RendererMTL::getColorRenderTarget(u32 ad
|
|||
return colorRenderTargetCache.add(sampleBuffer);
|
||||
}
|
||||
|
||||
Metal::DepthStencilRenderTarget& RendererMTL::getDepthRenderTarget() {
|
||||
Metal::DepthStencilRenderTarget sampleBuffer(device, depthBufferLoc, depthBufferFormat, fbSize[0], fbSize[1]);
|
||||
auto buffer = depthStencilRenderTargetCache.find(sampleBuffer);
|
||||
|
||||
if (buffer.has_value()) {
|
||||
return buffer.value().get();
|
||||
} else {
|
||||
return depthStencilRenderTargetCache.add(sampleBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
MTL::Texture* RendererMTL::getTexture(Metal::Texture& tex) {
|
||||
auto buffer = textureCache.find(tex);
|
||||
|
||||
|
@ -377,12 +432,12 @@ void RendererMTL::setupTextureEnvState(MTL::RenderCommandEncoder* encoder) {
|
|||
};
|
||||
|
||||
struct {
|
||||
u32 textureEnvSourceRegs[6];
|
||||
u32 textureEnvOperandRegs[6];
|
||||
u32 textureEnvCombinerRegs[6];
|
||||
u32 textureEnvScaleRegs[6];
|
||||
u32 textureEnvSourceRegs[6];
|
||||
u32 textureEnvOperandRegs[6];
|
||||
u32 textureEnvCombinerRegs[6];
|
||||
u32 textureEnvScaleRegs[6];
|
||||
} envState;
|
||||
u32 textureEnvColourRegs[6];
|
||||
u32 textureEnvColourRegs[6];
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
const u32 ioBase = ioBases[i];
|
||||
|
|
Loading…
Add table
Reference in a new issue