2012-11-26 18:58:24 +00:00
|
|
|
/*
|
|
|
|
===========================================================================
|
|
|
|
|
|
|
|
Doom 3 BFG Edition GPL Source Code
|
2012-11-28 15:47:07 +00:00
|
|
|
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
2018-10-07 14:42:28 +00:00
|
|
|
Copyright (C) 2013-2018 Robert Beckebans
|
|
|
|
Copyright (C) 2016-2017 Dustin Land
|
2012-11-26 18:58:24 +00:00
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
2012-11-26 18:58:24 +00:00
|
|
|
|
|
|
|
Doom 3 BFG Edition Source Code 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 Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
Doom 3 BFG Edition Source Code 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 Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
|
|
|
|
|
|
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
|
|
|
|
|
|
|
===========================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma hdrstop
|
2012-12-22 15:18:19 +00:00
|
|
|
#include "precompiled.h"
|
2012-11-26 18:58:24 +00:00
|
|
|
|
2017-09-03 08:22:36 +00:00
|
|
|
#include "RenderCommon.h"
|
2014-04-26 12:13:25 +00:00
|
|
|
#include "RenderProgs_embedded.h"
|
2012-11-26 18:58:24 +00:00
|
|
|
|
|
|
|
idCVar r_skipStripDeadCode( "r_skipStripDeadCode", "0", CVAR_BOOL, "Skip stripping dead code" );
|
2014-04-20 14:29:58 +00:00
|
|
|
|
2018-10-13 16:34:29 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
struct idCGBlock
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
idStr prefix; // tokens that comes before the name
|
|
|
|
idStr name; // the name
|
|
|
|
idStr postfix; // tokens that comes after the name
|
|
|
|
bool used; // whether or not this block is referenced anywhere
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
================================================
|
|
|
|
attribInfo_t
|
|
|
|
================================================
|
|
|
|
*/
|
2012-11-28 15:47:07 +00:00
|
|
|
attribInfo_t attribsPC[] =
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
// vertex attributes
|
|
|
|
{ "float4", "position", "POSITION", "in_Position", PC_ATTRIB_INDEX_VERTEX, AT_VS_IN, VERTEX_MASK_XYZ },
|
|
|
|
{ "float2", "texcoord", "TEXCOORD0", "in_TexCoord", PC_ATTRIB_INDEX_ST, AT_VS_IN, VERTEX_MASK_ST },
|
|
|
|
{ "float4", "normal", "NORMAL", "in_Normal", PC_ATTRIB_INDEX_NORMAL, AT_VS_IN, VERTEX_MASK_NORMAL },
|
|
|
|
{ "float4", "tangent", "TANGENT", "in_Tangent", PC_ATTRIB_INDEX_TANGENT, AT_VS_IN, VERTEX_MASK_TANGENT },
|
|
|
|
{ "float4", "color", "COLOR0", "in_Color", PC_ATTRIB_INDEX_COLOR, AT_VS_IN, VERTEX_MASK_COLOR },
|
|
|
|
{ "float4", "color2", "COLOR1", "in_Color2", PC_ATTRIB_INDEX_COLOR2, AT_VS_IN, VERTEX_MASK_COLOR2 },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// pre-defined vertex program output
|
2014-04-20 14:29:58 +00:00
|
|
|
{ "float4", "position", "POSITION", "gl_Position", 0, AT_VS_OUT | AT_VS_OUT_RESERVED, 0 },
|
2012-11-26 18:58:24 +00:00
|
|
|
{ "float", "clip0", "CLP0", "gl_ClipDistance[0]", 0, AT_VS_OUT, 0 },
|
|
|
|
{ "float", "clip1", "CLP1", "gl_ClipDistance[1]", 0, AT_VS_OUT, 0 },
|
|
|
|
{ "float", "clip2", "CLP2", "gl_ClipDistance[2]", 0, AT_VS_OUT, 0 },
|
|
|
|
{ "float", "clip3", "CLP3", "gl_ClipDistance[3]", 0, AT_VS_OUT, 0 },
|
|
|
|
{ "float", "clip4", "CLP4", "gl_ClipDistance[4]", 0, AT_VS_OUT, 0 },
|
|
|
|
{ "float", "clip5", "CLP5", "gl_ClipDistance[5]", 0, AT_VS_OUT, 0 },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// pre-defined fragment program input
|
2014-04-20 14:29:58 +00:00
|
|
|
{ "float4", "position", "WPOS", "gl_FragCoord", 0, AT_PS_IN | AT_PS_IN_RESERVED, 0 },
|
|
|
|
{ "half4", "hposition", "WPOS", "gl_FragCoord", 0, AT_PS_IN | AT_PS_IN_RESERVED, 0 },
|
|
|
|
{ "float", "facing", "FACE", "gl_FrontFacing", 0, AT_PS_IN | AT_PS_IN_RESERVED, 0 },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// fragment program output
|
2018-10-07 14:42:28 +00:00
|
|
|
{ "float4", "color", "COLOR", "fo_FragColor", 0, AT_PS_OUT /*| AT_PS_OUT_RESERVED*/, 0 },
|
2014-05-11 09:30:56 +00:00
|
|
|
{ "half4", "hcolor", "COLOR", "fo_FragColor", 0, AT_PS_OUT /*| AT_PS_OUT_RESERVED*/, 0 },
|
|
|
|
{ "float4", "color0", "COLOR0", "fo_FragColor", 0, AT_PS_OUT /*| AT_PS_OUT_RESERVED*/, 0 },
|
|
|
|
{ "float4", "color1", "COLOR1", "fo_FragColor", 1, AT_PS_OUT /*| AT_PS_OUT_RESERVED*/, 0 },
|
|
|
|
{ "float4", "color2", "COLOR2", "fo_FragColor", 2, AT_PS_OUT /*| AT_PS_OUT_RESERVED*/, 0 },
|
|
|
|
{ "float4", "color3", "COLOR3", "fo_FragColor", 3, AT_PS_OUT /*| AT_PS_OUT_RESERVED*/, 0 },
|
2014-04-20 14:29:58 +00:00
|
|
|
{ "float", "depth", "DEPTH", "gl_FragDepth", 4, AT_PS_OUT | AT_PS_OUT_RESERVED, 0 },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// vertex to fragment program pass through
|
2014-04-20 14:29:58 +00:00
|
|
|
{ "float4", "color", "COLOR", "vofi_Color", 0, AT_VS_OUT, 0 },
|
|
|
|
{ "float4", "color0", "COLOR0", "vofi_Color", 0, AT_VS_OUT, 0 },
|
|
|
|
{ "float4", "color1", "COLOR1", "vofi_SecondaryColor", 0, AT_VS_OUT, 0 },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
|
|
|
|
2014-04-20 14:29:58 +00:00
|
|
|
{ "float4", "color", "COLOR", "vofi_Color", 0, AT_PS_IN, 0 },
|
|
|
|
{ "float4", "color0", "COLOR0", "vofi_Color", 0, AT_PS_IN, 0 },
|
|
|
|
{ "float4", "color1", "COLOR1", "vofi_SecondaryColor", 0, AT_PS_IN, 0 },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-04-20 14:29:58 +00:00
|
|
|
{ "half4", "hcolor", "COLOR", "vofi_Color", 0, AT_PS_IN, 0 },
|
|
|
|
{ "half4", "hcolor0", "COLOR0", "vofi_Color", 0, AT_PS_IN, 0 },
|
|
|
|
{ "half4", "hcolor1", "COLOR1", "vofi_SecondaryColor", 0, AT_PS_IN, 0 },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
{ "float4", "texcoord0", "TEXCOORD0_centroid", "vofi_TexCoord0", 0, AT_PS_IN, 0 },
|
|
|
|
{ "float4", "texcoord1", "TEXCOORD1_centroid", "vofi_TexCoord1", 0, AT_PS_IN, 0 },
|
|
|
|
{ "float4", "texcoord2", "TEXCOORD2_centroid", "vofi_TexCoord2", 0, AT_PS_IN, 0 },
|
|
|
|
{ "float4", "texcoord3", "TEXCOORD3_centroid", "vofi_TexCoord3", 0, AT_PS_IN, 0 },
|
|
|
|
{ "float4", "texcoord4", "TEXCOORD4_centroid", "vofi_TexCoord4", 0, AT_PS_IN, 0 },
|
|
|
|
{ "float4", "texcoord5", "TEXCOORD5_centroid", "vofi_TexCoord5", 0, AT_PS_IN, 0 },
|
|
|
|
{ "float4", "texcoord6", "TEXCOORD6_centroid", "vofi_TexCoord6", 0, AT_PS_IN, 0 },
|
|
|
|
{ "float4", "texcoord7", "TEXCOORD7_centroid", "vofi_TexCoord7", 0, AT_PS_IN, 0 },
|
|
|
|
{ "float4", "texcoord8", "TEXCOORD8_centroid", "vofi_TexCoord8", 0, AT_PS_IN, 0 },
|
|
|
|
{ "float4", "texcoord9", "TEXCOORD9_centroid", "vofi_TexCoord9", 0, AT_PS_IN, 0 },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
{ "float4", "texcoord0", "TEXCOORD0", "vofi_TexCoord0", 0, AT_VS_OUT | AT_PS_IN, 0 },
|
|
|
|
{ "float4", "texcoord1", "TEXCOORD1", "vofi_TexCoord1", 0, AT_VS_OUT | AT_PS_IN, 0 },
|
|
|
|
{ "float4", "texcoord2", "TEXCOORD2", "vofi_TexCoord2", 0, AT_VS_OUT | AT_PS_IN, 0 },
|
|
|
|
{ "float4", "texcoord3", "TEXCOORD3", "vofi_TexCoord3", 0, AT_VS_OUT | AT_PS_IN, 0 },
|
|
|
|
{ "float4", "texcoord4", "TEXCOORD4", "vofi_TexCoord4", 0, AT_VS_OUT | AT_PS_IN, 0 },
|
|
|
|
{ "float4", "texcoord5", "TEXCOORD5", "vofi_TexCoord5", 0, AT_VS_OUT | AT_PS_IN, 0 },
|
|
|
|
{ "float4", "texcoord6", "TEXCOORD6", "vofi_TexCoord6", 0, AT_VS_OUT | AT_PS_IN, 0 },
|
|
|
|
{ "float4", "texcoord7", "TEXCOORD7", "vofi_TexCoord7", 0, AT_VS_OUT | AT_PS_IN, 0 },
|
|
|
|
{ "float4", "texcoord8", "TEXCOORD8", "vofi_TexCoord8", 0, AT_VS_OUT | AT_PS_IN, 0 },
|
|
|
|
{ "float4", "texcoord9", "TEXCOORD9", "vofi_TexCoord9", 0, AT_VS_OUT | AT_PS_IN, 0 },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
{ "half4", "htexcoord0", "TEXCOORD0", "vofi_TexCoord0", 0, AT_PS_IN, 0 },
|
|
|
|
{ "half4", "htexcoord1", "TEXCOORD1", "vofi_TexCoord1", 0, AT_PS_IN, 0 },
|
|
|
|
{ "half4", "htexcoord2", "TEXCOORD2", "vofi_TexCoord2", 0, AT_PS_IN, 0 },
|
|
|
|
{ "half4", "htexcoord3", "TEXCOORD3", "vofi_TexCoord3", 0, AT_PS_IN, 0 },
|
|
|
|
{ "half4", "htexcoord4", "TEXCOORD4", "vofi_TexCoord4", 0, AT_PS_IN, 0 },
|
|
|
|
{ "half4", "htexcoord5", "TEXCOORD5", "vofi_TexCoord5", 0, AT_PS_IN, 0 },
|
|
|
|
{ "half4", "htexcoord6", "TEXCOORD6", "vofi_TexCoord6", 0, AT_PS_IN, 0 },
|
|
|
|
{ "half4", "htexcoord7", "TEXCOORD7", "vofi_TexCoord7", 0, AT_PS_IN, 0 },
|
|
|
|
{ "half4", "htexcoord8", "TEXCOORD8", "vofi_TexCoord8", 0, AT_PS_IN, 0 },
|
|
|
|
{ "half4", "htexcoord9", "TEXCOORD9", "vofi_TexCoord9", 0, AT_PS_IN, 0 },
|
|
|
|
{ "float", "fog", "FOG", "gl_FogFragCoord", 0, AT_VS_OUT, 0 },
|
|
|
|
{ "float4", "fog", "FOG", "gl_FogFragCoord", 0, AT_PS_IN, 0 },
|
|
|
|
{ NULL, NULL, NULL, NULL, 0, 0, 0 }
|
|
|
|
};
|
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
const char* types[] =
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
"int",
|
|
|
|
"float",
|
|
|
|
"half",
|
|
|
|
"fixed",
|
|
|
|
"bool",
|
|
|
|
"cint",
|
|
|
|
"cfloat",
|
|
|
|
"void"
|
|
|
|
};
|
|
|
|
static const int numTypes = sizeof( types ) / sizeof( types[0] );
|
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
const char* typePosts[] =
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
"1", "2", "3", "4",
|
|
|
|
"1x1", "1x2", "1x3", "1x4",
|
|
|
|
"2x1", "2x2", "2x3", "2x4",
|
|
|
|
"3x1", "3x2", "3x3", "3x4",
|
|
|
|
"4x1", "4x2", "4x3", "4x4"
|
|
|
|
};
|
|
|
|
static const int numTypePosts = sizeof( typePosts ) / sizeof( typePosts[0] );
|
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
const char* prefixes[] =
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
"static",
|
|
|
|
"const",
|
|
|
|
"uniform",
|
|
|
|
"struct",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"sampler",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"sampler1D",
|
|
|
|
"sampler2D",
|
|
|
|
"sampler3D",
|
|
|
|
"samplerCUBE",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"sampler1DShadow", // GLSL
|
|
|
|
"sampler2DShadow", // GLSL
|
2014-05-10 12:40:01 +00:00
|
|
|
"sampler2DArrayShadow", // GLSL
|
2012-11-26 18:58:24 +00:00
|
|
|
"sampler3DShadow", // GLSL
|
|
|
|
"samplerCubeShadow", // GLSL
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
"sampler2DArray", // GLSL"
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"sampler2DMS", // GLSL
|
|
|
|
};
|
|
|
|
static const int numPrefixes = sizeof( prefixes ) / sizeof( prefixes[0] );
|
|
|
|
|
|
|
|
// For GLSL we need to have the names for the renderparms so we can look up their run time indices within the renderprograms
|
2014-05-10 12:40:01 +00:00
|
|
|
static const char* GLSLParmNames[RENDERPARM_TOTAL] =
|
2012-11-28 15:47:07 +00:00
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
"rpScreenCorrectionFactor",
|
|
|
|
"rpWindowCoord",
|
|
|
|
"rpDiffuseModifier",
|
|
|
|
"rpSpecularModifier",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"rpLocalLightOrigin",
|
|
|
|
"rpLocalViewOrigin",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"rpLightProjectionS",
|
|
|
|
"rpLightProjectionT",
|
|
|
|
"rpLightProjectionQ",
|
|
|
|
"rpLightFalloffS",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"rpBumpMatrixS",
|
|
|
|
"rpBumpMatrixT",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"rpDiffuseMatrixS",
|
|
|
|
"rpDiffuseMatrixT",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"rpSpecularMatrixS",
|
|
|
|
"rpSpecularMatrixT",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"rpVertexColorModulate",
|
|
|
|
"rpVertexColorAdd",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"rpColor",
|
|
|
|
"rpViewOrigin",
|
|
|
|
"rpGlobalEyePos",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"rpMVPmatrixX",
|
|
|
|
"rpMVPmatrixY",
|
|
|
|
"rpMVPmatrixZ",
|
|
|
|
"rpMVPmatrixW",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"rpModelMatrixX",
|
|
|
|
"rpModelMatrixY",
|
|
|
|
"rpModelMatrixZ",
|
|
|
|
"rpModelMatrixW",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"rpProjectionMatrixX",
|
|
|
|
"rpProjectionMatrixY",
|
|
|
|
"rpProjectionMatrixZ",
|
|
|
|
"rpProjectionMatrixW",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"rpModelViewMatrixX",
|
|
|
|
"rpModelViewMatrixY",
|
|
|
|
"rpModelViewMatrixZ",
|
|
|
|
"rpModelViewMatrixW",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"rpTextureMatrixS",
|
|
|
|
"rpTextureMatrixT",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"rpTexGen0S",
|
|
|
|
"rpTexGen0T",
|
|
|
|
"rpTexGen0Q",
|
|
|
|
"rpTexGen0Enabled",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"rpTexGen1S",
|
|
|
|
"rpTexGen1T",
|
|
|
|
"rpTexGen1Q",
|
|
|
|
"rpTexGen1Enabled",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"rpWobbleSkyX",
|
|
|
|
"rpWobbleSkyY",
|
|
|
|
"rpWobbleSkyZ",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
"rpOverbright",
|
|
|
|
"rpEnableSkinning",
|
2014-05-10 12:40:01 +00:00
|
|
|
"rpAlphaTest",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
// RB begin
|
|
|
|
"rpAmbientColor",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
"rpGlobalLightOrigin",
|
|
|
|
"rpJitterTexScale",
|
|
|
|
"rpJitterTexOffset",
|
|
|
|
"rpCascadeDistances",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
"rpShadowMatrices",
|
|
|
|
"rpShadowMatrix0Y",
|
|
|
|
"rpShadowMatrix0Z",
|
|
|
|
"rpShadowMatrix0W",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
"rpShadowMatrix1X",
|
|
|
|
"rpShadowMatrix1Y",
|
|
|
|
"rpShadowMatrix1Z",
|
|
|
|
"rpShadowMatrix1W",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
"rpShadowMatrix2X",
|
|
|
|
"rpShadowMatrix2Y",
|
|
|
|
"rpShadowMatrix2Z",
|
|
|
|
"rpShadowMatrix2W",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
"rpShadowMatrix3X",
|
|
|
|
"rpShadowMatrix3Y",
|
|
|
|
"rpShadowMatrix3Z",
|
|
|
|
"rpShadowMatrix3W",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
"rpShadowMatrix4X",
|
|
|
|
"rpShadowMatrix4Y",
|
|
|
|
"rpShadowMatrix4Z",
|
|
|
|
"rpShadowMatrix4W",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
"rpShadowMatrix5X",
|
|
|
|
"rpShadowMatrix5Y",
|
|
|
|
"rpShadowMatrix5Z",
|
|
|
|
"rpShadowMatrix5W",
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-13 11:50:44 +00:00
|
|
|
"rpUser0",
|
|
|
|
"rpUser1",
|
|
|
|
"rpUser2",
|
|
|
|
"rpUser3",
|
|
|
|
"rpUser4",
|
|
|
|
"rpUser5",
|
|
|
|
"rpUser6",
|
|
|
|
"rpUser7"
|
2014-05-10 12:40:01 +00:00
|
|
|
// RB end
|
|
|
|
};
|
|
|
|
|
|
|
|
// RB begin
|
|
|
|
const char* idRenderProgManager::GLSLMacroNames[MAX_SHADER_MACRO_NAMES] =
|
|
|
|
{
|
|
|
|
"USE_GPU_SKINNING",
|
|
|
|
"LIGHT_POINT",
|
|
|
|
"LIGHT_PARALLEL",
|
2015-12-21 10:39:19 +00:00
|
|
|
"BRIGHTPASS",
|
2016-01-18 21:21:32 +00:00
|
|
|
"HDR_DEBUG",
|
2016-07-10 21:46:24 +00:00
|
|
|
"USE_SRGB",
|
|
|
|
"USE_PBR"
|
2012-11-26 18:58:24 +00:00
|
|
|
};
|
2014-05-10 12:40:01 +00:00
|
|
|
// RB end
|
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
|
2014-04-26 12:13:25 +00:00
|
|
|
// RB: added embedded Cg shader resources
|
2018-10-28 12:22:36 +00:00
|
|
|
const char* idRenderProgManager::FindEmbeddedSourceShader( const char* name )
|
2014-04-26 12:13:25 +00:00
|
|
|
{
|
|
|
|
const char* embeddedSource = NULL;
|
|
|
|
for( int i = 0 ; cg_renderprogs[i].name ; i++ )
|
|
|
|
{
|
|
|
|
if( !idStr::Icmp( cg_renderprogs[i].name, name ) )
|
|
|
|
{
|
|
|
|
embeddedSource = cg_renderprogs[i].shaderText;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-04-26 12:13:25 +00:00
|
|
|
return embeddedSource;
|
|
|
|
}
|
|
|
|
|
|
|
|
class idParser_EmbeddedGLSL : public idParser
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
idParser_EmbeddedGLSL( int flags ) : idParser( flags )
|
|
|
|
{
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-04-26 12:13:25 +00:00
|
|
|
private:
|
2014-05-14 17:14:21 +00:00
|
|
|
int Directive_include( idToken* token, bool supressWarning )
|
2014-04-26 12:13:25 +00:00
|
|
|
{
|
2014-05-14 17:14:21 +00:00
|
|
|
if( idParser::Directive_include( token, true ) )
|
2014-05-10 12:40:01 +00:00
|
|
|
{
|
|
|
|
// RB: try local shaders in base/renderprogs/ first
|
|
|
|
return true;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-04-26 12:13:25 +00:00
|
|
|
idLexer* script;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-04-26 12:13:25 +00:00
|
|
|
idStr path;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 14:00:18 +00:00
|
|
|
/*
|
|
|
|
token was already parsed
|
2014-04-26 12:13:25 +00:00
|
|
|
if( !idParser::ReadSourceToken( &token ) )
|
|
|
|
{
|
|
|
|
idParser::Error( "#include without file name" );
|
|
|
|
return false;
|
|
|
|
}
|
2014-05-10 14:00:18 +00:00
|
|
|
*/
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 14:00:18 +00:00
|
|
|
if( token->linesCrossed > 0 )
|
2014-04-26 12:13:25 +00:00
|
|
|
{
|
|
|
|
idParser::Error( "#include without file name" );
|
|
|
|
return false;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 14:00:18 +00:00
|
|
|
if( token->type == TT_STRING )
|
2014-04-26 12:13:25 +00:00
|
|
|
{
|
|
|
|
script = new idLexer;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-04-26 12:13:25 +00:00
|
|
|
// try relative to the current file
|
|
|
|
path = scriptstack->GetFileName();
|
|
|
|
path.StripFilename();
|
|
|
|
path += "/";
|
2014-05-10 14:00:18 +00:00
|
|
|
path += *token;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-04-26 12:13:25 +00:00
|
|
|
//if( !script->LoadFile( path, OSPath ) )
|
2018-10-28 12:22:36 +00:00
|
|
|
const char* embeddedSource = idRenderProgManager::FindEmbeddedSourceShader( path );
|
2014-04-26 12:13:25 +00:00
|
|
|
if( embeddedSource == NULL )
|
|
|
|
{
|
|
|
|
// try absolute path
|
2014-05-10 14:00:18 +00:00
|
|
|
path = *token;
|
2018-10-28 12:22:36 +00:00
|
|
|
embeddedSource = idRenderProgManager::FindEmbeddedSourceShader( path );
|
2014-04-26 12:13:25 +00:00
|
|
|
if( embeddedSource == NULL )
|
|
|
|
{
|
|
|
|
// try from the include path
|
2014-05-10 14:00:18 +00:00
|
|
|
path = includepath + *token;
|
2018-10-28 12:22:36 +00:00
|
|
|
embeddedSource = idRenderProgManager::FindEmbeddedSourceShader( path );
|
2014-04-26 12:13:25 +00:00
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-04-26 12:13:25 +00:00
|
|
|
if( embeddedSource == NULL || !script->LoadMemory( embeddedSource, strlen( embeddedSource ), path ) )
|
|
|
|
{
|
|
|
|
delete script;
|
|
|
|
script = NULL;
|
|
|
|
}
|
|
|
|
}
|
2014-05-10 14:00:18 +00:00
|
|
|
else if( token->type == TT_PUNCTUATION && *token == "<" )
|
2014-04-26 12:13:25 +00:00
|
|
|
{
|
|
|
|
path = idParser::includepath;
|
2014-05-10 14:00:18 +00:00
|
|
|
while( idParser::ReadSourceToken( token ) )
|
2014-04-26 12:13:25 +00:00
|
|
|
{
|
2014-05-10 14:00:18 +00:00
|
|
|
if( token->linesCrossed > 0 )
|
2014-04-26 12:13:25 +00:00
|
|
|
{
|
2014-05-10 14:00:18 +00:00
|
|
|
idParser::UnreadSourceToken( token );
|
2014-04-26 12:13:25 +00:00
|
|
|
break;
|
|
|
|
}
|
2014-05-10 14:00:18 +00:00
|
|
|
if( token->type == TT_PUNCTUATION && *token == ">" )
|
2014-04-26 12:13:25 +00:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2014-05-10 14:00:18 +00:00
|
|
|
path += *token;
|
2014-04-26 12:13:25 +00:00
|
|
|
}
|
2014-05-10 14:00:18 +00:00
|
|
|
if( *token != ">" )
|
2014-04-26 12:13:25 +00:00
|
|
|
{
|
|
|
|
idParser::Warning( "#include missing trailing >" );
|
|
|
|
}
|
|
|
|
if( !path.Length() )
|
|
|
|
{
|
|
|
|
idParser::Error( "#include without file name between < >" );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if( idParser::flags & LEXFL_NOBASEINCLUDES )
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
script = new idLexer;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-28 12:22:36 +00:00
|
|
|
const char* embeddedSource = idRenderProgManager::FindEmbeddedSourceShader( includepath + path );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-04-26 12:13:25 +00:00
|
|
|
if( embeddedSource == NULL || !script->LoadMemory( embeddedSource, strlen( embeddedSource ), path ) )
|
|
|
|
{
|
|
|
|
delete script;
|
|
|
|
script = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
idParser::Error( "#include without file name" );
|
|
|
|
return false;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-04-26 12:13:25 +00:00
|
|
|
if( !script )
|
|
|
|
{
|
|
|
|
idParser::Error( "file '%s' not found", path.c_str() );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
script->SetFlags( idParser::flags );
|
|
|
|
script->SetPunctuations( idParser::punctuations );
|
|
|
|
idParser::PushScript( script );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
// RB end
|
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
/*
|
|
|
|
========================
|
|
|
|
StripDeadCode
|
|
|
|
========================
|
|
|
|
*/
|
2018-10-28 12:22:36 +00:00
|
|
|
idStr idRenderProgManager::StripDeadCode( const idStr& in, const char* name, const idStrList& compileMacros, bool builtin )
|
2012-11-28 15:47:07 +00:00
|
|
|
{
|
|
|
|
if( r_skipStripDeadCode.GetBool() )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
return in;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
//idLexer src( LEXFL_NOFATALERRORS );
|
2014-04-26 12:13:25 +00:00
|
|
|
idParser_EmbeddedGLSL src( LEXFL_NOFATALERRORS );
|
2012-11-26 18:58:24 +00:00
|
|
|
src.LoadMemory( in.c_str(), in.Length(), name );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2016-01-18 21:21:32 +00:00
|
|
|
idStrStatic<256> sourceName = "filename ";
|
|
|
|
sourceName += name;
|
|
|
|
src.AddDefine( sourceName );
|
2012-11-28 15:47:07 +00:00
|
|
|
src.AddDefine( "PC" );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
for( int i = 0; i < compileMacros.Num(); i++ )
|
|
|
|
{
|
|
|
|
src.AddDefine( compileMacros[i] );
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-04-20 14:29:58 +00:00
|
|
|
switch( glConfig.driverType )
|
|
|
|
{
|
|
|
|
case GLDRV_OPENGL_ES2:
|
|
|
|
case GLDRV_OPENGL_ES3:
|
2014-05-15 14:37:55 +00:00
|
|
|
//src.AddDefine( "GLES2" );
|
2014-04-20 14:29:58 +00:00
|
|
|
break;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
if( !builtin && glConfig.gpuSkinningAvailable )
|
2014-04-20 14:29:58 +00:00
|
|
|
{
|
|
|
|
src.AddDefine( "USE_GPU_SKINNING" );
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
src.AddDefine( "USE_UNIFORM_ARRAYS" );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-15 14:37:55 +00:00
|
|
|
if( r_useHalfLambertLighting.GetBool() )
|
|
|
|
{
|
|
|
|
src.AddDefine( "USE_HALF_LAMBERT" );
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2016-01-13 23:59:41 +00:00
|
|
|
if( r_useHDR.GetBool() )
|
2015-03-24 00:11:30 +00:00
|
|
|
{
|
2016-01-13 23:59:41 +00:00
|
|
|
src.AddDefine( "USE_LINEAR_RGB" );
|
2015-03-24 00:11:30 +00:00
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2015-12-27 16:45:41 +00:00
|
|
|
// SMAA configuration
|
|
|
|
src.AddDefine( "SMAA_GLSL_3" );
|
|
|
|
src.AddDefine( "SMAA_RT_METRICS rpScreenCorrectionFactor " );
|
|
|
|
src.AddDefine( "SMAA_PRESET_HIGH" );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-04-20 14:29:58 +00:00
|
|
|
idList< idCGBlock > blocks;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
blocks.SetNum( 100 );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
idToken token;
|
2012-11-28 15:47:07 +00:00
|
|
|
while( !src.EndOfFile() )
|
|
|
|
{
|
|
|
|
idCGBlock& block = blocks.Alloc();
|
2012-11-26 18:58:24 +00:00
|
|
|
// read prefix
|
2012-11-28 15:47:07 +00:00
|
|
|
while( src.ReadToken( &token ) )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
bool found = false;
|
2012-11-28 15:47:07 +00:00
|
|
|
for( int i = 0; i < numPrefixes; i++ )
|
|
|
|
{
|
|
|
|
if( token == prefixes[i] )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
if( !found )
|
|
|
|
{
|
|
|
|
for( int i = 0; i < numTypes; i++ )
|
|
|
|
{
|
|
|
|
if( token == types[i] )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
int typeLen = idStr::Length( types[i] );
|
2012-11-28 15:47:07 +00:00
|
|
|
if( token.Cmpn( types[i], typeLen ) == 0 )
|
|
|
|
{
|
|
|
|
for( int j = 0; j < numTypePosts; j++ )
|
|
|
|
{
|
|
|
|
if( idStr::Cmp( token.c_str() + typeLen, typePosts[j] ) == 0 )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
if( found )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
if( found )
|
|
|
|
{
|
|
|
|
if( block.prefix.Length() > 0 && token.WhiteSpaceBeforeToken() )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
block.prefix += ' ';
|
|
|
|
}
|
|
|
|
block.prefix += token;
|
2012-11-28 15:47:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
src.UnreadToken( &token );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
if( !src.ReadToken( &token ) )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
blocks.SetNum( blocks.Num() - 1 );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
block.name = token;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
if( src.PeekTokenString( "=" ) || src.PeekTokenString( ":" ) || src.PeekTokenString( "[" ) )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
src.ReadToken( &token );
|
|
|
|
block.postfix = token;
|
2012-11-28 15:47:07 +00:00
|
|
|
while( src.ReadToken( &token ) )
|
|
|
|
{
|
|
|
|
if( token == ";" )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
block.postfix += ';';
|
|
|
|
break;
|
2012-11-28 15:47:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( token.WhiteSpaceBeforeToken() )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
block.postfix += ' ';
|
|
|
|
}
|
|
|
|
block.postfix += token;
|
|
|
|
}
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
}
|
|
|
|
else if( src.PeekTokenString( "(" ) )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
idStr parms, body;
|
|
|
|
src.ParseBracedSection( parms, -1, true, '(', ')' );
|
2012-11-28 15:47:07 +00:00
|
|
|
if( src.CheckTokenString( ";" ) )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
block.postfix = parms + ";";
|
2012-11-28 15:47:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
src.ParseBracedSection( body, -1, true, '{', '}' );
|
|
|
|
block.postfix = parms + " " + body;
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
}
|
|
|
|
else if( src.PeekTokenString( "{" ) )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
src.ParseBracedSection( block.postfix, -1, true, '{', '}' );
|
2012-11-28 15:47:07 +00:00
|
|
|
if( src.CheckTokenString( ";" ) )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
block.postfix += ';';
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
}
|
|
|
|
else if( src.CheckTokenString( ";" ) )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
block.postfix = idStr( ';' );
|
2012-11-28 15:47:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
src.Warning( "Could not strip dead code -- unknown token %s\n", token.c_str() );
|
|
|
|
return in;
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
idList<int, TAG_RENDERPROG> stack;
|
2012-11-28 15:47:07 +00:00
|
|
|
for( int i = 0; i < blocks.Num(); i++ )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
blocks[i].used = ( ( blocks[i].name == "main" )
|
2012-11-28 15:47:07 +00:00
|
|
|
|| blocks[i].name.Right( 4 ) == "_ubo"
|
|
|
|
);
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
if( blocks[i].name == "include" )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
blocks[i].used = true;
|
|
|
|
blocks[i].name = ""; // clear out the include tag
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
if( blocks[i].used )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
stack.Append( i );
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
while( stack.Num() > 0 )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
int i = stack[stack.Num() - 1];
|
|
|
|
stack.SetNum( stack.Num() - 1 );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
idLexer src( LEXFL_NOFATALERRORS );
|
|
|
|
src.LoadMemory( blocks[i].postfix.c_str(), blocks[i].postfix.Length(), name );
|
2012-11-28 15:47:07 +00:00
|
|
|
while( src.ReadToken( &token ) )
|
|
|
|
{
|
|
|
|
for( int j = 0; j < blocks.Num(); j++ )
|
|
|
|
{
|
|
|
|
if( !blocks[j].used )
|
|
|
|
{
|
|
|
|
if( token == blocks[j].name )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
blocks[j].used = true;
|
|
|
|
stack.Append( j );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
idStr out;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
for( int i = 0; i < blocks.Num(); i++ )
|
|
|
|
{
|
|
|
|
if( blocks[i].used )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
out += blocks[i].prefix;
|
|
|
|
out += ' ';
|
|
|
|
out += blocks[i].name;
|
|
|
|
out += ' ';
|
|
|
|
out += blocks[i].postfix;
|
|
|
|
out += '\n';
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
struct typeConversion_t
|
|
|
|
{
|
|
|
|
const char* typeCG;
|
|
|
|
const char* typeGLSL;
|
|
|
|
} typeConversion[] =
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
{ "void", "void" },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
{ "fixed", "float" },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
{ "float", "float" },
|
|
|
|
{ "float2", "vec2" },
|
|
|
|
{ "float3", "vec3" },
|
|
|
|
{ "float4", "vec4" },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
{ "half", "float" },
|
|
|
|
{ "half2", "vec2" },
|
|
|
|
{ "half3", "vec3" },
|
|
|
|
{ "half4", "vec4" },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
{ "int", "int" },
|
|
|
|
{ "int2", "ivec2" },
|
|
|
|
{ "int3", "ivec3" },
|
|
|
|
{ "int4", "ivec4" },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
{ "bool", "bool" },
|
|
|
|
{ "bool2", "bvec2" },
|
|
|
|
{ "bool3", "bvec3" },
|
|
|
|
{ "bool4", "bvec4" },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
{ "float2x2", "mat2x2" },
|
|
|
|
{ "float2x3", "mat2x3" },
|
|
|
|
{ "float2x4", "mat2x4" },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
{ "float3x2", "mat3x2" },
|
|
|
|
{ "float3x3", "mat3x3" },
|
|
|
|
{ "float3x4", "mat3x4" },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
{ "float4x2", "mat4x2" },
|
|
|
|
{ "float4x3", "mat4x3" },
|
|
|
|
{ "float4x4", "mat4x4" },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
{ "sampler1D", "sampler1D" },
|
|
|
|
{ "sampler2D", "sampler2D" },
|
|
|
|
{ "sampler3D", "sampler3D" },
|
|
|
|
{ "samplerCUBE", "samplerCube" },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
{ "sampler1DShadow", "sampler1DShadow" },
|
|
|
|
{ "sampler2DShadow", "sampler2DShadow" },
|
|
|
|
{ "sampler3DShadow", "sampler3DShadow" },
|
|
|
|
{ "samplerCubeShadow", "samplerCubeShadow" },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
{ "sampler2DMS", "sampler2DMS" },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
// RB: HACK convert all text2D stuff to modern texture() usage
|
|
|
|
{ "texCUBE", "texture" },
|
|
|
|
{ "tex2Dproj", "textureProj" },
|
|
|
|
{ "tex2D", "texture" },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
{ NULL, NULL }
|
2014-04-20 14:29:58 +00:00
|
|
|
};
|
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
const char* vertexInsert =
|
2014-05-11 09:30:56 +00:00
|
|
|
{
|
2018-10-07 14:42:28 +00:00
|
|
|
"#version 450\n"
|
|
|
|
"#pragma shader_stage( vertex )\n"
|
|
|
|
"#extension GL_ARB_separate_shader_objects : enable\n"
|
|
|
|
//"#define PC\n"
|
2014-05-11 09:30:56 +00:00
|
|
|
"\n"
|
2018-10-07 14:42:28 +00:00
|
|
|
//"float saturate( float v ) { return clamp( v, 0.0, 1.0 ); }\n"
|
|
|
|
//"vec2 saturate( vec2 v ) { return clamp( v, 0.0, 1.0 ); }\n"
|
|
|
|
//"vec3 saturate( vec3 v ) { return clamp( v, 0.0, 1.0 ); }\n"
|
|
|
|
//"vec4 saturate( vec4 v ) { return clamp( v, 0.0, 1.0 ); }\n"
|
2014-05-11 09:30:56 +00:00
|
|
|
//"vec4 tex2Dlod( sampler2D sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.xy, texcoord.w ); }\n"
|
2018-10-07 14:42:28 +00:00
|
|
|
//"\n"
|
2012-11-26 18:58:24 +00:00
|
|
|
};
|
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
const char* fragmentInsert =
|
2014-04-20 14:29:58 +00:00
|
|
|
{
|
2018-10-07 14:42:28 +00:00
|
|
|
"#version 450\n"
|
|
|
|
"#pragma shader_stage( fragment )\n"
|
|
|
|
"#extension GL_ARB_separate_shader_objects : enable\n"
|
|
|
|
//"#define PC\n"
|
2014-04-20 14:29:58 +00:00
|
|
|
"\n"
|
|
|
|
"void clip( float v ) { if ( v < 0.0 ) { discard; } }\n"
|
|
|
|
"void clip( vec2 v ) { if ( any( lessThan( v, vec2( 0.0 ) ) ) ) { discard; } }\n"
|
|
|
|
"void clip( vec3 v ) { if ( any( lessThan( v, vec3( 0.0 ) ) ) ) { discard; } }\n"
|
|
|
|
"void clip( vec4 v ) { if ( any( lessThan( v, vec4( 0.0 ) ) ) ) { discard; } }\n"
|
|
|
|
"\n"
|
|
|
|
"float saturate( float v ) { return clamp( v, 0.0, 1.0 ); }\n"
|
|
|
|
"vec2 saturate( vec2 v ) { return clamp( v, 0.0, 1.0 ); }\n"
|
|
|
|
"vec3 saturate( vec3 v ) { return clamp( v, 0.0, 1.0 ); }\n"
|
|
|
|
"vec4 saturate( vec4 v ) { return clamp( v, 0.0, 1.0 ); }\n"
|
|
|
|
"\n"
|
2018-10-07 14:42:28 +00:00
|
|
|
//"vec4 tex2D( sampler2D sampler, vec2 texcoord ) { return texture( sampler, texcoord.xy ); }\n"
|
2014-04-20 14:29:58 +00:00
|
|
|
//"vec4 tex2D( sampler2DShadow sampler, vec3 texcoord ) { return vec4( texture( sampler, texcoord.xyz ) ); }\n"
|
2018-10-07 14:42:28 +00:00
|
|
|
//"\n"
|
2014-04-20 14:29:58 +00:00
|
|
|
//"vec4 tex2D( sampler2D sampler, vec2 texcoord, vec2 dx, vec2 dy ) { return textureGrad( sampler, texcoord.xy, dx, dy ); }\n"
|
|
|
|
//"vec4 tex2D( sampler2DShadow sampler, vec3 texcoord, vec2 dx, vec2 dy ) { return vec4( textureGrad( sampler, texcoord.xyz, dx, dy ) ); }\n"
|
|
|
|
//"\n"
|
2018-10-07 14:42:28 +00:00
|
|
|
//"vec4 texCUBE( samplerCube sampler, vec3 texcoord ) { return texture( sampler, texcoord.xyz ); }\n"
|
|
|
|
//"vec4 texCUBE( samplerCubeShadow sampler, vec4 texcoord ) { return vec4( texture( sampler, texcoord.xyzw ) ); }\n"
|
|
|
|
//"\n"
|
2014-04-20 14:29:58 +00:00
|
|
|
//"vec4 tex1Dproj( sampler1D sampler, vec2 texcoord ) { return textureProj( sampler, texcoord ); }\n"
|
2018-10-07 14:42:28 +00:00
|
|
|
//"vec4 tex2Dproj( sampler2D sampler, vec3 texcoord ) { return textureProj( sampler, texcoord ); }\n"
|
2014-04-20 14:29:58 +00:00
|
|
|
//"vec4 tex3Dproj( sampler3D sampler, vec4 texcoord ) { return textureProj( sampler, texcoord ); }\n"
|
2018-10-07 14:42:28 +00:00
|
|
|
//"\n"
|
2014-04-20 14:29:58 +00:00
|
|
|
//"vec4 tex1Dbias( sampler1D sampler, vec4 texcoord ) { return texture( sampler, texcoord.x, texcoord.w ); }\n"
|
|
|
|
//"vec4 tex2Dbias( sampler2D sampler, vec4 texcoord ) { return texture( sampler, texcoord.xy, texcoord.w ); }\n"
|
|
|
|
//"vec4 tex3Dbias( sampler3D sampler, vec4 texcoord ) { return texture( sampler, texcoord.xyz, texcoord.w ); }\n"
|
|
|
|
//"vec4 texCUBEbias( samplerCube sampler, vec4 texcoord ) { return texture( sampler, texcoord.xyz, texcoord.w ); }\n"
|
|
|
|
//"\n"
|
|
|
|
//"vec4 tex1Dlod( sampler1D sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.x, texcoord.w ); }\n"
|
|
|
|
//"vec4 tex2Dlod( sampler2D sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.xy, texcoord.w ); }\n"
|
|
|
|
//"vec4 tex3Dlod( sampler3D sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.xyz, texcoord.w ); }\n"
|
|
|
|
//"vec4 texCUBElod( samplerCube sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.xyz, texcoord.w ); }\n"
|
|
|
|
//"\n"
|
|
|
|
};
|
2018-10-07 14:42:28 +00:00
|
|
|
|
|
|
|
// RB begin
|
|
|
|
const char* vertexInsert_GLSL_ES_3_00 =
|
2014-04-20 14:29:58 +00:00
|
|
|
{
|
2018-10-07 14:42:28 +00:00
|
|
|
"#version 300 es\n"
|
2014-04-20 14:29:58 +00:00
|
|
|
"#define PC\n"
|
|
|
|
"precision mediump float;\n"
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
//"#extension GL_ARB_gpu_shader5 : enable\n"
|
2014-04-20 14:29:58 +00:00
|
|
|
"\n"
|
|
|
|
"float saturate( float v ) { return clamp( v, 0.0, 1.0 ); }\n"
|
|
|
|
"vec2 saturate( vec2 v ) { return clamp( v, 0.0, 1.0 ); }\n"
|
|
|
|
"vec3 saturate( vec3 v ) { return clamp( v, 0.0, 1.0 ); }\n"
|
|
|
|
"vec4 saturate( vec4 v ) { return clamp( v, 0.0, 1.0 ); }\n"
|
|
|
|
//"vec4 tex2Dlod( sampler2D sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.xy, texcoord.w ); }\n"
|
2018-10-07 14:42:28 +00:00
|
|
|
"\n"
|
2014-04-20 14:29:58 +00:00
|
|
|
};
|
|
|
|
|
2014-05-11 09:30:56 +00:00
|
|
|
const char* fragmentInsert_GLSL_ES_3_00 =
|
|
|
|
{
|
|
|
|
"#version 300 es\n"
|
|
|
|
"#define PC\n"
|
|
|
|
"precision mediump float;\n"
|
2015-11-17 11:46:45 +00:00
|
|
|
"precision lowp sampler2D;\n"
|
|
|
|
"precision lowp sampler2DShadow;\n"
|
|
|
|
"precision lowp sampler2DArray;\n"
|
|
|
|
"precision lowp sampler2DArrayShadow;\n"
|
|
|
|
"precision lowp samplerCube;\n"
|
|
|
|
"precision lowp samplerCubeShadow;\n"
|
|
|
|
"precision lowp sampler3D;\n"
|
2014-05-11 09:30:56 +00:00
|
|
|
"\n"
|
|
|
|
"void clip( float v ) { if ( v < 0.0 ) { discard; } }\n"
|
|
|
|
"void clip( vec2 v ) { if ( any( lessThan( v, vec2( 0.0 ) ) ) ) { discard; } }\n"
|
|
|
|
"void clip( vec3 v ) { if ( any( lessThan( v, vec3( 0.0 ) ) ) ) { discard; } }\n"
|
|
|
|
"void clip( vec4 v ) { if ( any( lessThan( v, vec4( 0.0 ) ) ) ) { discard; } }\n"
|
|
|
|
"\n"
|
|
|
|
"float saturate( float v ) { return clamp( v, 0.0, 1.0 ); }\n"
|
|
|
|
"vec2 saturate( vec2 v ) { return clamp( v, 0.0, 1.0 ); }\n"
|
|
|
|
"vec3 saturate( vec3 v ) { return clamp( v, 0.0, 1.0 ); }\n"
|
|
|
|
"vec4 saturate( vec4 v ) { return clamp( v, 0.0, 1.0 ); }\n"
|
|
|
|
"\n"
|
|
|
|
"vec4 tex2D( sampler2D sampler, vec2 texcoord ) { return texture( sampler, texcoord.xy ); }\n"
|
|
|
|
"vec4 tex2D( sampler2DShadow sampler, vec3 texcoord ) { return vec4( texture( sampler, texcoord.xyz ) ); }\n"
|
|
|
|
"\n"
|
|
|
|
"vec4 tex2D( sampler2D sampler, vec2 texcoord, vec2 dx, vec2 dy ) { return textureGrad( sampler, texcoord.xy, dx, dy ); }\n"
|
|
|
|
"vec4 tex2D( sampler2DShadow sampler, vec3 texcoord, vec2 dx, vec2 dy ) { return vec4( textureGrad( sampler, texcoord.xyz, dx, dy ) ); }\n"
|
|
|
|
"\n"
|
|
|
|
"vec4 texCUBE( samplerCube sampler, vec3 texcoord ) { return texture( sampler, texcoord.xyz ); }\n"
|
|
|
|
"vec4 texCUBE( samplerCubeShadow sampler, vec4 texcoord ) { return vec4( texture( sampler, texcoord.xyzw ) ); }\n"
|
|
|
|
"\n"
|
|
|
|
//"vec4 tex1Dproj( sampler1D sampler, vec2 texcoord ) { return textureProj( sampler, texcoord ); }\n"
|
|
|
|
"vec4 tex2Dproj( sampler2D sampler, vec3 texcoord ) { return textureProj( sampler, texcoord ); }\n"
|
|
|
|
"vec4 tex3Dproj( sampler3D sampler, vec4 texcoord ) { return textureProj( sampler, texcoord ); }\n"
|
|
|
|
"\n"
|
|
|
|
//"vec4 tex1Dbias( sampler1D sampler, vec4 texcoord ) { return texture( sampler, texcoord.x, texcoord.w ); }\n"
|
|
|
|
"vec4 tex2Dbias( sampler2D sampler, vec4 texcoord ) { return texture( sampler, texcoord.xy, texcoord.w ); }\n"
|
|
|
|
"vec4 tex3Dbias( sampler3D sampler, vec4 texcoord ) { return texture( sampler, texcoord.xyz, texcoord.w ); }\n"
|
|
|
|
"vec4 texCUBEbias( samplerCube sampler, vec4 texcoord ) { return texture( sampler, texcoord.xyz, texcoord.w ); }\n"
|
|
|
|
"\n"
|
|
|
|
//"vec4 tex1Dlod( sampler1D sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.x, texcoord.w ); }\n"
|
|
|
|
"vec4 tex2Dlod( sampler2D sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.xy, texcoord.w ); }\n"
|
|
|
|
"vec4 tex3Dlod( sampler3D sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.xyz, texcoord.w ); }\n"
|
|
|
|
"vec4 texCUBElod( samplerCube sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.xyz, texcoord.w ); }\n"
|
|
|
|
"\n"
|
|
|
|
};
|
2014-04-20 14:29:58 +00:00
|
|
|
// RB end
|
2012-11-26 18:58:24 +00:00
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
struct builtinConversion_t
|
|
|
|
{
|
|
|
|
const char* nameCG;
|
|
|
|
const char* nameGLSL;
|
|
|
|
} builtinConversion[] =
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
{ "frac", "fract" },
|
|
|
|
{ "lerp", "mix" },
|
|
|
|
{ "rsqrt", "inversesqrt" },
|
|
|
|
{ "ddx", "dFdx" },
|
|
|
|
{ "ddy", "dFdy" },
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
{ NULL, NULL }
|
|
|
|
};
|
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
struct inOutVariable_t
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
idStr type;
|
|
|
|
idStr nameCg;
|
|
|
|
idStr nameGLSL;
|
|
|
|
bool declareInOut;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
========================
|
|
|
|
ParseInOutStruct
|
|
|
|
========================
|
|
|
|
*/
|
2019-11-11 19:07:33 +00:00
|
|
|
void ParseInOutStruct( idLexer& src, int attribType, int attribIgnoreType, idList< inOutVariable_t >& inOutVars, bool in_Position4 )
|
2012-11-28 15:47:07 +00:00
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
src.ExpectTokenString( "{" );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
while( !src.CheckTokenString( "}" ) )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
inOutVariable_t var;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
idToken token;
|
|
|
|
src.ReadToken( &token );
|
|
|
|
var.type = token;
|
|
|
|
src.ReadToken( &token );
|
|
|
|
var.nameCg = token;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
if( !src.CheckTokenString( ":" ) )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
src.SkipUntilString( ";" );
|
|
|
|
continue;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
src.ReadToken( &token );
|
|
|
|
var.nameGLSL = token;
|
|
|
|
src.ExpectTokenString( ";" );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// convert the type
|
2012-11-28 15:47:07 +00:00
|
|
|
for( int i = 0; typeConversion[i].typeCG != NULL; i++ )
|
|
|
|
{
|
|
|
|
if( var.type.Cmp( typeConversion[i].typeCG ) == 0 )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
var.type = typeConversion[i].typeGLSL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// convert the semantic to a GLSL name
|
2012-11-28 15:47:07 +00:00
|
|
|
for( int i = 0; attribsPC[i].semantic != NULL; i++ )
|
|
|
|
{
|
|
|
|
if( ( attribsPC[i].flags & attribType ) != 0 )
|
|
|
|
{
|
|
|
|
if( var.nameGLSL.Cmp( attribsPC[i].semantic ) == 0 )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
var.nameGLSL = attribsPC[i].glsl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// check if it was defined previously
|
|
|
|
var.declareInOut = true;
|
2012-11-28 15:47:07 +00:00
|
|
|
for( int i = 0; i < inOutVars.Num(); i++ )
|
|
|
|
{
|
|
|
|
if( var.nameGLSL == inOutVars[i].nameGLSL )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
var.declareInOut = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-04-20 14:29:58 +00:00
|
|
|
// RB: ignore reserved builtin gl_ uniforms
|
2015-12-20 11:28:46 +00:00
|
|
|
//switch( glConfig.driverType )
|
2014-04-20 14:29:58 +00:00
|
|
|
{
|
2015-01-18 11:13:24 +00:00
|
|
|
//case GLDRV_OPENGL32_CORE_PROFILE:
|
|
|
|
//case GLDRV_OPENGL_ES2:
|
|
|
|
//case GLDRV_OPENGL_ES3:
|
|
|
|
//case GLDRV_OPENGL_MESA:
|
2015-12-20 11:28:46 +00:00
|
|
|
//default:
|
2014-04-20 14:29:58 +00:00
|
|
|
{
|
|
|
|
for( int i = 0; attribsPC[i].semantic != NULL; i++ )
|
|
|
|
{
|
|
|
|
if( var.nameGLSL.Cmp( attribsPC[i].glsl ) == 0 )
|
|
|
|
{
|
|
|
|
if( ( attribsPC[i].flags & attribIgnoreType ) != 0 )
|
|
|
|
{
|
|
|
|
var.declareInOut = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2015-12-20 11:28:46 +00:00
|
|
|
//break;
|
2014-04-20 14:29:58 +00:00
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
if( glConfig.driverType == GLDRV_VULKAN )
|
|
|
|
{
|
|
|
|
// RB: HACK change vec4 in_Position to vec3
|
2019-11-11 19:07:33 +00:00
|
|
|
if( !in_Position4 && var.nameGLSL == "in_Position" && var.type == "vec4" )
|
2018-10-07 14:42:28 +00:00
|
|
|
{
|
|
|
|
var.type = "vec3";
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
inOutVars.Append( var );
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
src.ExpectTokenString( ";" );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
========================
|
|
|
|
ConvertCG2GLSL
|
|
|
|
========================
|
|
|
|
*/
|
2019-11-11 19:07:33 +00:00
|
|
|
idStr idRenderProgManager::ConvertCG2GLSL( const idStr& in, const char* name, rpStage_t stage, idStr& outLayout, bool vkGLSL, bool hasGPUSkinning, vertexLayoutType_t vertexLayout )
|
2012-11-28 15:47:07 +00:00
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
idStr program;
|
|
|
|
program.ReAllocate( in.Length() * 2, false );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
idList< inOutVariable_t, TAG_RENDERPROG > varsIn;
|
|
|
|
idList< inOutVariable_t, TAG_RENDERPROG > varsOut;
|
|
|
|
idList< idStr > uniformList;
|
2018-10-07 14:42:28 +00:00
|
|
|
idList< idStr > samplerList;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
idLexer src( LEXFL_NOFATALERRORS );
|
|
|
|
src.LoadMemory( in.c_str(), in.Length(), name );
|
2019-11-11 19:07:33 +00:00
|
|
|
|
|
|
|
bool in_Position4 = ( vertexLayout == LAYOUT_DRAW_SHADOW_VERT ) || ( vertexLayout == LAYOUT_DRAW_SHADOW_VERT_SKINNED );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
bool inMain = false;
|
2018-10-07 14:42:28 +00:00
|
|
|
bool justEnteredMain = false;
|
2018-11-04 18:57:53 +00:00
|
|
|
const char* uniformArrayName = ( stage == SHADER_STAGE_VERTEX ) ? VERTEX_UNIFORM_ARRAY_NAME : FRAGMENT_UNIFORM_ARRAY_NAME;
|
2012-11-26 18:58:24 +00:00
|
|
|
char newline[128] = { "\n" };
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
idToken token;
|
2012-11-28 15:47:07 +00:00
|
|
|
while( src.ReadToken( &token ) )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
// check for uniforms
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
// RB: added special case for matrix arrays
|
|
|
|
while( token == "uniform" && ( src.CheckTokenString( "float4" ) || src.CheckTokenString( "float4x4" ) ) )
|
2012-11-28 15:47:07 +00:00
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
src.ReadToken( &token );
|
2014-05-10 12:40:01 +00:00
|
|
|
idStr uniform = token;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// strip ': register()' from uniforms
|
2012-11-28 15:47:07 +00:00
|
|
|
if( src.CheckTokenString( ":" ) )
|
|
|
|
{
|
|
|
|
if( src.CheckTokenString( "register" ) )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
src.SkipUntilString( ";" );
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
if( src.PeekTokenString( "[" ) )
|
|
|
|
{
|
|
|
|
while( src.ReadToken( &token ) )
|
|
|
|
{
|
|
|
|
uniform += token;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
if( token == "]" )
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
uniformList.Append( uniform );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
src.ReadToken( &token );
|
2012-11-26 18:58:24 +00:00
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
// RB: check for sampler uniforms
|
|
|
|
if( vkGLSL )
|
|
|
|
{
|
2018-10-28 15:11:05 +00:00
|
|
|
while( token == "uniform" &&
|
|
|
|
( src.PeekTokenString( "sampler2D" ) ||
|
|
|
|
src.PeekTokenString( "samplerCUBE" ) ||
|
|
|
|
src.PeekTokenString( "sampler3D" ) ||
|
|
|
|
src.PeekTokenString( "sampler2DArrayShadow" ) ||
|
|
|
|
src.PeekTokenString( "sampler2DArray" ) ) )
|
2018-10-07 14:42:28 +00:00
|
|
|
{
|
|
|
|
idStr sampler;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
// sampler2D or whatever
|
|
|
|
src.ReadToken( &token );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
// HACK
|
|
|
|
if( token == "samplerCUBE" )
|
|
|
|
{
|
|
|
|
sampler += "samplerCube";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sampler += token;
|
|
|
|
}
|
|
|
|
sampler += " ";
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
// the actual variable name
|
|
|
|
src.ReadToken( &token );
|
|
|
|
sampler += token;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
samplerList.Append( sampler );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
// strip ': register()' from uniforms
|
|
|
|
if( src.CheckTokenString( ":" ) )
|
|
|
|
{
|
|
|
|
if( src.CheckTokenString( "register" ) )
|
|
|
|
{
|
|
|
|
src.SkipUntilString( ";" );
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
src.ReadToken( &token );
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-11-04 18:57:53 +00:00
|
|
|
// RB: HACK to add matrices uniform block layer
|
|
|
|
if( token == "uniform" && src.PeekTokenString( "matrices_ubo" ) )
|
|
|
|
{
|
|
|
|
hasGPUSkinning = true;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-11-04 18:57:53 +00:00
|
|
|
//src.ReadToken( &token );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-11-04 18:57:53 +00:00
|
|
|
//src.SkipRestOfLine();
|
|
|
|
//program += "\nlayout( binding = 1 ) ";
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-11-04 18:57:53 +00:00
|
|
|
src.SkipRestOfLine();
|
|
|
|
continue;
|
|
|
|
}
|
2018-10-07 14:42:28 +00:00
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// convert the in/out structs
|
2012-11-28 15:47:07 +00:00
|
|
|
if( token == "struct" )
|
|
|
|
{
|
|
|
|
if( src.CheckTokenString( "VS_IN" ) )
|
|
|
|
{
|
2019-11-11 19:07:33 +00:00
|
|
|
ParseInOutStruct( src, AT_VS_IN, 0, varsIn, in_Position4 );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
program += "\n\n";
|
2012-11-28 15:47:07 +00:00
|
|
|
for( int i = 0; i < varsIn.Num(); i++ )
|
|
|
|
{
|
|
|
|
if( varsIn[i].declareInOut )
|
|
|
|
{
|
2018-10-07 14:42:28 +00:00
|
|
|
// RB: add layout locations
|
|
|
|
if( vkGLSL )
|
2014-04-20 14:29:58 +00:00
|
|
|
{
|
2018-10-07 14:42:28 +00:00
|
|
|
program += va( "layout( location = %i ) in %s %s;\n", i, varsIn[i].type.c_str(), varsIn[i].nameGLSL.c_str() );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
program += "in " + varsIn[i].type + " " + varsIn[i].nameGLSL + ";\n";
|
2014-04-20 14:29:58 +00:00
|
|
|
}
|
2012-11-26 18:58:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
continue;
|
2012-11-28 15:47:07 +00:00
|
|
|
}
|
|
|
|
else if( src.CheckTokenString( "VS_OUT" ) )
|
|
|
|
{
|
2018-10-07 14:42:28 +00:00
|
|
|
// RB
|
2019-11-11 19:07:33 +00:00
|
|
|
ParseInOutStruct( src, AT_VS_OUT, AT_VS_OUT_RESERVED, varsOut, in_Position4 );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
program += "\n";
|
2018-11-02 09:17:53 +00:00
|
|
|
int numDeclareOut = 0;
|
2012-11-28 15:47:07 +00:00
|
|
|
for( int i = 0; i < varsOut.Num(); i++ )
|
|
|
|
{
|
|
|
|
if( varsOut[i].declareInOut )
|
|
|
|
{
|
2018-10-07 14:42:28 +00:00
|
|
|
// RB: add layout locations
|
|
|
|
if( vkGLSL )
|
2014-04-20 14:29:58 +00:00
|
|
|
{
|
2018-11-02 09:17:53 +00:00
|
|
|
program += va( "layout( location = %i ) out %s %s;\n", numDeclareOut, varsOut[i].type.c_str(), varsOut[i].nameGLSL.c_str() );
|
2018-10-07 14:42:28 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
program += "out " + varsOut[i].type + " " + varsOut[i].nameGLSL + ";\n";
|
2014-04-20 14:29:58 +00:00
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-11-02 09:17:53 +00:00
|
|
|
numDeclareOut++;
|
2012-11-26 18:58:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
continue;
|
2012-11-28 15:47:07 +00:00
|
|
|
}
|
|
|
|
else if( src.CheckTokenString( "PS_IN" ) )
|
|
|
|
{
|
2019-11-11 19:07:33 +00:00
|
|
|
ParseInOutStruct( src, AT_PS_IN, AT_PS_IN_RESERVED, varsIn, in_Position4 );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
program += "\n\n";
|
2018-11-02 09:17:53 +00:00
|
|
|
int numDeclareOut = 0;
|
2012-11-28 15:47:07 +00:00
|
|
|
for( int i = 0; i < varsIn.Num(); i++ )
|
|
|
|
{
|
|
|
|
if( varsIn[i].declareInOut )
|
|
|
|
{
|
2018-10-07 14:42:28 +00:00
|
|
|
// RB: add layout locations
|
|
|
|
if( vkGLSL )
|
2014-04-20 14:29:58 +00:00
|
|
|
{
|
2018-11-02 09:17:53 +00:00
|
|
|
program += va( "layout( location = %i ) in %s %s;\n", numDeclareOut, varsIn[i].type.c_str(), varsIn[i].nameGLSL.c_str() );
|
2018-10-07 14:42:28 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
program += "in " + varsIn[i].type + " " + varsIn[i].nameGLSL + ";\n";
|
2014-04-20 14:29:58 +00:00
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-11-02 09:17:53 +00:00
|
|
|
numDeclareOut++;
|
2012-11-26 18:58:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
inOutVariable_t var;
|
|
|
|
var.type = "vec4";
|
|
|
|
var.nameCg = "position";
|
|
|
|
var.nameGLSL = "gl_FragCoord";
|
|
|
|
varsIn.Append( var );
|
|
|
|
continue;
|
2012-11-28 15:47:07 +00:00
|
|
|
}
|
|
|
|
else if( src.CheckTokenString( "PS_OUT" ) )
|
|
|
|
{
|
2014-04-20 14:29:58 +00:00
|
|
|
// RB begin
|
2019-11-11 19:07:33 +00:00
|
|
|
ParseInOutStruct( src, AT_PS_OUT, AT_PS_OUT_RESERVED, varsOut, in_Position4 );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
program += "\n";
|
2012-11-28 15:47:07 +00:00
|
|
|
for( int i = 0; i < varsOut.Num(); i++ )
|
|
|
|
{
|
|
|
|
if( varsOut[i].declareInOut )
|
|
|
|
{
|
2018-10-07 14:42:28 +00:00
|
|
|
// RB: add layout locations
|
|
|
|
if( vkGLSL )
|
|
|
|
{
|
|
|
|
program += va( "layout( location = %i ) out %s %s;\n", i, varsOut[i].type.c_str(), varsOut[i].nameGLSL.c_str() );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
program += "out " + varsOut[i].type + " " + varsOut[i].nameGLSL + ";\n";
|
|
|
|
}
|
2012-11-26 18:58:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// strip 'static'
|
2012-11-28 15:47:07 +00:00
|
|
|
if( token == "static" )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
|
|
|
|
src.SkipWhiteSpace( true ); // remove white space between 'static' and the next token
|
|
|
|
continue;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// strip ': register()' from uniforms
|
2012-11-28 15:47:07 +00:00
|
|
|
if( token == ":" )
|
|
|
|
{
|
|
|
|
if( src.CheckTokenString( "register" ) )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
src.SkipUntilString( ";" );
|
|
|
|
program += ";";
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// strip in/program parameters from main
|
2012-11-28 15:47:07 +00:00
|
|
|
if( token == "void" && src.CheckTokenString( "main" ) )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
src.ExpectTokenString( "(" );
|
2012-11-28 15:47:07 +00:00
|
|
|
while( src.ReadToken( &token ) )
|
|
|
|
{
|
|
|
|
if( token == ")" )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
program += "\nvoid main()";
|
|
|
|
inMain = true;
|
|
|
|
continue;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// strip 'const' from local variables in main()
|
2012-11-28 15:47:07 +00:00
|
|
|
if( token == "const" && inMain )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
|
|
|
|
src.SkipWhiteSpace( true ); // remove white space between 'const' and the next token
|
|
|
|
continue;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// maintain indentation
|
2012-11-28 15:47:07 +00:00
|
|
|
if( token == "{" )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
|
|
|
|
program += "{";
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
int len = Min( idStr::Length( newline ) + 1, ( int )sizeof( newline ) - 1 );
|
2012-11-26 18:58:24 +00:00
|
|
|
newline[len - 1] = '\t';
|
|
|
|
newline[len - 0] = '\0';
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
// RB: add this to every vertex shader
|
2019-11-11 19:07:33 +00:00
|
|
|
if( inMain && !justEnteredMain && ( stage == SHADER_STAGE_VERTEX ) && vkGLSL && !in_Position4 )
|
2018-10-07 14:42:28 +00:00
|
|
|
{
|
2018-11-02 09:17:53 +00:00
|
|
|
program += "\n\tvec4 position4 = vec4( in_Position, 1.0 );\n";
|
2018-10-07 14:42:28 +00:00
|
|
|
justEnteredMain = true;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
continue;
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
if( token == "}" )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
int len = Max( idStr::Length( newline ) - 1, 0 );
|
|
|
|
newline[len] = '\0';
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
|
|
|
|
program += "}";
|
|
|
|
continue;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// check for a type conversion
|
|
|
|
bool foundType = false;
|
2012-11-28 15:47:07 +00:00
|
|
|
for( int i = 0; typeConversion[i].typeCG != NULL; i++ )
|
|
|
|
{
|
|
|
|
if( token.Cmp( typeConversion[i].typeCG ) == 0 )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
|
|
|
|
program += typeConversion[i].typeGLSL;
|
|
|
|
foundType = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
if( foundType )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
continue;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
// check for uniforms that need to be converted to the array
|
|
|
|
bool isUniform = false;
|
|
|
|
for( int i = 0; i < uniformList.Num(); i++ )
|
2012-11-28 15:47:07 +00:00
|
|
|
{
|
2018-10-07 14:42:28 +00:00
|
|
|
if( token == uniformList[i] )
|
2012-11-28 15:47:07 +00:00
|
|
|
{
|
2018-10-07 14:42:28 +00:00
|
|
|
program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
// RB: for some unknown reasons has the Nvidia driver problems with regular uniforms when using glUniform4fv
|
|
|
|
// so we need these uniform arrays
|
|
|
|
// I added special check rpShadowMatrices so we can still index the uniforms from the shader
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
if( idStr::Cmp( uniformList[i].c_str(), "rpShadowMatrices" ) == 0 )
|
2012-11-28 15:47:07 +00:00
|
|
|
{
|
2018-10-28 15:11:05 +00:00
|
|
|
if( vkGLSL )
|
|
|
|
{
|
|
|
|
program += va( "%s[ ", uniformList[i].c_str() );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
program += va( "%s[/* %s */ %d + ", uniformArrayName, uniformList[i].c_str(), i );
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
if( src.ExpectTokenString( "[" ) )
|
2014-05-10 12:40:01 +00:00
|
|
|
{
|
2018-10-07 14:42:28 +00:00
|
|
|
idStr uniformIndexing;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
while( src.ReadToken( &token ) )
|
2014-05-10 12:40:01 +00:00
|
|
|
{
|
2018-10-07 14:42:28 +00:00
|
|
|
if( token == "]" )
|
2014-05-10 12:40:01 +00:00
|
|
|
{
|
2018-10-07 14:42:28 +00:00
|
|
|
break;
|
2014-05-10 12:40:01 +00:00
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
uniformIndexing += token;
|
|
|
|
uniformIndexing += " ";
|
2014-05-10 12:40:01 +00:00
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
program += uniformIndexing + "]";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( vkGLSL )
|
|
|
|
{
|
|
|
|
program += va( "%s", uniformList[i].c_str() );
|
2014-05-10 12:40:01 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
program += va( "%s[%d /* %s */]", uniformArrayName, i, uniformList[i].c_str() );
|
|
|
|
}
|
2012-11-26 18:58:24 +00:00
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
isUniform = true;
|
|
|
|
break;
|
2012-11-26 18:58:24 +00:00
|
|
|
}
|
2018-10-07 14:42:28 +00:00
|
|
|
}
|
|
|
|
if( isUniform )
|
|
|
|
{
|
|
|
|
continue;
|
2012-11-26 18:58:24 +00:00
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// check for input/output parameters
|
2012-11-28 15:47:07 +00:00
|
|
|
if( src.CheckTokenString( "." ) )
|
|
|
|
{
|
|
|
|
if( token == "vertex" || token == "fragment" )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
idToken member;
|
|
|
|
src.ReadToken( &member );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
bool foundInOut = false;
|
2012-11-28 15:47:07 +00:00
|
|
|
for( int i = 0; i < varsIn.Num(); i++ )
|
|
|
|
{
|
|
|
|
if( member.Cmp( varsIn[i].nameCg ) == 0 )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
/*
|
|
|
|
RB: HACK use position4 instead of in_Position directly
|
|
|
|
because I can't figure out how to do strides with Vulkan
|
|
|
|
*/
|
2019-11-11 19:07:33 +00:00
|
|
|
if( !in_Position4 && vkGLSL && ( varsIn[i].nameGLSL == "in_Position" ) )
|
2018-10-07 14:42:28 +00:00
|
|
|
{
|
|
|
|
program += "position4";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
program += varsIn[i].nameGLSL;
|
|
|
|
}
|
2012-11-26 18:58:24 +00:00
|
|
|
foundInOut = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
if( !foundInOut )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
src.Error( "invalid input parameter %s.%s", token.c_str(), member.c_str() );
|
|
|
|
program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
|
|
|
|
program += token;
|
|
|
|
program += ".";
|
|
|
|
program += member;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
if( token == "result" )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
idToken member;
|
|
|
|
src.ReadToken( &member );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
bool foundInOut = false;
|
2012-11-28 15:47:07 +00:00
|
|
|
for( int i = 0; i < varsOut.Num(); i++ )
|
|
|
|
{
|
|
|
|
if( member.Cmp( varsOut[i].nameCg ) == 0 )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
|
|
|
|
program += varsOut[i].nameGLSL;
|
|
|
|
foundInOut = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
if( !foundInOut )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
src.Error( "invalid output parameter %s.%s", token.c_str(), member.c_str() );
|
|
|
|
program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
|
|
|
|
program += token;
|
|
|
|
program += ".";
|
|
|
|
program += member;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
|
|
|
|
program += token;
|
|
|
|
program += ".";
|
|
|
|
continue;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// check for a function conversion
|
|
|
|
bool foundFunction = false;
|
2012-11-28 15:47:07 +00:00
|
|
|
for( int i = 0; builtinConversion[i].nameCG != NULL; i++ )
|
|
|
|
{
|
|
|
|
if( token.Cmp( builtinConversion[i].nameCG ) == 0 )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
|
|
|
|
program += builtinConversion[i].nameGLSL;
|
|
|
|
foundFunction = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
if( foundFunction )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
continue;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
|
|
|
|
program += token;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
idStr out;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2016-01-18 21:21:32 +00:00
|
|
|
// RB: tell shader debuggers what shader we look at
|
|
|
|
idStr filenameHint = "// filename " + idStr( name ) + "\n";
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-04-20 14:29:58 +00:00
|
|
|
// RB: changed to allow multiple versions of GLSL
|
2018-11-04 18:57:53 +00:00
|
|
|
if( ( stage == SHADER_STAGE_VERTEX ) )
|
2012-11-28 15:47:07 +00:00
|
|
|
{
|
2014-04-20 14:29:58 +00:00
|
|
|
switch( glConfig.driverType )
|
|
|
|
{
|
2014-05-11 09:30:56 +00:00
|
|
|
case GLDRV_OPENGL_MESA:
|
|
|
|
{
|
|
|
|
out.ReAllocate( idStr::Length( vertexInsert_GLSL_ES_3_00 ) + in.Length() * 2, false );
|
2016-01-18 21:21:32 +00:00
|
|
|
out += filenameHint;
|
2014-05-11 09:30:56 +00:00
|
|
|
out += vertexInsert_GLSL_ES_3_00;
|
|
|
|
break;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-04-20 14:29:58 +00:00
|
|
|
default:
|
|
|
|
{
|
2018-10-07 14:42:28 +00:00
|
|
|
out.ReAllocate( idStr::Length( vertexInsert ) + in.Length() * 2, false );
|
2016-01-18 21:21:32 +00:00
|
|
|
out += filenameHint;
|
2018-10-07 14:42:28 +00:00
|
|
|
out += vertexInsert;
|
2014-04-20 14:29:58 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-04-20 14:29:58 +00:00
|
|
|
switch( glConfig.driverType )
|
|
|
|
{
|
2014-05-11 09:30:56 +00:00
|
|
|
case GLDRV_OPENGL_MESA:
|
|
|
|
{
|
|
|
|
out.ReAllocate( idStr::Length( fragmentInsert_GLSL_ES_3_00 ) + in.Length() * 2, false );
|
2016-01-18 21:21:32 +00:00
|
|
|
out += filenameHint;
|
2014-05-11 09:30:56 +00:00
|
|
|
out += fragmentInsert_GLSL_ES_3_00;
|
|
|
|
break;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-04-20 14:29:58 +00:00
|
|
|
default:
|
|
|
|
{
|
2018-10-07 14:42:28 +00:00
|
|
|
out.ReAllocate( idStr::Length( fragmentInsert ) + in.Length() * 2, false );
|
2016-01-18 21:21:32 +00:00
|
|
|
out += filenameHint;
|
2018-10-07 14:42:28 +00:00
|
|
|
out += fragmentInsert;
|
2014-04-20 14:29:58 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-11-26 18:58:24 +00:00
|
|
|
}
|
2014-04-20 14:29:58 +00:00
|
|
|
// RB end
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
if( uniformList.Num() > 0 )
|
|
|
|
{
|
2018-10-07 14:42:28 +00:00
|
|
|
if( vkGLSL )
|
|
|
|
{
|
|
|
|
out += "\n";
|
2018-11-04 18:57:53 +00:00
|
|
|
if( ( stage == SHADER_STAGE_VERTEX ) )
|
2018-10-07 14:42:28 +00:00
|
|
|
{
|
|
|
|
out += "layout( binding = 0 ) uniform UBOV {\n";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-11-04 18:57:53 +00:00
|
|
|
//out += "layout( binding = 1 ) uniform UBOF {\n";
|
|
|
|
out += va( "layout( binding = %i ) uniform UBOF {\n", hasGPUSkinning ? 2 : 1 );
|
2018-10-07 14:42:28 +00:00
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
for( int i = 0; i < uniformList.Num(); i++ )
|
|
|
|
{
|
|
|
|
out += "\tvec4 ";
|
|
|
|
out += uniformList[i];
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-28 15:11:05 +00:00
|
|
|
// TODO fix this ugly hack
|
|
|
|
if( uniformList[i] == "rpShadowMatrices" )
|
|
|
|
{
|
|
|
|
out += "[6*4]";
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
out += ";\n";
|
|
|
|
}
|
|
|
|
out += "};\n";
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-11-04 18:57:53 +00:00
|
|
|
if( hasGPUSkinning && ( stage == SHADER_STAGE_VERTEX ) )
|
|
|
|
{
|
|
|
|
out += "\nlayout( binding = 1 ) uniform UBO_MAT {\n";
|
|
|
|
out += "\t vec4 matrices[ 408 ];\n";
|
|
|
|
out += "};\n";
|
|
|
|
}
|
2018-10-07 14:42:28 +00:00
|
|
|
}
|
|
|
|
else
|
2012-11-28 15:47:07 +00:00
|
|
|
{
|
2014-05-10 12:40:01 +00:00
|
|
|
int extraSize = 0;
|
|
|
|
for( int i = 0; i < uniformList.Num(); i++ )
|
|
|
|
{
|
|
|
|
if( idStr::Cmp( uniformList[i].c_str(), "rpShadowMatrices" ) == 0 )
|
|
|
|
{
|
|
|
|
extraSize += ( 6 * 4 );
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
out += va( "\nuniform vec4 %s[%d];\n", uniformArrayName, uniformList.Num() + extraSize );
|
2012-11-28 15:47:07 +00:00
|
|
|
}
|
2018-10-07 14:42:28 +00:00
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
// RB: add samplers with layout bindings
|
|
|
|
if( vkGLSL )
|
|
|
|
{
|
2018-11-04 18:57:53 +00:00
|
|
|
int bindingOffset = 1;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-11-04 18:57:53 +00:00
|
|
|
if( hasGPUSkinning )
|
|
|
|
{
|
|
|
|
bindingOffset++;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-11-04 18:57:53 +00:00
|
|
|
if( uniformList.Num() > 0 )
|
|
|
|
{
|
|
|
|
bindingOffset++;
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
for( int i = 0; i < samplerList.Num(); i++ )
|
2012-11-28 15:47:07 +00:00
|
|
|
{
|
2018-10-07 14:42:28 +00:00
|
|
|
out += va( "layout( binding = %i ) uniform %s;\n", i + bindingOffset , samplerList[i].c_str() );
|
2012-11-26 18:58:24 +00:00
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
out += program;
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2019-11-11 19:07:33 +00:00
|
|
|
outLayout += "uniforms [\n";
|
2012-11-28 15:47:07 +00:00
|
|
|
for( int i = 0; i < uniformList.Num(); i++ )
|
|
|
|
{
|
2019-11-11 19:07:33 +00:00
|
|
|
outLayout += "\t";
|
|
|
|
outLayout += uniformList[i];
|
|
|
|
outLayout += "\n";
|
2012-11-26 18:58:24 +00:00
|
|
|
}
|
2019-11-11 19:07:33 +00:00
|
|
|
outLayout += "]\n";
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2019-11-11 19:07:33 +00:00
|
|
|
outLayout += "bindings [\n";
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
if( uniformList.Num() > 0 )
|
|
|
|
{
|
2019-11-11 19:07:33 +00:00
|
|
|
outLayout += "\tubo\n";
|
2018-10-07 14:42:28 +00:00
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-11-04 18:57:53 +00:00
|
|
|
if( hasGPUSkinning && ( stage == SHADER_STAGE_VERTEX ) )
|
|
|
|
{
|
2019-11-11 19:07:33 +00:00
|
|
|
outLayout += "\tubo\n";
|
2018-11-04 18:57:53 +00:00
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-07 14:42:28 +00:00
|
|
|
for( int i = 0; i < samplerList.Num(); i++ )
|
|
|
|
{
|
2019-11-11 19:07:33 +00:00
|
|
|
outLayout += "\tsampler\n";
|
2018-10-07 14:42:28 +00:00
|
|
|
}
|
2019-11-11 19:07:33 +00:00
|
|
|
outLayout += "]\n";
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-10-01 17:07:12 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
/*
|
|
|
|
================================================================================================
|
|
|
|
idRenderProgManager::FindGLSLProgram
|
|
|
|
================================================================================================
|
|
|
|
*/
|
2012-11-28 15:47:07 +00:00
|
|
|
int idRenderProgManager::FindGLSLProgram( const char* name, int vIndex, int fIndex )
|
|
|
|
{
|
2018-10-13 16:34:29 +00:00
|
|
|
for( int i = 0; i < renderProgs.Num(); ++i )
|
2012-11-28 15:47:07 +00:00
|
|
|
{
|
2018-10-13 16:34:29 +00:00
|
|
|
if( ( renderProgs[i].vertexShaderIndex == vIndex ) && ( renderProgs[i].fragmentShaderIndex == fIndex ) )
|
2012-11-28 15:47:07 +00:00
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2018-10-13 11:50:44 +00:00
|
|
|
renderProg_t program;
|
2012-11-26 18:58:24 +00:00
|
|
|
program.name = name;
|
2018-10-13 16:34:29 +00:00
|
|
|
int index = renderProgs.Append( program );
|
2012-11-26 18:58:24 +00:00
|
|
|
LoadGLSLProgram( index, vIndex, fIndex );
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
================================================================================================
|
|
|
|
idRenderProgManager::GetGLSLParmName
|
|
|
|
================================================================================================
|
|
|
|
*/
|
2012-11-28 15:47:07 +00:00
|
|
|
const char* idRenderProgManager::GetGLSLParmName( int rp ) const
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
assert( rp < RENDERPARM_TOTAL );
|
|
|
|
return GLSLParmNames[ rp ];
|
|
|
|
}
|
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
// RB begin
|
|
|
|
const char* idRenderProgManager::GetGLSLMacroName( shaderFeature_t sf ) const
|
|
|
|
{
|
|
|
|
assert( sf < MAX_SHADER_MACRO_NAMES );
|
2019-11-11 19:27:44 +00:00
|
|
|
|
2014-05-10 12:40:01 +00:00
|
|
|
return GLSLMacroNames[ sf ];
|
|
|
|
}
|
|
|
|
// RB end
|
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
/*
|
|
|
|
================================================================================================
|
|
|
|
idRenderProgManager::SetUniformValue
|
|
|
|
================================================================================================
|
|
|
|
*/
|
2012-11-28 15:47:07 +00:00
|
|
|
void idRenderProgManager::SetUniformValue( const renderParm_t rp, const float* value )
|
|
|
|
{
|
|
|
|
for( int i = 0; i < 4; i++ )
|
|
|
|
{
|
2018-10-13 16:34:29 +00:00
|
|
|
uniforms[rp][i] = value[i];
|
2012-11-26 18:58:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-13 12:42:30 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
/*
|
|
|
|
================================================================================================
|
|
|
|
idRenderProgManager::ZeroUniforms
|
|
|
|
================================================================================================
|
|
|
|
*/
|
2012-11-28 15:47:07 +00:00
|
|
|
void idRenderProgManager::ZeroUniforms()
|
|
|
|
{
|
2018-10-13 16:34:29 +00:00
|
|
|
memset( uniforms.Ptr(), 0, uniforms.Allocated() );
|
2012-11-26 18:58:24 +00:00
|
|
|
}
|
|
|
|
|