summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/PixelShaderGen.cpp
diff options
context:
space:
mode:
authorLC <mathew1800@gmail.com>2020-11-09 22:08:42 -0500
committerGitHub <noreply@github.com>2020-11-09 22:08:42 -0500
commit0a2564a89d1fc669acf07ded151229910ba7addd (patch)
tree3b26b51bfe5bcccb8c3bbe29da8507fda191eaa4 /Source/Core/VideoCommon/PixelShaderGen.cpp
parent43e2f0e88f80686c2b76dcba4241a7be64e7bf55 (diff)
parenta5b28f1f07b0f310f407462ebb86eafbf4d63f20 (diff)
Merge pull request #9234 from lioncash/rename-fmt
ShaderGenCommon: Rename WriteFmt() to Write()
Diffstat (limited to 'Source/Core/VideoCommon/PixelShaderGen.cpp')
-rw-r--r--Source/Core/VideoCommon/PixelShaderGen.cpp645
1 files changed, 317 insertions, 328 deletions
diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp
index 8d4abb704f..288761af8e 100644
--- a/Source/Core/VideoCommon/PixelShaderGen.cpp
+++ b/Source/Core/VideoCommon/PixelShaderGen.cpp
@@ -365,98 +365,98 @@ void WritePixelShaderCommonHeader(ShaderCode& out, APIType api_type, u32 num_tex
const ShaderHostConfig& host_config, bool bounding_box)
{
// dot product for integer vectors
- out.WriteFmt("int idot(int3 x, int3 y)\n"
- "{{\n"
- "\tint3 tmp = x * y;\n"
- "\treturn tmp.x + tmp.y + tmp.z;\n"
- "}}\n");
-
- out.WriteFmt("int idot(int4 x, int4 y)\n"
- "{{\n"
- "\tint4 tmp = x * y;\n"
- "\treturn tmp.x + tmp.y + tmp.z + tmp.w;\n"
- "}}\n\n");
+ out.Write("int idot(int3 x, int3 y)\n"
+ "{{\n"
+ "\tint3 tmp = x * y;\n"
+ "\treturn tmp.x + tmp.y + tmp.z;\n"
+ "}}\n");
+
+ out.Write("int idot(int4 x, int4 y)\n"
+ "{{\n"
+ "\tint4 tmp = x * y;\n"
+ "\treturn tmp.x + tmp.y + tmp.z + tmp.w;\n"
+ "}}\n\n");
// rounding + casting to integer at once in a single function
- out.WriteFmt("int iround(float x) {{ return int (round(x)); }}\n"
- "int2 iround(float2 x) {{ return int2(round(x)); }}\n"
- "int3 iround(float3 x) {{ return int3(round(x)); }}\n"
- "int4 iround(float4 x) {{ return int4(round(x)); }}\n\n");
+ out.Write("int iround(float x) {{ return int (round(x)); }}\n"
+ "int2 iround(float2 x) {{ return int2(round(x)); }}\n"
+ "int3 iround(float3 x) {{ return int3(round(x)); }}\n"
+ "int4 iround(float4 x) {{ return int4(round(x)); }}\n\n");
if (api_type == APIType::OpenGL || api_type == APIType::Vulkan)
{
- out.WriteFmt("SAMPLER_BINDING(0) uniform sampler2DArray samp[8];\n");
+ out.Write("SAMPLER_BINDING(0) uniform sampler2DArray samp[8];\n");
}
else // D3D
{
// Declare samplers
- out.WriteFmt("SamplerState samp[8] : register(s0);\n"
- "\n"
- "Texture2DArray Tex[8] : register(t0);\n");
+ out.Write("SamplerState samp[8] : register(s0);\n"
+ "\n"
+ "Texture2DArray Tex[8] : register(t0);\n");
}
- out.WriteFmt("\n");
+ out.Write("\n");
if (api_type == APIType::OpenGL || api_type == APIType::Vulkan)
- out.WriteFmt("UBO_BINDING(std140, 1) uniform PSBlock {{\n");
+ out.Write("UBO_BINDING(std140, 1) uniform PSBlock {{\n");
else
- out.WriteFmt("cbuffer PSBlock : register(b0) {{\n");
-
- out.WriteFmt("\tint4 " I_COLORS "[4];\n"
- "\tint4 " I_KCOLORS "[4];\n"
- "\tint4 " I_ALPHA ";\n"
- "\tfloat4 " I_TEXDIMS "[8];\n"
- "\tint4 " I_ZBIAS "[2];\n"
- "\tint4 " I_INDTEXSCALE "[2];\n"
- "\tint4 " I_INDTEXMTX "[6];\n"
- "\tint4 " I_FOGCOLOR ";\n"
- "\tint4 " I_FOGI ";\n"
- "\tfloat4 " I_FOGF ";\n"
- "\tfloat4 " I_FOGRANGE "[3];\n"
- "\tfloat4 " I_ZSLOPE ";\n"
- "\tfloat2 " I_EFBSCALE ";\n"
- "\tuint bpmem_genmode;\n"
- "\tuint bpmem_alphaTest;\n"
- "\tuint bpmem_fogParam3;\n"
- "\tuint bpmem_fogRangeBase;\n"
- "\tuint bpmem_dstalpha;\n"
- "\tuint bpmem_ztex_op;\n"
- "\tbool bpmem_late_ztest;\n"
- "\tbool bpmem_rgba6_format;\n"
- "\tbool bpmem_dither;\n"
- "\tbool bpmem_bounding_box;\n"
- "\tuint4 bpmem_pack1[16];\n" // .xy - combiners, .z - tevind
- "\tuint4 bpmem_pack2[8];\n" // .x - tevorder, .y - tevksel
- "\tint4 konstLookup[32];\n"
- "\tbool blend_enable;\n"
- "\tuint blend_src_factor;\n"
- "\tuint blend_src_factor_alpha;\n"
- "\tuint blend_dst_factor;\n"
- "\tuint blend_dst_factor_alpha;\n"
- "\tbool blend_subtract;\n"
- "\tbool blend_subtract_alpha;\n"
- "}};\n\n");
- out.WriteFmt("#define bpmem_combiners(i) (bpmem_pack1[(i)].xy)\n"
- "#define bpmem_tevind(i) (bpmem_pack1[(i)].z)\n"
- "#define bpmem_iref(i) (bpmem_pack1[(i)].w)\n"
- "#define bpmem_tevorder(i) (bpmem_pack2[(i)].x)\n"
- "#define bpmem_tevksel(i) (bpmem_pack2[(i)].y)\n\n");
+ out.Write("cbuffer PSBlock : register(b0) {{\n");
+
+ out.Write("\tint4 " I_COLORS "[4];\n"
+ "\tint4 " I_KCOLORS "[4];\n"
+ "\tint4 " I_ALPHA ";\n"
+ "\tfloat4 " I_TEXDIMS "[8];\n"
+ "\tint4 " I_ZBIAS "[2];\n"
+ "\tint4 " I_INDTEXSCALE "[2];\n"
+ "\tint4 " I_INDTEXMTX "[6];\n"
+ "\tint4 " I_FOGCOLOR ";\n"
+ "\tint4 " I_FOGI ";\n"
+ "\tfloat4 " I_FOGF ";\n"
+ "\tfloat4 " I_FOGRANGE "[3];\n"
+ "\tfloat4 " I_ZSLOPE ";\n"
+ "\tfloat2 " I_EFBSCALE ";\n"
+ "\tuint bpmem_genmode;\n"
+ "\tuint bpmem_alphaTest;\n"
+ "\tuint bpmem_fogParam3;\n"
+ "\tuint bpmem_fogRangeBase;\n"
+ "\tuint bpmem_dstalpha;\n"
+ "\tuint bpmem_ztex_op;\n"
+ "\tbool bpmem_late_ztest;\n"
+ "\tbool bpmem_rgba6_format;\n"
+ "\tbool bpmem_dither;\n"
+ "\tbool bpmem_bounding_box;\n"
+ "\tuint4 bpmem_pack1[16];\n" // .xy - combiners, .z - tevind
+ "\tuint4 bpmem_pack2[8];\n" // .x - tevorder, .y - tevksel
+ "\tint4 konstLookup[32];\n"
+ "\tbool blend_enable;\n"
+ "\tuint blend_src_factor;\n"
+ "\tuint blend_src_factor_alpha;\n"
+ "\tuint blend_dst_factor;\n"
+ "\tuint blend_dst_factor_alpha;\n"
+ "\tbool blend_subtract;\n"
+ "\tbool blend_subtract_alpha;\n"
+ "}};\n\n");
+ out.Write("#define bpmem_combiners(i) (bpmem_pack1[(i)].xy)\n"
+ "#define bpmem_tevind(i) (bpmem_pack1[(i)].z)\n"
+ "#define bpmem_iref(i) (bpmem_pack1[(i)].w)\n"
+ "#define bpmem_tevorder(i) (bpmem_pack2[(i)].x)\n"
+ "#define bpmem_tevksel(i) (bpmem_pack2[(i)].y)\n\n");
if (host_config.per_pixel_lighting)
{
- out.WriteFmt("{}", s_lighting_struct);
+ out.Write("{}", s_lighting_struct);
if (api_type == APIType::OpenGL || api_type == APIType::Vulkan)
- out.WriteFmt("UBO_BINDING(std140, 2) uniform VSBlock {{\n");
+ out.Write("UBO_BINDING(std140, 2) uniform VSBlock {{\n");
else
- out.WriteFmt("cbuffer VSBlock : register(b1) {{\n");
+ out.Write("cbuffer VSBlock : register(b1) {{\n");
- out.WriteFmt("{}", s_shader_uniforms);
- out.WriteFmt("}};\n");
+ out.Write("{}", s_shader_uniforms);
+ out.Write("}};\n");
}
if (bounding_box)
{
- out.WriteFmt(R"(
+ out.Write(R"(
#ifdef API_D3D
globallycoherent RWBuffer<int> bbox_data : register(u2);
#define atomicMin InterlockedMin
@@ -541,9 +541,9 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
const bool stereo = host_config.stereo;
const u32 numStages = uid_data->genMode_numtevstages + 1;
- out.WriteFmt("// Pixel Shader for TEV stages\n");
- out.WriteFmt("// {} TEV stages, {} texgens, {} IND stages\n", numStages,
- uid_data->genMode_numtexgens, uid_data->genMode_numindstages);
+ out.Write("// Pixel Shader for TEV stages\n");
+ out.Write("// {} TEV stages, {} texgens, {} IND stages\n", numStages,
+ uid_data->genMode_numtexgens, uid_data->genMode_numindstages);
// Stuff that is shared between ubershaders and pixelgen.
WritePixelShaderCommonHeader(out, api_type, uid_data->genMode_numtexgens, host_config,
@@ -588,11 +588,11 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
if (api_type == APIType::OpenGL || api_type == APIType::Vulkan)
{
// This is a #define which signals whatever early-z method the driver supports.
- out.WriteFmt("FORCE_EARLY_Z; \n");
+ out.Write("FORCE_EARLY_Z; \n");
}
else
{
- out.WriteFmt("[earlydepthstencil]\n");
+ out.Write("[earlydepthstencil]\n");
}
}
@@ -610,13 +610,13 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
{
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_FRAGMENT_SHADER_INDEX_DECORATION))
{
- out.WriteFmt("FRAGMENT_OUTPUT_LOCATION(0) out vec4 ocol0;\n"
- "FRAGMENT_OUTPUT_LOCATION(1) out vec4 ocol1;\n");
+ out.Write("FRAGMENT_OUTPUT_LOCATION(0) out vec4 ocol0;\n"
+ "FRAGMENT_OUTPUT_LOCATION(1) out vec4 ocol1;\n");
}
else
{
- out.WriteFmt("FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 0) out vec4 ocol0;\n"
- "FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 1) out vec4 ocol1;\n");
+ out.Write("FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 0) out vec4 ocol0;\n"
+ "FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 1) out vec4 ocol1;\n");
}
}
else if (use_shader_blend)
@@ -627,142 +627,141 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
// shader
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_FRAGMENT_SHADER_INDEX_DECORATION))
{
- out.WriteFmt("FRAGMENT_OUTPUT_LOCATION(0) FRAGMENT_INOUT vec4 real_ocol0;\n");
+ out.Write("FRAGMENT_OUTPUT_LOCATION(0) FRAGMENT_INOUT vec4 real_ocol0;\n");
}
else
{
- out.WriteFmt("FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 0) FRAGMENT_INOUT vec4 real_ocol0;\n");
+ out.Write("FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 0) FRAGMENT_INOUT vec4 real_ocol0;\n");
}
}
else
{
- out.WriteFmt("FRAGMENT_OUTPUT_LOCATION(0) out vec4 ocol0;\n");
+ out.Write("FRAGMENT_OUTPUT_LOCATION(0) out vec4 ocol0;\n");
}
if (uid_data->per_pixel_depth)
- out.WriteFmt("#define depth gl_FragDepth\n");
+ out.Write("#define depth gl_FragDepth\n");
if (host_config.backend_geometry_shaders)
{
- out.WriteFmt("VARYING_LOCATION(0) in VertexData {{\n");
+ out.Write("VARYING_LOCATION(0) in VertexData {{\n");
GenerateVSOutputMembers(out, api_type, uid_data->genMode_numtexgens, host_config,
GetInterpolationQualifier(msaa, ssaa, true, true));
if (stereo)
- out.WriteFmt("\tflat int layer;\n");
+ out.Write("\tflat int layer;\n");
- out.WriteFmt("}};\n");
+ out.Write("}};\n");
}
else
{
// Let's set up attributes
u32 counter = 0;
- out.WriteFmt("VARYING_LOCATION({}) {} in float4 colors_0;\n", counter++,
- GetInterpolationQualifier(msaa, ssaa));
- out.WriteFmt("VARYING_LOCATION({}) {} in float4 colors_1;\n", counter++,
- GetInterpolationQualifier(msaa, ssaa));
+ out.Write("VARYING_LOCATION({}) {} in float4 colors_0;\n", counter++,
+ GetInterpolationQualifier(msaa, ssaa));
+ out.Write("VARYING_LOCATION({}) {} in float4 colors_1;\n", counter++,
+ GetInterpolationQualifier(msaa, ssaa));
for (u32 i = 0; i < uid_data->genMode_numtexgens; ++i)
{
- out.WriteFmt("VARYING_LOCATION({}) {} in float3 tex{};\n", counter++,
- GetInterpolationQualifier(msaa, ssaa), i);
+ out.Write("VARYING_LOCATION({}) {} in float3 tex{};\n", counter++,
+ GetInterpolationQualifier(msaa, ssaa), i);
}
if (!host_config.fast_depth_calc)
{
- out.WriteFmt("VARYING_LOCATION({}) {} in float4 clipPos;\n", counter++,
- GetInterpolationQualifier(msaa, ssaa));
+ out.Write("VARYING_LOCATION({}) {} in float4 clipPos;\n", counter++,
+ GetInterpolationQualifier(msaa, ssaa));
}
if (per_pixel_lighting)
{
- out.WriteFmt("VARYING_LOCATION({}) {} in float3 Normal;\n", counter++,
- GetInterpolationQualifier(msaa, ssaa));
- out.WriteFmt("VARYING_LOCATION({}) {} in float3 WorldPos;\n", counter++,
- GetInterpolationQualifier(msaa, ssaa));
+ out.Write("VARYING_LOCATION({}) {} in float3 Normal;\n", counter++,
+ GetInterpolationQualifier(msaa, ssaa));
+ out.Write("VARYING_LOCATION({}) {} in float3 WorldPos;\n", counter++,
+ GetInterpolationQualifier(msaa, ssaa));
}
}
- out.WriteFmt("void main()\n{{\n");
- out.WriteFmt("\tfloat4 rawpos = gl_FragCoord;\n");
+ out.Write("void main()\n{{\n");
+ out.Write("\tfloat4 rawpos = gl_FragCoord;\n");
if (use_shader_blend)
{
// Store off a copy of the initial fb value for blending
- out.WriteFmt("\tfloat4 initial_ocol0 = FB_FETCH_VALUE;\n"
- "\tfloat4 ocol0;\n"
- "\tfloat4 ocol1;\n");
+ out.Write("\tfloat4 initial_ocol0 = FB_FETCH_VALUE;\n"
+ "\tfloat4 ocol0;\n"
+ "\tfloat4 ocol1;\n");
}
}
else // D3D
{
- out.WriteFmt("void main(\n");
+ out.Write("void main(\n");
if (uid_data->uint_output)
{
- out.WriteFmt(" out uint4 ocol0 : SV_Target,\n");
+ out.Write(" out uint4 ocol0 : SV_Target,\n");
}
else
{
- out.WriteFmt(" out float4 ocol0 : SV_Target0,\n"
- " out float4 ocol1 : SV_Target1,\n");
+ out.Write(" out float4 ocol0 : SV_Target0,\n"
+ " out float4 ocol1 : SV_Target1,\n");
}
- out.WriteFmt("{}"
- " in float4 rawpos : SV_Position,\n",
- uid_data->per_pixel_depth ? " out float depth : SV_Depth,\n" : "");
+ out.Write("{}"
+ " in float4 rawpos : SV_Position,\n",
+ uid_data->per_pixel_depth ? " out float depth : SV_Depth,\n" : "");
- out.WriteFmt(" in {} float4 colors_0 : COLOR0,\n", GetInterpolationQualifier(msaa, ssaa));
- out.WriteFmt(" in {} float4 colors_1 : COLOR1\n", GetInterpolationQualifier(msaa, ssaa));
+ out.Write(" in {} float4 colors_0 : COLOR0,\n", GetInterpolationQualifier(msaa, ssaa));
+ out.Write(" in {} float4 colors_1 : COLOR1\n", GetInterpolationQualifier(msaa, ssaa));
// compute window position if needed because binding semantic WPOS is not widely supported
for (u32 i = 0; i < uid_data->genMode_numtexgens; ++i)
{
- out.WriteFmt(",\n in {} float3 tex{} : TEXCOORD{}", GetInterpolationQualifier(msaa, ssaa), i,
- i);
+ out.Write(",\n in {} float3 tex{} : TEXCOORD{}", GetInterpolationQualifier(msaa, ssaa), i,
+ i);
}
if (!host_config.fast_depth_calc)
{
- out.WriteFmt(",\n in {} float4 clipPos : TEXCOORD{}", GetInterpolationQualifier(msaa, ssaa),
- uid_data->genMode_numtexgens);
+ out.Write(",\n in {} float4 clipPos : TEXCOORD{}", GetInterpolationQualifier(msaa, ssaa),
+ uid_data->genMode_numtexgens);
}
if (per_pixel_lighting)
{
- out.WriteFmt(",\n in {} float3 Normal : TEXCOORD{}", GetInterpolationQualifier(msaa, ssaa),
- uid_data->genMode_numtexgens + 1);
- out.WriteFmt(",\n in {} float3 WorldPos : TEXCOORD{}", GetInterpolationQualifier(msaa, ssaa),
- uid_data->genMode_numtexgens + 2);
+ out.Write(",\n in {} float3 Normal : TEXCOORD{}", GetInterpolationQualifier(msaa, ssaa),
+ uid_data->genMode_numtexgens + 1);
+ out.Write(",\n in {} float3 WorldPos : TEXCOORD{}", GetInterpolationQualifier(msaa, ssaa),
+ uid_data->genMode_numtexgens + 2);
}
if (host_config.backend_geometry_shaders)
{
- out.WriteFmt(",\n in float clipDist0 : SV_ClipDistance0\n"
- ",\n in float clipDist1 : SV_ClipDistance1\n");
+ out.Write(",\n in float clipDist0 : SV_ClipDistance0\n"
+ ",\n in float clipDist1 : SV_ClipDistance1\n");
}
if (stereo)
- out.WriteFmt(",\n in uint layer : SV_RenderTargetArrayIndex\n");
- out.WriteFmt(" ) {{\n");
+ out.Write(",\n in uint layer : SV_RenderTargetArrayIndex\n");
+ out.Write(" ) {{\n");
}
- out.WriteFmt(
- "\tint4 c0 = " I_COLORS "[1], c1 = " I_COLORS "[2], c2 = " I_COLORS "[3], prev = " I_COLORS
- "[0];\n"
- "\tint4 rastemp = int4(0, 0, 0, 0), textemp = int4(0, 0, 0, 0), konsttemp = int4(0, 0, "
- "0, 0);\n"
- "\tint3 comp16 = int3(1, 256, 0), comp24 = int3(1, 256, 256*256);\n"
- "\tint alphabump=0;\n"
- "\tint3 tevcoord=int3(0, 0, 0);\n"
- "\tint2 wrappedcoord=int2(0,0), tempcoord=int2(0,0);\n"
- "\tint4 "
- "tevin_a=int4(0,0,0,0),tevin_b=int4(0,0,0,0),tevin_c=int4(0,0,0,0),tevin_d=int4(0,0,0,"
- "0);\n\n"); // tev combiner inputs
+ out.Write("\tint4 c0 = " I_COLORS "[1], c1 = " I_COLORS "[2], c2 = " I_COLORS
+ "[3], prev = " I_COLORS "[0];\n"
+ "\tint4 rastemp = int4(0, 0, 0, 0), textemp = int4(0, 0, 0, 0), konsttemp = int4(0, 0, "
+ "0, 0);\n"
+ "\tint3 comp16 = int3(1, 256, 0), comp24 = int3(1, 256, 256*256);\n"
+ "\tint alphabump=0;\n"
+ "\tint3 tevcoord=int3(0, 0, 0);\n"
+ "\tint2 wrappedcoord=int2(0,0), tempcoord=int2(0,0);\n"
+ "\tint4 "
+ "tevin_a=int4(0,0,0,0),tevin_b=int4(0,0,0,0),tevin_c=int4(0,0,0,0),tevin_d=int4(0,0,0,"
+ "0);\n\n"); // tev combiner inputs
// On GLSL, input variables must not be assigned to.
// This is why we declare these variables locally instead.
- out.WriteFmt("\tfloat4 col0 = colors_0;\n"
- "\tfloat4 col1 = colors_1;\n");
+ out.Write("\tfloat4 col0 = colors_0;\n"
+ "\tfloat4 col1 = colors_1;\n");
if (per_pixel_lighting)
{
- out.WriteFmt("\tfloat3 _norm0 = normalize(Normal.xyz);\n\n"
- "\tfloat3 pos = WorldPos;\n");
+ out.Write("\tfloat3 _norm0 = normalize(Normal.xyz);\n\n"
+ "\tfloat3 pos = WorldPos;\n");
- out.WriteFmt("\tint4 lacc;\n"
- "\tfloat3 ldir, h, cosAttn, distAttn;\n"
- "\tfloat dist, dist2, attn;\n");
+ out.Write("\tint4 lacc;\n"
+ "\tfloat3 ldir, h, cosAttn, distAttn;\n"
+ "\tfloat dist, dist2, attn;\n");
// TODO: Our current constant usage code isn't able to handle more than one buffer.
// So we can't mark the VS constant as used here. But keep them here as reference.
@@ -776,16 +775,16 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
// HACK to handle cases where the tex gen is not enabled
if (uid_data->genMode_numtexgens == 0)
{
- out.WriteFmt("\tint2 fixpoint_uv0 = int2(0, 0);\n\n");
+ out.Write("\tint2 fixpoint_uv0 = int2(0, 0);\n\n");
}
else
{
out.SetConstantsUsed(C_TEXDIMS, C_TEXDIMS + uid_data->genMode_numtexgens - 1);
for (u32 i = 0; i < uid_data->genMode_numtexgens; ++i)
{
- out.WriteFmt("\tint2 fixpoint_uv{} = int2(", i);
- out.WriteFmt("(tex{}.z == 0.0 ? tex{}.xy : tex{}.xy / tex{}.z)", i, i, i, i);
- out.WriteFmt(" * " I_TEXDIMS "[{}].zw);\n", i);
+ out.Write("\tint2 fixpoint_uv{} = int2(", i);
+ out.Write("(tex{}.z == 0.0 ? tex{}.xy : tex{}.xy / tex{}.z)", i, i, i, i);
+ out.Write(" * " I_TEXDIMS "[{}].zw);\n", i);
// TODO: S24 overflows here?
}
}
@@ -800,15 +799,15 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
if (texcoord < uid_data->genMode_numtexgens)
{
out.SetConstantsUsed(C_INDTEXSCALE + i / 2, C_INDTEXSCALE + i / 2);
- out.WriteFmt("\ttempcoord = fixpoint_uv{} >> " I_INDTEXSCALE "[{}].{};\n", texcoord, i / 2,
- (i & 1) != 0 ? "zw" : "xy");
+ out.Write("\ttempcoord = fixpoint_uv{} >> " I_INDTEXSCALE "[{}].{};\n", texcoord, i / 2,
+ (i & 1) != 0 ? "zw" : "xy");
}
else
{
- out.WriteFmt("\ttempcoord = int2(0, 0);\n");
+ out.Write("\ttempcoord = int2(0, 0);\n");
}
- out.WriteFmt("\tint3 iindtex{} = ", i);
+ out.Write("\tint3 iindtex{} = ", i);
SampleTexture(out, "float2(tempcoord)", "abg", texmap, stereo, api_type);
}
}
@@ -828,14 +827,14 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
last_ac.hex = uid_data->stagehash[uid_data->genMode_numtevstages].ac;
if (last_cc.dest != 0)
{
- out.WriteFmt("\tprev.rgb = {};\n", tev_c_output_table[last_cc.dest]);
+ out.Write("\tprev.rgb = {};\n", tev_c_output_table[last_cc.dest]);
}
if (last_ac.dest != 0)
{
- out.WriteFmt("\tprev.a = {};\n", tev_a_output_table[last_ac.dest]);
+ out.Write("\tprev.a = {};\n", tev_a_output_table[last_ac.dest]);
}
}
- out.WriteFmt("\tprev = prev & 255;\n");
+ out.Write("\tprev = prev & 255;\n");
// NOTE: Fragment may not be discarded if alpha test always fails and early depth test is enabled
// (in this case we need to write a depth value if depth test passes regardless of the alpha
@@ -852,14 +851,14 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
out.SetConstantsUsed(C_ZSLOPE, C_ZSLOPE);
out.SetConstantsUsed(C_EFBSCALE, C_EFBSCALE);
- out.WriteFmt("\tfloat2 screenpos = rawpos.xy * " I_EFBSCALE ".xy;\n");
+ out.Write("\tfloat2 screenpos = rawpos.xy * " I_EFBSCALE ".xy;\n");
// Opengl has reversed vertical screenspace coordinates
if (api_type == APIType::OpenGL)
- out.WriteFmt("\tscreenpos.y = {}.0 - screenpos.y;\n", EFB_HEIGHT);
+ out.Write("\tscreenpos.y = {}.0 - screenpos.y;\n", EFB_HEIGHT);
- out.WriteFmt("\tint zCoord = int(" I_ZSLOPE ".z + " I_ZSLOPE ".x * screenpos.x + " I_ZSLOPE
- ".y * screenpos.y);\n");
+ out.Write("\tint zCoord = int(" I_ZSLOPE ".z + " I_ZSLOPE ".x * screenpos.x + " I_ZSLOPE
+ ".y * screenpos.y);\n");
}
else if (!host_config.fast_depth_calc)
{
@@ -870,17 +869,17 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
// the host GPU driver from performing any early depth test optimizations.
out.SetConstantsUsed(C_ZBIAS + 1, C_ZBIAS + 1);
// the screen space depth value = far z + (clip z / clip w) * z range
- out.WriteFmt("\tint zCoord = " I_ZBIAS "[1].x + int((clipPos.z / clipPos.w) * float(" I_ZBIAS
- "[1].y));\n");
+ out.Write("\tint zCoord = " I_ZBIAS "[1].x + int((clipPos.z / clipPos.w) * float(" I_ZBIAS
+ "[1].y));\n");
}
else
{
if (!host_config.backend_reversed_depth_range)
- out.WriteFmt("\tint zCoord = int((1.0 - rawpos.z) * 16777216.0);\n");
+ out.Write("\tint zCoord = int((1.0 - rawpos.z) * 16777216.0);\n");
else
- out.WriteFmt("\tint zCoord = int(rawpos.z * 16777216.0);\n");
+ out.Write("\tint zCoord = int(rawpos.z * 16777216.0);\n");
}
- out.WriteFmt("\tzCoord = clamp(zCoord, 0, 0xFFFFFF);\n");
+ out.Write("\tzCoord = clamp(zCoord, 0, 0xFFFFFF);\n");
// depth texture can safely be ignored if the result won't be written to the depth buffer
// (early_ztest) and isn't used for fog either
@@ -890,9 +889,9 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
if (uid_data->per_pixel_depth && uid_data->early_ztest)
{
if (!host_config.backend_reversed_depth_range)
- out.WriteFmt("\tdepth = 1.0 - float(zCoord) / 16777216.0;\n");
+ out.Write("\tdepth = 1.0 - float(zCoord) / 16777216.0;\n");
else
- out.WriteFmt("\tdepth = float(zCoord) / 16777216.0;\n");
+ out.Write("\tdepth = float(zCoord) / 16777216.0;\n");
}
// Note: depth texture output is only written to depth buffer if late depth test is used
@@ -903,17 +902,17 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
// use the texture input of the last texture stage (textemp), hopefully this has been read and
// is in correct format...
out.SetConstantsUsed(C_ZBIAS, C_ZBIAS + 1);
- out.WriteFmt("\tzCoord = idot(" I_ZBIAS "[0].xyzw, textemp.xyzw) + " I_ZBIAS "[1].w {};\n",
- (uid_data->ztex_op == ZTEXTURE_ADD) ? "+ zCoord" : "");
- out.WriteFmt("\tzCoord = zCoord & 0xFFFFFF;\n");
+ out.Write("\tzCoord = idot(" I_ZBIAS "[0].xyzw, textemp.xyzw) + " I_ZBIAS "[1].w {};\n",
+ (uid_data->ztex_op == ZTEXTURE_ADD) ? "+ zCoord" : "");
+ out.Write("\tzCoord = zCoord & 0xFFFFFF;\n");
}
if (uid_data->per_pixel_depth && uid_data->late_ztest)
{
if (!host_config.backend_reversed_depth_range)
- out.WriteFmt("\tdepth = 1.0 - float(zCoord) / 16777216.0;\n");
+ out.Write("\tdepth = 1.0 - float(zCoord) / 16777216.0;\n");
else
- out.WriteFmt("\tdepth = float(zCoord) / 16777216.0;\n");
+ out.Write("\tdepth = float(zCoord) / 16777216.0;\n");
}
// No dithering for RGB8 mode
@@ -921,8 +920,8 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
{
// Flipper uses a standard 2x2 Bayer Matrix for 6 bit dithering
// Here the matrix is encoded into the two factor constants
- out.WriteFmt("\tint2 dither = int2(rawpos.xy) & 1;\n");
- out.WriteFmt("\tprev.rgb = (prev.rgb - (prev.rgb >> 6)) + abs(dither.y * 3 - dither.x * 2);\n");
+ out.Write("\tint2 dither = int2(rawpos.xy) & 1;\n");
+ out.Write("\tprev.rgb = (prev.rgb - (prev.rgb >> 6)) + abs(dither.y * 3 - dither.x * 2);\n");
}
WriteFog(out, uid_data);
@@ -935,9 +934,9 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
WriteBlend(out, uid_data);
if (uid_data->bounding_box)
- out.WriteFmt("\tUpdateBoundingBox(rawpos.xy);\n");
+ out.Write("\tUpdateBoundingBox(rawpos.xy);\n");
- out.WriteFmt("}}\n");
+ out.Write("}}\n");
return out;
}
@@ -946,7 +945,7 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
APIType api_type, bool stereo)
{
const auto& stage = uid_data->stagehash[n];
- out.WriteFmt("\n\t// TEV stage {}\n", n);
+ out.Write("\n\t// TEV stage {}\n", n);
// HACK to handle cases where the tex gen is not enabled
u32 texcoord = stage.tevorders_texcoord;
@@ -959,7 +958,7 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
TevStageIndirect tevind;
tevind.hex = stage.tevind;
- out.WriteFmt("\t// indirect op\n");
+ out.Write("\t// indirect op\n");
// Perform the indirect op on the incoming regular coordinates
// using iindtex{} as the offset coords
@@ -980,8 +979,8 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
"248",
};
- out.WriteFmt("alphabump = iindtex{}.{} & {};\n", tevind.bt.Value(),
- tev_ind_alpha_sel[tevind.bs], tev_ind_alpha_mask[tevind.fmt]);
+ out.Write("alphabump = iindtex{}.{} & {};\n", tevind.bt.Value(), tev_ind_alpha_sel[tevind.bs],
+ tev_ind_alpha_mask[tevind.fmt]);
}
else
{
@@ -997,8 +996,8 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
"15",
"7",
};
- out.WriteFmt("\tint3 iindtevcrd{} = iindtex{} & {};\n", n, tevind.bt.Value(),
- tev_ind_fmt_mask[tevind.fmt]);
+ out.Write("\tint3 iindtevcrd{} = iindtex{} & {};\n", n, tevind.bt.Value(),
+ tev_ind_fmt_mask[tevind.fmt]);
// bias - TODO: Check if this needs to be this complicated...
// indexed by bias
@@ -1016,19 +1015,19 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
if (tevind.bias == ITB_S || tevind.bias == ITB_T || tevind.bias == ITB_U)
{
- out.WriteFmt("\tiindtevcrd{}.{} += int({});\n", n, tev_ind_bias_field[tevind.bias],
- tev_ind_bias_add[tevind.fmt]);
+ out.Write("\tiindtevcrd{}.{} += int({});\n", n, tev_ind_bias_field[tevind.bias],
+ tev_ind_bias_add[tevind.fmt]);
}
else if (tevind.bias == ITB_ST || tevind.bias == ITB_SU || tevind.bias == ITB_TU)
{
- out.WriteFmt("\tiindtevcrd{}.{} += int2({}, {});\n", n, tev_ind_bias_field[tevind.bias],
- tev_ind_bias_add[tevind.fmt], tev_ind_bias_add[tevind.fmt]);
+ out.Write("\tiindtevcrd{}.{} += int2({}, {});\n", n, tev_ind_bias_field[tevind.bias],
+ tev_ind_bias_add[tevind.fmt], tev_ind_bias_add[tevind.fmt]);
}
else if (tevind.bias == ITB_STU)
{
- out.WriteFmt("\tiindtevcrd{}.{} += int3({}, {}, {});\n", n, tev_ind_bias_field[tevind.bias],
- tev_ind_bias_add[tevind.fmt], tev_ind_bias_add[tevind.fmt],
- tev_ind_bias_add[tevind.fmt]);
+ out.Write("\tiindtevcrd{}.{} += int3({}, {}, {});\n", n, tev_ind_bias_field[tevind.bias],
+ tev_ind_bias_add[tevind.fmt], tev_ind_bias_add[tevind.fmt],
+ tev_ind_bias_add[tevind.fmt]);
}
// multiply by offset matrix and scale - calculations are likely to overflow badly,
@@ -1038,26 +1037,23 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
const u32 mtxidx = 2 * (tevind.mid - 1);
out.SetConstantsUsed(C_INDTEXMTX + mtxidx, C_INDTEXMTX + mtxidx);
- out.WriteFmt("\tint2 indtevtrans{} = int2(idot(" I_INDTEXMTX
- "[{}].xyz, iindtevcrd{}), idot(" I_INDTEXMTX
- "[{}].xyz, iindtevcrd{})) >> 3;\n",
- n, mtxidx, n, mtxidx + 1, n);
+ out.Write("\tint2 indtevtrans{} = int2(idot(" I_INDTEXMTX
+ "[{}].xyz, iindtevcrd{}), idot(" I_INDTEXMTX "[{}].xyz, iindtevcrd{})) >> 3;\n",
+ n, mtxidx, n, mtxidx + 1, n);
// TODO: should use a shader uid branch for this for better performance
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_BITWISE_OP_NEGATION))
{
- out.WriteFmt("\tint indtexmtx_w_inverse_{} = -" I_INDTEXMTX "[{}].w;\n", n, mtxidx);
- out.WriteFmt("\tif (" I_INDTEXMTX "[{}].w >= 0) indtevtrans{} >>= " I_INDTEXMTX
- "[{}].w;\n",
- mtxidx, n, mtxidx);
- out.WriteFmt("\telse indtevtrans{} <<= indtexmtx_w_inverse_{};\n", n, n);
+ out.Write("\tint indtexmtx_w_inverse_{} = -" I_INDTEXMTX "[{}].w;\n", n, mtxidx);
+ out.Write("\tif (" I_INDTEXMTX "[{}].w >= 0) indtevtrans{} >>= " I_INDTEXMTX "[{}].w;\n",
+ mtxidx, n, mtxidx);
+ out.Write("\telse indtevtrans{} <<= indtexmtx_w_inverse_{};\n", n, n);
}
else
{
- out.WriteFmt("\tif (" I_INDTEXMTX "[{}].w >= 0) indtevtrans{} >>= " I_INDTEXMTX
- "[{}].w;\n",
- mtxidx, n, mtxidx);
- out.WriteFmt("\telse indtevtrans{} <<= (-" I_INDTEXMTX "[{}].w);\n", n, mtxidx);
+ out.Write("\tif (" I_INDTEXMTX "[{}].w >= 0) indtevtrans{} >>= " I_INDTEXMTX "[{}].w;\n",
+ mtxidx, n, mtxidx);
+ out.Write("\telse indtevtrans{} <<= (-" I_INDTEXMTX "[{}].w);\n", n, mtxidx);
}
}
else if (tevind.mid <= 7 && has_tex_coord)
@@ -1066,22 +1062,20 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
const u32 mtxidx = 2 * (tevind.mid - 5);
out.SetConstantsUsed(C_INDTEXMTX + mtxidx, C_INDTEXMTX + mtxidx);
- out.WriteFmt("\tint2 indtevtrans{} = int2(fixpoint_uv{} * iindtevcrd{}.xx) >> 8;\n", n,
- texcoord, n);
+ out.Write("\tint2 indtevtrans{} = int2(fixpoint_uv{} * iindtevcrd{}.xx) >> 8;\n", n,
+ texcoord, n);
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_BITWISE_OP_NEGATION))
{
- out.WriteFmt("\tint indtexmtx_w_inverse_{} = -" I_INDTEXMTX "[{}].w;\n", n, mtxidx);
- out.WriteFmt("\tif (" I_INDTEXMTX "[{}].w >= 0) indtevtrans{} >>= " I_INDTEXMTX
- "[{}].w;\n",
- mtxidx, n, mtxidx);
- out.WriteFmt("\telse indtevtrans{} <<= (indtexmtx_w_inverse_{});\n", n, n);
+ out.Write("\tint indtexmtx_w_inverse_{} = -" I_INDTEXMTX "[{}].w;\n", n, mtxidx);
+ out.Write("\tif (" I_INDTEXMTX "[{}].w >= 0) indtevtrans{} >>= " I_INDTEXMTX "[{}].w;\n",
+ mtxidx, n, mtxidx);
+ out.Write("\telse indtevtrans{} <<= (indtexmtx_w_inverse_{});\n", n, n);
}
else
{
- out.WriteFmt("\tif (" I_INDTEXMTX "[{}].w >= 0) indtevtrans{} >>= " I_INDTEXMTX
- "[{}].w;\n",
- mtxidx, n, mtxidx);
- out.WriteFmt("\telse indtevtrans{} <<= (-" I_INDTEXMTX "[{}].w);\n", n, mtxidx);
+ out.Write("\tif (" I_INDTEXMTX "[{}].w >= 0) indtevtrans{} >>= " I_INDTEXMTX "[{}].w;\n",
+ mtxidx, n, mtxidx);
+ out.Write("\telse indtevtrans{} <<= (-" I_INDTEXMTX "[{}].w);\n", n, mtxidx);
}
}
else if (tevind.mid <= 11 && has_tex_coord)
@@ -1090,33 +1084,31 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
const u32 mtxidx = 2 * (tevind.mid - 9);
out.SetConstantsUsed(C_INDTEXMTX + mtxidx, C_INDTEXMTX + mtxidx);
- out.WriteFmt("\tint2 indtevtrans{} = int2(fixpoint_uv{} * iindtevcrd{}.yy) >> 8;\n", n,
- texcoord, n);
+ out.Write("\tint2 indtevtrans{} = int2(fixpoint_uv{} * iindtevcrd{}.yy) >> 8;\n", n,
+ texcoord, n);
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_BITWISE_OP_NEGATION))
{
- out.WriteFmt("\tint indtexmtx_w_inverse_{} = -" I_INDTEXMTX "[{}].w;\n", n, mtxidx);
- out.WriteFmt("\tif (" I_INDTEXMTX "[{}].w >= 0) indtevtrans{} >>= " I_INDTEXMTX
- "[{}].w;\n",
- mtxidx, n, mtxidx);
- out.WriteFmt("\telse indtevtrans{} <<= (indtexmtx_w_inverse_{});\n", n, n);
+ out.Write("\tint indtexmtx_w_inverse_{} = -" I_INDTEXMTX "[{}].w;\n", n, mtxidx);
+ out.Write("\tif (" I_INDTEXMTX "[{}].w >= 0) indtevtrans{} >>= " I_INDTEXMTX "[{}].w;\n",
+ mtxidx, n, mtxidx);
+ out.Write("\telse indtevtrans{} <<= (indtexmtx_w_inverse_{});\n", n, n);
}
else
{
- out.WriteFmt("\tif (" I_INDTEXMTX "[{}].w >= 0) indtevtrans{} >>= " I_INDTEXMTX
- "[{}].w;\n",
- mtxidx, n, mtxidx);
- out.WriteFmt("\telse indtevtrans{} <<= (-" I_INDTEXMTX "[{}].w);\n", n, mtxidx);
+ out.Write("\tif (" I_INDTEXMTX "[{}].w >= 0) indtevtrans{} >>= " I_INDTEXMTX "[{}].w;\n",
+ mtxidx, n, mtxidx);
+ out.Write("\telse indtevtrans{} <<= (-" I_INDTEXMTX "[{}].w);\n", n, mtxidx);
}
}
else
{
- out.WriteFmt("\tint2 indtevtrans{} = int2(0, 0);\n", n);
+ out.Write("\tint2 indtevtrans{} = int2(0, 0);\n", n);
}
}
else
{
- out.WriteFmt("\tint2 indtevtrans{} = int2(0, 0);\n", n);
+ out.Write("\tint2 indtevtrans{} = int2(0, 0);\n", n);
}
// ---------
@@ -1131,40 +1123,40 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
// wrap S
if (tevind.sw == ITW_OFF)
{
- out.WriteFmt("\twrappedcoord.x = fixpoint_uv{}.x;\n", texcoord);
+ out.Write("\twrappedcoord.x = fixpoint_uv{}.x;\n", texcoord);
}
else if (tevind.sw == ITW_0)
{
- out.WriteFmt("\twrappedcoord.x = 0;\n");
+ out.Write("\twrappedcoord.x = 0;\n");
}
else
{
- out.WriteFmt("\twrappedcoord.x = fixpoint_uv{}.x & ({} - 1);\n", texcoord,
- tev_ind_wrap_start[tevind.sw]);
+ out.Write("\twrappedcoord.x = fixpoint_uv{}.x & ({} - 1);\n", texcoord,
+ tev_ind_wrap_start[tevind.sw]);
}
// wrap T
if (tevind.tw == ITW_OFF)
{
- out.WriteFmt("\twrappedcoord.y = fixpoint_uv{}.y;\n", texcoord);
+ out.Write("\twrappedcoord.y = fixpoint_uv{}.y;\n", texcoord);
}
else if (tevind.tw == ITW_0)
{
- out.WriteFmt("\twrappedcoord.y = 0;\n");
+ out.Write("\twrappedcoord.y = 0;\n");
}
else
{
- out.WriteFmt("\twrappedcoord.y = fixpoint_uv{}.y & ({} - 1);\n", texcoord,
- tev_ind_wrap_start[tevind.tw]);
+ out.Write("\twrappedcoord.y = fixpoint_uv{}.y & ({} - 1);\n", texcoord,
+ tev_ind_wrap_start[tevind.tw]);
}
if (tevind.fb_addprev) // add previous tevcoord
- out.WriteFmt("\ttevcoord.xy += wrappedcoord + indtevtrans{};\n", n);
+ out.Write("\ttevcoord.xy += wrappedcoord + indtevtrans{};\n", n);
else
- out.WriteFmt("\ttevcoord.xy = wrappedcoord + indtevtrans{};\n", n);
+ out.Write("\ttevcoord.xy = wrappedcoord + indtevtrans{};\n", n);
// Emulate s24 overflows
- out.WriteFmt("\ttevcoord.xy = (tevcoord.xy << 8) >> 8;\n");
+ out.Write("\ttevcoord.xy = (tevcoord.xy << 8) >> 8;\n");
}
TevStageCombiner::ColorCombiner cc;
@@ -1186,7 +1178,7 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
'\0',
};
- out.WriteFmt("\trastemp = {}.{};\n", tev_ras_table[stage.tevorders_colorchan], rasswap);
+ out.Write("\trastemp = {}.{};\n", tev_ras_table[stage.tevorders_colorchan], rasswap);
}
if (stage.tevorders_enable)
@@ -1204,24 +1196,24 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
{
// calc tevcord
if (has_tex_coord)
- out.WriteFmt("\ttevcoord.xy = fixpoint_uv{};\n", texcoord);
+ out.Write("\ttevcoord.xy = fixpoint_uv{};\n", texcoord);
else
- out.WriteFmt("\ttevcoord.xy = int2(0, 0);\n");
+ out.Write("\ttevcoord.xy = int2(0, 0);\n");
}
- out.WriteFmt("\ttextemp = ");
+ out.Write("\ttextemp = ");
SampleTexture(out, "float2(tevcoord.xy)", texswap, stage.tevorders_texmap, stereo, api_type);
}
else
{
- out.WriteFmt("\ttextemp = int4(255, 255, 255, 255);\n");
+ out.Write("\ttextemp = int4(255, 255, 255, 255);\n");
}
if (cc.a == TEVCOLORARG_KONST || cc.b == TEVCOLORARG_KONST || cc.c == TEVCOLORARG_KONST ||
cc.d == TEVCOLORARG_KONST || ac.a == TEVALPHAARG_KONST || ac.b == TEVALPHAARG_KONST ||
ac.c == TEVALPHAARG_KONST || ac.d == TEVALPHAARG_KONST)
{
- out.WriteFmt("\tkonsttemp = int4({}, {});\n", tev_ksel_table_c[stage.tevksel_kc],
- tev_ksel_table_a[stage.tevksel_ka]);
+ out.Write("\tkonsttemp = int4({}, {});\n", tev_ksel_table_c[stage.tevksel_kc],
+ tev_ksel_table_a[stage.tevksel_ka]);
if (stage.tevksel_kc > 7)
{
@@ -1250,16 +1242,16 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
if (ac.dest >= GX_TEVREG0)
out.SetConstantsUsed(C_COLORS + ac.dest, C_COLORS + ac.dest);
- out.WriteFmt("\ttevin_a = int4({}, {})&int4(255, 255, 255, 255);\n", tev_c_input_table[cc.a],
- tev_a_input_table[ac.a]);
- out.WriteFmt("\ttevin_b = int4({}, {})&int4(255, 255, 255, 255);\n", tev_c_input_table[cc.b],
- tev_a_input_table[ac.b]);
- out.WriteFmt("\ttevin_c = int4({}, {})&int4(255, 255, 255, 255);\n", tev_c_input_table[cc.c],
- tev_a_input_table[ac.c]);
- out.WriteFmt("\ttevin_d = int4({}, {});\n", tev_c_input_table[cc.d], tev_a_input_table[ac.d]);
+ out.Write("\ttevin_a = int4({}, {})&int4(255, 255, 255, 255);\n", tev_c_input_table[cc.a],
+ tev_a_input_table[ac.a]);
+ out.Write("\ttevin_b = int4({}, {})&int4(255, 255, 255, 255);\n", tev_c_input_table[cc.b],
+ tev_a_input_table[ac.b]);
+ out.Write("\ttevin_c = int4({}, {})&int4(255, 255, 255, 255);\n", tev_c_input_table[cc.c],
+ tev_a_input_table[ac.c]);
+ out.Write("\ttevin_d = int4({}, {});\n", tev_c_input_table[cc.d], tev_a_input_table[ac.d]);
- out.WriteFmt("\t// color combine\n");
- out.WriteFmt("\t{} = clamp(", tev_c_output_table[cc.dest]);
+ out.Write("\t// color combine\n");
+ out.Write("\t{} = clamp(", tev_c_output_table[cc.dest]);
if (cc.bias != TEVBIAS_COMPARE)
{
WriteTevRegular(out, "rgb", cc.bias, cc.op, cc.clamp, cc.shift, false);
@@ -1282,17 +1274,17 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
};
const u32 mode = (cc.shift << 1) | cc.op;
- out.WriteFmt(" tevin_d.rgb + ");
- out.WriteFmt("{}", function_table[mode]);
+ out.Write(" tevin_d.rgb + ");
+ out.Write("{}", function_table[mode]);
}
if (cc.clamp)
- out.WriteFmt(", int3(0,0,0), int3(255,255,255))");
+ out.Write(", int3(0,0,0), int3(255,255,255))");
else
- out.WriteFmt(", int3(-1024,-1024,-1024), int3(1023,1023,1023))");
- out.WriteFmt(";\n");
+ out.Write(", int3(-1024,-1024,-1024), int3(1023,1023,1023))");
+ out.Write(";\n");
- out.WriteFmt("\t// alpha combine\n");
- out.WriteFmt("\t{} = clamp(", tev_a_output_table[ac.dest]);
+ out.Write("\t// alpha combine\n");
+ out.Write("\t{} = clamp(", tev_a_output_table[ac.dest]);
if (ac.bias != TEVBIAS_COMPARE)
{
WriteTevRegular(out, "a", ac.bias, ac.op, ac.clamp, ac.shift, true);
@@ -1311,15 +1303,15 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
};
const u32 mode = (ac.shift << 1) | ac.op;
- out.WriteFmt(" tevin_d.a + ");
- out.WriteFmt("{}", function_table[mode]);
+ out.Write(" tevin_d.a + ");
+ out.Write("{}", function_table[mode]);
}
if (ac.clamp)
- out.WriteFmt(", 0, 255)");
+ out.Write(", 0, 255)");
else
- out.WriteFmt(", -1024, 1023)");
+ out.Write(", -1024, 1023)");
- out.WriteFmt(";\n");
+ out.Write(";\n");
}
static void WriteTevRegular(ShaderCode& out, std::string_view components, int bias, int op,
@@ -1364,14 +1356,12 @@ static void WriteTevRegular(ShaderCode& out, std::string_view components, int bi
// - c is scaled from 0..255 to 0..256, which allows dividing the result by 256 instead of 255
// - if scale is bigger than one, it is moved inside the lerp calculation for increased accuracy
// - a rounding bias is added before dividing by 256
- out.WriteFmt("(((tevin_d.{}{}){})", components, tev_bias_table[bias],
- tev_scale_table_left[shift]);
- out.WriteFmt(" {} ", tev_op_table[op]);
- out.WriteFmt(
- "(((((tevin_a.{}<<8) + (tevin_b.{}-tevin_a.{})*(tevin_c.{}+(tevin_c.{}>>7))){}){})>>8)",
- components, components, components, components, components, tev_scale_table_left[shift],
- tev_lerp_bias[2 * op + ((shift == 3) == alpha)]);
- out.WriteFmt("){}", tev_scale_table_right[shift]);
+ out.Write("(((tevin_d.{}{}){})", components, tev_bias_table[bias], tev_scale_table_left[shift]);
+ out.Write(" {} ", tev_op_table[op]);
+ out.Write("(((((tevin_a.{}<<8) + (tevin_b.{}-tevin_a.{})*(tevin_c.{}+(tevin_c.{}>>7))){}){})>>8)",
+ components, components, components, components, components, tev_scale_table_left[shift],
+ tev_lerp_bias[2 * op + ((shift == 3) == alpha)]);
+ out.Write("){}", tev_scale_table_right[shift]);
}
static void SampleTexture(ShaderCode& out, std::string_view texcoords, std::string_view texswap,
@@ -1381,15 +1371,14 @@ static void SampleTexture(ShaderCode& out, std::string_view texcoords, std::stri
if (api_type == APIType::D3D)
{
- out.WriteFmt("iround(255.0 * Tex[{}].Sample(samp[{}], float3({}.xy * " I_TEXDIMS
- "[{}].xy, {}))).{};\n",
- texmap, texmap, texcoords, texmap, stereo ? "layer" : "0.0", texswap);
+ out.Write("iround(255.0 * Tex[{}].Sample(samp[{}], float3({}.xy * " I_TEXDIMS
+ "[{}].xy, {}))).{};\n",
+ texmap, texmap, texcoords, texmap, stereo ? "layer" : "0.0", texswap);
}
else
{
- out.WriteFmt("iround(255.0 * texture(samp[{}], float3({}.xy * " I_TEXDIMS
- "[{}].xy, {}))).{};\n",
- texmap, texcoords, texmap, stereo ? "layer" : "0.0", texswap);
+ out.Write("iround(255.0 * texture(samp[{}], float3({}.xy * " I_TEXDIMS "[{}].xy, {}))).{};\n",
+ texmap, texcoords, texmap, stereo ? "layer" : "0.0", texswap);
}
}
@@ -1422,52 +1411,52 @@ static void WriteAlphaTest(ShaderCode& out, const pixel_shader_uid_data* uid_dat
const auto write_alpha_func = [&out](int index, std::string_view ref) {
const bool has_no_arguments = index == 0 || index == tev_alpha_funcs_table.size() - 1;
if (has_no_arguments)
- out.WriteFmt("{}", tev_alpha_funcs_table[index]);
+ out.Write("{}", tev_alpha_funcs_table[index]);
else
- out.WriteFmt(tev_alpha_funcs_table[index], ref);
+ out.Write(tev_alpha_funcs_table[index], ref);
};
out.SetConstantsUsed(C_ALPHA, C_ALPHA);
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_NEGATED_BOOLEAN))
- out.WriteFmt("\tif(( ");
+ out.Write("\tif(( ");
else
- out.WriteFmt("\tif(!( ");
+ out.Write("\tif(!( ");
// Lookup the first component from the alpha function table
const int comp0_index = uid_data->alpha_test_comp0;
write_alpha_func(comp0_index, alpha_ref[0]);
// Lookup the logic op
- out.WriteFmt("{}", tev_alpha_funclogic_table[uid_data->alpha_test_logic]);
+ out.Write("{}", tev_alpha_funclogic_table[uid_data->alpha_test_logic]);
// Lookup the second component from the alpha function table
const int comp1_index = uid_data->alpha_test_comp1;
write_alpha_func(comp1_index, alpha_ref[1]);
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_NEGATED_BOOLEAN))
- out.WriteFmt(") == false) {{\n");
+ out.Write(") == false) {{\n");
else
- out.WriteFmt(")) {{\n");
+ out.Write(")) {{\n");
- out.WriteFmt("\t\tocol0 = float4(0.0, 0.0, 0.0, 0.0);\n");
+ out.Write("\t\tocol0 = float4(0.0, 0.0, 0.0, 0.0);\n");
if (use_dual_source && !(api_type == APIType::D3D && uid_data->uint_output))
- out.WriteFmt("\t\tocol1 = float4(0.0, 0.0, 0.0, 0.0);\n");
+ out.Write("\t\tocol1 = float4(0.0, 0.0, 0.0, 0.0);\n");
if (per_pixel_depth)
{
- out.WriteFmt("\t\tdepth = {};\n",
- !g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? "0.0" : "1.0");
+ out.Write("\t\tdepth = {};\n",
+ !g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? "0.0" : "1.0");
}
// ZCOMPLOC HACK:
if (!uid_data->alpha_test_use_zcomploc_hack)
{
- out.WriteFmt("\t\tdiscard;\n");
+ out.Write("\t\tdiscard;\n");
if (api_type == APIType::D3D)
- out.WriteFmt("\t\treturn;\n");
+ out.Write("\t\treturn;\n");
}
- out.WriteFmt("\t}}\n");
+ out.Write("\t}}\n");
}
constexpr std::array<const char*, 8> tev_fog_funcs_table{
@@ -1497,14 +1486,14 @@ static void WriteFog(ShaderCode& out, const pixel_shader_uid_data* uid_data)
// renderer)
// Maybe we want to use "ze = (A << B_SHF)/((B << B_SHF) - Zs)" instead?
// That's equivalent, but keeps the lower bits of Zs.
- out.WriteFmt("\tfloat ze = (" I_FOGF ".x * 16777216.0) / float(" I_FOGI
- ".y - (zCoord >> " I_FOGI ".w));\n");
+ out.Write("\tfloat ze = (" I_FOGF ".x * 16777216.0) / float(" I_FOGI ".y - (zCoord >> " I_FOGI
+ ".w));\n");
}
else
{
// orthographic
// ze = a*Zs (here, no B_SHF)
- out.WriteFmt("\tfloat ze = " I_FOGF ".x * float(zCoord) / 16777216.0;\n");
+ out.Write("\tfloat ze = " I_FOGF ".x * float(zCoord) / 16777216.0;\n");
}
// x_adjust = sqrt((x-center)^2 + k^2)/k
@@ -1512,22 +1501,22 @@ static void WriteFog(ShaderCode& out, const pixel_shader_uid_data* uid_data)
if (uid_data->fog_RangeBaseEnabled)
{
out.SetConstantsUsed(C_FOGF, C_FOGF);
- out.WriteFmt("\tfloat offset = (2.0 * (rawpos.x / " I_FOGF ".w)) - 1.0 - " I_FOGF ".z;\n"
- "\tfloat floatindex = clamp(9.0 - abs(offset) * 9.0, 0.0, 9.0);\n"
- "\tuint indexlower = uint(floatindex);\n"
- "\tuint indexupper = indexlower + 1u;\n"
- "\tfloat klower = " I_FOGRANGE "[indexlower >> 2u][indexlower & 3u];\n"
- "\tfloat kupper = " I_FOGRANGE "[indexupper >> 2u][indexupper & 3u];\n"
- "\tfloat k = lerp(klower, kupper, frac(floatindex));\n"
- "\tfloat x_adjust = sqrt(offset * offset + k * k) / k;\n"
- "\tze *= x_adjust;\n");
+ out.Write("\tfloat offset = (2.0 * (rawpos.x / " I_FOGF ".w)) - 1.0 - " I_FOGF ".z;\n"
+ "\tfloat floatindex = clamp(9.0 - abs(offset) * 9.0, 0.0, 9.0);\n"
+ "\tuint indexlower = uint(floatindex);\n"
+ "\tuint indexupper = indexlower + 1u;\n"
+ "\tfloat klower = " I_FOGRANGE "[indexlower >> 2u][indexlower & 3u];\n"
+ "\tfloat kupper = " I_FOGRANGE "[indexupper >> 2u][indexupper & 3u];\n"
+ "\tfloat k = lerp(klower, kupper, frac(floatindex));\n"
+ "\tfloat x_adjust = sqrt(offset * offset + k * k) / k;\n"
+ "\tze *= x_adjust;\n");
}
- out.WriteFmt("\tfloat fog = clamp(ze - " I_FOGF ".y, 0.0, 1.0);\n");
+ out.Write("\tfloat fog = clamp(ze - " I_FOGF ".y, 0.0, 1.0);\n");
if (uid_data->fog_fsel > 3)
{
- out.WriteFmt("{}", tev_fog_funcs_table[uid_data->fog_fsel]);
+ out.Write("{}", tev_fog_funcs_table[uid_data->fog_fsel]);
}
else
{
@@ -1535,8 +1524,8 @@ static void WriteFog(ShaderCode& out, const pixel_shader_uid_data* uid_data)
WARN_LOG(VIDEO, "Unknown Fog Type! %08x", uid_data->fog_fsel);
}
- out.WriteFmt("\tint ifog = iround(fog * 256.0);\n");
- out.WriteFmt("\tprev.rgb = (prev.rgb * (256 - ifog) + " I_FOGCOLOR ".rgb * ifog) >> 8;\n");
+ out.Write("\tint ifog = iround(fog * 256.0);\n");
+ out.Write("\tprev.rgb = (prev.rgb * (256 - ifog) + " I_FOGCOLOR ".rgb * ifog) >> 8;\n");
}
static void WriteColor(ShaderCode& out, APIType api_type, const pixel_shader_uid_data* uid_data,
@@ -1546,33 +1535,33 @@ static void WriteColor(ShaderCode& out, APIType api_type, const pixel_shader_uid
if (api_type == APIType::D3D && uid_data->uint_output)
{
if (uid_data->rgba6_format)
- out.WriteFmt("\tocol0 = uint4(prev & 0xFC);\n");
+ out.Write("\tocol0 = uint4(prev & 0xFC);\n");
else
- out.WriteFmt("\tocol0 = uint4(prev);\n");
+ out.Write("\tocol0 = uint4(prev);\n");
return;
}
if (uid_data->rgba6_format)
- out.WriteFmt("\tocol0.rgb = float3(prev.rgb >> 2) / 63.0;\n");
+ out.Write("\tocol0.rgb = float3(prev.rgb >> 2) / 63.0;\n");
else
- out.WriteFmt("\tocol0.rgb = float3(prev.rgb) / 255.0;\n");
+ out.Write("\tocol0.rgb = float3(prev.rgb) / 255.0;\n");
// Colors will be blended against the 8-bit alpha from ocol1 and
// the 6-bit alpha from ocol0 will be written to the framebuffer
if (uid_data->useDstAlpha)
{
out.SetConstantsUsed(C_ALPHA, C_ALPHA);
- out.WriteFmt("\tocol0.a = float(" I_ALPHA ".a >> 2) / 63.0;\n");
+ out.Write("\tocol0.a = float(" I_ALPHA ".a >> 2) / 63.0;\n");
// Use dual-source color blending to perform dst alpha in a single pass
if (use_dual_source)
- out.WriteFmt("\tocol1 = float4(0.0, 0.0, 0.0, float(prev.a) / 255.0);\n");
+ out.Write("\tocol1 = float4(0.0, 0.0, 0.0, float(prev.a) / 255.0);\n");
}
else
{
- out.WriteFmt("\tocol0.a = float(prev.a >> 2) / 63.0;\n");
+ out.Write("\tocol0.a = float(prev.a >> 2) / 63.0;\n");
if (use_dual_source)
- out.WriteFmt("\tocol1 = float4(0.0, 0.0, 0.0, float(prev.a) / 255.0);\n");
+ out.Write("\tocol1 = float4(0.0, 0.0, 0.0, float(prev.a) / 255.0);\n");
}
}
@@ -1620,34 +1609,34 @@ static void WriteBlend(ShaderCode& out, const pixel_shader_uid_data* uid_data)
"initial_ocol0.a;", // DSTALPHA
"1.0 - initial_ocol0.a;", // INVDSTALPHA
};
- out.WriteFmt("\tfloat4 blend_src;\n");
- out.WriteFmt("\tblend_src.rgb = {}\n", blend_src_factor[uid_data->blend_src_factor]);
- out.WriteFmt("\tblend_src.a = {}\n", blend_src_factor_alpha[uid_data->blend_src_factor_alpha]);
- out.WriteFmt("\tfloat4 blend_dst;\n");
- out.WriteFmt("\tblend_dst.rgb = {}\n", blend_dst_factor[uid_data->blend_dst_factor]);
- out.WriteFmt("\tblend_dst.a = {}\n", blend_dst_factor_alpha[uid_data->blend_dst_factor_alpha]);
-
- out.WriteFmt("\tfloat4 blend_result;\n");
+ out.Write("\tfloat4 blend_src;\n");
+ out.Write("\tblend_src.rgb = {}\n", blend_src_factor[uid_data->blend_src_factor]);
+ out.Write("\tblend_src.a = {}\n", blend_src_factor_alpha[uid_data->blend_src_factor_alpha]);
+ out.Write("\tfloat4 blend_dst;\n");
+ out.Write("\tblend_dst.rgb = {}\n", blend_dst_factor[uid_data->blend_dst_factor]);
+ out.Write("\tblend_dst.a = {}\n", blend_dst_factor_alpha[uid_data->blend_dst_factor_alpha]);
+
+ out.Write("\tfloat4 blend_result;\n");
if (uid_data->blend_subtract)
{
- out.WriteFmt("\tblend_result.rgb = initial_ocol0.rgb * blend_dst.rgb - ocol0.rgb * "
- "blend_src.rgb;\n");
+ out.Write("\tblend_result.rgb = initial_ocol0.rgb * blend_dst.rgb - ocol0.rgb * "
+ "blend_src.rgb;\n");
}
else
{
- out.WriteFmt(
+ out.Write(
"\tblend_result.rgb = initial_ocol0.rgb * blend_dst.rgb + ocol0.rgb * blend_src.rgb;\n");
}
if (uid_data->blend_subtract_alpha)
- out.WriteFmt("\tblend_result.a = initial_ocol0.a * blend_dst.a - ocol0.a * blend_src.a;\n");
+ out.Write("\tblend_result.a = initial_ocol0.a * blend_dst.a - ocol0.a * blend_src.a;\n");
else
- out.WriteFmt("\tblend_result.a = initial_ocol0.a * blend_dst.a + ocol0.a * blend_src.a;\n");
+ out.Write("\tblend_result.a = initial_ocol0.a * blend_dst.a + ocol0.a * blend_src.a;\n");
}
else
{
- out.WriteFmt("\tfloat4 blend_result = ocol0;\n");
+ out.Write("\tfloat4 blend_result = ocol0;\n");
}
- out.WriteFmt("\treal_ocol0 = blend_result;\n");
+ out.Write("\treal_ocol0 = blend_result;\n");
}