mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-16 18:59:48 +12:00
add: render target caches
This commit is contained in:
parent
67e3a1d8eb
commit
53c9611ac2
4 changed files with 85 additions and 1 deletions
77
include/renderer_mtl/render_target.hpp
Normal file
77
include/renderer_mtl/render_target.hpp
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
#pragma once
|
||||||
|
#include <array>
|
||||||
|
#include <string>
|
||||||
|
#include <Metal/Metal.hpp>
|
||||||
|
#include "PICA/regs.hpp"
|
||||||
|
#include "boost/icl/interval.hpp"
|
||||||
|
#include "helpers.hpp"
|
||||||
|
#include "math_util.hpp"
|
||||||
|
#include "opengl.hpp"
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using Interval = boost::icl::right_open_interval<T>;
|
||||||
|
|
||||||
|
namespace Metal {
|
||||||
|
|
||||||
|
struct RenderTarget {
|
||||||
|
MTL::Device* device;
|
||||||
|
|
||||||
|
u32 location;
|
||||||
|
PICA::TextureFmt format;
|
||||||
|
OpenGL::uvec2 size;
|
||||||
|
bool valid;
|
||||||
|
|
||||||
|
// Range of VRAM taken up by buffer
|
||||||
|
Interval<u32> range;
|
||||||
|
|
||||||
|
MTL::Texture* texture = nullptr;
|
||||||
|
|
||||||
|
RenderTarget() : valid(false) {}
|
||||||
|
|
||||||
|
RenderTarget(MTL::Device* dev, u32 loc, PICA::TextureFmt format, u32 x, u32 y, bool valid = true)
|
||||||
|
: device(dev), location(loc), format(format), size({x, y}), valid(valid) {
|
||||||
|
|
||||||
|
u64 endLoc = (u64)loc + sizeInBytes();
|
||||||
|
// Check if start and end are valid here
|
||||||
|
range = Interval<u32>(loc, (u32)endLoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Math::Rect<u32> getSubRect(u32 inputAddress, u32 width, u32 height) {
|
||||||
|
const u32 startOffset = (inputAddress - location) / sizePerPixel(format);
|
||||||
|
const u32 x0 = (startOffset % (size.x() * 8)) / 8;
|
||||||
|
const u32 y0 = (startOffset / (size.x() * 8)) * 8;
|
||||||
|
return Math::Rect<u32>{x0, y0, x0 + width, y0 + height};
|
||||||
|
}
|
||||||
|
|
||||||
|
// For 2 textures to "match" we only care about their locations, formats, and dimensions to match
|
||||||
|
// For other things, such as filtering mode, etc, we can just switch the attributes of the cached texture
|
||||||
|
bool matches(Texture& other) {
|
||||||
|
return location == other.location && format == other.format &&
|
||||||
|
size.x() == other.size.x() && size.y() == other.size.y();
|
||||||
|
}
|
||||||
|
|
||||||
|
void allocate() {
|
||||||
|
MTL::TextureDescriptor* descriptor = MTL::TextureDescriptor::alloc()->init();
|
||||||
|
descriptor->setTextureType(MTL::TextureType2D);
|
||||||
|
descriptor->setPixelFormat(MTL::PixelFormatRGBA8Unorm);
|
||||||
|
descriptor->setWidth(size.u());
|
||||||
|
descriptor->setHeight(size.v());
|
||||||
|
descriptor->setUsage(MTL::TextureUsageRenderTarget | MTL::TextureUsageShaderRead);
|
||||||
|
descriptor->setStorageMode(MTL::StorageModePrivate);
|
||||||
|
texture = device->newTexture(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void free() {
|
||||||
|
valid = false;
|
||||||
|
|
||||||
|
if (texture) {
|
||||||
|
texture->release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 sizeInBytes() {
|
||||||
|
return (size_t)size.x() * (size_t)size.y() * PICA::sizePerPixel(format);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Metal
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "renderer.hpp"
|
#include "renderer.hpp"
|
||||||
#include "texture.hpp"
|
#include "texture.hpp"
|
||||||
|
#include "render_target.hpp"
|
||||||
// HACK: use the OpenGL cache
|
// HACK: use the OpenGL cache
|
||||||
#include "../renderer_gl/surface_cache.hpp"
|
#include "../renderer_gl/surface_cache.hpp"
|
||||||
|
|
||||||
|
@ -34,6 +35,8 @@ class RendererMTL final : public Renderer {
|
||||||
MTL::CommandQueue* commandQueue;
|
MTL::CommandQueue* commandQueue;
|
||||||
|
|
||||||
// Caches
|
// Caches
|
||||||
|
SurfaceCache<Metal::Texture, 16, true> colorRenderTargetCache;
|
||||||
|
SurfaceCache<Metal::Texture, 16, true> depthStencilRenderTargetCache;
|
||||||
SurfaceCache<Metal::Texture, 256, true> textureCache;
|
SurfaceCache<Metal::Texture, 256, true> textureCache;
|
||||||
|
|
||||||
// HACK
|
// HACK
|
||||||
|
|
|
@ -18,6 +18,8 @@ RendererMTL::RendererMTL(GPU& gpu, const std::array<u32, regNum>& internalRegs,
|
||||||
RendererMTL::~RendererMTL() {}
|
RendererMTL::~RendererMTL() {}
|
||||||
|
|
||||||
void RendererMTL::reset() {
|
void RendererMTL::reset() {
|
||||||
|
colorRenderTargetCache.reset();
|
||||||
|
depthStencilRenderTargetCache.reset();
|
||||||
textureCache.reset();
|
textureCache.reset();
|
||||||
|
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
|
@ -233,6 +235,8 @@ void RendererMTL::screenshot(const std::string& name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererMTL::deinitGraphicsContext() {
|
void RendererMTL::deinitGraphicsContext() {
|
||||||
|
colorRenderTargetCache.reset();
|
||||||
|
depthStencilRenderTargetCache.reset();
|
||||||
textureCache.reset();
|
textureCache.reset();
|
||||||
|
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
|
|
|
@ -12,7 +12,7 @@ void Texture::allocate() {
|
||||||
descriptor->setPixelFormat(MTL::PixelFormatRGBA8Unorm);
|
descriptor->setPixelFormat(MTL::PixelFormatRGBA8Unorm);
|
||||||
descriptor->setWidth(size.u());
|
descriptor->setWidth(size.u());
|
||||||
descriptor->setHeight(size.v());
|
descriptor->setHeight(size.v());
|
||||||
descriptor->setUsage(MTL::TextureUsageShaderRead | MTL::TextureUsageShaderWrite);
|
descriptor->setUsage(MTL::TextureUsageShaderRead);
|
||||||
descriptor->setStorageMode(MTL::StorageModeShared); // TODO: use private + staging buffers?
|
descriptor->setStorageMode(MTL::StorageModeShared); // TODO: use private + staging buffers?
|
||||||
texture = device->newTexture(descriptor);
|
texture = device->newTexture(descriptor);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue