Merge pull request #4577 from degasus/videocommon

OGL/Vulkan: Drop destination alpha pass.
This commit is contained in:
Markus Wick 2017-01-04 20:05:26 +01:00 committed by GitHub
commit 389f8297c3
33 changed files with 79 additions and 202 deletions

View File

@ -551,9 +551,9 @@ void PixelShaderCache::Shutdown()
g_ps_disk_cache.Close();
}
bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode)
bool PixelShaderCache::SetShader()
{
PixelShaderUid uid = GetPixelShaderUid(dstAlphaMode);
PixelShaderUid uid = GetPixelShaderUid();
// Check if the shader is already set
if (last_entry)

View File

@ -9,8 +9,6 @@
#include "VideoCommon/PixelShaderGen.h"
enum DSTALPHA_MODE;
namespace DX11
{
class PixelShaderCache
@ -19,7 +17,7 @@ public:
static void Init();
static void Clear();
static void Shutdown();
static bool SetShader(DSTALPHA_MODE dstAlphaMode); // TODO: Should be renamed to LoadShader
static bool SetShader(); // TODO: Should be renamed to LoadShader
static bool InsertByteCode(const PixelShaderUid& uid, const void* bytecode,
unsigned int bytecodelen);

View File

@ -940,8 +940,12 @@ void Renderer::RestoreAPIState()
BPFunctions::SetScissor();
}
void Renderer::ApplyState(bool bUseDstAlpha)
void Renderer::ApplyState()
{
// TODO: Refactor this logic here.
bool bUseDstAlpha = bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate &&
bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24;
gx_state.blend.use_dst_alpha = bUseDstAlpha;
D3D::stateman->PushBlendState(gx_state_cache.Get(gx_state.blend));
D3D::stateman->PushDepthState(gx_state_cache.Get(gx_state.zmode));

View File

@ -29,7 +29,7 @@ public:
bool IsFullscreen() const override;
// TODO: Fix confusing names (see ResetAPIState and RestoreAPIState)
void ApplyState(bool bUseDstAlpha) override;
void ApplyState() override;
void RestoreState() override;
void ApplyCullDisable();

View File

@ -147,9 +147,9 @@ void VertexManager::Draw(u32 stride)
static_cast<Renderer*>(g_renderer.get())->RestoreCull();
}
void VertexManager::vFlush(bool useDstAlpha)
void VertexManager::vFlush()
{
if (!PixelShaderCache::SetShader(useDstAlpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE))
if (!PixelShaderCache::SetShader())
{
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR, true, { printf("Fail to set pixel shader\n"); });
return;
@ -179,7 +179,7 @@ void VertexManager::vFlush(bool useDstAlpha)
PrepareDrawBuffers(stride);
VertexLoaderManager::GetCurrentVertexFormat()->SetupVertexPointers();
g_renderer->ApplyState(useDstAlpha);
g_renderer->ApplyState();
Draw(stride);

View File

@ -25,7 +25,7 @@ private:
void PrepareDrawBuffers(u32 stride);
void Draw(u32 stride);
// temp
void vFlush(bool useDstAlpha) override;
void vFlush() override;
u32 m_vertexDrawOffset;
u32 m_indexDrawOffset;

View File

@ -920,8 +920,12 @@ void Renderer::RestoreAPIState()
static bool s_previous_use_dst_alpha = false;
static D3DVertexFormat* s_previous_vertex_format = nullptr;
void Renderer::ApplyState(bool use_dst_alpha)
void Renderer::ApplyState()
{
// TODO: Refactor this logic here.
bool use_dst_alpha = bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate &&
bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24;
if (use_dst_alpha != s_previous_use_dst_alpha)
{
s_previous_use_dst_alpha = use_dst_alpha;

View File

@ -27,7 +27,7 @@ public:
void SetViewport() override;
// TODO: Fix confusing names (see ResetAPIState and RestoreAPIState)
void ApplyState(bool use_dst_alpha) override;
void ApplyState() override;
void RestoreState() override;
void ApplyCullDisable();

View File

@ -132,12 +132,12 @@ void ShaderCache::Shutdown()
s_vs_disk_cache.Close();
}
void ShaderCache::LoadAndSetActiveShaders(DSTALPHA_MODE ps_dst_alpha_mode, u32 gs_primitive_type)
void ShaderCache::LoadAndSetActiveShaders(u32 gs_primitive_type)
{
SetCurrentPrimitiveTopology(gs_primitive_type);
GeometryShaderUid gs_uid = GetGeometryShaderUid(gs_primitive_type);
PixelShaderUid ps_uid = GetPixelShaderUid(ps_dst_alpha_mode);
PixelShaderUid ps_uid = GetPixelShaderUid();
VertexShaderUid vs_uid = GetVertexShaderUid();
bool gs_changed = gs_uid != s_last_geometry_shader_uid;
@ -156,7 +156,7 @@ void ShaderCache::LoadAndSetActiveShaders(DSTALPHA_MODE ps_dst_alpha_mode, u32 g
if (ps_changed)
{
HandlePSUIDChange(ps_uid, ps_dst_alpha_mode);
HandlePSUIDChange(ps_uid);
}
if (vs_changed)
@ -219,7 +219,7 @@ void ShaderCache::HandleGSUIDChange(GeometryShaderUid gs_uid, u32 gs_primitive_t
}
}
void ShaderCache::HandlePSUIDChange(PixelShaderUid ps_uid, DSTALPHA_MODE ps_dst_alpha_mode)
void ShaderCache::HandlePSUIDChange(PixelShaderUid ps_uid)
{
s_last_pixel_shader_uid = ps_uid;

View File

@ -19,7 +19,7 @@ public:
static void Clear();
static void Shutdown();
static void LoadAndSetActiveShaders(DSTALPHA_MODE ps_dst_alpha_mode, u32 gs_primitive_type);
static void LoadAndSetActiveShaders(u32 gs_primitive_type);
template <class UidType, class ShaderCacheType>
static D3D12_SHADER_BYTECODE InsertByteCode(const UidType& uid, ShaderCacheType* shader_cache,
@ -43,7 +43,7 @@ private:
static void SetCurrentPrimitiveTopology(u32 gs_primitive_type);
static void HandleGSUIDChange(GeometryShaderUid gs_uid, u32 gs_primitive_type);
static void HandlePSUIDChange(PixelShaderUid ps_uid, DSTALPHA_MODE ps_dst_alpha_mode);
static void HandlePSUIDChange(PixelShaderUid ps_uid);
static void HandleVSUIDChange(VertexShaderUid vs_uid);
};
}

View File

@ -135,10 +135,9 @@ void VertexManager::Draw(u32 stride)
INCSTAT(stats.thisFrame.numDrawCalls);
}
void VertexManager::vFlush(bool use_dst_alpha)
void VertexManager::vFlush()
{
ShaderCache::LoadAndSetActiveShaders(use_dst_alpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE,
m_current_primitive_type);
ShaderCache::LoadAndSetActiveShaders(m_current_primitive_type);
if (g_ActiveConfig.backend_info.bSupportsBBox && BoundingBox::active)
BBox::Invalidate();
@ -147,7 +146,7 @@ void VertexManager::vFlush(bool use_dst_alpha)
PrepareDrawBuffers(stride);
g_renderer->ApplyState(use_dst_alpha);
g_renderer->ApplyState();
Draw(stride);

View File

@ -29,7 +29,7 @@ protected:
private:
void PrepareDrawBuffers(u32 stride);
void Draw(u32 stride);
void vFlush(bool use_dst_alpha) override;
void vFlush() override;
u32 m_vertex_draw_offset;
u32 m_index_draw_offset;

View File

@ -33,9 +33,9 @@ void ShaderCache<Uid>::Clear()
}
template <typename Uid>
bool ShaderCache<Uid>::SetShader(DSTALPHA_MODE dst_alpha_mode, u32 primitive_type)
bool ShaderCache<Uid>::SetShader(u32 primitive_type)
{
Uid uid = GetUid(dst_alpha_mode, primitive_type, APIType::OpenGL);
Uid uid = GetUid(primitive_type, APIType::OpenGL);
// Check if the shader is already set
if (m_last_entry)

View File

@ -22,10 +22,10 @@ public:
virtual ~ShaderCache();
void Clear();
bool SetShader(DSTALPHA_MODE dst_alpha_mode, u32 primitive_type);
bool SetShader(u32 primitive_type);
protected:
virtual Uid GetUid(DSTALPHA_MODE dst_alpha_mode, u32 primitive_type, APIType api_type) = 0;
virtual Uid GetUid(u32 primitive_type, APIType api_type) = 0;
virtual ShaderCode GenerateCode(APIType api_type, Uid uid) = 0;
private:
@ -40,8 +40,7 @@ public:
static std::unique_ptr<VertexShaderCache> s_instance;
protected:
VertexShaderUid GetUid(DSTALPHA_MODE dst_alpha_mode, u32 primitive_type,
APIType api_type) override
VertexShaderUid GetUid(u32 primitive_type, APIType api_type) override
{
return GetVertexShaderUid();
}
@ -57,8 +56,7 @@ public:
static std::unique_ptr<GeometryShaderCache> s_instance;
protected:
GeometryShaderUid GetUid(DSTALPHA_MODE dst_alpha_mode, u32 primitive_type,
APIType api_type) override
GeometryShaderUid GetUid(u32 primitive_type, APIType api_type) override
{
return GetGeometryShaderUid(primitive_type);
}
@ -74,9 +72,9 @@ public:
static std::unique_ptr<PixelShaderCache> s_instance;
protected:
PixelShaderUid GetUid(DSTALPHA_MODE dst_alpha_mode, u32 primitive_type, APIType api_type) override
PixelShaderUid GetUid(u32 primitive_type, APIType api_type) override
{
return GetPixelShaderUid(dst_alpha_mode);
return GetPixelShaderUid();
}
ShaderCode GenerateCode(APIType api_type, PixelShaderUid uid) override
{

View File

@ -40,14 +40,11 @@ void VertexManager::ResetBuffer(u32 stride)
IndexGenerator::Start(&m_local_i_buffer[0]);
}
void VertexManager::vFlush(bool use_dst_alpha)
void VertexManager::vFlush()
{
VertexShaderCache::s_instance->SetShader(
use_dst_alpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE, m_current_primitive_type);
GeometryShaderCache::s_instance->SetShader(
use_dst_alpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE, m_current_primitive_type);
PixelShaderCache::s_instance->SetShader(
use_dst_alpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE, m_current_primitive_type);
VertexShaderCache::s_instance->SetShader(m_current_primitive_type);
GeometryShaderCache::s_instance->SetShader(m_current_primitive_type);
PixelShaderCache::s_instance->SetShader(m_current_primitive_type);
}
} // namespace

View File

@ -21,7 +21,7 @@ protected:
void ResetBuffer(u32 stride) override;
private:
void vFlush(bool use_dst_alpha) override;
void vFlush() override;
std::vector<u8> m_local_v_buffer;
std::vector<u16> m_local_i_buffer;
};

View File

@ -174,10 +174,10 @@ void ProgramShaderCache::UploadConstants()
}
}
SHADER* ProgramShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 primitive_type)
SHADER* ProgramShaderCache::SetShader(u32 primitive_type)
{
SHADERUID uid;
GetShaderId(&uid, dstAlphaMode, primitive_type);
GetShaderId(&uid, primitive_type);
// Check if the shader is already set
if (last_entry)
@ -388,9 +388,9 @@ GLuint ProgramShaderCache::CompileSingleShader(GLuint type, const std::string& c
return result;
}
void ProgramShaderCache::GetShaderId(SHADERUID* uid, DSTALPHA_MODE dstAlphaMode, u32 primitive_type)
void ProgramShaderCache::GetShaderId(SHADERUID* uid, u32 primitive_type)
{
uid->puid = GetPixelShaderUid(dstAlphaMode);
uid->puid = GetPixelShaderUid();
uid->vuid = GetVertexShaderUid();
uid->guid = GetGeometryShaderUid(primitive_type);
}

View File

@ -62,8 +62,8 @@ public:
};
static PCacheEntry GetShaderProgram();
static SHADER* SetShader(DSTALPHA_MODE dstAlphaMode, u32 primitive_type);
static void GetShaderId(SHADERUID* uid, DSTALPHA_MODE dstAlphaMode, u32 primitive_type);
static SHADER* SetShader(u32 primitive_type);
static void GetShaderId(SHADERUID* uid, u32 primitive_type);
static bool CompileShader(SHADER& shader, const std::string& vcode, const std::string& pcode,
const std::string& gcode = "");

View File

@ -136,7 +136,7 @@ void VertexManager::Draw(u32 stride)
static_cast<Renderer*>(g_renderer.get())->SetGenerationMode();
}
void VertexManager::vFlush(bool useDstAlpha)
void VertexManager::vFlush()
{
GLVertexFormat* nativeVertexFmt = (GLVertexFormat*)VertexLoaderManager::GetCurrentVertexFormat();
u32 stride = nativeVertexFmt->GetVertexStride();
@ -149,19 +149,7 @@ void VertexManager::vFlush(bool useDstAlpha)
PrepareDrawBuffers(stride);
// Makes sure we can actually do Dual source blending
bool dualSourcePossible = g_ActiveConfig.backend_info.bSupportsDualSourceBlend;
// If host supports GL_ARB_blend_func_extended, we can do dst alpha in
// the same pass as regular rendering.
if (useDstAlpha && dualSourcePossible)
{
ProgramShaderCache::SetShader(DSTALPHA_DUAL_SOURCE_BLEND, m_current_primitive_type);
}
else
{
ProgramShaderCache::SetShader(DSTALPHA_NONE, m_current_primitive_type);
}
ProgramShaderCache::SetShader(m_current_primitive_type);
// upload global constants
ProgramShaderCache::UploadConstants();
@ -171,38 +159,6 @@ void VertexManager::vFlush(bool useDstAlpha)
Draw(stride);
// If the GPU does not support dual-source blending, we can approximate the effect by drawing
// the object a second time, with the write mask set to alpha only using a shader that outputs
// the destination/constant alpha value (which would normally be SRC_COLOR.a).
//
// This is also used when logic ops and destination alpha is enabled, since we can't enable
// blending and logic ops concurrently.
bool logic_op_enabled = (bpmem.blendmode.logicopenable && !bpmem.blendmode.blendenable &&
GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL);
if (useDstAlpha && (!dualSourcePossible || logic_op_enabled))
{
ProgramShaderCache::SetShader(DSTALPHA_ALPHA_PASS, m_current_primitive_type);
// only update alpha
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
glDisable(GL_BLEND);
if (logic_op_enabled)
glDisable(GL_COLOR_LOGIC_OP);
Draw(stride);
// restore color mask
g_renderer->SetColorMask();
if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract)
glEnable(GL_BLEND);
if (logic_op_enabled)
glEnable(GL_COLOR_LOGIC_OP);
}
#if defined(_DEBUG) || defined(DEBUGFAST)
if (g_ActiveConfig.iLog & CONF_SAVESHADERS)
{

View File

@ -41,7 +41,7 @@ protected:
private:
void Draw(u32 stride);
void vFlush(bool useDstAlpha) override;
void vFlush() override;
void PrepareDrawBuffers(u32 stride);
// Alternative buffers in CPU memory for primatives we are going to discard.

View File

@ -54,7 +54,7 @@ void SWVertexLoader::ResetBuffer(u32 stride)
IndexGenerator::Start(GetIndexBuffer());
}
void SWVertexLoader::vFlush(bool useDstAlpha)
void SWVertexLoader::vFlush()
{
DebugUtil::OnObjectBegin();

View File

@ -25,7 +25,7 @@ protected:
void ResetBuffer(u32 stride) override;
u16* GetIndexBuffer() { return &LocalIBuffer[0]; }
private:
void vFlush(bool useDstAlpha) override;
void vFlush() override;
std::vector<u8> LocalVBuffer;
std::vector<u16> LocalIBuffer;

View File

@ -1218,7 +1218,7 @@ void Renderer::ResizeSwapChain()
OnSwapChainResized();
}
void Renderer::ApplyState(bool bUseDstAlpha)
void Renderer::ApplyState()
{
}

View File

@ -52,7 +52,7 @@ public:
void ReinterpretPixelData(unsigned int convtype) override;
void ApplyState(bool bUseDstAlpha) override;
void ApplyState() override;
void ResetAPIState() override;
void RestoreAPIState() override;

View File

@ -304,10 +304,10 @@ void StateTracker::SetBlendState(const BlendState& state)
m_dirty_flags |= DIRTY_FLAG_PIPELINE;
}
bool StateTracker::CheckForShaderChanges(u32 gx_primitive_type, DSTALPHA_MODE dstalpha_mode)
bool StateTracker::CheckForShaderChanges(u32 gx_primitive_type)
{
VertexShaderUid vs_uid = GetVertexShaderUid();
PixelShaderUid ps_uid = GetPixelShaderUid(dstalpha_mode);
PixelShaderUid ps_uid = GetPixelShaderUid();
bool changed = false;
@ -340,16 +340,6 @@ bool StateTracker::CheckForShaderChanges(u32 gx_primitive_type, DSTALPHA_MODE ds
changed = true;
}
if (m_dstalpha_mode != dstalpha_mode)
{
// Switching to/from alpha pass requires a pipeline change, since the blend state
// is overridden in the destination alpha pass.
if (m_dstalpha_mode == DSTALPHA_ALPHA_PASS || dstalpha_mode == DSTALPHA_ALPHA_PASS)
changed = true;
m_dstalpha_mode = dstalpha_mode;
}
if (changed)
m_dirty_flags |= DIRTY_FLAG_PIPELINE;
@ -881,22 +871,6 @@ void StateTracker::EndClearRenderPass()
EndRenderPass();
}
PipelineInfo StateTracker::GetAlphaPassPipelineConfig(const PipelineInfo& info) const
{
PipelineInfo temp_info = info;
// Skip depth writes for this pass. The results will be the same, so no
// point in overwriting depth values with the same value.
temp_info.depth_stencil_state.write_enable = VK_FALSE;
// Only allow alpha writes, and disable blending.
temp_info.blend_state.blend_enable = VK_FALSE;
temp_info.blend_state.logic_op_enable = VK_FALSE;
temp_info.blend_state.write_mask = VK_COLOR_COMPONENT_A_BIT;
return temp_info;
}
VkPipeline StateTracker::GetPipelineAndCacheUID(const PipelineInfo& info)
{
auto result = g_object_cache->GetPipelineWithCacheResult(info);
@ -915,17 +889,7 @@ bool StateTracker::UpdatePipeline()
return false;
// Grab a new pipeline object, this can fail.
// We have to use a different blend state for the alpha pass of the dstalpha fallback.
if (m_dstalpha_mode == DSTALPHA_ALPHA_PASS)
{
// We need to retain the existing state, since we don't want to break the next draw.
PipelineInfo temp_info = GetAlphaPassPipelineConfig(m_pipeline_state);
m_pipeline_object = GetPipelineAndCacheUID(temp_info);
}
else
{
m_pipeline_object = GetPipelineAndCacheUID(m_pipeline_state);
}
m_pipeline_object = GetPipelineAndCacheUID(m_pipeline_state);
m_dirty_flags |= DIRTY_FLAG_PIPELINE_BINDING;
return m_pipeline_object != VK_NULL_HANDLE;

View File

@ -58,7 +58,7 @@ public:
void SetDepthStencilState(const DepthStencilState& state);
void SetBlendState(const BlendState& state);
bool CheckForShaderChanges(u32 gx_primitive_type, DSTALPHA_MODE dstalpha_mode);
bool CheckForShaderChanges(u32 gx_primitive_type);
void UpdateVertexShaderConstants();
void UpdateGeometryShaderConstants();
@ -172,9 +172,6 @@ private:
// If not, ends the render pass if it is a clear render pass.
bool IsViewportWithinRenderArea() const;
// Gets a pipeline state that can be used to draw the alpha pass with constant alpha enabled.
PipelineInfo GetAlphaPassPipelineConfig(const PipelineInfo& info) const;
// Obtains a Vulkan pipeline object for the specified pipeline configuration.
// Also adds this pipeline configuration to the UID cache if it is not present already.
VkPipeline GetPipelineAndCacheUID(const PipelineInfo& info);
@ -205,7 +202,6 @@ private:
// pipeline state
PipelineInfo m_pipeline_state = {};
DSTALPHA_MODE m_dstalpha_mode = DSTALPHA_NONE;
VkPipeline m_pipeline_object = VK_NULL_HANDLE;
// shader bindings

View File

@ -124,7 +124,7 @@ void VertexManager::ResetBuffer(u32 stride)
static_cast<u32>(m_index_stream_buffer->GetCurrentOffset() / sizeof(u16));
}
void VertexManager::vFlush(bool use_dst_alpha)
void VertexManager::vFlush()
{
const VertexFormat* vertex_format =
static_cast<VertexFormat*>(VertexLoaderManager::GetCurrentVertexFormat());
@ -153,13 +153,8 @@ void VertexManager::vFlush(bool use_dst_alpha)
break;
}
// Can we do single-pass dst alpha?
DSTALPHA_MODE dstalpha_mode = DSTALPHA_NONE;
if (use_dst_alpha && g_vulkan_context->SupportsDualSourceBlend())
dstalpha_mode = DSTALPHA_DUAL_SOURCE_BLEND;
// Check for any shader stage changes
StateTracker::GetInstance()->CheckForShaderChanges(m_current_primitive_type, dstalpha_mode);
StateTracker::GetInstance()->CheckForShaderChanges(m_current_primitive_type);
// Update any changed constants
StateTracker::GetInstance()->UpdateVertexShaderConstants();
@ -202,27 +197,6 @@ void VertexManager::vFlush(bool use_dst_alpha)
vkCmdDrawIndexed(g_command_buffer_mgr->GetCurrentCommandBuffer(), index_count, 1,
m_current_draw_base_index, m_current_draw_base_vertex, 0);
// If the GPU does not support dual-source blending, we can approximate the effect by drawing
// the object a second time, with the write mask set to alpha only using a shader that outputs
// the destination/constant alpha value (which would normally be SRC_COLOR.a).
//
// This is also used when logic ops and destination alpha is enabled, since we can't enable
// blending and logic ops concurrently (and the logical operation applies to all channels).
bool logic_op_enabled = bpmem.blendmode.logicopenable && !bpmem.blendmode.blendenable;
if (use_dst_alpha && (!g_vulkan_context->SupportsDualSourceBlend() || logic_op_enabled))
{
StateTracker::GetInstance()->CheckForShaderChanges(m_current_primitive_type,
DSTALPHA_ALPHA_PASS);
if (!StateTracker::GetInstance()->Bind())
{
WARN_LOG(VIDEO, "Skipped draw of %u indices (alpha pass)", index_count);
return;
}
vkCmdDrawIndexed(g_command_buffer_mgr->GetCurrentCommandBuffer(), index_count, 1,
m_current_draw_base_index, m_current_draw_base_vertex, 0);
}
StateTracker::GetInstance()->OnDraw();
}

View File

@ -31,7 +31,7 @@ protected:
void ResetBuffer(u32 stride) override;
private:
void vFlush(bool use_dst_alpha) override;
void vFlush() override;
std::vector<u8> m_cpu_vertex_buffer;
std::vector<u16> m_cpu_index_buffer;

View File

@ -156,13 +156,15 @@ static const char* tevAOutputTable[] = {"prev.a", "c0.a", "c1.a", "c2.a"};
// leak
// into this UID; This is really unhelpful if these UIDs ever move from one machine to
// another.
PixelShaderUid GetPixelShaderUid(DSTALPHA_MODE dstAlphaMode)
PixelShaderUid GetPixelShaderUid()
{
PixelShaderUid out;
pixel_shader_uid_data* uid_data = out.GetUidData<pixel_shader_uid_data>();
memset(uid_data, 0, sizeof(*uid_data));
uid_data->dstAlphaMode = dstAlphaMode;
uid_data->useDstAlpha = bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate &&
bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24;
uid_data->genMode_numindstages = bpmem.genMode.numindstages;
uid_data->genMode_numtevstages = bpmem.genMode.numtevstages;
uid_data->genMode_numtexgens = bpmem.genMode.numtexgens;
@ -327,13 +329,9 @@ PixelShaderUid GetPixelShaderUid(DSTALPHA_MODE dstAlphaMode)
uid_data->ztex_op = bpmem.ztex2.op;
uid_data->early_ztest = bpmem.UseEarlyDepthTest();
uid_data->fog_fsel = bpmem.fog.c_proj_fsel.fsel;
if (dstAlphaMode != DSTALPHA_ALPHA_PASS)
{
uid_data->fog_fsel = bpmem.fog.c_proj_fsel.fsel;
uid_data->fog_proj = bpmem.fog.c_proj_fsel.proj;
uid_data->fog_RangeBaseEnabled = bpmem.fogRange.Base.Enabled;
}
uid_data->fog_fsel = bpmem.fog.c_proj_fsel.fsel;
uid_data->fog_proj = bpmem.fog.c_proj_fsel.proj;
uid_data->fog_RangeBaseEnabled = bpmem.fogRange.Base.Enabled;
return out;
}
@ -510,7 +508,7 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const pixel_shader_uid_data*
const bool use_dual_source =
g_ActiveConfig.backend_info.bSupportsDualSourceBlend &&
(!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) ||
uid_data->dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND);
uid_data->useDstAlpha);
if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan)
{
@ -795,8 +793,7 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const pixel_shader_uid_data*
out.Write("\tprev.rgb = (prev.rgb - (prev.rgb >> 6)) + abs(dither.y * 3 - dither.x * 2);\n");
}
if (uid_data->dstAlphaMode != DSTALPHA_ALPHA_PASS)
WriteFog(out, uid_data);
WriteFog(out, uid_data);
// Write the color and alpha values to the framebuffer
WriteColor(out, uid_data, use_dual_source);
@ -1308,7 +1305,7 @@ static void WriteColor(ShaderCode& out, const pixel_shader_uid_data* uid_data, b
// 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->dstAlphaMode == DSTALPHA_NONE)
if (!uid_data->useDstAlpha)
{
out.Write("\tocol0.a = float(prev.a >> 2) / 63.0;\n");
if (use_dual_source)
@ -1322,7 +1319,7 @@ static void WriteColor(ShaderCode& out, const pixel_shader_uid_data* uid_data, b
// Use dual-source color blending to perform dst alpha in a single pass
if (use_dual_source)
{
if (uid_data->dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND)
if (uid_data->useDstAlpha)
out.Write("\tocol1.a = float(prev.a) / 255.0;\n");
else
out.Write("\tocol1.a = float(" I_ALPHA ".a) / 255.0;\n");

View File

@ -10,14 +10,6 @@
enum class APIType;
// Different ways to achieve rendering with destination alpha
enum DSTALPHA_MODE
{
DSTALPHA_NONE, // Render normally, without destination alpha
DSTALPHA_ALPHA_PASS, // Render normally first, then render again for alpha
DSTALPHA_DUAL_SOURCE_BLEND // Use dual-source blending
};
#pragma pack(1)
struct pixel_shader_uid_data
{
@ -26,7 +18,8 @@ struct pixel_shader_uid_data
u32 num_values; // TODO: Shouldn't be a u32
u32 NumValues() const { return num_values; }
u32 components : 2;
u32 dstAlphaMode : 2;
u32 pad0 : 1;
u32 useDstAlpha : 1;
u32 Pretest : 2;
u32 nIndirectStagesUsed : 4;
u32 stereo : 1;
@ -170,4 +163,4 @@ struct pixel_shader_uid_data
typedef ShaderUid<pixel_shader_uid_data> PixelShaderUid;
ShaderCode GeneratePixelShaderCode(APIType ApiType, const pixel_shader_uid_data* uid_data);
PixelShaderUid GetPixelShaderUid(DSTALPHA_MODE dstAlphaMode);
PixelShaderUid GetPixelShaderUid();

View File

@ -74,7 +74,7 @@ public:
virtual void SetViewport() {}
virtual void SetFullscreen(bool enable_fullscreen) {}
virtual bool IsFullscreen() const { return false; }
virtual void ApplyState(bool bUseDstAlpha) {}
virtual void ApplyState() {}
virtual void RestoreState() {}
virtual void ResetAPIState() {}
virtual void RestoreAPIState() {}

View File

@ -253,12 +253,9 @@ void VertexManagerBase::Flush()
GeometryShaderManager::SetConstants();
PixelShaderManager::SetConstants();
bool useDstAlpha = bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate &&
bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24;
if (PerfQueryBase::ShouldEmulate())
g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP);
g_vertex_manager->vFlush(useDstAlpha);
g_vertex_manager->vFlush();
if (PerfQueryBase::ShouldEmulate())
g_perf_query->DisableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP);
}

View File

@ -82,7 +82,7 @@ protected:
private:
bool m_is_flushed = true;
virtual void vFlush(bool useDstAlpha) = 0;
virtual void vFlush() = 0;
virtual void CreateDeviceObjects() {}
virtual void DestroyDeviceObjects() {}