libultraship
Reimplementations of libultra (N64 SDK) functions for modern hardware
Loading...
Searching...
No Matches
gfx_metal.h
Go to the documentation of this file.
1//
2// gfx_metal.h
3// libultraship
4//
5// Created by David Chavez on 16.08.22.
6//
7#pragma once
8#ifdef __APPLE__
9
10#include <memory>
11#include "gfx_rendering_api.h"
12#include "../interpreter.h"
13
14#include <imgui_impl_sdl2.h>
15#include <simd/simd.h>
16
17namespace Ship {
18class ConsoleVariable;
19class ResourceManager;
20} // namespace Ship
21
23static constexpr size_t kMaxVertexBufferPoolSize = 3;
25static constexpr size_t METAL_MAX_MULTISAMPLE_SAMPLE_COUNT = 8;
27static constexpr size_t MAX_PIXEL_DEPTH_COORDS = 1024;
28
29namespace MTL {
30class Texture;
31class SamplerState;
32class CommandBuffer;
33class RenderPassDescriptor;
34class RenderCommandEncoder;
35class SamplerState;
36class ScissorRect;
37class Device;
38class Function;
39class Buffer;
40class RenderPipelineState;
41class ComputePipelineState;
42class CommandQueue;
43class Viewport;
44} // namespace MTL
45
46namespace CA {
47class MetalDrawable;
48class MetalLayer;
49} // namespace CA
50
51namespace NS {
52class AutoreleasePool;
53}
54
56static size_t cantor(uint64_t a, uint64_t b) {
57 return (a + b) * (a + b + 1) / 2 + b;
58}
59
62 size_t operator()(const std::pair<uint64_t, uint32_t>& p) const {
63 auto value1 = p.first;
64 auto value2 = p.second;
65 return cantor(value1, value2);
66 }
67};
68
69namespace Fast {
70
75 uint64_t shader_id0;
76 uint64_t shader_id1;
77
78 uint8_t numInputs;
79 uint8_t numFloats;
81 bool markedForDeletion = false;
82
83 // hashed by msaa_level
84 MTL::RenderPipelineState* pipeline_state_variants[9];
85};
86
91 MTL::Texture* texture;
92 MTL::Texture* msaaTexture;
93 MTL::SamplerState* sampler;
94 uint32_t width;
95 uint32_t height;
96 uint32_t filtering;
98};
99
104 MTL::CommandBuffer* mCommandBuffer;
105 MTL::RenderPassDescriptor* mRenderPassDescriptor;
106 MTL::RenderCommandEncoder* mCommandEncoder;
107
108 MTL::Texture* mDepthTexture;
109 MTL::Texture* mMsaaDepthTexture;
110 uint32_t mTextureId;
112 uint32_t mMsaaLevel;
114
115 // State
119
123 MTL::ScissorRect* mScissorRect;
124 MTL::Viewport* mViewport;
125
126 int8_t mLastDepthTest = -1;
127 int8_t mLastDepthMask = -1;
128 int8_t mLastZmodeDecal = -1;
129
130 // When true, command buffer is created on the readback queue (no enqueue ordering).
131 // First ReadFramebufferToCPU returns zeros and flips this; real data from frame 2+.
132 bool mUseReadbackQueue = false;
133};
134
137 simd::int1 frameCount;
138 simd::float1 noiseScale;
139};
140
144 simd::float1 prim_depth;
145};
146
151
154 public:
156 GfxRenderingAPIMetal(std::shared_ptr<Ship::ConsoleVariable> consoleVariable = nullptr,
157 std::shared_ptr<Ship::ResourceManager> resourceManager = nullptr);
158 ~GfxRenderingAPIMetal() override = default;
159
162 const char* GetName() override;
163 int GetMaxTextureSize() override;
165 void UnloadShader(ShaderProgram* oldPrg) override;
166 void LoadShader(ShaderProgram* newPrg) override;
167 ShaderProgram* CreateAndLoadNewShader(uint64_t shaderId0, uint64_t shaderId1) override;
168 ShaderProgram* LookupShader(uint64_t shaderId0, uint64_t shaderId1) override;
169 void ShaderGetInfo(ShaderProgram* prg, uint8_t* numInputs, bool usedTextures[2]) override;
170 void ClearShaderCache() override;
171 uint32_t NewTexture() override;
172 void SelectTexture(int tile, uint32_t textureId) override;
173 void UploadTexture(const uint8_t* rgba32Buf, uint32_t width, uint32_t height) override;
174 void SetSamplerParameters(int sampler, bool linear_filter, uint32_t cms, uint32_t cmt) override;
175 void SetDepthTestAndMask(bool depth_test, bool z_upd) override;
176 void SetCurrentPrimDepth(float depth) override;
177 void SetZmodeDecal(bool decal) override;
178 void SetViewport(int x, int y, int width, int height) override;
179 void SetScissor(int x, int y, int width, int height) override;
180 void SetUseAlpha(bool useAlpha) override;
181 void DrawTriangles(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris) override;
182 void Init() override;
183 void OnResize() override;
184 void StartFrame() override;
185 void EndFrame() override;
186 void FinishRender() override;
187 int CreateFramebuffer() override;
188 void UpdateFramebufferParameters(int fb_id, uint32_t width, uint32_t height, uint32_t msaa_level,
189 bool opengl_invertY, bool render_target, bool has_depth_buffer,
190 bool can_extract_depth) override;
191 void StartDrawToFramebuffer(int fbId, float noiseScale) override;
192 void CopyFramebuffer(int fbDstId, int fbSrcId, int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0,
193 int dstX1, int dstY1) override;
194 void ClearFramebuffer(bool color, bool depth) override;
195 void ReadFramebufferToCPU(int fbId, uint32_t width, uint32_t height, uint16_t* rgba16Buf) override;
196 void ResolveMSAAColorBuffer(int fbIdTarge, int fbIdSrc) override;
197 std::unordered_map<std::pair<float, float>, uint16_t, hash_pair_ff>
198 GetPixelDepth(int fb_id, const std::set<std::pair<float, float>>& coordinates) override;
199 void* GetFramebufferTextureId(int fbId) override;
200 void SelectTextureFb(int fbId) override;
201 void DeleteTexture(uint32_t texId) override;
202 void SetTextureFilter(FilteringMode mode) override;
204 void SetSrgbMode() override;
205 ImTextureID GetTextureById(int id) override;
209 void NewFrame();
213 void RenderDrawData(ImDrawData* drawData);
215 bool MetalInit(SDL_Renderer* renderer);
216
217 private:
218 bool NonUniformThreadGroupSupported();
219 void SetupScreenFramebuffer(uint32_t width, uint32_t height);
220 // Elements that only need to be setup once
221 SDL_Renderer* mRenderer;
222 CA::MetalLayer* mLayer; // CA::MetalLayer*
223 MTL::Device* mDevice;
224 MTL::CommandQueue* mCommandQueue;
225 MTL::CommandQueue* mReadbackQueue;
226
227 int mCurrentVertexBufferPoolIndex = 0;
228 MTL::Buffer* mVertexBufferPool[kMaxVertexBufferPoolSize];
229 std::unordered_map<std::pair<uint64_t, uint32_t>, struct ShaderProgramMetal, hash_pair_shader_ids>
230 mShaderProgramPool;
231
232 std::vector<struct TextureDataMetal> mTextures;
233 std::vector<FramebufferMetal> mFramebuffers;
234 FrameUniforms mFrameUniforms;
235 CoordUniforms mCoordUniforms;
236 DrawUniforms mDrawUniforms;
237 MTL::Buffer* mFrameUniformBuffer;
238
239 uint32_t mMsaaNumQualityLevels[METAL_MAX_MULTISAMPLE_SAMPLE_COUNT];
240
241 // Depth querying
242 MTL::Buffer* mCoordUniformBuffer;
243 MTL::Buffer* mDepthValueOutputBuffer;
244 size_t mCoordBufferSize;
245 MTL::Function* mDepthComputeFunction;
246 MTL::Function* mConvertToRgb5a1Function;
247 MTL::ComputePipelineState* mConvertToRgb5a1PipelineState = nullptr;
248 std::shared_ptr<Ship::ConsoleVariable> mConsoleVariable;
249 std::shared_ptr<Ship::ResourceManager> mResourceManager;
250
251 // Screen FB deferred readback: blit in EndFrame, CPU conversion next frame.
252 // mScreenReadbackCmdBuf retains the command buffer that encoded the blit so
253 // we can waitUntilCompleted before reading the shared buffer contents.
254 MTL::CommandBuffer* mScreenReadbackCmdBuf = nullptr;
255 MTL::Buffer* mScreenReadbackBuffer = nullptr;
256 uint32_t mScreenReadbackWidth = 0;
257 uint32_t mScreenReadbackHeight = 0;
258 bool mScreenReadbackDataReady = false;
259 bool mScreenReadbackRequested = false;
260
261 // Current state
262 struct ShaderProgramMetal* mShaderProgram;
263 CA::MetalDrawable* mCurrentDrawable;
264 std::set<int> mDrawnFramebuffers;
265 NS::AutoreleasePool* mFrameAutoreleasePool;
266
267 int mCurrentTile;
268 uint32_t mCurrentTextureIds[SHADER_MAX_TEXTURES];
269
270 int32_t mRenderTargetHeight;
271 int mCurrentFramebuffer;
272 size_t mCurrentVertexBufferOffset;
273 FilteringMode mCurrentFilterMode = FILTER_THREE_POINT;
274
275 bool mNonUniformThreadgroupSupported;
276};
277
278} // namespace Fast
279
282
283#endif
Metal implementation of the Fast3D rendering API.
Definition gfx_metal.h:153
const char * GetName() override
int GetMaxTextureSize() override
void RenderDrawData(ImDrawData *drawData)
Renders ImGui draw data using the active Metal command encoder.
void SetSrgbMode() override
void SetCurrentPrimDepth(float depth) override
void NewFrame()
Begins a new ImGui frame for the Metal renderer bridge.
int CreateFramebuffer() override
void SetScissor(int x, int y, int width, int height) override
bool MetalInit(SDL_Renderer *renderer)
Initializes Metal/SDL bridge objects for this renderer instance.
void ResolveMSAAColorBuffer(int fbIdTarge, int fbIdSrc) override
void EndFrame() override
void CopyFramebuffer(int fbDstId, int fbSrcId, int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1) override
void LoadShader(ShaderProgram *newPrg) override
void UnloadShader(ShaderProgram *oldPrg) override
void OnResize() override
void SelectTexture(int tile, uint32_t textureId) override
void SetSamplerParameters(int sampler, bool linear_filter, uint32_t cms, uint32_t cmt) override
uint32_t NewTexture() override
GfxClipParameters GetClipParameters() override
void SetTextureFilter(FilteringMode mode) override
void SelectTextureFb(int fbId) override
void FinishRender() override
void SetUseAlpha(bool useAlpha) override
void ClearShaderCache() override
void SetViewport(int x, int y, int width, int height) override
void SetupFloatingFrame()
Prepares floating-frame state for rendering ImGui draw data.
void ClearFramebuffer(bool color, bool depth) override
void UpdateFramebufferParameters(int fb_id, uint32_t width, uint32_t height, uint32_t msaa_level, bool opengl_invertY, bool render_target, bool has_depth_buffer, bool can_extract_depth) override
ImTextureID GetTextureById(int id) override
void DrawTriangles(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris) override
ShaderProgram * LookupShader(uint64_t shaderId0, uint64_t shaderId1) override
GfxRenderingAPIMetal(std::shared_ptr< Ship::ConsoleVariable > consoleVariable=nullptr, std::shared_ptr< Ship::ResourceManager > resourceManager=nullptr)
Constructs the Metal renderer with optional shared dependencies.
ShaderProgram * CreateAndLoadNewShader(uint64_t shaderId0, uint64_t shaderId1) override
void SetDepthTestAndMask(bool depth_test, bool z_upd) override
void SetZmodeDecal(bool decal) override
void UploadTexture(const uint8_t *rgba32Buf, uint32_t width, uint32_t height) override
void StartDrawToFramebuffer(int fbId, float noiseScale) override
void StartFrame() override
void ReadFramebufferToCPU(int fbId, uint32_t width, uint32_t height, uint16_t *rgba16Buf) override
void DeleteTexture(uint32_t texId) override
void ShaderGetInfo(ShaderProgram *prg, uint8_t *numInputs, bool usedTextures[2]) override
void * GetFramebufferTextureId(int fbId) override
std::unordered_map< std::pair< float, float >, uint16_t, hash_pair_ff > GetPixelDepth(int fb_id, const std::set< std::pair< float, float > > &coordinates) override
FilteringMode GetTextureFilter() override
~GfxRenderingAPIMetal() override=default
Definition gfx_rendering_api.h:30
static constexpr size_t kMaxVertexBufferPoolSize
Number of rotating vertex buffers kept to reduce CPU/GPU sync stalls.
Definition gfx_metal.h:23
bool Metal_IsSupported()
Returns true when Metal is available on the current runtime platform.
static size_t cantor(uint64_t a, uint64_t b)
Combines two integer keys using the Cantor pairing function.
Definition gfx_metal.h:56
static constexpr size_t MAX_PIXEL_DEPTH_COORDS
Maximum number of pixel-depth coordinates queried in a single pass.
Definition gfx_metal.h:27
static constexpr size_t METAL_MAX_MULTISAMPLE_SAMPLE_COUNT
Maximum multisample count supported by this Metal backend implementation.
Definition gfx_metal.h:25
#define SHADER_MAX_TEXTURES
Definition interpreter.h:105
Definition gfx_direct3d_common.h:19
FilteringMode
Definition gfx_rendering_api.h:17
@ FILTER_THREE_POINT
Definition gfx_rendering_api.h:17
Core namespace for the libultraship engine framework.
Definition gfx_direct3d_common.h:14
Buffer payload used for batched pixel-depth coordinate queries.
Definition gfx_metal.h:148
simd::uint2 coords[MAX_PIXEL_DEPTH_COORDS]
Definition gfx_metal.h:149
Per-draw uniforms consumed by Metal shader programs.
Definition gfx_metal.h:142
simd::int1 textureFiltering[SHADER_MAX_TEXTURES]
Definition gfx_metal.h:143
simd::float1 prim_depth
Definition gfx_metal.h:144
Per-frame uniforms consumed by Metal shader programs.
Definition gfx_metal.h:136
simd::float1 noiseScale
Definition gfx_metal.h:138
simd::int1 frameCount
Definition gfx_metal.h:137
Framebuffer state for an offscreen or onscreen Metal render target.
Definition gfx_metal.h:103
MTL::Texture * mLastBoundTextures[SHADER_MAX_TEXTURES]
Definition gfx_metal.h:121
int8_t mLastZmodeDecal
Definition gfx_metal.h:128
MTL::SamplerState * mLastBoundSamplers[SHADER_MAX_TEXTURES]
Definition gfx_metal.h:122
uint32_t mTextureId
Definition gfx_metal.h:110
bool mHasDepthBuffer
Definition gfx_metal.h:111
struct ShaderProgramMetal * mLastShaderProgram
Definition gfx_metal.h:120
int8_t mLastDepthMask
Definition gfx_metal.h:127
MTL::RenderCommandEncoder * mCommandEncoder
Definition gfx_metal.h:106
uint32_t mMsaaLevel
Definition gfx_metal.h:112
MTL::ScissorRect * mScissorRect
Definition gfx_metal.h:123
MTL::RenderPassDescriptor * mRenderPassDescriptor
Definition gfx_metal.h:105
MTL::CommandBuffer * mCommandBuffer
Definition gfx_metal.h:104
bool mRenderTarget
Definition gfx_metal.h:113
bool mHasBoundVertexShader
Definition gfx_metal.h:117
bool mHasEndedEncoding
Definition gfx_metal.h:116
int8_t mLastDepthTest
Definition gfx_metal.h:126
MTL::Texture * mDepthTexture
Definition gfx_metal.h:108
MTL::Viewport * mViewport
Definition gfx_metal.h:124
MTL::Texture * mMsaaDepthTexture
Definition gfx_metal.h:109
bool mHasBoundFragShader
Definition gfx_metal.h:118
bool mUseReadbackQueue
Definition gfx_metal.h:132
Definition gfx_rendering_api.h:12
Cached Metal shader program and pipeline variants for one combiner key.
Definition gfx_metal.h:74
uint64_t shader_id1
Definition gfx_metal.h:76
uint64_t shader_id0
Definition gfx_metal.h:75
uint8_t numFloats
Definition gfx_metal.h:79
bool markedForDeletion
Definition gfx_metal.h:81
MTL::RenderPipelineState * pipeline_state_variants[9]
Definition gfx_metal.h:84
bool usedTextures[SHADER_MAX_TEXTURES]
Definition gfx_metal.h:80
uint8_t numInputs
Definition gfx_metal.h:78
OpenGL shader program metadata cached by the Fast3D renderer.
Definition gfx_opengl.h:37
Metal texture object metadata tracked by the renderer cache.
Definition gfx_metal.h:90
MTL::SamplerState * sampler
Definition gfx_metal.h:93
uint32_t filtering
Definition gfx_metal.h:96
MTL::Texture * texture
Definition gfx_metal.h:91
uint32_t width
Definition gfx_metal.h:94
bool linear_filtering
Definition gfx_metal.h:97
uint32_t height
Definition gfx_metal.h:95
MTL::Texture * msaaTexture
Definition gfx_metal.h:92
Definition gfx_rendering_api.h:20
Hash functor for (shaderId, msaaLevel) pairs used by shader caches.
Definition gfx_metal.h:61
size_t operator()(const std::pair< uint64_t, uint32_t > &p) const
Definition gfx_metal.h:62