Merge pull request #5284 from stenzek/vulkan-videocommon-blending-state

Vulkan: Use BlendingState from VideoCommon
This commit is contained in:
Stenzek 2017-04-18 22:16:32 +10:00 committed by GitHub
commit d1dc9d5a0c
22 changed files with 132 additions and 364 deletions

View File

@ -1085,11 +1085,6 @@ void Renderer::SetLogicOpMode()
}
}
void Renderer::SetDitherMode()
{
// TODO: Set dither mode to bpmem.blendmode.dither
}
void Renderer::SetSamplerState(int stage, int texindex, bool custom_tex)
{
const FourTexUnits& tex = bpmem.tex[texindex];

View File

@ -25,7 +25,6 @@ public:
void SetGenerationMode() override;
void SetDepthMode() override;
void SetLogicOpMode() override;
void SetDitherMode() override;
void SetSamplerState(int stage, int texindex, bool custom_tex) override;
void SetInterlacingMode() override;
void SetViewport() override;

View File

@ -1108,11 +1108,6 @@ void Renderer::SetLogicOpMode()
D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PSO, true);
}
void Renderer::SetDitherMode()
{
// EXISTINGD3D11TODO: Set dither mode to bpmem.blendmode.dither
}
void Renderer::SetSamplerState(int stage, int tex_index, bool custom_tex)
{
const FourTexUnits& tex = bpmem.tex[tex_index];

View File

@ -26,7 +26,6 @@ public:
void SetGenerationMode() override;
void SetDepthMode() override;
void SetLogicOpMode() override;
void SetDitherMode() override;
void SetSamplerState(int stage, int tex_index, bool custom_tex) override;
void SetInterlacingMode() override;
void SetViewport() override;

View File

@ -1214,7 +1214,7 @@ void Renderer::SetBlendMode(bool forceUpdate)
state.Generate(bpmem);
bool useDualSource =
g_ActiveConfig.backend_info.bSupportsDualSourceBlend &&
state.usedualsrc && g_ActiveConfig.backend_info.bSupportsDualSourceBlend &&
(!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) || state.dstalpha);
const GLenum src_factors[8] = {
@ -1274,11 +1274,6 @@ void Renderer::SetBlendMode(bool forceUpdate)
glDisable(GL_COLOR_LOGIC_OP);
}
if (state.dither)
glEnable(GL_DITHER);
else
glDisable(GL_DITHER);
glColorMask(state.colorupdate, state.colorupdate, state.colorupdate, state.alphaupdate);
}

View File

@ -145,34 +145,6 @@ union DepthStencilState
u32 bits;
};
// Blend state info
union BlendState
{
struct
{
union
{
BitField<0, 1, VkBool32> blend_enable;
BitField<1, 3, VkBlendOp> blend_op;
BitField<4, 5, VkBlendFactor> src_blend;
BitField<9, 5, VkBlendFactor> dst_blend;
BitField<14, 3, VkBlendOp> alpha_blend_op;
BitField<17, 5, VkBlendFactor> src_alpha_blend;
BitField<22, 5, VkBlendFactor> dst_alpha_blend;
BitField<27, 4, VkColorComponentFlags> write_mask;
u32 low_bits;
};
union
{
BitField<0, 1, VkBool32> logic_op_enable;
BitField<1, 4, VkLogicOp> logic_op;
u32 high_bits;
};
};
u64 bits;
};
// Sampler info
union SamplerState
{

View File

@ -1163,14 +1163,10 @@ void FramebufferManager::DrawPokeVertices(const EFBPokeVertex* vertices, size_t
pipeline_info.rasterization_state.bits = Util::GetNoCullRasterizationState().bits;
pipeline_info.rasterization_state.samples = m_efb_samples;
pipeline_info.depth_stencil_state.bits = Util::GetNoDepthTestingDepthStencilState().bits;
pipeline_info.blend_state.bits = Util::GetNoBlendingBlendState().bits;
pipeline_info.blend_state.write_mask = 0;
pipeline_info.blend_state.hex = Util::GetNoBlendingBlendState().hex;
pipeline_info.blend_state.colorupdate = write_color;
pipeline_info.blend_state.alphaupdate = write_color;
pipeline_info.primitive_topology = m_poke_primitive_topology;
if (write_color)
{
pipeline_info.blend_state.write_mask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
}
if (write_depth)
{
pipeline_info.depth_stencil_state.test_enable = VK_TRUE;

View File

@ -135,33 +135,95 @@ GetVulkanDepthStencilState(const DepthStencilState& state)
};
}
static VkPipelineColorBlendAttachmentState GetVulkanAttachmentBlendState(const BlendState& state)
static VkPipelineColorBlendAttachmentState GetVulkanAttachmentBlendState(const BlendingState& state)
{
VkPipelineColorBlendAttachmentState vk_state = {
state.blend_enable, // VkBool32 blendEnable
state.src_blend, // VkBlendFactor srcColorBlendFactor
state.dst_blend, // VkBlendFactor dstColorBlendFactor
state.blend_op, // VkBlendOp colorBlendOp
state.src_alpha_blend, // VkBlendFactor srcAlphaBlendFactor
state.dst_alpha_blend, // VkBlendFactor dstAlphaBlendFactor
state.alpha_blend_op, // VkBlendOp alphaBlendOp
state.write_mask // VkColorComponentFlags colorWriteMask
};
VkPipelineColorBlendAttachmentState vk_state = {};
vk_state.blendEnable = static_cast<VkBool32>(state.blendenable);
vk_state.colorBlendOp = state.subtract ? VK_BLEND_OP_REVERSE_SUBTRACT : VK_BLEND_OP_ADD;
vk_state.alphaBlendOp = state.subtractAlpha ? VK_BLEND_OP_REVERSE_SUBTRACT : VK_BLEND_OP_ADD;
if (state.usedualsrc && g_vulkan_context->SupportsDualSourceBlend())
{
static constexpr std::array<VkBlendFactor, 8> src_factors = {
{VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_DST_COLOR,
VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}};
static constexpr std::array<VkBlendFactor, 8> dst_factors = {
{VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_SRC_COLOR,
VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}};
vk_state.srcColorBlendFactor = src_factors[state.srcfactor];
vk_state.srcAlphaBlendFactor = src_factors[state.srcfactoralpha];
vk_state.dstColorBlendFactor = dst_factors[state.dstfactor];
vk_state.dstAlphaBlendFactor = dst_factors[state.dstfactoralpha];
}
else
{
static constexpr std::array<VkBlendFactor, 8> src_factors = {
{VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_DST_COLOR,
VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_FACTOR_SRC_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}};
static constexpr std::array<VkBlendFactor, 8> dst_factors = {
{VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_SRC_COLOR,
VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_FACTOR_SRC_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}};
vk_state.srcColorBlendFactor = src_factors[state.srcfactor];
vk_state.srcAlphaBlendFactor = src_factors[state.srcfactoralpha];
vk_state.dstColorBlendFactor = dst_factors[state.dstfactor];
vk_state.dstAlphaBlendFactor = dst_factors[state.dstfactoralpha];
}
if (state.colorupdate)
{
vk_state.colorWriteMask =
VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT;
}
else
{
vk_state.colorWriteMask = 0;
}
if (state.alphaupdate)
vk_state.colorWriteMask |= VK_COLOR_COMPONENT_A_BIT;
return vk_state;
}
static VkPipelineColorBlendStateCreateInfo
GetVulkanColorBlendState(const BlendState& state,
GetVulkanColorBlendState(const BlendingState& state,
const VkPipelineColorBlendAttachmentState* attachments,
uint32_t num_attachments)
{
static constexpr std::array<VkLogicOp, 16> vk_logic_ops = {
{VK_LOGIC_OP_CLEAR, VK_LOGIC_OP_AND, VK_LOGIC_OP_AND_REVERSE, VK_LOGIC_OP_COPY,
VK_LOGIC_OP_AND_INVERTED, VK_LOGIC_OP_NO_OP, VK_LOGIC_OP_XOR, VK_LOGIC_OP_OR,
VK_LOGIC_OP_NOR, VK_LOGIC_OP_EQUIVALENT, VK_LOGIC_OP_INVERT, VK_LOGIC_OP_OR_REVERSE,
VK_LOGIC_OP_COPY_INVERTED, VK_LOGIC_OP_OR_INVERTED, VK_LOGIC_OP_NAND, VK_LOGIC_OP_SET}};
VkBool32 vk_logic_op_enable = static_cast<VkBool32>(state.logicopenable);
if (vk_logic_op_enable && !g_vulkan_context->SupportsLogicOps())
{
// At the time of writing, Adreno and Mali drivers didn't support logic ops.
// The "emulation" through blending path has been removed, so just disable it completely.
// These drivers don't support dual-source blend either, so issues are to be expected.
vk_logic_op_enable = VK_FALSE;
}
VkLogicOp vk_logic_op = vk_logic_op_enable ? vk_logic_ops[state.logicmode] : VK_LOGIC_OP_CLEAR;
VkPipelineColorBlendStateCreateInfo vk_state = {
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType
nullptr, // const void* pNext
0, // VkPipelineColorBlendStateCreateFlags flags
state.logic_op_enable, // VkBool32 logicOpEnable
state.logic_op, // VkLogicOp logicOp
vk_logic_op_enable, // VkBool32 logicOpEnable
vk_logic_op, // VkLogicOp logicOp
num_attachments, // uint32_t attachmentCount
attachments, // const VkPipelineColorBlendAttachmentState* pAttachments
{1.0f, 1.0f, 1.0f, 1.0f} // float blendConstants[4]

View File

@ -18,6 +18,7 @@
#include "VideoCommon/GeometryShaderGen.h"
#include "VideoCommon/PixelShaderGen.h"
#include "VideoCommon/RenderState.h"
#include "VideoCommon/VertexShaderGen.h"
namespace Vulkan
@ -36,7 +37,7 @@ struct PipelineInfo
VkShaderModule gs;
VkShaderModule ps;
VkRenderPass render_pass;
BlendState blend_state;
BlendingState blend_state;
RasterizationState rasterization_state;
DepthStencilState depth_stencil_state;
VkPrimitiveTopology primitive_topology;

View File

@ -395,11 +395,10 @@ void RasterFont::PrintMultiLineText(VkRenderPass render_pass, const std::string&
draw.SetPSSampler(0, m_texture->GetView(), g_object_cache->GetLinearSampler());
// Setup alpha blending
BlendState blend_state = Util::GetNoBlendingBlendState();
blend_state.blend_enable = VK_TRUE;
blend_state.src_blend = VK_BLEND_FACTOR_SRC_ALPHA;
blend_state.blend_op = VK_BLEND_OP_ADD;
blend_state.dst_blend = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
BlendingState blend_state = Util::GetNoBlendingBlendState();
blend_state.blendenable = true;
blend_state.srcfactor = BlendMode::SRCALPHA;
blend_state.dstfactor = BlendMode::INVSRCALPHA;
draw.SetBlendState(blend_state);
draw.Draw();

View File

@ -35,6 +35,7 @@
#include "VideoCommon/OnScreenDisplay.h"
#include "VideoCommon/PixelEngine.h"
#include "VideoCommon/PixelShaderManager.h"
#include "VideoCommon/RenderState.h"
#include "VideoCommon/SamplerCommon.h"
#include "VideoCommon/TextureCacheBase.h"
#include "VideoCommon/VideoBackendBase.h"
@ -432,13 +433,9 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool color_enable, bool alpha
StateTracker::GetInstance()->SetPendingRebind();
// Mask away the appropriate colors and use a shader
BlendState blend_state = Util::GetNoBlendingBlendState();
u32 write_mask = 0;
if (color_enable)
write_mask |= VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT;
if (alpha_enable)
write_mask |= VK_COLOR_COMPONENT_A_BIT;
blend_state.write_mask = write_mask;
BlendingState blend_state = Util::GetNoBlendingBlendState();
blend_state.colorupdate = color_enable;
blend_state.alphaupdate = alpha_enable;
DepthStencilState depth_state = Util::GetNoDepthTestingDepthStencilState();
depth_state.test_enable = z_enable ? VK_TRUE : VK_FALSE;
@ -1324,232 +1321,12 @@ void Renderer::SetDepthMode()
StateTracker::GetInstance()->SetDepthStencilState(new_ds_state);
}
void Renderer::SetColorMask()
{
u32 color_mask = 0;
if (bpmem.alpha_test.TestResult() != AlphaTest::FAIL)
{
if (bpmem.blendmode.alphaupdate && bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24)
color_mask |= VK_COLOR_COMPONENT_A_BIT;
if (bpmem.blendmode.colorupdate)
color_mask |= VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT;
}
BlendState new_blend_state = {};
new_blend_state.bits = StateTracker::GetInstance()->GetBlendState().bits;
new_blend_state.write_mask = color_mask;
StateTracker::GetInstance()->SetBlendState(new_blend_state);
}
void Renderer::SetBlendMode(bool force_update)
{
BlendState new_blend_state = {};
new_blend_state.bits = StateTracker::GetInstance()->GetBlendState().bits;
BlendingState state;
state.Generate(bpmem);
// Fast path for blending disabled
if (!bpmem.blendmode.blendenable)
{
new_blend_state.blend_enable = VK_FALSE;
new_blend_state.blend_op = VK_BLEND_OP_ADD;
new_blend_state.src_blend = VK_BLEND_FACTOR_ONE;
new_blend_state.dst_blend = VK_BLEND_FACTOR_ZERO;
new_blend_state.alpha_blend_op = VK_BLEND_OP_ADD;
new_blend_state.src_alpha_blend = VK_BLEND_FACTOR_ONE;
new_blend_state.dst_alpha_blend = VK_BLEND_FACTOR_ZERO;
StateTracker::GetInstance()->SetBlendState(new_blend_state);
return;
}
// Fast path for subtract blending
else if (bpmem.blendmode.subtract)
{
new_blend_state.blend_enable = VK_TRUE;
new_blend_state.blend_op = VK_BLEND_OP_REVERSE_SUBTRACT;
new_blend_state.src_blend = VK_BLEND_FACTOR_ONE;
new_blend_state.dst_blend = VK_BLEND_FACTOR_ONE;
new_blend_state.alpha_blend_op = VK_BLEND_OP_REVERSE_SUBTRACT;
new_blend_state.src_alpha_blend = VK_BLEND_FACTOR_ONE;
new_blend_state.dst_alpha_blend = VK_BLEND_FACTOR_ONE;
StateTracker::GetInstance()->SetBlendState(new_blend_state);
return;
}
// Our render target always uses an alpha channel, so we need to override the blend functions to
// assume a destination alpha of 1 if the render target isn't supposed to have an alpha channel.
bool target_has_alpha = bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24;
bool use_dst_alpha = bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && target_has_alpha;
bool use_dual_src = g_vulkan_context->SupportsDualSourceBlend();
new_blend_state.blend_enable = VK_TRUE;
new_blend_state.blend_op = VK_BLEND_OP_ADD;
switch (bpmem.blendmode.srcfactor)
{
case BlendMode::ZERO:
new_blend_state.src_blend = VK_BLEND_FACTOR_ZERO;
break;
case BlendMode::ONE:
new_blend_state.src_blend = VK_BLEND_FACTOR_ONE;
break;
case BlendMode::DSTCLR:
new_blend_state.src_blend = VK_BLEND_FACTOR_DST_COLOR;
break;
case BlendMode::INVDSTCLR:
new_blend_state.src_blend = VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
break;
case BlendMode::SRCALPHA:
new_blend_state.src_blend =
use_dual_src ? VK_BLEND_FACTOR_SRC1_ALPHA : VK_BLEND_FACTOR_SRC_ALPHA;
break;
case BlendMode::INVSRCALPHA:
new_blend_state.src_blend =
use_dual_src ? VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA : VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
break;
case BlendMode::DSTALPHA:
new_blend_state.src_blend = target_has_alpha ? VK_BLEND_FACTOR_DST_ALPHA : VK_BLEND_FACTOR_ONE;
break;
case BlendMode::INVDSTALPHA:
new_blend_state.src_blend =
target_has_alpha ? VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA : VK_BLEND_FACTOR_ZERO;
break;
default:
new_blend_state.src_blend = VK_BLEND_FACTOR_ONE;
break;
}
switch (bpmem.blendmode.dstfactor)
{
case BlendMode::ZERO:
new_blend_state.dst_blend = VK_BLEND_FACTOR_ZERO;
break;
case BlendMode::ONE:
new_blend_state.dst_blend = VK_BLEND_FACTOR_ONE;
break;
case BlendMode::SRCCLR:
new_blend_state.dst_blend = VK_BLEND_FACTOR_SRC_COLOR;
break;
case BlendMode::INVSRCCLR:
new_blend_state.dst_blend = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
break;
case BlendMode::SRCALPHA:
new_blend_state.dst_blend =
use_dual_src ? VK_BLEND_FACTOR_SRC1_ALPHA : VK_BLEND_FACTOR_SRC_ALPHA;
break;
case BlendMode::INVSRCALPHA:
new_blend_state.dst_blend =
use_dual_src ? VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA : VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
break;
case BlendMode::DSTALPHA:
new_blend_state.dst_blend = target_has_alpha ? VK_BLEND_FACTOR_DST_ALPHA : VK_BLEND_FACTOR_ONE;
break;
case BlendMode::INVDSTALPHA:
new_blend_state.dst_blend =
target_has_alpha ? VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA : VK_BLEND_FACTOR_ZERO;
break;
default:
new_blend_state.dst_blend = VK_BLEND_FACTOR_ONE;
break;
}
if (use_dst_alpha)
{
// Destination alpha sets 1*SRC
new_blend_state.alpha_blend_op = VK_BLEND_OP_ADD;
new_blend_state.src_alpha_blend = VK_BLEND_FACTOR_ONE;
new_blend_state.dst_alpha_blend = VK_BLEND_FACTOR_ZERO;
}
else
{
new_blend_state.alpha_blend_op = VK_BLEND_OP_ADD;
new_blend_state.src_alpha_blend = Util::GetAlphaBlendFactor(new_blend_state.src_blend);
new_blend_state.dst_alpha_blend = Util::GetAlphaBlendFactor(new_blend_state.dst_blend);
}
StateTracker::GetInstance()->SetBlendState(new_blend_state);
}
void Renderer::SetLogicOpMode()
{
BlendState new_blend_state = {};
new_blend_state.bits = StateTracker::GetInstance()->GetBlendState().bits;
// Does our device support logic ops?
bool logic_op_enable = bpmem.blendmode.logicopenable && !bpmem.blendmode.blendenable;
if (g_vulkan_context->SupportsLogicOps())
{
if (logic_op_enable)
{
static const std::array<VkLogicOp, 16> logic_ops = {
{VK_LOGIC_OP_CLEAR, VK_LOGIC_OP_AND, VK_LOGIC_OP_AND_REVERSE, VK_LOGIC_OP_COPY,
VK_LOGIC_OP_AND_INVERTED, VK_LOGIC_OP_NO_OP, VK_LOGIC_OP_XOR, VK_LOGIC_OP_OR,
VK_LOGIC_OP_NOR, VK_LOGIC_OP_EQUIVALENT, VK_LOGIC_OP_INVERT, VK_LOGIC_OP_OR_REVERSE,
VK_LOGIC_OP_COPY_INVERTED, VK_LOGIC_OP_OR_INVERTED, VK_LOGIC_OP_NAND, VK_LOGIC_OP_SET}};
new_blend_state.logic_op_enable = VK_TRUE;
new_blend_state.logic_op = logic_ops[bpmem.blendmode.logicmode];
}
else
{
new_blend_state.logic_op_enable = VK_FALSE;
new_blend_state.logic_op = VK_LOGIC_OP_CLEAR;
}
StateTracker::GetInstance()->SetBlendState(new_blend_state);
}
else
{
// No logic op support, approximate with blending instead.
// This is by no means correct, but necessary for some devices.
if (logic_op_enable)
{
struct LogicOpBlend
{
VkBlendFactor src_factor;
VkBlendOp op;
VkBlendFactor dst_factor;
};
static const std::array<LogicOpBlend, 16> logic_ops = {
{{VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD, VK_BLEND_FACTOR_ZERO},
{VK_BLEND_FACTOR_DST_COLOR, VK_BLEND_OP_ADD, VK_BLEND_FACTOR_ZERO},
{VK_BLEND_FACTOR_ONE, VK_BLEND_OP_SUBTRACT, VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR},
{VK_BLEND_FACTOR_ONE, VK_BLEND_OP_ADD, VK_BLEND_FACTOR_ZERO},
{VK_BLEND_FACTOR_DST_COLOR, VK_BLEND_OP_REVERSE_SUBTRACT, VK_BLEND_FACTOR_ONE},
{VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD, VK_BLEND_FACTOR_ONE},
{VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_OP_MAX,
VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR},
{VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_OP_ADD, VK_BLEND_FACTOR_ONE},
{VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_OP_MAX,
VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR},
{VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_OP_MAX, VK_BLEND_FACTOR_SRC_COLOR},
{VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_OP_ADD,
VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR},
{VK_BLEND_FACTOR_ONE, VK_BLEND_OP_ADD, VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR},
{VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_OP_ADD,
VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR},
{VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_OP_ADD, VK_BLEND_FACTOR_ONE},
{VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_OP_ADD,
VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR},
{VK_BLEND_FACTOR_ONE, VK_BLEND_OP_ADD, VK_BLEND_FACTOR_ONE}}};
new_blend_state.blend_enable = VK_TRUE;
new_blend_state.blend_op = logic_ops[bpmem.blendmode.logicmode].op;
new_blend_state.src_blend = logic_ops[bpmem.blendmode.logicmode].src_factor;
new_blend_state.dst_blend = logic_ops[bpmem.blendmode.logicmode].dst_factor;
new_blend_state.alpha_blend_op = new_blend_state.blend_op;
new_blend_state.src_alpha_blend = Util::GetAlphaBlendFactor(new_blend_state.src_blend);
new_blend_state.dst_alpha_blend = Util::GetAlphaBlendFactor(new_blend_state.dst_blend);
StateTracker::GetInstance()->SetBlendState(new_blend_state);
}
else
{
// This is unfortunate. Since we clobber the blend state when enabling logic ops,
// we have to call SetBlendMode again to restore the current blend state.
SetBlendMode(true);
return;
}
}
StateTracker::GetInstance()->SetBlendState(state);
}
void Renderer::SetSamplerState(int stage, int texindex, bool custom_tex)
@ -1630,10 +1407,6 @@ void Renderer::ResetSamplerStates()
g_object_cache->ClearSamplerCache();
}
void Renderer::SetDitherMode()
{
}
void Renderer::SetInterlacingMode()
{
}

View File

@ -56,13 +56,10 @@ public:
void ResetAPIState() override;
void RestoreAPIState() override;
void SetColorMask() override;
void SetBlendMode(bool force_update) override;
void SetScissorRect(const EFBRectangle& rc) override;
void SetGenerationMode() override;
void SetDepthMode() override;
void SetLogicOpMode() override;
void SetDitherMode() override;
void SetSamplerState(int stage, int texindex, bool custom_tex) override;
void SetInterlacingMode() override;
void SetViewport() override;

View File

@ -59,17 +59,14 @@ bool StateTracker::Initialize()
m_pipeline_state.depth_stencil_state.test_enable = VK_TRUE;
m_pipeline_state.depth_stencil_state.write_enable = VK_TRUE;
m_pipeline_state.depth_stencil_state.compare_op = VK_COMPARE_OP_LESS;
m_pipeline_state.blend_state.blend_enable = VK_FALSE;
m_pipeline_state.blend_state.blend_op = VK_BLEND_OP_ADD;
m_pipeline_state.blend_state.src_blend = VK_BLEND_FACTOR_ONE;
m_pipeline_state.blend_state.dst_blend = VK_BLEND_FACTOR_ZERO;
m_pipeline_state.blend_state.alpha_blend_op = VK_BLEND_OP_ADD;
m_pipeline_state.blend_state.src_alpha_blend = VK_BLEND_FACTOR_ONE;
m_pipeline_state.blend_state.dst_alpha_blend = VK_BLEND_FACTOR_ZERO;
m_pipeline_state.blend_state.logic_op_enable = VK_FALSE;
m_pipeline_state.blend_state.logic_op = VK_LOGIC_OP_CLEAR;
m_pipeline_state.blend_state.write_mask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
m_pipeline_state.blend_state.hex = 0;
m_pipeline_state.blend_state.blendenable = false;
m_pipeline_state.blend_state.srcfactor = BlendMode::ONE;
m_pipeline_state.blend_state.srcfactoralpha = BlendMode::ONE;
m_pipeline_state.blend_state.dstfactor = BlendMode::ZERO;
m_pipeline_state.blend_state.dstfactoralpha = BlendMode::ZERO;
m_pipeline_state.blend_state.colorupdate = true;
m_pipeline_state.blend_state.alphaupdate = true;
// Enable depth clamping if supported by driver.
if (g_ActiveConfig.backend_info.bSupportsDepthClamp)
@ -144,7 +141,7 @@ void StateTracker::LoadPipelineUIDCache()
void StateTracker::AppendToPipelineUIDCache(const PipelineInfo& info)
{
SerializedPipelineUID sinfo;
sinfo.blend_state_bits = info.blend_state.bits;
sinfo.blend_state_bits = info.blend_state.hex;
sinfo.rasterizer_state_bits = info.rasterization_state.bits;
sinfo.depth_stencil_state_bits = info.depth_stencil_state.bits;
sinfo.vertex_decl = m_pipeline_state.vertex_format->GetVertexDeclaration();
@ -189,9 +186,9 @@ bool StateTracker::PrecachePipelineUID(const SerializedPipelineUID& uid)
return false;
}
pinfo.render_pass = m_load_render_pass;
pinfo.blend_state.bits = uid.blend_state_bits;
pinfo.rasterization_state.bits = uid.rasterizer_state_bits;
pinfo.depth_stencil_state.bits = uid.depth_stencil_state_bits;
pinfo.blend_state.hex = uid.blend_state_bits;
pinfo.primitive_topology = uid.primitive_topology;
VkPipeline pipeline = g_object_cache->GetPipeline(pinfo);
@ -295,12 +292,12 @@ void StateTracker::SetDepthStencilState(const DepthStencilState& state)
m_dirty_flags |= DIRTY_FLAG_PIPELINE;
}
void StateTracker::SetBlendState(const BlendState& state)
void StateTracker::SetBlendState(const BlendingState& state)
{
if (m_pipeline_state.blend_state.bits == state.bits)
if (m_pipeline_state.blend_state.hex == state.hex)
return;
m_pipeline_state.blend_state.bits = state.bits;
m_pipeline_state.blend_state.hex = state.hex;
m_dirty_flags |= DIRTY_FLAG_PIPELINE;
}

View File

@ -41,7 +41,7 @@ public:
{
return m_pipeline_state.depth_stencil_state;
}
const BlendState& GetBlendState() const { return m_pipeline_state.blend_state; }
const BlendingState& GetBlendState() const { return m_pipeline_state.blend_state; }
void SetVertexBuffer(VkBuffer buffer, VkDeviceSize offset);
void SetIndexBuffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType type);
@ -57,7 +57,7 @@ public:
void SetRasterizationState(const RasterizationState& state);
void SetDepthStencilState(const DepthStencilState& state);
void SetBlendState(const BlendState& state);
void SetBlendState(const BlendingState& state);
bool CheckForShaderChanges(u32 gx_primitive_type);
@ -123,9 +123,9 @@ private:
// Serialized version of PipelineInfo, used when loading/saving the pipeline UID cache.
struct SerializedPipelineUID
{
u64 blend_state_bits;
u32 rasterizer_state_bits;
u32 depth_stencil_state_bits;
u32 blend_state_bits;
PortableVertexDeclaration vertex_decl;
VertexShaderUid vs_uid;
GeometryShaderUid gs_uid;

View File

@ -143,20 +143,17 @@ DepthStencilState GetNoDepthTestingDepthStencilState()
return state;
}
BlendState GetNoBlendingBlendState()
BlendingState GetNoBlendingBlendState()
{
BlendState state = {};
state.blend_enable = VK_FALSE;
state.blend_op = VK_BLEND_OP_ADD;
state.src_blend = VK_BLEND_FACTOR_ONE;
state.dst_blend = VK_BLEND_FACTOR_ZERO;
state.alpha_blend_op = VK_BLEND_OP_ADD;
state.src_alpha_blend = VK_BLEND_FACTOR_ONE;
state.dst_alpha_blend = VK_BLEND_FACTOR_ZERO;
state.logic_op_enable = VK_FALSE;
state.logic_op = VK_LOGIC_OP_CLEAR;
state.write_mask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
BlendingState state = {};
state.blendenable = false;
state.srcfactor = BlendMode::ONE;
state.srcfactoralpha = BlendMode::ZERO;
state.dstfactor = BlendMode::ONE;
state.dstfactoralpha = BlendMode::ZERO;
state.logicopenable = false;
state.colorupdate = true;
state.alphaupdate = true;
return state;
}
@ -289,7 +286,7 @@ UtilityShaderDraw::UtilityShaderDraw(VkCommandBuffer command_buffer,
m_pipeline_info.ps = pixel_shader;
m_pipeline_info.rasterization_state.bits = Util::GetNoCullRasterizationState().bits;
m_pipeline_info.depth_stencil_state.bits = Util::GetNoDepthTestingDepthStencilState().bits;
m_pipeline_info.blend_state.bits = Util::GetNoBlendingBlendState().bits;
m_pipeline_info.blend_state.hex = Util::GetNoBlendingBlendState().hex;
m_pipeline_info.primitive_topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
}
@ -397,9 +394,9 @@ void UtilityShaderDraw::SetDepthStencilState(const DepthStencilState& state)
m_pipeline_info.depth_stencil_state.bits = state.bits;
}
void UtilityShaderDraw::SetBlendState(const BlendState& state)
void UtilityShaderDraw::SetBlendState(const BlendingState& state)
{
m_pipeline_info.blend_state.bits = state.bits;
m_pipeline_info.blend_state.hex = state.hex;
}
void UtilityShaderDraw::BeginRenderPass(VkFramebuffer framebuffer, const VkRect2D& region,

View File

@ -10,6 +10,7 @@
#include "Common/CommonTypes.h"
#include "VideoBackends/Vulkan/Constants.h"
#include "VideoBackends/Vulkan/ObjectCache.h"
#include "VideoCommon/RenderState.h"
namespace Vulkan
{
@ -35,7 +36,7 @@ VkBlendFactor GetAlphaBlendFactor(VkBlendFactor factor);
RasterizationState GetNoCullRasterizationState();
DepthStencilState GetNoDepthTestingDepthStencilState();
BlendState GetNoBlendingBlendState();
BlendingState GetNoBlendingBlendState();
// Combines viewport and scissor updates
void SetViewportAndScissor(VkCommandBuffer command_buffer, int x, int y, int width, int height,
@ -147,7 +148,7 @@ public:
void SetRasterizationState(const RasterizationState& state);
void SetDepthStencilState(const DepthStencilState& state);
void SetBlendState(const BlendState& state);
void SetBlendState(const BlendingState& state);
void BeginRenderPass(VkFramebuffer framebuffer, const VkRect2D& region,
const VkClearValue* clear_value = nullptr);

View File

@ -74,10 +74,7 @@ void SetBlendMode()
{
g_renderer->SetBlendMode(false);
}
void SetDitherMode()
{
g_renderer->SetDitherMode();
}
void SetLogicOpMode()
{
g_renderer->SetLogicOpMode();

View File

@ -19,7 +19,6 @@ void SetGenerationMode();
void SetScissor();
void SetDepthMode();
void SetBlendMode();
void SetDitherMode();
void SetLogicOpMode();
void SetColorMask();
void ClearScreen(const EFBRectangle& rc);

View File

@ -152,10 +152,6 @@ static void BPWritten(const BPCmd& bp)
if (bp.changes & 0xF002) // logicopenable | logicmode
SetLogicOpMode();
// Set Dithering Mode
if (bp.changes & 4) // dither
SetDitherMode();
// Set Color Mask
if (bp.changes & 0x18) // colorupdate | alphaupdate
SetColorMask();
@ -1383,7 +1379,6 @@ void BPReload()
SetScissor();
SetDepthMode();
SetLogicOpMode();
SetDitherMode();
SetBlendMode();
SetColorMask();
OnPixelFormatChange();

View File

@ -69,7 +69,6 @@ public:
virtual void SetGenerationMode() {}
virtual void SetDepthMode() {}
virtual void SetLogicOpMode() {}
virtual void SetDitherMode() {}
virtual void SetSamplerState(int stage, int texindex, bool custom_tex) {}
virtual void SetInterlacingMode() {}
virtual void SetViewport() {}

View File

@ -61,10 +61,10 @@ void BlendingState::Generate(const BPMemory& bp)
bool target_has_alpha = bp.zcontrol.pixel_format == PEControl::RGBA6_Z24;
bool alpha_test_may_success = bp.alpha_test.TestResult() != AlphaTest::FAIL;
dither = bp.blendmode.dither;
colorupdate = bp.blendmode.colorupdate && alpha_test_may_success;
alphaupdate = bp.blendmode.alphaupdate && target_has_alpha && alpha_test_may_success;
dstalpha = bp.dstalpha.enable && alphaupdate;
usedualsrc = true;
// The subtract bit has the highest priority
if (bp.blendmode.subtract)

View File

@ -16,11 +16,11 @@ union BlendingState
BitField<0, 1, u32> blendenable;
BitField<1, 1, u32> logicopenable;
BitField<2, 1, u32> dstalpha;
BitField<3, 1, u32> dither;
BitField<4, 1, u32> colorupdate;
BitField<5, 1, u32> alphaupdate;
BitField<6, 1, u32> subtract;
BitField<7, 1, u32> subtractAlpha;
BitField<3, 1, u32> colorupdate;
BitField<4, 1, u32> alphaupdate;
BitField<5, 1, u32> subtract;
BitField<6, 1, u32> subtractAlpha;
BitField<7, 1, u32> usedualsrc;
BitField<8, 3, BlendMode::BlendFactor> dstfactor;
BitField<11, 3, BlendMode::BlendFactor> srcfactor;
BitField<14, 3, BlendMode::BlendFactor> dstfactoralpha;