mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
Merge pull request #8509 from lioncash/shader-str
VideoCommon/FramebufferShaderGen: Minor clean up
This commit is contained in:
commit
9ef50a1d4b
@ -1,17 +1,26 @@
|
||||
// Copyright 2019 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "VideoCommon/FramebufferShaderGen.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string_view>
|
||||
|
||||
#include "VideoCommon/FramebufferManager.h"
|
||||
#include "VideoCommon/TextureDecoder.h"
|
||||
#include "VideoCommon/VertexShaderGen.h"
|
||||
|
||||
namespace FramebufferShaderGen
|
||||
{
|
||||
static APIType GetAPIType()
|
||||
namespace
|
||||
{
|
||||
APIType GetAPIType()
|
||||
{
|
||||
return g_ActiveConfig.backend_info.api_type;
|
||||
}
|
||||
|
||||
static void EmitUniformBufferDeclaration(std::stringstream& ss)
|
||||
void EmitUniformBufferDeclaration(std::ostringstream& ss)
|
||||
{
|
||||
if (GetAPIType() == APIType::D3D)
|
||||
ss << "cbuffer PSBlock : register(b0)\n";
|
||||
@ -19,8 +28,8 @@ static void EmitUniformBufferDeclaration(std::stringstream& ss)
|
||||
ss << "UBO_BINDING(std140, 1) uniform PSBlock\n";
|
||||
}
|
||||
|
||||
static void EmitSamplerDeclarations(std::stringstream& ss, u32 start = 0, u32 end = 1,
|
||||
bool multisampled = false)
|
||||
void EmitSamplerDeclarations(std::ostringstream& ss, u32 start = 0, u32 end = 1,
|
||||
bool multisampled = false)
|
||||
{
|
||||
switch (GetAPIType())
|
||||
{
|
||||
@ -51,17 +60,17 @@ static void EmitSamplerDeclarations(std::stringstream& ss, u32 start = 0, u32 en
|
||||
}
|
||||
}
|
||||
|
||||
static void EmitSampleTexture(std::stringstream& ss, u32 n, const char* coords)
|
||||
void EmitSampleTexture(std::ostringstream& ss, u32 n, std::string_view coords)
|
||||
{
|
||||
switch (GetAPIType())
|
||||
{
|
||||
case APIType::D3D:
|
||||
ss << "tex" << n << ".Sample(samp" << n << ", " << coords << ")";
|
||||
ss << "tex" << n << ".Sample(samp" << n << ", " << coords << ')';
|
||||
break;
|
||||
|
||||
case APIType::OpenGL:
|
||||
case APIType::Vulkan:
|
||||
ss << "texture(samp" << n << ", " << coords << ")";
|
||||
ss << "texture(samp" << n << ", " << coords << ')';
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -71,12 +80,12 @@ static void EmitSampleTexture(std::stringstream& ss, u32 n, const char* coords)
|
||||
|
||||
// Emits a texel fetch/load instruction. Assumes that "coords" is a 4-element vector, with z
|
||||
// containing the layer, and w containing the mipmap level.
|
||||
static void EmitTextureLoad(std::stringstream& ss, u32 n, const char* coords)
|
||||
void EmitTextureLoad(std::ostringstream& ss, u32 n, std::string_view coords)
|
||||
{
|
||||
switch (GetAPIType())
|
||||
{
|
||||
case APIType::D3D:
|
||||
ss << "tex" << n << ".Load(" << coords << ")";
|
||||
ss << "tex" << n << ".Load(" << coords << ')';
|
||||
break;
|
||||
|
||||
case APIType::OpenGL:
|
||||
@ -89,10 +98,9 @@ static void EmitTextureLoad(std::stringstream& ss, u32 n, const char* coords)
|
||||
}
|
||||
}
|
||||
|
||||
static void EmitVertexMainDeclaration(std::stringstream& ss, u32 num_tex_inputs,
|
||||
u32 num_color_inputs, bool position_input,
|
||||
u32 num_tex_outputs, u32 num_color_outputs,
|
||||
const char* extra_inputs = "")
|
||||
void EmitVertexMainDeclaration(std::ostringstream& ss, u32 num_tex_inputs, u32 num_color_inputs,
|
||||
bool position_input, u32 num_tex_outputs, u32 num_color_outputs,
|
||||
std::string_view extra_inputs = {})
|
||||
{
|
||||
switch (GetAPIType())
|
||||
{
|
||||
@ -118,11 +126,15 @@ static void EmitVertexMainDeclaration(std::stringstream& ss, u32 num_tex_inputs,
|
||||
case APIType::Vulkan:
|
||||
{
|
||||
for (u32 i = 0; i < num_tex_inputs; i++)
|
||||
{
|
||||
ss << "ATTRIBUTE_LOCATION(" << (SHADER_TEXTURE0_ATTRIB + i) << ") in float3 rawtex" << i
|
||||
<< ";\n";
|
||||
}
|
||||
for (u32 i = 0; i < num_color_inputs; i++)
|
||||
{
|
||||
ss << "ATTRIBUTE_LOCATION(" << (SHADER_COLOR0_ATTRIB + i) << ") in float4 rawcolor" << i
|
||||
<< ";\n";
|
||||
}
|
||||
if (position_input)
|
||||
ss << "ATTRIBUTE_LOCATION(" << SHADER_POSITION_ATTRIB << ") in float4 rawpos;\n";
|
||||
|
||||
@ -143,7 +155,7 @@ static void EmitVertexMainDeclaration(std::stringstream& ss, u32 num_tex_inputs,
|
||||
ss << "VARYING_LOCATION(" << (num_tex_inputs + i) << ") out float4 v_col" << i << ";\n";
|
||||
}
|
||||
ss << "#define opos gl_Position\n";
|
||||
ss << extra_inputs << "\n";
|
||||
ss << extra_inputs << '\n';
|
||||
ss << "void main()\n";
|
||||
}
|
||||
break;
|
||||
@ -152,9 +164,9 @@ static void EmitVertexMainDeclaration(std::stringstream& ss, u32 num_tex_inputs,
|
||||
}
|
||||
}
|
||||
|
||||
static void EmitPixelMainDeclaration(std::stringstream& ss, u32 num_tex_inputs,
|
||||
u32 num_color_inputs, const char* output_type = "float4",
|
||||
const char* extra_vars = "", bool emit_frag_coord = false)
|
||||
void EmitPixelMainDeclaration(std::ostringstream& ss, u32 num_tex_inputs, u32 num_color_inputs,
|
||||
std::string_view output_type = "float4",
|
||||
std::string_view extra_vars = {}, bool emit_frag_coord = false)
|
||||
{
|
||||
switch (GetAPIType())
|
||||
{
|
||||
@ -203,16 +215,17 @@ static void EmitPixelMainDeclaration(std::stringstream& ss, u32 num_tex_inputs,
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
std::string GenerateScreenQuadVertexShader()
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
EmitVertexMainDeclaration(ss, 0, 0, false, 1, 0,
|
||||
GetAPIType() == APIType::D3D ? "in uint id : SV_VertexID, " :
|
||||
"#define id gl_VertexID\n");
|
||||
ss << "{\n";
|
||||
ss << " v_tex0 = float3(float((id << 1) & 2), float(id & 2), 0.0f);\n";
|
||||
ss << " opos = float4(v_tex0.xy * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);\n";
|
||||
ss << "{\n"
|
||||
" v_tex0 = float3(float((id << 1) & 2), float(id & 2), 0.0f);\n"
|
||||
" opos = float4(v_tex0.xy * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);\n";
|
||||
|
||||
// NDC space is flipped in Vulkan. We also flip in GL so that (0,0) is in the lower-left.
|
||||
if (GetAPIType() == APIType::Vulkan || GetAPIType() == APIType::OpenGL)
|
||||
@ -225,50 +238,52 @@ std::string GenerateScreenQuadVertexShader()
|
||||
|
||||
std::string GeneratePassthroughGeometryShader(u32 num_tex, u32 num_colors)
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
if (GetAPIType() == APIType::D3D)
|
||||
{
|
||||
ss << "struct VS_OUTPUT\n";
|
||||
ss << "{\n";
|
||||
ss << "struct VS_OUTPUT\n"
|
||||
"{\n";
|
||||
for (u32 i = 0; i < num_tex; i++)
|
||||
ss << " float3 tex" << i << " : TEXCOORD" << i << ";\n";
|
||||
for (u32 i = 0; i < num_colors; i++)
|
||||
ss << " float4 color" << i << " : COLOR" << i << ";\n";
|
||||
ss << " float4 position : SV_Position;\n";
|
||||
ss << "};\n";
|
||||
ss << "struct GS_OUTPUT\n";
|
||||
ss << "{";
|
||||
ss << " float4 position : SV_Position;\n"
|
||||
"};\n";
|
||||
|
||||
ss << "struct GS_OUTPUT\n"
|
||||
"{";
|
||||
for (u32 i = 0; i < num_tex; i++)
|
||||
ss << " float3 tex" << i << " : TEXCOORD" << i << ";\n";
|
||||
for (u32 i = 0; i < num_colors; i++)
|
||||
ss << " float4 color" << i << " : COLOR" << i << ";\n";
|
||||
ss << " float4 position : SV_Position;\n";
|
||||
ss << " uint slice : SV_RenderTargetArrayIndex;\n";
|
||||
ss << "};\n\n";
|
||||
ss << "[maxvertexcount(6)]\n";
|
||||
ss << "void main(triangle VS_OUTPUT vso[3], inout TriangleStream<GS_OUTPUT> output)\n";
|
||||
ss << "{\n";
|
||||
ss << " for (uint slice = 0; slice < 2u; slice++)\n";
|
||||
ss << " {\n";
|
||||
ss << " for (int i = 0; i < 3; i++)\n";
|
||||
ss << " {\n";
|
||||
ss << " GS_OUTPUT gso;\n";
|
||||
ss << " gso.position = vso[i].position;\n";
|
||||
ss << " float4 position : SV_Position;\n"
|
||||
" uint slice : SV_RenderTargetArrayIndex;\n"
|
||||
"};\n\n";
|
||||
|
||||
ss << "[maxvertexcount(6)]\n"
|
||||
"void main(triangle VS_OUTPUT vso[3], inout TriangleStream<GS_OUTPUT> output)\n"
|
||||
"{\n"
|
||||
" for (uint slice = 0; slice < 2u; slice++)\n"
|
||||
" {\n"
|
||||
" for (int i = 0; i < 3; i++)\n"
|
||||
" {\n"
|
||||
" GS_OUTPUT gso;\n"
|
||||
" gso.position = vso[i].position;\n";
|
||||
for (u32 i = 0; i < num_tex; i++)
|
||||
ss << " gso.tex" << i << " = float3(vso[i].tex" << i << ".xy, float(slice));\n";
|
||||
for (u32 i = 0; i < num_colors; i++)
|
||||
ss << " gso.color" << i << " = vso[i].color" << i << ";\n";
|
||||
ss << " gso.slice = slice;\n";
|
||||
ss << " output.Append(gso);\n";
|
||||
ss << " }\n";
|
||||
ss << " output.RestartStrip();\n";
|
||||
ss << " }\n";
|
||||
ss << "}\n";
|
||||
ss << " gso.slice = slice;\n"
|
||||
" output.Append(gso);\n"
|
||||
" }\n"
|
||||
" output.RestartStrip();\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
}
|
||||
else if (GetAPIType() == APIType::OpenGL || GetAPIType() == APIType::Vulkan)
|
||||
{
|
||||
ss << "layout(triangles) in;\n";
|
||||
ss << "layout(triangle_strip, max_vertices = 6) out;\n";
|
||||
ss << "layout(triangles) in;\n"
|
||||
"layout(triangle_strip, max_vertices = 6) out;\n";
|
||||
if (num_tex > 0 || num_colors > 0)
|
||||
{
|
||||
ss << "VARYING_LOCATION(0) in VertexData {\n";
|
||||
@ -277,6 +292,7 @@ std::string GeneratePassthroughGeometryShader(u32 num_tex, u32 num_colors)
|
||||
for (u32 i = 0; i < num_colors; i++)
|
||||
ss << " float4 v_col" << i << ";\n";
|
||||
ss << "} v_in[];\n";
|
||||
|
||||
ss << "VARYING_LOCATION(0) out VertexData {\n";
|
||||
for (u32 i = 0; i < num_tex; i++)
|
||||
ss << " float3 v_tex" << i << ";\n";
|
||||
@ -284,12 +300,12 @@ std::string GeneratePassthroughGeometryShader(u32 num_tex, u32 num_colors)
|
||||
ss << " float4 v_col" << i << ";\n";
|
||||
ss << "} v_out;\n";
|
||||
}
|
||||
ss << "\n";
|
||||
ss << "void main()\n";
|
||||
ss << "{\n";
|
||||
ss << " for (int j = 0; j < 2; j++)\n";
|
||||
ss << " {\n";
|
||||
ss << " gl_Layer = j;\n";
|
||||
ss << "\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" for (int j = 0; j < 2; j++)\n"
|
||||
" {\n"
|
||||
" gl_Layer = j;\n";
|
||||
|
||||
// We have to explicitly unroll this loop otherwise the GL compiler gets cranky.
|
||||
for (u32 v = 0; v < 3; v++)
|
||||
@ -302,9 +318,9 @@ std::string GeneratePassthroughGeometryShader(u32 num_tex, u32 num_colors)
|
||||
ss << " v_out.v_col" << i << " = v_in[" << v << "].v_col" << i << ";\n";
|
||||
ss << " EmitVertex();\n\n";
|
||||
}
|
||||
ss << " EndPrimitive();\n";
|
||||
ss << " }\n";
|
||||
ss << "}\n";
|
||||
ss << " EndPrimitive();\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
@ -312,20 +328,20 @@ std::string GeneratePassthroughGeometryShader(u32 num_tex, u32 num_colors)
|
||||
|
||||
std::string GenerateTextureCopyVertexShader()
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
EmitUniformBufferDeclaration(ss);
|
||||
ss << "{";
|
||||
ss << " float2 src_offset;\n";
|
||||
ss << " float2 src_size;\n";
|
||||
ss << "};\n\n";
|
||||
ss << "{"
|
||||
" float2 src_offset;\n"
|
||||
" float2 src_size;\n"
|
||||
"};\n\n";
|
||||
|
||||
EmitVertexMainDeclaration(ss, 0, 0, false, 1, 0,
|
||||
GetAPIType() == APIType::D3D ? "in uint id : SV_VertexID, " :
|
||||
"#define id gl_VertexID");
|
||||
ss << "{\n";
|
||||
ss << " v_tex0 = float3(float((id << 1) & 2), float(id & 2), 0.0f);\n";
|
||||
ss << " opos = float4(v_tex0.xy * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);\n";
|
||||
ss << " v_tex0 = float3(src_offset + (src_size * v_tex0.xy), 0.0f);\n";
|
||||
ss << "{\n"
|
||||
" v_tex0 = float3(float((id << 1) & 2), float(id & 2), 0.0f);\n"
|
||||
" opos = float4(v_tex0.xy * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);\n"
|
||||
" v_tex0 = float3(src_offset + (src_size * v_tex0.xy), 0.0f);\n";
|
||||
|
||||
// NDC space is flipped in Vulkan. We also flip in GL so that (0,0) is in the lower-left.
|
||||
if (GetAPIType() == APIType::Vulkan || GetAPIType() == APIType::OpenGL)
|
||||
@ -338,35 +354,35 @@ std::string GenerateTextureCopyVertexShader()
|
||||
|
||||
std::string GenerateTextureCopyPixelShader()
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
EmitSamplerDeclarations(ss, 0, 1, false);
|
||||
EmitPixelMainDeclaration(ss, 1, 0);
|
||||
ss << "{\n";
|
||||
ss << " ocol0 = ";
|
||||
ss << "{\n"
|
||||
" ocol0 = ";
|
||||
EmitSampleTexture(ss, 0, "v_tex0");
|
||||
ss << ";\n";
|
||||
ss << "}\n";
|
||||
ss << ";\n"
|
||||
"}\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string GenerateColorPixelShader()
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
EmitPixelMainDeclaration(ss, 0, 1);
|
||||
ss << "{\n";
|
||||
ss << " ocol0 = v_col0;\n";
|
||||
ss << "}\n";
|
||||
ss << "{\n"
|
||||
" ocol0 = v_col0;\n"
|
||||
"}\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string GenerateResolveDepthPixelShader(u32 samples)
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
EmitSamplerDeclarations(ss, 0, 1, true);
|
||||
EmitPixelMainDeclaration(ss, 1, 0, "float",
|
||||
GetAPIType() == APIType::D3D ? "in float4 ipos : SV_Position, " : "");
|
||||
ss << "{\n";
|
||||
ss << " int layer = int(v_tex0.z);\n";
|
||||
ss << "{\n"
|
||||
" int layer = int(v_tex0.z);\n";
|
||||
if (GetAPIType() == APIType::D3D)
|
||||
ss << " int3 coords = int3(int2(ipos.xy), layer);\n";
|
||||
else
|
||||
@ -389,20 +405,20 @@ std::string GenerateResolveDepthPixelShader(u32 samples)
|
||||
|
||||
std::string GenerateClearVertexShader()
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
EmitUniformBufferDeclaration(ss);
|
||||
ss << "{\n";
|
||||
ss << " float4 clear_color;\n";
|
||||
ss << " float clear_depth;\n";
|
||||
ss << "};\n";
|
||||
ss << "{\n"
|
||||
" float4 clear_color;\n"
|
||||
" float clear_depth;\n"
|
||||
"};\n";
|
||||
|
||||
EmitVertexMainDeclaration(ss, 0, 0, false, 0, 1,
|
||||
GetAPIType() == APIType::D3D ? "in uint id : SV_VertexID, " :
|
||||
"#define id gl_VertexID\n");
|
||||
ss << "{\n";
|
||||
ss << " float2 coord = float2(float((id << 1) & 2), float(id & 2));\n";
|
||||
ss << " opos = float4(coord * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), clear_depth, 1.0f);\n";
|
||||
ss << " v_col0 = clear_color;\n";
|
||||
ss << "{\n"
|
||||
" float2 coord = float2(float((id << 1) & 2), float(id & 2));\n"
|
||||
" opos = float4(coord * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), clear_depth, 1.0f);\n"
|
||||
" v_col0 = clear_color;\n";
|
||||
|
||||
// NDC space is flipped in Vulkan
|
||||
if (GetAPIType() == APIType::Vulkan)
|
||||
@ -415,11 +431,11 @@ std::string GenerateClearVertexShader()
|
||||
|
||||
std::string GenerateEFBPokeVertexShader()
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
EmitVertexMainDeclaration(ss, 0, 1, true, 0, 1);
|
||||
ss << "{\n";
|
||||
ss << " v_col0 = rawcolor0;\n";
|
||||
ss << " opos = float4(rawpos.xyz, 1.0f);\n";
|
||||
ss << "{\n"
|
||||
" v_col0 = rawcolor0;\n"
|
||||
" opos = float4(rawpos.xyz, 1.0f);\n";
|
||||
if (g_ActiveConfig.backend_info.bSupportsLargePoints)
|
||||
ss << " gl_PointSize = rawpos.w;\n";
|
||||
|
||||
@ -433,7 +449,7 @@ std::string GenerateEFBPokeVertexShader()
|
||||
|
||||
std::string GenerateFormatConversionShader(EFBReinterpretType convtype, u32 samples)
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
EmitSamplerDeclarations(ss, 0, 1, samples > 1);
|
||||
EmitPixelMainDeclaration(
|
||||
ss, 1, 0, "float4",
|
||||
@ -442,8 +458,8 @@ std::string GenerateFormatConversionShader(EFBReinterpretType convtype, u32 samp
|
||||
"in float4 ipos : SV_Position, in uint isample : SV_SampleIndex, " :
|
||||
"in float4 ipos : SV_Position, ") :
|
||||
"");
|
||||
ss << "{\n";
|
||||
ss << " int layer = int(v_tex0.z);\n";
|
||||
ss << "{\n"
|
||||
" int layer = int(v_tex0.z);\n";
|
||||
if (GetAPIType() == APIType::D3D)
|
||||
ss << " int3 coords = int3(int2(ipos.xy), layer);\n";
|
||||
else
|
||||
@ -480,13 +496,13 @@ std::string GenerateFormatConversionShader(EFBReinterpretType convtype, u32 samp
|
||||
switch (convtype)
|
||||
{
|
||||
case EFBReinterpretType::RGB8ToRGBA6:
|
||||
ss << " int4 src8 = int4(round(val * 255.f));\n";
|
||||
ss << " int4 dst6;\n";
|
||||
ss << " dst6.r = src8.r >> 2;\n";
|
||||
ss << " dst6.g = ((src8.r & 0x3) << 4) | (src8.g >> 4);\n";
|
||||
ss << " dst6.b = ((src8.g & 0xF) << 2) | (src8.b >> 6);\n";
|
||||
ss << " dst6.a = src8.b & 0x3F;\n";
|
||||
ss << " ocol0 = float4(dst6) / 63.f;\n";
|
||||
ss << " int4 src8 = int4(round(val * 255.f));\n"
|
||||
" int4 dst6;\n"
|
||||
" dst6.r = src8.r >> 2;\n"
|
||||
" dst6.g = ((src8.r & 0x3) << 4) | (src8.g >> 4);\n"
|
||||
" dst6.b = ((src8.g & 0xF) << 2) | (src8.b >> 6);\n"
|
||||
" dst6.a = src8.b & 0x3F;\n"
|
||||
" ocol0 = float4(dst6) / 63.f;\n";
|
||||
break;
|
||||
|
||||
case EFBReinterpretType::RGB8ToRGB565:
|
||||
@ -494,13 +510,13 @@ std::string GenerateFormatConversionShader(EFBReinterpretType convtype, u32 samp
|
||||
break;
|
||||
|
||||
case EFBReinterpretType::RGBA6ToRGB8:
|
||||
ss << " int4 src6 = int4(round(val * 63.f));\n";
|
||||
ss << " int4 dst8;\n";
|
||||
ss << " dst8.r = (src6.r << 2) | (src6.g >> 4);\n";
|
||||
ss << " dst8.g = ((src6.g & 0xF) << 4) | (src6.b >> 2);\n";
|
||||
ss << " dst8.b = ((src6.b & 0x3) << 6) | src6.a;\n";
|
||||
ss << " dst8.a = 255;\n";
|
||||
ss << " ocol0 = float4(dst8) / 255.f;\n";
|
||||
ss << " int4 src6 = int4(round(val * 63.f));\n"
|
||||
" int4 dst8;\n"
|
||||
" dst8.r = (src6.r << 2) | (src6.g >> 4);\n"
|
||||
" dst8.g = ((src6.g & 0xF) << 4) | (src6.b >> 2);\n"
|
||||
" dst8.b = ((src6.b & 0x3) << 6) | src6.a;\n"
|
||||
" dst8.a = 255;\n"
|
||||
" ocol0 = float4(dst8) / 255.f;\n";
|
||||
break;
|
||||
|
||||
case EFBReinterpretType::RGBA6ToRGB565:
|
||||
@ -523,12 +539,12 @@ std::string GenerateFormatConversionShader(EFBReinterpretType convtype, u32 samp
|
||||
|
||||
std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureFormat to_format)
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
EmitSamplerDeclarations(ss, 0, 1, false);
|
||||
EmitPixelMainDeclaration(ss, 1, 0, "float4", "", true);
|
||||
ss << "{\n";
|
||||
ss << " int layer = int(v_tex0.z);\n";
|
||||
ss << " int4 coords = int4(int2(frag_coord.xy), layer, 0);\n";
|
||||
ss << "{\n"
|
||||
" int layer = int(v_tex0.z);\n"
|
||||
" int4 coords = int4(int2(frag_coord.xy), layer, 0);\n";
|
||||
|
||||
// Convert to a 32-bit value encompassing all channels, filling the most significant bits with
|
||||
// zeroes.
|
||||
@ -540,8 +556,8 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF
|
||||
{
|
||||
ss << " float4 temp_value = ";
|
||||
EmitTextureLoad(ss, 0, "coords");
|
||||
ss << ";\n";
|
||||
ss << " raw_value = uint(temp_value.r * 255.0);\n";
|
||||
ss << ";\n"
|
||||
" raw_value = uint(temp_value.r * 255.0);\n";
|
||||
}
|
||||
break;
|
||||
|
||||
@ -549,8 +565,8 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF
|
||||
{
|
||||
ss << " float4 temp_value = ";
|
||||
EmitTextureLoad(ss, 0, "coords");
|
||||
ss << ";\n";
|
||||
ss << " raw_value = uint(temp_value.r * 255.0) | (uint(temp_value.a * 255.0) << 8);\n";
|
||||
ss << ";\n"
|
||||
" raw_value = uint(temp_value.r * 255.0) | (uint(temp_value.a * 255.0) << 8);\n";
|
||||
}
|
||||
break;
|
||||
|
||||
@ -558,8 +574,8 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF
|
||||
{
|
||||
ss << " float4 temp_value = ";
|
||||
EmitTextureLoad(ss, 0, "coords");
|
||||
ss << ";\n";
|
||||
ss << " raw_value = uint(temp_value.r * 15.0) | (uint(temp_value.a * 15.0) << 4);\n";
|
||||
ss << ";\n"
|
||||
" raw_value = uint(temp_value.r * 15.0) | (uint(temp_value.a * 15.0) << 4);\n";
|
||||
}
|
||||
break;
|
||||
|
||||
@ -567,9 +583,9 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF
|
||||
{
|
||||
ss << " float4 temp_value = ";
|
||||
EmitTextureLoad(ss, 0, "coords");
|
||||
ss << ";\n";
|
||||
ss << " raw_value = uint(temp_value.b * 31.0) | (uint(temp_value.g * 63.0) << 5) |\n";
|
||||
ss << " (uint(temp_value.r * 31.0) << 11);\n";
|
||||
ss << ";\n"
|
||||
" raw_value = uint(temp_value.b * 31.0) | (uint(temp_value.g * 63.0) << 5) |\n"
|
||||
" (uint(temp_value.r * 31.0) << 11);\n";
|
||||
}
|
||||
break;
|
||||
|
||||
@ -580,13 +596,13 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF
|
||||
ss << ";\n";
|
||||
|
||||
// 0.8784 = 224 / 255 which is the maximum alpha value that can be represented in 3 bits
|
||||
ss << " if (temp_value.a > 0.878f) {\n";
|
||||
ss << " raw_value = (uint(temp_value.b * 31.0)) | (uint(temp_value.g * 31.0) << 5) |\n";
|
||||
ss << " (uint(temp_value.r * 31.0) << 10) | 0x8000u;\n";
|
||||
ss << " } else {\n";
|
||||
ss << " raw_value = (uint(temp_value.b * 15.0)) | (uint(temp_value.g * 15.0) << 4) |\n";
|
||||
ss << " (uint(temp_value.r * 15.0) << 8) | (uint(temp_value.a * 7.0) << 12);\n";
|
||||
ss << " }\n";
|
||||
ss << " if (temp_value.a > 0.878f) {\n"
|
||||
" raw_value = (uint(temp_value.b * 31.0)) | (uint(temp_value.g * 31.0) << 5) |\n"
|
||||
" (uint(temp_value.r * 31.0) << 10) | 0x8000u;\n"
|
||||
" } else {\n"
|
||||
" raw_value = (uint(temp_value.b * 15.0)) | (uint(temp_value.g * 15.0) << 4) |\n"
|
||||
" (uint(temp_value.r * 15.0) << 8) | (uint(temp_value.a * 7.0) << 12);\n"
|
||||
" }\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -597,45 +613,45 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF
|
||||
case TextureFormat::I8:
|
||||
case TextureFormat::C8:
|
||||
{
|
||||
ss << " float orgba = float(raw_value & 0xFFu) / 255.0;\n";
|
||||
ss << " ocol0 = float4(orgba, orgba, orgba, orgba);\n";
|
||||
ss << " float orgba = float(raw_value & 0xFFu) / 255.0;\n"
|
||||
" ocol0 = float4(orgba, orgba, orgba, orgba);\n";
|
||||
}
|
||||
break;
|
||||
|
||||
case TextureFormat::IA8:
|
||||
{
|
||||
ss << " float orgb = float(raw_value & 0xFFu) / 255.0;\n";
|
||||
ss << " ocol0 = float4(orgb, orgb, orgb, float((raw_value >> 8) & 0xFFu) / 255.0);\n";
|
||||
ss << " float orgb = float(raw_value & 0xFFu) / 255.0;\n"
|
||||
" ocol0 = float4(orgb, orgb, orgb, float((raw_value >> 8) & 0xFFu) / 255.0);\n";
|
||||
}
|
||||
break;
|
||||
|
||||
case TextureFormat::IA4:
|
||||
{
|
||||
ss << " float orgb = float(raw_value & 0xFu) / 15.0;\n";
|
||||
ss << " ocol0 = float4(orgb, orgb, orgb, float((raw_value >> 4) & 0xFu) / 15.0);\n";
|
||||
ss << " float orgb = float(raw_value & 0xFu) / 15.0;\n"
|
||||
" ocol0 = float4(orgb, orgb, orgb, float((raw_value >> 4) & 0xFu) / 15.0);\n";
|
||||
}
|
||||
break;
|
||||
|
||||
case TextureFormat::RGB565:
|
||||
{
|
||||
ss << " ocol0 = float4(float((raw_value >> 10) & 0x1Fu) / 31.0,\n";
|
||||
ss << " float((raw_value >> 5) & 0x1Fu) / 31.0,\n";
|
||||
ss << " float(raw_value & 0x1Fu) / 31.0, 1.0);\n";
|
||||
ss << " ocol0 = float4(float((raw_value >> 10) & 0x1Fu) / 31.0,\n"
|
||||
" float((raw_value >> 5) & 0x1Fu) / 31.0,\n"
|
||||
" float(raw_value & 0x1Fu) / 31.0, 1.0);\n";
|
||||
}
|
||||
break;
|
||||
|
||||
case TextureFormat::RGB5A3:
|
||||
{
|
||||
ss << " if ((raw_value & 0x8000u) != 0u) {\n";
|
||||
ss << " ocol0 = float4(float((raw_value >> 10) & 0x1Fu) / 31.0,\n";
|
||||
ss << " float((raw_value >> 5) & 0x1Fu) / 31.0,\n";
|
||||
ss << " float(raw_value & 0x1Fu) / 31.0, 1.0);\n";
|
||||
ss << " } else {\n";
|
||||
ss << " ocol0 = float4(float((raw_value >> 8) & 0x0Fu) / 15.0,\n";
|
||||
ss << " float((raw_value >> 4) & 0x0Fu) / 15.0,\n";
|
||||
ss << " float(raw_value & 0x0Fu) / 15.0,\n";
|
||||
ss << " float((raw_value >> 12) & 0x07u) / 7.0);\n";
|
||||
ss << " }\n";
|
||||
ss << " if ((raw_value & 0x8000u) != 0u) {\n"
|
||||
" ocol0 = float4(float((raw_value >> 10) & 0x1Fu) / 31.0,\n"
|
||||
" float((raw_value >> 5) & 0x1Fu) / 31.0,\n"
|
||||
" float(raw_value & 0x1Fu) / 31.0, 1.0);\n"
|
||||
" } else {\n"
|
||||
" ocol0 = float4(float((raw_value >> 8) & 0x0Fu) / 15.0,\n"
|
||||
" float((raw_value >> 4) & 0x0Fu) / 15.0,\n"
|
||||
" float(raw_value & 0x0Fu) / 15.0,\n"
|
||||
" float((raw_value >> 12) & 0x07u) / 7.0);\n"
|
||||
" }\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -646,37 +662,37 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF
|
||||
|
||||
std::string GenerateEFBRestorePixelShader()
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
EmitSamplerDeclarations(ss, 0, 2, false);
|
||||
EmitPixelMainDeclaration(ss, 1, 0, "float4",
|
||||
GetAPIType() == APIType::D3D ? "out float depth : SV_Depth, " : "");
|
||||
ss << "{\n";
|
||||
ss << " ocol0 = ";
|
||||
ss << "{\n"
|
||||
" ocol0 = ";
|
||||
EmitSampleTexture(ss, 0, "v_tex0");
|
||||
ss << ";\n";
|
||||
ss << " " << (GetAPIType() == APIType::D3D ? "depth" : "gl_FragDepth") << " = ";
|
||||
EmitSampleTexture(ss, 1, "v_tex0");
|
||||
ss << ".r;\n";
|
||||
ss << "}\n";
|
||||
ss << ".r;\n"
|
||||
"}\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string GenerateImGuiVertexShader()
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
|
||||
// Uniform buffer contains the viewport size, and we transform in the vertex shader.
|
||||
EmitUniformBufferDeclaration(ss);
|
||||
ss << "{\n";
|
||||
ss << "float2 u_rcp_viewport_size_mul2;\n";
|
||||
ss << "};\n\n";
|
||||
ss << "{\n"
|
||||
"float2 u_rcp_viewport_size_mul2;\n"
|
||||
"};\n\n";
|
||||
|
||||
EmitVertexMainDeclaration(ss, 1, 1, true, 1, 1);
|
||||
ss << "{\n"
|
||||
<< " v_tex0 = float3(rawtex0.xy, 0.0);\n"
|
||||
<< " v_col0 = rawcolor0;\n"
|
||||
<< " opos = float4(rawpos.x * u_rcp_viewport_size_mul2.x - 1.0,"
|
||||
<< " 1.0 - rawpos.y * u_rcp_viewport_size_mul2.y, 0.0, 1.0);\n";
|
||||
" v_tex0 = float3(rawtex0.xy, 0.0);\n"
|
||||
" v_col0 = rawcolor0;\n"
|
||||
" opos = float4(rawpos.x * u_rcp_viewport_size_mul2.x - 1.0,"
|
||||
" 1.0 - rawpos.y * u_rcp_viewport_size_mul2.y, 0.0, 1.0);\n";
|
||||
|
||||
// NDC space is flipped in Vulkan.
|
||||
if (GetAPIType() == APIType::Vulkan)
|
||||
@ -688,14 +704,14 @@ std::string GenerateImGuiVertexShader()
|
||||
|
||||
std::string GenerateImGuiPixelShader()
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
EmitSamplerDeclarations(ss, 0, 1, false);
|
||||
EmitPixelMainDeclaration(ss, 1, 1);
|
||||
ss << "{\n";
|
||||
ss << " ocol0 = ";
|
||||
ss << "{\n"
|
||||
" ocol0 = ";
|
||||
EmitSampleTexture(ss, 0, "float3(v_tex0.xy, 0.0)");
|
||||
ss << " * v_col0;\n";
|
||||
ss << "}\n";
|
||||
ss << " * v_col0;\n"
|
||||
"}\n";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
@ -1,25 +1,17 @@
|
||||
// Copyright 2019 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
enum class EFBReinterpretType;
|
||||
enum class TextureFormat;
|
||||
|
||||
namespace FramebufferShaderGen
|
||||
{
|
||||
struct Config
|
||||
{
|
||||
Config(APIType api_type_, u32 efb_samples_, u32 efb_layers_, bool ssaa_)
|
||||
: api_type(api_type_), efb_samples(efb_samples_), efb_layers(efb_layers_), ssaa(ssaa_)
|
||||
{
|
||||
}
|
||||
|
||||
APIType api_type;
|
||||
u32 efb_samples;
|
||||
u32 efb_layers;
|
||||
bool ssaa;
|
||||
};
|
||||
|
||||
std::string GenerateScreenQuadVertexShader();
|
||||
std::string GeneratePassthroughGeometryShader(u32 num_tex, u32 num_colors);
|
||||
std::string GenerateTextureCopyVertexShader();
|
||||
|
Loading…
Reference in New Issue
Block a user