Merge pull request #5284 from stenzek/vulkan-videocommon-blending-state
Vulkan: Use BlendingState from VideoCommon
This commit is contained in:
commit
d1dc9d5a0c
|
@ -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)
|
void Renderer::SetSamplerState(int stage, int texindex, bool custom_tex)
|
||||||
{
|
{
|
||||||
const FourTexUnits& tex = bpmem.tex[texindex];
|
const FourTexUnits& tex = bpmem.tex[texindex];
|
||||||
|
|
|
@ -25,7 +25,6 @@ public:
|
||||||
void SetGenerationMode() override;
|
void SetGenerationMode() override;
|
||||||
void SetDepthMode() override;
|
void SetDepthMode() override;
|
||||||
void SetLogicOpMode() override;
|
void SetLogicOpMode() override;
|
||||||
void SetDitherMode() override;
|
|
||||||
void SetSamplerState(int stage, int texindex, bool custom_tex) override;
|
void SetSamplerState(int stage, int texindex, bool custom_tex) override;
|
||||||
void SetInterlacingMode() override;
|
void SetInterlacingMode() override;
|
||||||
void SetViewport() override;
|
void SetViewport() override;
|
||||||
|
|
|
@ -1108,11 +1108,6 @@ void Renderer::SetLogicOpMode()
|
||||||
D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PSO, true);
|
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)
|
void Renderer::SetSamplerState(int stage, int tex_index, bool custom_tex)
|
||||||
{
|
{
|
||||||
const FourTexUnits& tex = bpmem.tex[tex_index];
|
const FourTexUnits& tex = bpmem.tex[tex_index];
|
||||||
|
|
|
@ -26,7 +26,6 @@ public:
|
||||||
void SetGenerationMode() override;
|
void SetGenerationMode() override;
|
||||||
void SetDepthMode() override;
|
void SetDepthMode() override;
|
||||||
void SetLogicOpMode() override;
|
void SetLogicOpMode() override;
|
||||||
void SetDitherMode() override;
|
|
||||||
void SetSamplerState(int stage, int tex_index, bool custom_tex) override;
|
void SetSamplerState(int stage, int tex_index, bool custom_tex) override;
|
||||||
void SetInterlacingMode() override;
|
void SetInterlacingMode() override;
|
||||||
void SetViewport() override;
|
void SetViewport() override;
|
||||||
|
|
|
@ -1214,7 +1214,7 @@ void Renderer::SetBlendMode(bool forceUpdate)
|
||||||
state.Generate(bpmem);
|
state.Generate(bpmem);
|
||||||
|
|
||||||
bool useDualSource =
|
bool useDualSource =
|
||||||
g_ActiveConfig.backend_info.bSupportsDualSourceBlend &&
|
state.usedualsrc && g_ActiveConfig.backend_info.bSupportsDualSourceBlend &&
|
||||||
(!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) || state.dstalpha);
|
(!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) || state.dstalpha);
|
||||||
|
|
||||||
const GLenum src_factors[8] = {
|
const GLenum src_factors[8] = {
|
||||||
|
@ -1274,11 +1274,6 @@ void Renderer::SetBlendMode(bool forceUpdate)
|
||||||
glDisable(GL_COLOR_LOGIC_OP);
|
glDisable(GL_COLOR_LOGIC_OP);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.dither)
|
|
||||||
glEnable(GL_DITHER);
|
|
||||||
else
|
|
||||||
glDisable(GL_DITHER);
|
|
||||||
|
|
||||||
glColorMask(state.colorupdate, state.colorupdate, state.colorupdate, state.alphaupdate);
|
glColorMask(state.colorupdate, state.colorupdate, state.colorupdate, state.alphaupdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,34 +145,6 @@ union DepthStencilState
|
||||||
u32 bits;
|
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
|
// Sampler info
|
||||||
union SamplerState
|
union SamplerState
|
||||||
{
|
{
|
||||||
|
|
|
@ -1163,14 +1163,10 @@ void FramebufferManager::DrawPokeVertices(const EFBPokeVertex* vertices, size_t
|
||||||
pipeline_info.rasterization_state.bits = Util::GetNoCullRasterizationState().bits;
|
pipeline_info.rasterization_state.bits = Util::GetNoCullRasterizationState().bits;
|
||||||
pipeline_info.rasterization_state.samples = m_efb_samples;
|
pipeline_info.rasterization_state.samples = m_efb_samples;
|
||||||
pipeline_info.depth_stencil_state.bits = Util::GetNoDepthTestingDepthStencilState().bits;
|
pipeline_info.depth_stencil_state.bits = Util::GetNoDepthTestingDepthStencilState().bits;
|
||||||
pipeline_info.blend_state.bits = Util::GetNoBlendingBlendState().bits;
|
pipeline_info.blend_state.hex = Util::GetNoBlendingBlendState().hex;
|
||||||
pipeline_info.blend_state.write_mask = 0;
|
pipeline_info.blend_state.colorupdate = write_color;
|
||||||
|
pipeline_info.blend_state.alphaupdate = write_color;
|
||||||
pipeline_info.primitive_topology = m_poke_primitive_topology;
|
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)
|
if (write_depth)
|
||||||
{
|
{
|
||||||
pipeline_info.depth_stencil_state.test_enable = VK_TRUE;
|
pipeline_info.depth_stencil_state.test_enable = VK_TRUE;
|
||||||
|
|
|
@ -135,33 +135,95 @@ GetVulkanDepthStencilState(const DepthStencilState& state)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static VkPipelineColorBlendAttachmentState GetVulkanAttachmentBlendState(const BlendState& state)
|
static VkPipelineColorBlendAttachmentState GetVulkanAttachmentBlendState(const BlendingState& state)
|
||||||
{
|
{
|
||||||
VkPipelineColorBlendAttachmentState vk_state = {
|
VkPipelineColorBlendAttachmentState vk_state = {};
|
||||||
state.blend_enable, // VkBool32 blendEnable
|
vk_state.blendEnable = static_cast<VkBool32>(state.blendenable);
|
||||||
state.src_blend, // VkBlendFactor srcColorBlendFactor
|
vk_state.colorBlendOp = state.subtract ? VK_BLEND_OP_REVERSE_SUBTRACT : VK_BLEND_OP_ADD;
|
||||||
state.dst_blend, // VkBlendFactor dstColorBlendFactor
|
vk_state.alphaBlendOp = state.subtractAlpha ? VK_BLEND_OP_REVERSE_SUBTRACT : VK_BLEND_OP_ADD;
|
||||||
state.blend_op, // VkBlendOp colorBlendOp
|
|
||||||
state.src_alpha_blend, // VkBlendFactor srcAlphaBlendFactor
|
if (state.usedualsrc && g_vulkan_context->SupportsDualSourceBlend())
|
||||||
state.dst_alpha_blend, // VkBlendFactor dstAlphaBlendFactor
|
{
|
||||||
state.alpha_blend_op, // VkBlendOp alphaBlendOp
|
static constexpr std::array<VkBlendFactor, 8> src_factors = {
|
||||||
state.write_mask // VkColorComponentFlags colorWriteMask
|
{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;
|
return vk_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VkPipelineColorBlendStateCreateInfo
|
static VkPipelineColorBlendStateCreateInfo
|
||||||
GetVulkanColorBlendState(const BlendState& state,
|
GetVulkanColorBlendState(const BlendingState& state,
|
||||||
const VkPipelineColorBlendAttachmentState* attachments,
|
const VkPipelineColorBlendAttachmentState* attachments,
|
||||||
uint32_t num_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 = {
|
VkPipelineColorBlendStateCreateInfo vk_state = {
|
||||||
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType
|
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType
|
||||||
nullptr, // const void* pNext
|
nullptr, // const void* pNext
|
||||||
0, // VkPipelineColorBlendStateCreateFlags flags
|
0, // VkPipelineColorBlendStateCreateFlags flags
|
||||||
state.logic_op_enable, // VkBool32 logicOpEnable
|
vk_logic_op_enable, // VkBool32 logicOpEnable
|
||||||
state.logic_op, // VkLogicOp logicOp
|
vk_logic_op, // VkLogicOp logicOp
|
||||||
num_attachments, // uint32_t attachmentCount
|
num_attachments, // uint32_t attachmentCount
|
||||||
attachments, // const VkPipelineColorBlendAttachmentState* pAttachments
|
attachments, // const VkPipelineColorBlendAttachmentState* pAttachments
|
||||||
{1.0f, 1.0f, 1.0f, 1.0f} // float blendConstants[4]
|
{1.0f, 1.0f, 1.0f, 1.0f} // float blendConstants[4]
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include "VideoCommon/GeometryShaderGen.h"
|
#include "VideoCommon/GeometryShaderGen.h"
|
||||||
#include "VideoCommon/PixelShaderGen.h"
|
#include "VideoCommon/PixelShaderGen.h"
|
||||||
|
#include "VideoCommon/RenderState.h"
|
||||||
#include "VideoCommon/VertexShaderGen.h"
|
#include "VideoCommon/VertexShaderGen.h"
|
||||||
|
|
||||||
namespace Vulkan
|
namespace Vulkan
|
||||||
|
@ -36,7 +37,7 @@ struct PipelineInfo
|
||||||
VkShaderModule gs;
|
VkShaderModule gs;
|
||||||
VkShaderModule ps;
|
VkShaderModule ps;
|
||||||
VkRenderPass render_pass;
|
VkRenderPass render_pass;
|
||||||
BlendState blend_state;
|
BlendingState blend_state;
|
||||||
RasterizationState rasterization_state;
|
RasterizationState rasterization_state;
|
||||||
DepthStencilState depth_stencil_state;
|
DepthStencilState depth_stencil_state;
|
||||||
VkPrimitiveTopology primitive_topology;
|
VkPrimitiveTopology primitive_topology;
|
||||||
|
|
|
@ -395,11 +395,10 @@ void RasterFont::PrintMultiLineText(VkRenderPass render_pass, const std::string&
|
||||||
draw.SetPSSampler(0, m_texture->GetView(), g_object_cache->GetLinearSampler());
|
draw.SetPSSampler(0, m_texture->GetView(), g_object_cache->GetLinearSampler());
|
||||||
|
|
||||||
// Setup alpha blending
|
// Setup alpha blending
|
||||||
BlendState blend_state = Util::GetNoBlendingBlendState();
|
BlendingState blend_state = Util::GetNoBlendingBlendState();
|
||||||
blend_state.blend_enable = VK_TRUE;
|
blend_state.blendenable = true;
|
||||||
blend_state.src_blend = VK_BLEND_FACTOR_SRC_ALPHA;
|
blend_state.srcfactor = BlendMode::SRCALPHA;
|
||||||
blend_state.blend_op = VK_BLEND_OP_ADD;
|
blend_state.dstfactor = BlendMode::INVSRCALPHA;
|
||||||
blend_state.dst_blend = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
|
||||||
draw.SetBlendState(blend_state);
|
draw.SetBlendState(blend_state);
|
||||||
|
|
||||||
draw.Draw();
|
draw.Draw();
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "VideoCommon/OnScreenDisplay.h"
|
#include "VideoCommon/OnScreenDisplay.h"
|
||||||
#include "VideoCommon/PixelEngine.h"
|
#include "VideoCommon/PixelEngine.h"
|
||||||
#include "VideoCommon/PixelShaderManager.h"
|
#include "VideoCommon/PixelShaderManager.h"
|
||||||
|
#include "VideoCommon/RenderState.h"
|
||||||
#include "VideoCommon/SamplerCommon.h"
|
#include "VideoCommon/SamplerCommon.h"
|
||||||
#include "VideoCommon/TextureCacheBase.h"
|
#include "VideoCommon/TextureCacheBase.h"
|
||||||
#include "VideoCommon/VideoBackendBase.h"
|
#include "VideoCommon/VideoBackendBase.h"
|
||||||
|
@ -432,13 +433,9 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool color_enable, bool alpha
|
||||||
StateTracker::GetInstance()->SetPendingRebind();
|
StateTracker::GetInstance()->SetPendingRebind();
|
||||||
|
|
||||||
// Mask away the appropriate colors and use a shader
|
// Mask away the appropriate colors and use a shader
|
||||||
BlendState blend_state = Util::GetNoBlendingBlendState();
|
BlendingState blend_state = Util::GetNoBlendingBlendState();
|
||||||
u32 write_mask = 0;
|
blend_state.colorupdate = color_enable;
|
||||||
if (color_enable)
|
blend_state.alphaupdate = alpha_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;
|
|
||||||
|
|
||||||
DepthStencilState depth_state = Util::GetNoDepthTestingDepthStencilState();
|
DepthStencilState depth_state = Util::GetNoDepthTestingDepthStencilState();
|
||||||
depth_state.test_enable = z_enable ? VK_TRUE : VK_FALSE;
|
depth_state.test_enable = z_enable ? VK_TRUE : VK_FALSE;
|
||||||
|
@ -1324,232 +1321,12 @@ void Renderer::SetDepthMode()
|
||||||
StateTracker::GetInstance()->SetDepthStencilState(new_ds_state);
|
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)
|
void Renderer::SetBlendMode(bool force_update)
|
||||||
{
|
{
|
||||||
BlendState new_blend_state = {};
|
BlendingState state;
|
||||||
new_blend_state.bits = StateTracker::GetInstance()->GetBlendState().bits;
|
state.Generate(bpmem);
|
||||||
|
|
||||||
// Fast path for blending disabled
|
StateTracker::GetInstance()->SetBlendState(state);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::SetSamplerState(int stage, int texindex, bool custom_tex)
|
void Renderer::SetSamplerState(int stage, int texindex, bool custom_tex)
|
||||||
|
@ -1630,10 +1407,6 @@ void Renderer::ResetSamplerStates()
|
||||||
g_object_cache->ClearSamplerCache();
|
g_object_cache->ClearSamplerCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::SetDitherMode()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::SetInterlacingMode()
|
void Renderer::SetInterlacingMode()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,13 +56,10 @@ public:
|
||||||
void ResetAPIState() override;
|
void ResetAPIState() override;
|
||||||
void RestoreAPIState() override;
|
void RestoreAPIState() override;
|
||||||
|
|
||||||
void SetColorMask() override;
|
|
||||||
void SetBlendMode(bool force_update) override;
|
void SetBlendMode(bool force_update) override;
|
||||||
void SetScissorRect(const EFBRectangle& rc) override;
|
void SetScissorRect(const EFBRectangle& rc) override;
|
||||||
void SetGenerationMode() override;
|
void SetGenerationMode() override;
|
||||||
void SetDepthMode() override;
|
void SetDepthMode() override;
|
||||||
void SetLogicOpMode() override;
|
|
||||||
void SetDitherMode() override;
|
|
||||||
void SetSamplerState(int stage, int texindex, bool custom_tex) override;
|
void SetSamplerState(int stage, int texindex, bool custom_tex) override;
|
||||||
void SetInterlacingMode() override;
|
void SetInterlacingMode() override;
|
||||||
void SetViewport() override;
|
void SetViewport() override;
|
||||||
|
|
|
@ -59,17 +59,14 @@ bool StateTracker::Initialize()
|
||||||
m_pipeline_state.depth_stencil_state.test_enable = VK_TRUE;
|
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.write_enable = VK_TRUE;
|
||||||
m_pipeline_state.depth_stencil_state.compare_op = VK_COMPARE_OP_LESS;
|
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.hex = 0;
|
||||||
m_pipeline_state.blend_state.blend_op = VK_BLEND_OP_ADD;
|
m_pipeline_state.blend_state.blendenable = false;
|
||||||
m_pipeline_state.blend_state.src_blend = VK_BLEND_FACTOR_ONE;
|
m_pipeline_state.blend_state.srcfactor = BlendMode::ONE;
|
||||||
m_pipeline_state.blend_state.dst_blend = VK_BLEND_FACTOR_ZERO;
|
m_pipeline_state.blend_state.srcfactoralpha = BlendMode::ONE;
|
||||||
m_pipeline_state.blend_state.alpha_blend_op = VK_BLEND_OP_ADD;
|
m_pipeline_state.blend_state.dstfactor = BlendMode::ZERO;
|
||||||
m_pipeline_state.blend_state.src_alpha_blend = VK_BLEND_FACTOR_ONE;
|
m_pipeline_state.blend_state.dstfactoralpha = BlendMode::ZERO;
|
||||||
m_pipeline_state.blend_state.dst_alpha_blend = VK_BLEND_FACTOR_ZERO;
|
m_pipeline_state.blend_state.colorupdate = true;
|
||||||
m_pipeline_state.blend_state.logic_op_enable = VK_FALSE;
|
m_pipeline_state.blend_state.alphaupdate = true;
|
||||||
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;
|
|
||||||
|
|
||||||
// Enable depth clamping if supported by driver.
|
// Enable depth clamping if supported by driver.
|
||||||
if (g_ActiveConfig.backend_info.bSupportsDepthClamp)
|
if (g_ActiveConfig.backend_info.bSupportsDepthClamp)
|
||||||
|
@ -144,7 +141,7 @@ void StateTracker::LoadPipelineUIDCache()
|
||||||
void StateTracker::AppendToPipelineUIDCache(const PipelineInfo& info)
|
void StateTracker::AppendToPipelineUIDCache(const PipelineInfo& info)
|
||||||
{
|
{
|
||||||
SerializedPipelineUID sinfo;
|
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.rasterizer_state_bits = info.rasterization_state.bits;
|
||||||
sinfo.depth_stencil_state_bits = info.depth_stencil_state.bits;
|
sinfo.depth_stencil_state_bits = info.depth_stencil_state.bits;
|
||||||
sinfo.vertex_decl = m_pipeline_state.vertex_format->GetVertexDeclaration();
|
sinfo.vertex_decl = m_pipeline_state.vertex_format->GetVertexDeclaration();
|
||||||
|
@ -189,9 +186,9 @@ bool StateTracker::PrecachePipelineUID(const SerializedPipelineUID& uid)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pinfo.render_pass = m_load_render_pass;
|
pinfo.render_pass = m_load_render_pass;
|
||||||
pinfo.blend_state.bits = uid.blend_state_bits;
|
|
||||||
pinfo.rasterization_state.bits = uid.rasterizer_state_bits;
|
pinfo.rasterization_state.bits = uid.rasterizer_state_bits;
|
||||||
pinfo.depth_stencil_state.bits = uid.depth_stencil_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;
|
pinfo.primitive_topology = uid.primitive_topology;
|
||||||
|
|
||||||
VkPipeline pipeline = g_object_cache->GetPipeline(pinfo);
|
VkPipeline pipeline = g_object_cache->GetPipeline(pinfo);
|
||||||
|
@ -295,12 +292,12 @@ void StateTracker::SetDepthStencilState(const DepthStencilState& state)
|
||||||
m_dirty_flags |= DIRTY_FLAG_PIPELINE;
|
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;
|
return;
|
||||||
|
|
||||||
m_pipeline_state.blend_state.bits = state.bits;
|
m_pipeline_state.blend_state.hex = state.hex;
|
||||||
m_dirty_flags |= DIRTY_FLAG_PIPELINE;
|
m_dirty_flags |= DIRTY_FLAG_PIPELINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
{
|
{
|
||||||
return m_pipeline_state.depth_stencil_state;
|
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 SetVertexBuffer(VkBuffer buffer, VkDeviceSize offset);
|
||||||
void SetIndexBuffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType type);
|
void SetIndexBuffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType type);
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ public:
|
||||||
|
|
||||||
void SetRasterizationState(const RasterizationState& state);
|
void SetRasterizationState(const RasterizationState& state);
|
||||||
void SetDepthStencilState(const DepthStencilState& state);
|
void SetDepthStencilState(const DepthStencilState& state);
|
||||||
void SetBlendState(const BlendState& state);
|
void SetBlendState(const BlendingState& state);
|
||||||
|
|
||||||
bool CheckForShaderChanges(u32 gx_primitive_type);
|
bool CheckForShaderChanges(u32 gx_primitive_type);
|
||||||
|
|
||||||
|
@ -123,9 +123,9 @@ private:
|
||||||
// Serialized version of PipelineInfo, used when loading/saving the pipeline UID cache.
|
// Serialized version of PipelineInfo, used when loading/saving the pipeline UID cache.
|
||||||
struct SerializedPipelineUID
|
struct SerializedPipelineUID
|
||||||
{
|
{
|
||||||
u64 blend_state_bits;
|
|
||||||
u32 rasterizer_state_bits;
|
u32 rasterizer_state_bits;
|
||||||
u32 depth_stencil_state_bits;
|
u32 depth_stencil_state_bits;
|
||||||
|
u32 blend_state_bits;
|
||||||
PortableVertexDeclaration vertex_decl;
|
PortableVertexDeclaration vertex_decl;
|
||||||
VertexShaderUid vs_uid;
|
VertexShaderUid vs_uid;
|
||||||
GeometryShaderUid gs_uid;
|
GeometryShaderUid gs_uid;
|
||||||
|
|
|
@ -143,20 +143,17 @@ DepthStencilState GetNoDepthTestingDepthStencilState()
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlendState GetNoBlendingBlendState()
|
BlendingState GetNoBlendingBlendState()
|
||||||
{
|
{
|
||||||
BlendState state = {};
|
BlendingState state = {};
|
||||||
state.blend_enable = VK_FALSE;
|
state.blendenable = false;
|
||||||
state.blend_op = VK_BLEND_OP_ADD;
|
state.srcfactor = BlendMode::ONE;
|
||||||
state.src_blend = VK_BLEND_FACTOR_ONE;
|
state.srcfactoralpha = BlendMode::ZERO;
|
||||||
state.dst_blend = VK_BLEND_FACTOR_ZERO;
|
state.dstfactor = BlendMode::ONE;
|
||||||
state.alpha_blend_op = VK_BLEND_OP_ADD;
|
state.dstfactoralpha = BlendMode::ZERO;
|
||||||
state.src_alpha_blend = VK_BLEND_FACTOR_ONE;
|
state.logicopenable = false;
|
||||||
state.dst_alpha_blend = VK_BLEND_FACTOR_ZERO;
|
state.colorupdate = true;
|
||||||
state.logic_op_enable = VK_FALSE;
|
state.alphaupdate = true;
|
||||||
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;
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +286,7 @@ UtilityShaderDraw::UtilityShaderDraw(VkCommandBuffer command_buffer,
|
||||||
m_pipeline_info.ps = pixel_shader;
|
m_pipeline_info.ps = pixel_shader;
|
||||||
m_pipeline_info.rasterization_state.bits = Util::GetNoCullRasterizationState().bits;
|
m_pipeline_info.rasterization_state.bits = Util::GetNoCullRasterizationState().bits;
|
||||||
m_pipeline_info.depth_stencil_state.bits = Util::GetNoDepthTestingDepthStencilState().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;
|
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;
|
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,
|
void UtilityShaderDraw::BeginRenderPass(VkFramebuffer framebuffer, const VkRect2D& region,
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "VideoBackends/Vulkan/Constants.h"
|
#include "VideoBackends/Vulkan/Constants.h"
|
||||||
#include "VideoBackends/Vulkan/ObjectCache.h"
|
#include "VideoBackends/Vulkan/ObjectCache.h"
|
||||||
|
#include "VideoCommon/RenderState.h"
|
||||||
|
|
||||||
namespace Vulkan
|
namespace Vulkan
|
||||||
{
|
{
|
||||||
|
@ -35,7 +36,7 @@ VkBlendFactor GetAlphaBlendFactor(VkBlendFactor factor);
|
||||||
|
|
||||||
RasterizationState GetNoCullRasterizationState();
|
RasterizationState GetNoCullRasterizationState();
|
||||||
DepthStencilState GetNoDepthTestingDepthStencilState();
|
DepthStencilState GetNoDepthTestingDepthStencilState();
|
||||||
BlendState GetNoBlendingBlendState();
|
BlendingState GetNoBlendingBlendState();
|
||||||
|
|
||||||
// Combines viewport and scissor updates
|
// Combines viewport and scissor updates
|
||||||
void SetViewportAndScissor(VkCommandBuffer command_buffer, int x, int y, int width, int height,
|
void SetViewportAndScissor(VkCommandBuffer command_buffer, int x, int y, int width, int height,
|
||||||
|
@ -147,7 +148,7 @@ public:
|
||||||
|
|
||||||
void SetRasterizationState(const RasterizationState& state);
|
void SetRasterizationState(const RasterizationState& state);
|
||||||
void SetDepthStencilState(const DepthStencilState& state);
|
void SetDepthStencilState(const DepthStencilState& state);
|
||||||
void SetBlendState(const BlendState& state);
|
void SetBlendState(const BlendingState& state);
|
||||||
|
|
||||||
void BeginRenderPass(VkFramebuffer framebuffer, const VkRect2D& region,
|
void BeginRenderPass(VkFramebuffer framebuffer, const VkRect2D& region,
|
||||||
const VkClearValue* clear_value = nullptr);
|
const VkClearValue* clear_value = nullptr);
|
||||||
|
|
|
@ -74,10 +74,7 @@ void SetBlendMode()
|
||||||
{
|
{
|
||||||
g_renderer->SetBlendMode(false);
|
g_renderer->SetBlendMode(false);
|
||||||
}
|
}
|
||||||
void SetDitherMode()
|
|
||||||
{
|
|
||||||
g_renderer->SetDitherMode();
|
|
||||||
}
|
|
||||||
void SetLogicOpMode()
|
void SetLogicOpMode()
|
||||||
{
|
{
|
||||||
g_renderer->SetLogicOpMode();
|
g_renderer->SetLogicOpMode();
|
||||||
|
|
|
@ -19,7 +19,6 @@ void SetGenerationMode();
|
||||||
void SetScissor();
|
void SetScissor();
|
||||||
void SetDepthMode();
|
void SetDepthMode();
|
||||||
void SetBlendMode();
|
void SetBlendMode();
|
||||||
void SetDitherMode();
|
|
||||||
void SetLogicOpMode();
|
void SetLogicOpMode();
|
||||||
void SetColorMask();
|
void SetColorMask();
|
||||||
void ClearScreen(const EFBRectangle& rc);
|
void ClearScreen(const EFBRectangle& rc);
|
||||||
|
|
|
@ -152,10 +152,6 @@ static void BPWritten(const BPCmd& bp)
|
||||||
if (bp.changes & 0xF002) // logicopenable | logicmode
|
if (bp.changes & 0xF002) // logicopenable | logicmode
|
||||||
SetLogicOpMode();
|
SetLogicOpMode();
|
||||||
|
|
||||||
// Set Dithering Mode
|
|
||||||
if (bp.changes & 4) // dither
|
|
||||||
SetDitherMode();
|
|
||||||
|
|
||||||
// Set Color Mask
|
// Set Color Mask
|
||||||
if (bp.changes & 0x18) // colorupdate | alphaupdate
|
if (bp.changes & 0x18) // colorupdate | alphaupdate
|
||||||
SetColorMask();
|
SetColorMask();
|
||||||
|
@ -1383,7 +1379,6 @@ void BPReload()
|
||||||
SetScissor();
|
SetScissor();
|
||||||
SetDepthMode();
|
SetDepthMode();
|
||||||
SetLogicOpMode();
|
SetLogicOpMode();
|
||||||
SetDitherMode();
|
|
||||||
SetBlendMode();
|
SetBlendMode();
|
||||||
SetColorMask();
|
SetColorMask();
|
||||||
OnPixelFormatChange();
|
OnPixelFormatChange();
|
||||||
|
|
|
@ -69,7 +69,6 @@ public:
|
||||||
virtual void SetGenerationMode() {}
|
virtual void SetGenerationMode() {}
|
||||||
virtual void SetDepthMode() {}
|
virtual void SetDepthMode() {}
|
||||||
virtual void SetLogicOpMode() {}
|
virtual void SetLogicOpMode() {}
|
||||||
virtual void SetDitherMode() {}
|
|
||||||
virtual void SetSamplerState(int stage, int texindex, bool custom_tex) {}
|
virtual void SetSamplerState(int stage, int texindex, bool custom_tex) {}
|
||||||
virtual void SetInterlacingMode() {}
|
virtual void SetInterlacingMode() {}
|
||||||
virtual void SetViewport() {}
|
virtual void SetViewport() {}
|
||||||
|
|
|
@ -61,10 +61,10 @@ void BlendingState::Generate(const BPMemory& bp)
|
||||||
bool target_has_alpha = bp.zcontrol.pixel_format == PEControl::RGBA6_Z24;
|
bool target_has_alpha = bp.zcontrol.pixel_format == PEControl::RGBA6_Z24;
|
||||||
bool alpha_test_may_success = bp.alpha_test.TestResult() != AlphaTest::FAIL;
|
bool alpha_test_may_success = bp.alpha_test.TestResult() != AlphaTest::FAIL;
|
||||||
|
|
||||||
dither = bp.blendmode.dither;
|
|
||||||
colorupdate = bp.blendmode.colorupdate && alpha_test_may_success;
|
colorupdate = bp.blendmode.colorupdate && alpha_test_may_success;
|
||||||
alphaupdate = bp.blendmode.alphaupdate && target_has_alpha && alpha_test_may_success;
|
alphaupdate = bp.blendmode.alphaupdate && target_has_alpha && alpha_test_may_success;
|
||||||
dstalpha = bp.dstalpha.enable && alphaupdate;
|
dstalpha = bp.dstalpha.enable && alphaupdate;
|
||||||
|
usedualsrc = true;
|
||||||
|
|
||||||
// The subtract bit has the highest priority
|
// The subtract bit has the highest priority
|
||||||
if (bp.blendmode.subtract)
|
if (bp.blendmode.subtract)
|
||||||
|
|
|
@ -16,11 +16,11 @@ union BlendingState
|
||||||
BitField<0, 1, u32> blendenable;
|
BitField<0, 1, u32> blendenable;
|
||||||
BitField<1, 1, u32> logicopenable;
|
BitField<1, 1, u32> logicopenable;
|
||||||
BitField<2, 1, u32> dstalpha;
|
BitField<2, 1, u32> dstalpha;
|
||||||
BitField<3, 1, u32> dither;
|
BitField<3, 1, u32> colorupdate;
|
||||||
BitField<4, 1, u32> colorupdate;
|
BitField<4, 1, u32> alphaupdate;
|
||||||
BitField<5, 1, u32> alphaupdate;
|
BitField<5, 1, u32> subtract;
|
||||||
BitField<6, 1, u32> subtract;
|
BitField<6, 1, u32> subtractAlpha;
|
||||||
BitField<7, 1, u32> subtractAlpha;
|
BitField<7, 1, u32> usedualsrc;
|
||||||
BitField<8, 3, BlendMode::BlendFactor> dstfactor;
|
BitField<8, 3, BlendMode::BlendFactor> dstfactor;
|
||||||
BitField<11, 3, BlendMode::BlendFactor> srcfactor;
|
BitField<11, 3, BlendMode::BlendFactor> srcfactor;
|
||||||
BitField<14, 3, BlendMode::BlendFactor> dstfactoralpha;
|
BitField<14, 3, BlendMode::BlendFactor> dstfactoralpha;
|
||||||
|
|
Loading…
Reference in New Issue