mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-07-20 22:02:59 +12:00
Merge pull request #745 from wheremyfoodat/ios
iOS driver & Metal renderer improvements
This commit is contained in:
commit
761f9264ba
16 changed files with 587 additions and 384 deletions
|
@ -55,6 +55,13 @@ struct EmulatorConfig {
|
|||
static constexpr bool audioEnabledDefault = false;
|
||||
#endif
|
||||
|
||||
// We default to OpenGL on all platforms other than iOS
|
||||
#if defined(PANDA3DS_IOS)
|
||||
static constexpr RendererType rendererDefault = RendererType::Metal;
|
||||
#else
|
||||
static constexpr RendererType rendererDefault = RendererType::OpenGL;
|
||||
#endif
|
||||
|
||||
bool shaderJitEnabled = shaderJitDefault;
|
||||
bool useUbershaders = ubershaderDefault;
|
||||
bool accelerateShaders = accelerateShadersDefault;
|
||||
|
@ -65,7 +72,7 @@ struct EmulatorConfig {
|
|||
bool forceShadergenForLights = true;
|
||||
int lightShadergenThreshold = 1;
|
||||
|
||||
RendererType rendererType = RendererType::OpenGL;
|
||||
RendererType rendererType = rendererDefault;
|
||||
Audio::DSPCore::Type dspType = Audio::DSPCore::Type::HLE;
|
||||
|
||||
bool sdCardInserted = true;
|
||||
|
|
6
include/ios_driver.h
Normal file
6
include/ios_driver.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
|
||||
void iosCreateEmulator();
|
||||
void iosRunFrame(CAMetalLayer* layer);
|
|
@ -86,6 +86,10 @@ class Renderer {
|
|||
// Called to notify the core to use OpenGL ES and not desktop GL
|
||||
virtual void setupGLES() {}
|
||||
|
||||
// Only relevant for Metal renderer on iOS
|
||||
// Passes a SwiftUI MTKView's layer (CAMetalLayer) to the renderer
|
||||
virtual void setMTKLayer(void* layer) {};
|
||||
|
||||
// This function is called on every draw call before parsing vertex data.
|
||||
// It is responsible for things like looking up which vertex/fragment shaders to use, recompiling them if they don't exist, choosing between
|
||||
// ubershaders and shadergen, and so on.
|
||||
|
|
|
@ -8,8 +8,9 @@
|
|||
#include "boost/icl/interval.hpp"
|
||||
#include "helpers.hpp"
|
||||
#include "math_util.hpp"
|
||||
#include "opengl.hpp"
|
||||
#include "renderer_mtl/pica_to_mtl.hpp"
|
||||
// TODO: remove dependency on OpenGL
|
||||
#include "opengl.hpp"
|
||||
|
||||
template <typename T>
|
||||
using Interval = boost::icl::right_open_interval<T>;
|
||||
|
@ -27,7 +28,8 @@ namespace Metal {
|
|||
// Range of VRAM taken up by buffer
|
||||
Interval<u32> range;
|
||||
|
||||
PICA::PixelFormatInfo formatInfo;
|
||||
PICA::MTLPixelFormatInfo formatInfo;
|
||||
MTL::Texture* base = nullptr;
|
||||
MTL::Texture* texture = nullptr;
|
||||
MTL::SamplerState* sampler = nullptr;
|
||||
|
||||
|
@ -52,22 +54,7 @@ namespace Metal {
|
|||
void free();
|
||||
u64 sizeInBytes();
|
||||
|
||||
u8 decodeTexelU8(u32 u, u32 v, PICA::TextureFmt fmt, std::span<const u8> data);
|
||||
u16 decodeTexelU16(u32 u, u32 v, PICA::TextureFmt fmt, std::span<const u8> data);
|
||||
u32 decodeTexelU32(u32 u, u32 v, PICA::TextureFmt fmt, std::span<const u8> data);
|
||||
|
||||
// Get the morton interleave offset of a texel based on its U and V values
|
||||
static u32 mortonInterleave(u32 u, u32 v);
|
||||
// Get the byte offset of texel (u, v) in the texture
|
||||
static u32 getSwizzledOffset(u32 u, u32 v, u32 width, u32 bytesPerPixel);
|
||||
static u32 getSwizzledOffset_4bpp(u32 u, u32 v, u32 width);
|
||||
|
||||
// Returns the format of this texture as a string
|
||||
std::string_view formatToString() { return PICA::textureFormatToString(format); }
|
||||
|
||||
// Returns the texel at coordinates (u, v) of an ETC1(A4) texture
|
||||
// TODO: Make hasAlpha a template parameter
|
||||
u32 getTexelETC(bool hasAlpha, u32 u, u32 v, u32 width, std::span<const u8> data);
|
||||
u32 decodeETC(u32 alpha, u32 u, u32 v, u64 colourData);
|
||||
};
|
||||
} // namespace Metal
|
||||
|
|
|
@ -3,31 +3,28 @@
|
|||
#include <Metal/Metal.hpp>
|
||||
|
||||
#include "PICA/regs.hpp"
|
||||
// TODO: remove dependency on OpenGL
|
||||
#include "opengl.hpp"
|
||||
|
||||
namespace PICA {
|
||||
struct PixelFormatInfo {
|
||||
struct MTLPixelFormatInfo {
|
||||
MTL::PixelFormat pixelFormat;
|
||||
size_t bytesPerTexel;
|
||||
void (*decoder)(OpenGL::uvec2, u32, u32, std::span<const u8>, u8*);
|
||||
|
||||
bool needsSwizzle = false;
|
||||
MTL::TextureSwizzleChannels swizzle{
|
||||
.red = MTL::TextureSwizzleRed,
|
||||
.green = MTL::TextureSwizzleGreen,
|
||||
.blue = MTL::TextureSwizzleBlue,
|
||||
.alpha = MTL::TextureSwizzleAlpha,
|
||||
};
|
||||
};
|
||||
|
||||
constexpr PixelFormatInfo pixelFormatInfos[14] = {
|
||||
{MTL::PixelFormatRGBA8Unorm, 4}, // RGBA8
|
||||
{MTL::PixelFormatRGBA8Unorm, 4}, // RGB8
|
||||
{MTL::PixelFormatBGR5A1Unorm, 2}, // RGBA5551
|
||||
{MTL::PixelFormatB5G6R5Unorm, 2}, // RGB565
|
||||
{MTL::PixelFormatABGR4Unorm, 2}, // RGBA4
|
||||
{MTL::PixelFormatRGBA8Unorm, 4}, // IA8
|
||||
{MTL::PixelFormatRG8Unorm, 2}, // RG8
|
||||
{MTL::PixelFormatRGBA8Unorm, 4}, // I8
|
||||
{MTL::PixelFormatA8Unorm, 1}, // A8
|
||||
{MTL::PixelFormatABGR4Unorm, 2}, // IA4
|
||||
{MTL::PixelFormatABGR4Unorm, 2}, // I4
|
||||
{MTL::PixelFormatA8Unorm, 1}, // A4
|
||||
{MTL::PixelFormatRGBA8Unorm, 4}, // ETC1
|
||||
{MTL::PixelFormatRGBA8Unorm, 4}, // ETC1A4
|
||||
};
|
||||
extern MTLPixelFormatInfo mtlPixelFormatInfos[14];
|
||||
|
||||
inline PixelFormatInfo getPixelFormatInfo(TextureFmt format) { return pixelFormatInfos[static_cast<int>(format)]; }
|
||||
void checkForMTLPixelFormatSupport(MTL::Device* device);
|
||||
inline MTLPixelFormatInfo getMTLPixelFormatInfo(TextureFmt format) { return mtlPixelFormatInfos[static_cast<int>(format)]; }
|
||||
|
||||
inline MTL::PixelFormat toMTLPixelFormatColor(ColorFmt format) {
|
||||
switch (format) {
|
||||
|
@ -35,7 +32,11 @@ namespace PICA {
|
|||
case ColorFmt::RGB8: return MTL::PixelFormatRGBA8Unorm;
|
||||
case ColorFmt::RGBA5551: return MTL::PixelFormatRGBA8Unorm; // TODO: use MTL::PixelFormatBGR5A1Unorm?
|
||||
case ColorFmt::RGB565: return MTL::PixelFormatRGBA8Unorm; // TODO: use MTL::PixelFormatB5G6R5Unorm?
|
||||
#ifdef PANDA3DS_IOS
|
||||
case ColorFmt::RGBA4: return MTL::PixelFormatRGBA8Unorm; // IOS + Metal doesn't support AGBR4 properly, at least on simulator
|
||||
#else
|
||||
case ColorFmt::RGBA4: return MTL::PixelFormatABGR4Unorm;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,11 +42,13 @@ class RendererMTL final : public Renderer {
|
|||
virtual void initGraphicsContext([[maybe_unused]] GL::Context* context) override {}
|
||||
#endif
|
||||
|
||||
private:
|
||||
CA::MetalLayer* metalLayer;
|
||||
virtual void setMTKLayer(void* layer) override;
|
||||
|
||||
MTL::Device* device;
|
||||
MTL::CommandQueue* commandQueue;
|
||||
private:
|
||||
CA::MetalLayer* metalLayer = nullptr;
|
||||
|
||||
MTL::Device* device = nullptr;
|
||||
MTL::CommandQueue* commandQueue = nullptr;
|
||||
|
||||
Metal::CommandEncoder commandEncoder;
|
||||
|
||||
|
@ -98,6 +100,7 @@ class RendererMTL final : public Renderer {
|
|||
void endRenderPass() {
|
||||
if (renderCommandEncoder) {
|
||||
renderCommandEncoder->endEncoding();
|
||||
renderCommandEncoder->release();
|
||||
renderCommandEncoder = nullptr;
|
||||
}
|
||||
}
|
||||
|
|
24
include/renderer_mtl/texture_decoder.hpp
Normal file
24
include/renderer_mtl/texture_decoder.hpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
#include "helpers.hpp"
|
||||
// TODO: remove dependency on OpenGL
|
||||
#include "opengl.hpp"
|
||||
|
||||
void decodeTexelABGR8ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelBGR8ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelA1BGR5ToBGR5A1(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelA1BGR5ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelB5G6R5ToB5G6R5(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelB5G6R5ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelABGR4ToABGR4(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelABGR4ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelAI8ToRG8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelGR8ToRG8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelI8ToR8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelA8ToA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelAI4ToABGR4(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelAI4ToRG8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelI4ToR8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelA4ToA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelETC1ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelETC1A4ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
Loading…
Add table
Add a link
Reference in a new issue