Skip to content

Commit

Permalink
Vertex Shader
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaacMarovitz committed Dec 28, 2024
1 parent 5f4af93 commit dcdcecf
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 1 deletion.
61 changes: 61 additions & 0 deletions core/rend/metal/metal_shaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,64 @@ Copyright 2024 flyinghead
*/

#include "metal_shaders.h"

static const char VertexShaderSource[] = R"(
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
constant bool pp_gouraud [[function_constant(0)]];
constant bool div_pos_z [[function_constant(1)]];
struct VertexShaderUniforms
{
float4x4 ndc_mat;
};
struct VertexIn
{
float4 in_pos [[attribute(0)]];
float4 in_base [[attribute(1)]];
float4 in_offs [[attribute(2)]];
float2 in_uv [[attribute(3)]];
};
struct VertexOut
{
float4 vtx_base INTERPOLATION;
float4 vtx_offs INTERPOLATION;
float3 vtx_uv;
float4 position [[position]];
};
vertex VertexOut vs_main(VertexIn in [[stage_in]], constant VertexShaderUniforms& uniforms [[buffer(0)]])
{
float4 vpos = uniforms.ndc_mat * in.in_pos;
if (div_pos_z) {
vpos /= vpos.z;
vpos.z = vpos.w;
}
VertexOut out = {};
out.vtx_base = in.in_base;
out.vtx_offs = in.in_offs;
out.vtx_uv = float3(in.in_uv, vpos.z);
if (pp_gouraud && !div_pos_z) {
out.vtx_base *= vpos.z;
out.vtx_offs *= vpos.z;
}
if (!div_pos_z) {
out.vtx_uv.xy *= vpos.z;
vpos.w = 1.0;
vpos.z = 0.0;
}
out.position = vpos;
return out;
}
)";
84 changes: 83 additions & 1 deletion core/rend/metal/metal_shaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,86 @@ Copyright 2024 flyinghead
You should have received a copy of the GNU General Public License
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#pragma once
#include <Metal/Metal.hpp>

#include "types.h"
#include <map>


struct VertexShaderParams
{
bool gouraud;
bool naomi2;
bool divPosZ;

u32 hash() { return (u32)gouraud | ((u32)naomi2 << 1) | ((u32)divPosZ << 2); }
};

struct FragmentShaderParams
{
bool alphaTest;
bool insideClipTest;
bool useAlpha;
bool texture;
bool ignoreTexAlpha;
int shaderInstr;
bool offset;
int fog;
bool gouraud;
bool bumpmap;
bool clamping;
bool trilinear;
int palette;
bool divPosZ;
bool dithering;

u32 hash()
{
return ((u32)alphaTest) | ((u32)insideClipTest << 1) | ((u32)useAlpha << 2)
| ((u32)texture << 3) | ((u32)ignoreTexAlpha << 4) | (shaderInstr << 5)
| ((u32)offset << 7) | ((u32)fog << 8) | ((u32)gouraud << 10)
| ((u32)bumpmap << 11) | ((u32)clamping << 12) | ((u32)trilinear << 13)
| ((u32)palette << 14) | ((u32)divPosZ << 16) | ((u32)dithering << 17);
}
};

class MetalShaders
{
public:
MTL::Function *GetVertexShader(const VertexShaderParams& params) { return getShader(vertexShaders, params); }

void term()
{
for (auto &[u, func] : vertexShaders) {
func->release();
}

vertexShaders.clear();

for (auto &[u, func] : fragmentShaders) {
func->release();
}

fragmentShaders.clear();
}

private:
MTL::Device device;

template<typename T>
MTL::Function *getShader(std::map<u32, MTL::Function*> &map, T params)
{
u32 h = params.hash();
auto it = map.find(h);
if (it != map.end())
return it->second;
map[h] = compileShader(params);
return map[h];
}
MTL::Function *compileShader(const VertexShaderParams& params);
MTL::Function *compileShader(const FragmentShaderParams& params);

std::map<u32, MTL::Function*> vertexShaders;
std::map<u32, MTL::Function*> fragmentShaders;
};

0 comments on commit dcdcecf

Please sign in to comment.