mirror of
https://github.com/libretro/RetroArch
synced 2025-01-31 15:32:59 +00:00
121 lines
4.6 KiB
Metal
121 lines
4.6 KiB
Metal
/* RetroArch - A frontend for libretro.
|
|
* Copyright (C) 2018 - Stuart Carnie
|
|
* copyright (c) 2011-2021 - Daniel De Matteis
|
|
*
|
|
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
|
* of the GNU General Public License as published by the Free Software Found-
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with RetroArch.
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/* File for Metal kernel and shader functions */
|
|
|
|
#include <metal_stdlib>
|
|
#include <simd/simd.h>
|
|
|
|
/* Including header shared between this Metal shader code and Swift/C code executing Metal API commands */
|
|
#import "metal_shader_types.h"
|
|
|
|
using namespace metal;
|
|
|
|
#pragma mark - functions using projected coordinates
|
|
|
|
vertex ColorInOut basic_vertex_proj_tex(const Vertex in [[ stage_in ]],
|
|
const device Uniforms &uniforms [[ buffer(BufferIndexUniforms) ]])
|
|
{
|
|
ColorInOut out;
|
|
out.position = uniforms.projectionMatrix * float4(in.position, 1.0);
|
|
out.texCoord = in.texCoord;
|
|
return out;
|
|
}
|
|
|
|
fragment float4 basic_fragment_proj_tex(ColorInOut in [[stage_in]],
|
|
constant Uniforms & uniforms [[ buffer(BufferIndexUniforms) ]],
|
|
texture2d<half> tex [[ texture(TextureIndexColor) ]],
|
|
sampler samp [[ sampler(SamplerIndexDraw) ]])
|
|
{
|
|
half4 colorSample = tex.sample(samp, in.texCoord.xy);
|
|
return float4(colorSample);
|
|
}
|
|
|
|
#pragma mark - functions for rendering sprites
|
|
|
|
vertex FontFragmentIn sprite_vertex(const SpriteVertex in [[ stage_in ]], const device Uniforms &uniforms [[ buffer(BufferIndexUniforms) ]])
|
|
{
|
|
FontFragmentIn out;
|
|
out.position = uniforms.projectionMatrix * float4(in.position, 0, 1);
|
|
out.texCoord = in.texCoord;
|
|
out.color = in.color;
|
|
return out;
|
|
}
|
|
|
|
fragment float4 sprite_fragment_a8(FontFragmentIn in [[ stage_in ]],
|
|
texture2d<half> tex [[ texture(TextureIndexColor) ]],
|
|
sampler samp [[ sampler(SamplerIndexDraw) ]])
|
|
{
|
|
half4 colorSample = tex.sample(samp, in.texCoord.xy);
|
|
return float4(in.color.rgb, in.color.a * colorSample.r);
|
|
}
|
|
|
|
#pragma mark - functions for rendering sprites
|
|
|
|
vertex FontFragmentIn stock_vertex(const SpriteVertex in [[ stage_in ]], const device Uniforms &uniforms [[ buffer(BufferIndexUniforms) ]])
|
|
{
|
|
FontFragmentIn out;
|
|
out.position = uniforms.projectionMatrix * float4(in.position, 0, 1);
|
|
out.texCoord = in.texCoord;
|
|
out.color = in.color;
|
|
return out;
|
|
}
|
|
|
|
fragment float4 stock_fragment(FontFragmentIn in [[ stage_in ]],
|
|
texture2d<float> tex [[ texture(TextureIndexColor) ]],
|
|
sampler samp [[ sampler(SamplerIndexDraw) ]])
|
|
{
|
|
float4 colorSample = tex.sample(samp, in.texCoord.xy);
|
|
return colorSample * in.color;
|
|
}
|
|
|
|
fragment half4 stock_fragment_color(FontFragmentIn in [[ stage_in ]])
|
|
{
|
|
return half4(in.color);
|
|
}
|
|
|
|
#pragma mark - filter kernels
|
|
|
|
kernel void convert_bgra4444_to_bgra8888(texture2d<ushort, access::read> in [[ texture(0) ]],
|
|
texture2d<half, access::write> out [[ texture(1) ]],
|
|
uint2 gid [[ thread_position_in_grid ]])
|
|
{
|
|
ushort pix = in.read(gid).r;
|
|
uchar4 pix2 = uchar4(
|
|
extract_bits(pix, 4, 4),
|
|
extract_bits(pix, 8, 4),
|
|
extract_bits(pix, 12, 4),
|
|
extract_bits(pix, 0, 4)
|
|
);
|
|
|
|
out.write(half4(pix2) / 15.0, gid);
|
|
}
|
|
|
|
kernel void convert_rgb565_to_bgra8888(texture2d<ushort, access::read> in [[ texture(0) ]],
|
|
texture2d<half, access::write> out [[ texture(1) ]],
|
|
uint2 gid [[ thread_position_in_grid ]])
|
|
{
|
|
ushort pix = in.read(gid).r;
|
|
uchar4 pix2 = uchar4(
|
|
extract_bits(pix, 11, 5),
|
|
extract_bits(pix, 5, 6),
|
|
extract_bits(pix, 0, 5),
|
|
0xf
|
|
);
|
|
|
|
out.write(half4(pix2) / half4(0x1f, 0x3f, 0x1f, 0xf), gid);
|
|
}
|