Metal extended shader support

This commit is contained in:
Jack Andersen 2016-07-31 10:52:04 -10:00
parent 13f0726c40
commit c4c3e1883f
12 changed files with 228 additions and 12 deletions

View File

@ -8,6 +8,7 @@
#include "Shaders/CModelShaders.hpp" #include "Shaders/CModelShaders.hpp"
#include "Graphics/CBooRenderer.hpp" #include "Graphics/CBooRenderer.hpp"
#include "GameGlobalObjects.hpp" #include "GameGlobalObjects.hpp"
#include <array>
namespace urde namespace urde
{ {

View File

@ -27,6 +27,11 @@ CModelShaders::GetShaderExtensions(boo::IGraphicsDataFactory::Platform plat)
} }
} }
const hecl::Backend::TextureInfo CModelShaders::ThermalTextures[] =
{
{hecl::Backend::TexGenSrc::Normal, 7, 0, 7, true}
};
CModelShaders::CModelShaders(const hecl::Runtime::FileStoreManager& storeMgr, CModelShaders::CModelShaders(const hecl::Runtime::FileStoreManager& storeMgr,
boo::IGraphicsDataFactory* gfxFactory) boo::IGraphicsDataFactory* gfxFactory)
: m_shaderCache(storeMgr, gfxFactory, GetShaderExtensions(gfxFactory->platform())) {} : m_shaderCache(storeMgr, gfxFactory, GetShaderExtensions(gfxFactory->platform())) {}

View File

@ -20,6 +20,7 @@ class CModelShaders
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat); static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat);
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsHLSL(boo::IGraphicsDataFactory::Platform plat); static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsHLSL(boo::IGraphicsDataFactory::Platform plat);
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat); static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat);
static const hecl::Backend::TextureInfo ThermalTextures[];
public: public:
struct Light struct Light
{ {

View File

@ -64,11 +64,6 @@ static const char* ThermalBlockNames[] = {HECL_GLSL_VERT_UNIFORM_BLOCK_NAME,
HECL_GLSL_TEXMTX_UNIFORM_BLOCK_NAME, HECL_GLSL_TEXMTX_UNIFORM_BLOCK_NAME,
"ThermalUniform"}; "ThermalUniform"};
static const hecl::Backend::TextureInfo ThermalTextures[] =
{
{hecl::Backend::TexGenSrc::Normal, 7, 0, 7, true}
};
hecl::Runtime::ShaderCacheExtensions hecl::Runtime::ShaderCacheExtensions
CModelShaders::GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat) CModelShaders::GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat)
{ {

View File

@ -43,13 +43,34 @@ static const char* LightingMetal =
" return saturate(ret);\n" " return saturate(ret);\n"
"}\n"; "}\n";
static const char* ThermalPostMetal =
"struct ThermalUniform\n"
"{\n"
" float4 mulColor;\n"
" float4 addColor;\n"
"};\n"
"static float4 ThermalPostFunc(thread VertToFrag& vtf, constant ThermalUniform& lu, texture2d<float> tex7, float4 colorIn)\n"
"{\n"
" return tex7.sample(samp, vtf.extTcgs0).rrrr * lu.mulColor + lu.addColor;\n"
"}\n"
"\n";
static const char* BlockNames[] = {"LightingUniform"}; static const char* BlockNames[] = {"LightingUniform"};
static const char* ThermalBlockNames[] = {"ThermalUniform"};
hecl::Runtime::ShaderCacheExtensions hecl::Runtime::ShaderCacheExtensions
CModelShaders::GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat) CModelShaders::GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat)
{ {
hecl::Runtime::ShaderCacheExtensions ext(plat); hecl::Runtime::ShaderCacheExtensions ext(plat);
ext.registerExtensionSlot({LightingMetal, "LightingFunc"}, {}, 1, BlockNames);
/* Normal lit shading */
ext.registerExtensionSlot({LightingMetal, "LightingFunc"}, {}, 1, BlockNames, 0, nullptr,
hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original);
/* Thermal Visor shading */
ext.registerExtensionSlot({}, {ThermalPostMetal, "ThermalPostFunc"}, 1, ThermalBlockNames, 1, ThermalTextures,
hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::One);
return ext; return ext;
} }

View File

@ -123,6 +123,16 @@ void CSpaceWarpFilter::draw(const zeus::CVector3f& pt)
else else
m_uniform.m_matrix[3][2] = pt.z; m_uniform.m_matrix[3][2] = pt.z;
if (clipRect.x4_left)
{
clipRect.x4_left -= 1;
clipRect.xc_width += 1;
}
if (clipRect.x8_top)
{
clipRect.x8_top -= 1;
clipRect.x10_height += 1;
}
if (clipRect.x4_left + clipRect.xc_width < CGraphics::g_ViewportResolution.x) if (clipRect.x4_left + clipRect.xc_width < CGraphics::g_ViewportResolution.x)
clipRect.xc_width += 1; clipRect.xc_width += 1;
if (clipRect.x8_top + clipRect.x10_height < CGraphics::g_ViewportResolution.y) if (clipRect.x8_top + clipRect.x10_height < CGraphics::g_ViewportResolution.y)

View File

@ -12,6 +12,7 @@ class CSpaceWarpFilter
{ {
friend struct CSpaceWarpFilterGLDataBindingFactory; friend struct CSpaceWarpFilterGLDataBindingFactory;
friend struct CSpaceWarpFilterVulkanDataBindingFactory; friend struct CSpaceWarpFilterVulkanDataBindingFactory;
friend struct CSpaceWarpFilterMetalDataBindingFactory;
struct Uniform struct Uniform
{ {

View File

@ -3,11 +3,88 @@
namespace urde namespace urde
{ {
static const char* VS =
"#include <metal_stdlib>\n"
"using namespace metal;\n"
"struct VertData\n"
"{\n"
" float4 posIn [[ attribute(0) ]];\n"
" float4 uvIn [[ attribute(1) ]];\n"
"};\n"
"struct SpaceWarpUniform\n"
"{\n"
" float4x4 mainMtx;\n"
" float4x4 indMtx;\n"
" float4 strength;\n"
"};\n"
"\n"
"struct VertToFrag\n"
"{\n"
" float4 position [[ position ]];\n"
" float2 sceneUv;\n"
" float2 indUv;\n"
" float2 strength;\n"
"};\n"
"\n"
"vertex VertToFrag vmain(VertData v [[ stage_in ]], constant SpaceWarpUniform& swu [[ buffer(2) ]])\n"
"{\n"
" VertToFrag vtf;\n"
" vtf.position = swu.mainMtx * float4(v.posIn.xy, 0.0, 1.0);\n"
" vtf.sceneUv = vtf.position.xy * float2(0.5) + float2(0.5);\n"
" vtf.sceneUv.y = -vtf.sceneUv.y;\n"
" vtf.indUv = (float3x3(swu.indMtx[0].xyz, swu.indMtx[1].xyz, swu.indMtx[2].xyz) * float3(v.uvIn.xy, 1.0)).xy;\n"
" vtf.indUv.y = -vtf.indUv.y;\n"
" vtf.strength = swu.strength.xy;\n"
" return vtf;\n"
"}\n";
static const char* FS =
"#include <metal_stdlib>\n"
"using namespace metal;\n"
"constexpr sampler samp(address::repeat, filter::linear);\n"
"struct VertToFrag\n"
"{\n"
" float4 position [[ position ]];\n"
" float2 sceneUv;\n"
" float2 indUv;\n"
" float2 strength;\n"
"};\n"
"\n"
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]], texture2d<float> sceneTex [[ texture(0) ]], texture2d<float> indTex [[ texture(1) ]])\n"
"{\n"
" return sceneTex.sample(samp, vtf.sceneUv + (indTex.sample(samp, vtf.indUv).xy * float2(2.0) - float2(1.0 - 1.0 / 256.0)) * vtf.strength.xy);\n"
"}\n";
URDE_DECL_SPECIALIZE_SHADER(CSpaceWarpFilter)
struct CSpaceWarpFilterMetalDataBindingFactory : TShader<CSpaceWarpFilter>::IDataBindingFactory
{
boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CSpaceWarpFilter& filter)
{
boo::MetalDataFactory::Context& cctx = static_cast<boo::MetalDataFactory::Context&>(ctx);
boo::IGraphicsBuffer* bufs[] = {filter.m_uniBuf};
boo::ITexture* texs[] = {CGraphics::g_SpareTexture, filter.m_warpTex};
return cctx.newShaderDataBinding(TShader<CSpaceWarpFilter>::m_pipeline,
TShader<CSpaceWarpFilter>::m_vtxFmt,
filter.m_vbo, nullptr, nullptr, 1, bufs,
nullptr, nullptr, nullptr, 2, texs);
}
};
TShader<CSpaceWarpFilter>::IDataBindingFactory* CSpaceWarpFilter::Initialize(boo::MetalDataFactory::Context& ctx, TShader<CSpaceWarpFilter>::IDataBindingFactory* CSpaceWarpFilter::Initialize(boo::MetalDataFactory::Context& ctx,
boo::IShaderPipeline*& pipeOut, boo::IShaderPipeline*& pipeOut,
boo::IVertexFormat*& vtxFmtOut) boo::IVertexFormat*& vtxFmtOut)
{ {
return nullptr; const boo::VertexElementDescriptor VtxVmt[] =
{
{nullptr, nullptr, boo::VertexSemantic::Position4},
{nullptr, nullptr, boo::VertexSemantic::UV4}
};
vtxFmtOut = ctx.newVertexFormat(2, VtxVmt);
pipeOut = ctx.newShaderPipeline(VS, FS, vtxFmtOut, CGraphics::g_ViewportSamples, boo::BlendFactor::One,
boo::BlendFactor::Zero, boo::Primitive::TriStrips, false, false, false);
return new CSpaceWarpFilterMetalDataBindingFactory;
} }
} }

View File

@ -12,6 +12,7 @@ class CThermalColdFilter
{ {
friend struct CThermalColdFilterGLDataBindingFactory; friend struct CThermalColdFilterGLDataBindingFactory;
friend struct CThermalColdFilterVulkanDataBindingFactory; friend struct CThermalColdFilterVulkanDataBindingFactory;
friend struct CThemalColdFilterMetalDataBindingFactory;
struct Uniform struct Uniform
{ {

View File

@ -3,11 +3,115 @@
namespace urde namespace urde
{ {
static const char* VS =
"#include <metal_stdlib>\n"
"using namespace metal;\n"
"struct VertData\n"
"{\n"
" float4 posIn [[ attribute(0) ]];\n"
" float4 uvIn [[ attribute(1) ]];\n"
"};\n"
"\n"
"struct ThermalColdUniform\n"
"{\n"
" float4x4 shiftMtx;\n"
" float4x4 indMtx;\n"
" float4 shiftScale;\n"
" float4 colorReg0;\n"
" float4 colorReg1;\n"
" float4 colorReg2;\n"
"};\n"
"\n"
"struct VertToFrag\n"
"{\n"
" float4 position [[ position ]];\n"
" float3 indMtx0;\n"
" float3 indMtx1;\n"
" float3 indMtx2;\n"
" float4 colorReg0;\n"
" float4 colorReg1;\n"
" float4 colorReg2;\n"
" float2 sceneUv;\n"
" float2 shiftUv;\n"
" float2 shiftScale;\n"
"};\n"
"\n"
"vertex VertToFrag vmain(VertData v [[ stage_in ]], constant ThermalColdUniform& tcu [[ buffer(2) ]])\n"
"{\n"
" VertToFrag vtf;\n"
" vtf.indMtx0 = tcu.indMtx[0].xyz;\n"
" vtf.indMtx1 = tcu.indMtx[1].xyz;\n"
" vtf.indMtx2 = tcu.indMtx[2].xyz;\n"
" vtf.colorReg0 = tcu.colorReg0;\n"
" vtf.colorReg1 = tcu.colorReg1;\n"
" vtf.colorReg2 = tcu.colorReg2;\n"
" vtf.sceneUv = v.uvIn.xy;\n"
" vtf.shiftUv = (float3x3(tcu.shiftMtx[0].xyz, tcu.shiftMtx[1].xyz, tcu.shiftMtx[2].xyz) * v.uvIn.xyz).xy;\n"
" vtf.shiftScale = tcu.shiftScale.xy;\n"
" vtf.position = float4(v.posIn.xyz, 1.0);\n"
" return vtf;\n"
"}\n";
static const char* FS =
"#include <metal_stdlib>\n"
"using namespace metal;\n"
"constexpr sampler samp(address::repeat, filter::linear);\n"
"struct VertToFrag\n"
"{\n"
" float4 position [[ position ]];\n"
" float3 indMtx0;\n"
" float3 indMtx1;\n"
" float3 indMtx2;\n"
" float4 colorReg0;\n"
" float4 colorReg1;\n"
" float4 colorReg2;\n"
" float2 sceneUv;\n"
" float2 shiftUv;\n"
" float2 shiftScale;\n"
"};\n"
"\n"
"constant float4 kRGBToYPrime = {0.299, 0.587, 0.114, 0.0};\n"
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]], texture2d<float> sceneTex [[ texture(0) ]], texture2d<float> shiftTex [[ texture(1) ]])\n"
"{\n"
" float2 shiftCoordTexel = shiftTex.sample(samp, vtf.shiftUv).xy;\n"
" float2 shiftCoord = vtf.sceneUv + shiftCoordTexel * vtf.shiftScale;\n"
" float shiftScene0 = dot(sceneTex.sample(samp, shiftCoord), kRGBToYPrime);\n"
" float shiftScene1 = dot(sceneTex.sample(samp, shiftCoord + float2(vtf.shiftScale.x / 8.0, 0.0)), kRGBToYPrime);\n"
" float2 indCoord = (float3x3(vtf.indMtx0, vtf.indMtx1, vtf.indMtx2) * float3(shiftScene0 - 0.5, shiftScene1 - 0.5, 1.0)).xy;\n"
" float indScene = dot(sceneTex.sample(samp, vtf.sceneUv + indCoord), kRGBToYPrime);\n"
" return vtf.colorReg0 * indScene + vtf.colorReg1 * shiftScene0 + vtf.colorReg2;\n"
"}\n";
URDE_DECL_SPECIALIZE_SHADER(CThermalColdFilter)
struct CThemalColdFilterMetalDataBindingFactory : TShader<CThermalColdFilter>::IDataBindingFactory
{
boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CThermalColdFilter& filter)
{
boo::MetalDataFactory::Context& cctx = static_cast<boo::MetalDataFactory::Context&>(ctx);
boo::IGraphicsBuffer* bufs[] = {filter.m_uniBuf};
boo::ITexture* texs[] = {CGraphics::g_SpareTexture, filter.m_shiftTex};
return cctx.newShaderDataBinding(TShader<CThermalColdFilter>::m_pipeline,
TShader<CThermalColdFilter>::m_vtxFmt,
filter.m_vbo, nullptr, nullptr, 1, bufs,
nullptr, nullptr, nullptr, 2, texs);
}
};
TShader<CThermalColdFilter>::IDataBindingFactory* CThermalColdFilter::Initialize(boo::MetalDataFactory::Context& ctx, TShader<CThermalColdFilter>::IDataBindingFactory* CThermalColdFilter::Initialize(boo::MetalDataFactory::Context& ctx,
boo::IShaderPipeline*& pipeOut, boo::IShaderPipeline*& pipeOut,
boo::IVertexFormat*& vtxFmtOut) boo::IVertexFormat*& vtxFmtOut)
{ {
return nullptr; const boo::VertexElementDescriptor VtxVmt[] =
{
{nullptr, nullptr, boo::VertexSemantic::Position4},
{nullptr, nullptr, boo::VertexSemantic::UV4}
};
vtxFmtOut = ctx.newVertexFormat(2, VtxVmt);
pipeOut = ctx.newShaderPipeline(VS, FS, vtxFmtOut, CGraphics::g_ViewportSamples, boo::BlendFactor::One,
boo::BlendFactor::Zero, boo::Primitive::TriStrips, false, false, false);
return new CThemalColdFilterMetalDataBindingFactory;
} }
} }

2
hecl

@ -1 +1 @@
Subproject commit 3f47a0524451e46c73915e81de85e0a926a29e12 Subproject commit cb3e8d09fe2def4bf594d5d4f8822440dddb3ce9

@ -1 +1 @@
Subproject commit 99069bd069a93ab2d98dcd09b799711d2f93754c Subproject commit d242e2deb63b2fc6da526e7245d4dfa487731af4