mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-15 05:47:56 -07:00
Merge pull request #4577 from degasus/videocommon
OGL/Vulkan: Drop destination alpha pass.
This commit is contained in:
commit
389f8297c3
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 = "");
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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.
|
||||
|
@ -54,7 +54,7 @@ void SWVertexLoader::ResetBuffer(u32 stride)
|
||||
IndexGenerator::Start(GetIndexBuffer());
|
||||
}
|
||||
|
||||
void SWVertexLoader::vFlush(bool useDstAlpha)
|
||||
void SWVertexLoader::vFlush()
|
||||
{
|
||||
DebugUtil::OnObjectBegin();
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -1218,7 +1218,7 @@ void Renderer::ResizeSwapChain()
|
||||
OnSwapChainResized();
|
||||
}
|
||||
|
||||
void Renderer::ApplyState(bool bUseDstAlpha)
|
||||
void Renderer::ApplyState()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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();
|
||||
|
@ -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() {}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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() {}
|
||||
|
Loading…
Reference in New Issue
Block a user