Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ShaderGen: Output uint when logic op is enabled for D3D ubershaders #6026

Merged
merged 2 commits into from Sep 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions Source/Core/VideoBackends/D3D/PixelShaderCache.cpp
Expand Up @@ -593,6 +593,7 @@ bool PixelShaderCache::SetShader()
return SetUberShader();

PixelShaderUid uid = GetPixelShaderUid();
ClearUnusedPixelShaderUidBits(APIType::D3D, &uid);
if (last_entry && uid == last_uid)
{
if (last_entry->pending)
Expand Down Expand Up @@ -656,6 +657,7 @@ bool PixelShaderCache::SetShader()
bool PixelShaderCache::SetUberShader()
{
UberShader::PixelShaderUid uid = UberShader::GetPixelShaderUid();
UberShader::ClearUnusedPixelShaderUidBits(APIType::D3D, &uid);

if (last_uber_entry && last_uber_uid == uid)
{
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp
Expand Up @@ -231,6 +231,7 @@ SHADER* ProgramShaderCache::SetShader(u32 primitive_type, const GLVertexFormat*
uid.puid = GetPixelShaderUid();
uid.vuid = GetVertexShaderUid();
uid.guid = GetGeometryShaderUid(primitive_type);
ClearUnusedPixelShaderUidBits(APIType::OpenGL, &uid.puid);

// Check if the shader is already set
if (last_entry && uid == last_uid)
Expand Down Expand Up @@ -298,6 +299,7 @@ SHADER* ProgramShaderCache::SetUberShader(u32 primitive_type, const GLVertexForm
uid.puid = UberShader::GetPixelShaderUid();
uid.vuid = UberShader::GetVertexShaderUid();
uid.guid = GetGeometryShaderUid(primitive_type);
UberShader::ClearUnusedPixelShaderUidBits(APIType::OpenGL, &uid.puid);

// We need to use the ubershader vertex format with all attributes enabled.
// Otherwise, the NV driver can generate variants for the vertex shaders.
Expand Down
5 changes: 4 additions & 1 deletion Source/Core/VideoBackends/Vulkan/StateTracker.cpp
Expand Up @@ -338,8 +338,9 @@ bool StateTracker::CheckForShaderChanges(u32 gx_primitive_type)
{
VertexShaderUid vs_uid = GetVertexShaderUid();
PixelShaderUid ps_uid = GetPixelShaderUid();
bool changed = false;
ClearUnusedPixelShaderUidBits(APIType::Vulkan, &ps_uid);

bool changed = false;
bool use_ubershaders = g_ActiveConfig.bDisableSpecializedShaders;
if (g_ActiveConfig.CanBackgroundCompileShaders() && !g_ActiveConfig.bDisableSpecializedShaders)
{
Expand Down Expand Up @@ -405,6 +406,7 @@ bool StateTracker::CheckForShaderChanges(u32 gx_primitive_type)
}

UberShader::PixelShaderUid uber_ps_uid = UberShader::GetPixelShaderUid();
UberShader::ClearUnusedPixelShaderUidBits(APIType::Vulkan, &uber_ps_uid);
VkShaderModule ps = g_shader_cache->GetPixelUberShaderForUid(uber_ps_uid);
if (ps != m_pipeline_state.ps)
{
Expand Down Expand Up @@ -983,6 +985,7 @@ VkPipeline StateTracker::GetPipelineAndCacheUID()
PipelineInfo uber_info = m_pipeline_state;
UberShader::VertexShaderUid uber_vuid = UberShader::GetVertexShaderUid();
UberShader::PixelShaderUid uber_puid = UberShader::GetPixelShaderUid();
UberShader::ClearUnusedPixelShaderUidBits(APIType::Vulkan, &uber_puid);
uber_info.vs = g_shader_cache->GetVertexUberShaderForUid(uber_vuid);
uber_info.ps = g_shader_cache->GetPixelUberShaderForUid(uber_puid);

Expand Down
10 changes: 10 additions & 0 deletions Source/Core/VideoCommon/PixelShaderGen.cpp
Expand Up @@ -322,6 +322,16 @@ PixelShaderUid GetPixelShaderUid()
return out;
}

void ClearUnusedPixelShaderUidBits(APIType ApiType, PixelShaderUid* uid)
{
pixel_shader_uid_data* uid_data = uid->GetUidData<pixel_shader_uid_data>();

// OpenGL and Vulkan convert implicitly normalized color outputs to their uint representation.
// Therefore, it is not necessary to use a uint output on these backends.
if (ApiType != APIType::D3D)
uid_data->uint_output = 0;
}

void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, u32 num_texgens,
bool per_pixel_lighting, bool bounding_box)
{
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoCommon/PixelShaderGen.h
Expand Up @@ -162,5 +162,5 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host
const pixel_shader_uid_data* uid_data);
void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, u32 num_texgens,
bool per_pixel_lighting, bool bounding_box);
ShaderCode GeneratePixelShaderCode(APIType ApiType, const pixel_shader_uid_data* uid_data);

This comment was marked as off-topic.

void ClearUnusedPixelShaderUidBits(APIType ApiType, PixelShaderUid* uid);
PixelShaderUid GetPixelShaderUid();
42 changes: 29 additions & 13 deletions Source/Core/VideoCommon/UberShaderPixel.cpp
Expand Up @@ -29,6 +29,16 @@ PixelShaderUid GetPixelShaderUid()
return out;
}

void ClearUnusedPixelShaderUidBits(APIType ApiType, PixelShaderUid* uid)
{
pixel_ubershader_uid_data* uid_data = uid->GetUidData<pixel_ubershader_uid_data>();

// OpenGL and Vulkan convert implicitly normalized color outputs to their uint representation.
// Therefore, it is not necessary to use a uint output on these backends.
if (ApiType != APIType::D3D)
uid_data->uint_output = 0;
}

ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
const pixel_ubershader_uid_data* uid_data)
{
Expand Down Expand Up @@ -654,13 +664,19 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
if (early_depth && host_config.backend_early_z)
out.Write("[earlydepthstencil]\n");

out.Write("void main(\n"
" out float4 ocol0 : SV_Target0,\n"
" out float4 ocol1 : SV_Target1,\n"
" %s\n",
per_pixel_depth ? "\n out float depth : SV_Depth," : "");
out.Write("void main(\n");
if (uid_data->uint_output)
{
out.Write(" out uint4 ocol0 : SV_Target,\n");
}
else
{
out.Write(" out float4 ocol0 : SV_Target0,\n"
" out float4 ocol1 : SV_Target1,\n");
}
if (per_pixel_depth)
out.Write(" out float depth : SV_Depth,\n");
out.Write(" in float4 rawpos : SV_Position,\n");

out.Write(" in %s float4 colors_0 : COLOR0,\n", GetInterpolationQualifier(msaa, ssaa));
out.Write(" in %s float4 colors_1 : COLOR1", GetInterpolationQualifier(msaa, ssaa));

Expand Down Expand Up @@ -1186,14 +1202,14 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
out.Write(" else\n"
" ocol0.a = float(TevResult.a >> 2) / 63.0;\n"
" \n");
}

if (use_dual_source)
{
out.Write(" // Dest alpha override (dual source blending)\n"
" // Colors will be blended against the alpha from ocol1 and\n"
" // the alpha from ocol0 will be written to the framebuffer.\n"
" ocol1 = float4(0.0, 0.0, 0.0, float(TevResult.a) / 255.0);\n");
if (use_dual_source)
{
out.Write(" // Dest alpha override (dual source blending)\n"
" // Colors will be blended against the alpha from ocol1 and\n"
" // the alpha from ocol0 will be written to the framebuffer.\n"
" ocol1 = float4(0.0, 0.0, 0.0, float(TevResult.a) / 255.0);\n");
}
}

if (bounding_box)
Expand Down
1 change: 1 addition & 0 deletions Source/Core/VideoCommon/UberShaderPixel.h
Expand Up @@ -29,4 +29,5 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
const pixel_ubershader_uid_data* uid_data);

void EnumeratePixelShaderUids(const std::function<void(const PixelShaderUid&)>& callback);
void ClearUnusedPixelShaderUidBits(APIType ApiType, PixelShaderUid* uid);
}