renderer_vulkan: Support additional dynamic states
This commit is contained in:
@ -38,7 +38,7 @@ static inline u64 ComputeStructHash64(const T& data) noexcept {
|
|||||||
* Combines the seed parameter with the provided hash, producing a new unique hash
|
* Combines the seed parameter with the provided hash, producing a new unique hash
|
||||||
* Implementation from: http://boost.sourceforge.net/doc/html/boost/hash_combine.html
|
* Implementation from: http://boost.sourceforge.net/doc/html/boost/hash_combine.html
|
||||||
*/
|
*/
|
||||||
inline u64 HashCombine(std::size_t& seed, const u64 hash) {
|
inline u64 HashCombine(std::size_t seed, const u64 hash) {
|
||||||
return seed ^= hash + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
return seed ^= hash + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <boost/container/static_vector.hpp>
|
||||||
#include "common/common_paths.h"
|
#include "common/common_paths.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
@ -59,6 +60,37 @@ vk::ShaderStageFlagBits MakeShaderStage(std::size_t index) {
|
|||||||
return vk::ShaderStageFlagBits::eVertex;
|
return vk::ShaderStageFlagBits::eVertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 PipelineInfo::Hash(const Instance& instance) const {
|
||||||
|
u64 info_hash = 0;
|
||||||
|
const auto AppendHash = [&info_hash](const auto& data) {
|
||||||
|
const u64 data_hash = Common::ComputeStructHash64(data);
|
||||||
|
info_hash = Common::HashCombine(info_hash, data_hash);
|
||||||
|
};
|
||||||
|
|
||||||
|
AppendHash(vertex_layout);
|
||||||
|
AppendHash(attachments);
|
||||||
|
|
||||||
|
if (!instance.IsExtendedDynamicStateSupported()) {
|
||||||
|
AppendHash(rasterization);
|
||||||
|
AppendHash(depth_stencil);
|
||||||
|
}
|
||||||
|
if (!instance.IsExtendedDynamicState2Supported()) {
|
||||||
|
AppendHash(blending.logic_op);
|
||||||
|
}
|
||||||
|
if (!instance.IsExtendedDynamicState3LogicOpSupported() ||
|
||||||
|
!instance.IsExtendedDynamicState3BlendEnableSupported()) {
|
||||||
|
AppendHash(blending.blend_enable);
|
||||||
|
}
|
||||||
|
if (!instance.IsExtendedDynamicState3BlendEqSupported()) {
|
||||||
|
AppendHash(blending.value);
|
||||||
|
}
|
||||||
|
if (!instance.IsExtendedDynamicState3ColorMaskSupported()) {
|
||||||
|
AppendHash(blending.color_write_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
return info_hash;
|
||||||
|
}
|
||||||
|
|
||||||
PipelineCache::Shader::Shader(const Instance& instance) : device{instance.GetDevice()} {}
|
PipelineCache::Shader::Shader(const Instance& instance) : device{instance.GetDevice()} {}
|
||||||
|
|
||||||
PipelineCache::Shader::Shader(const Instance& instance, vk::ShaderStageFlagBits stage,
|
PipelineCache::Shader::Shader(const Instance& instance, vk::ShaderStageFlagBits stage,
|
||||||
@ -80,8 +112,8 @@ PipelineCache::GraphicsPipeline::GraphicsPipeline(
|
|||||||
Common::ThreadWorker* worker_)
|
Common::ThreadWorker* worker_)
|
||||||
: instance{instance_}, worker{worker_}, pipeline_layout{layout_},
|
: instance{instance_}, worker{worker_}, pipeline_layout{layout_},
|
||||||
pipeline_cache{pipeline_cache_}, info{info_}, stages{stages_},
|
pipeline_cache{pipeline_cache_}, info{info_}, stages{stages_},
|
||||||
renderpass{
|
renderpass{renderpass_cache_.GetRenderpass(info.attachments.color_format,
|
||||||
renderpass_cache_.GetRenderpass(info.color_attachment, info.depth_attachment, false)} {
|
info.attachments.depth_format, false)} {
|
||||||
|
|
||||||
// Ask the driver if it can give us the pipeline quickly
|
// Ask the driver if it can give us the pipeline quickly
|
||||||
if (Build(true)) {
|
if (Build(true)) {
|
||||||
@ -170,7 +202,7 @@ bool PipelineCache::GraphicsPipeline::Build(bool fail_on_compile_required) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const vk::PipelineColorBlendAttachmentState colorblend_attachment = {
|
const vk::PipelineColorBlendAttachmentState colorblend_attachment = {
|
||||||
.blendEnable = info.blending.blend_enable.Value(),
|
.blendEnable = info.blending.blend_enable,
|
||||||
.srcColorBlendFactor = PicaToVK::BlendFunc(info.blending.src_color_blend_factor),
|
.srcColorBlendFactor = PicaToVK::BlendFunc(info.blending.src_color_blend_factor),
|
||||||
.dstColorBlendFactor = PicaToVK::BlendFunc(info.blending.dst_color_blend_factor),
|
.dstColorBlendFactor = PicaToVK::BlendFunc(info.blending.dst_color_blend_factor),
|
||||||
.colorBlendOp = PicaToVK::BlendEquation(info.blending.color_blend_eq),
|
.colorBlendOp = PicaToVK::BlendEquation(info.blending.color_blend_eq),
|
||||||
@ -181,8 +213,8 @@ bool PipelineCache::GraphicsPipeline::Build(bool fail_on_compile_required) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const vk::PipelineColorBlendStateCreateInfo color_blending = {
|
const vk::PipelineColorBlendStateCreateInfo color_blending = {
|
||||||
.logicOpEnable = !info.blending.blend_enable.Value() && !instance.NeedsLogicOpEmulation(),
|
.logicOpEnable = !info.blending.blend_enable && !instance.NeedsLogicOpEmulation(),
|
||||||
.logicOp = PicaToVK::LogicOp(info.blending.logic_op.Value()),
|
.logicOp = PicaToVK::LogicOp(info.blending.logic_op),
|
||||||
.attachmentCount = 1,
|
.attachmentCount = 1,
|
||||||
.pAttachments = &colorblend_attachment,
|
.pAttachments = &colorblend_attachment,
|
||||||
.blendConstants = std::array{1.0f, 1.0f, 1.0f, 1.0f},
|
.blendConstants = std::array{1.0f, 1.0f, 1.0f, 1.0f},
|
||||||
@ -209,27 +241,39 @@ bool PipelineCache::GraphicsPipeline::Build(bool fail_on_compile_required) {
|
|||||||
.pScissors = &scissor,
|
.pScissors = &scissor,
|
||||||
};
|
};
|
||||||
|
|
||||||
const bool extended_dynamic_states = instance.IsExtendedDynamicStateSupported();
|
boost::container::static_vector<vk::DynamicState, 20> dynamic_states = {
|
||||||
const std::array dynamic_states = {
|
vk::DynamicState::eViewport, vk::DynamicState::eScissor,
|
||||||
vk::DynamicState::eViewport,
|
vk::DynamicState::eStencilCompareMask, vk::DynamicState::eStencilWriteMask,
|
||||||
vk::DynamicState::eScissor,
|
vk::DynamicState::eStencilReference, vk::DynamicState::eBlendConstants,
|
||||||
vk::DynamicState::eStencilCompareMask,
|
|
||||||
vk::DynamicState::eStencilWriteMask,
|
|
||||||
vk::DynamicState::eStencilReference,
|
|
||||||
vk::DynamicState::eBlendConstants,
|
|
||||||
// VK_EXT_extended_dynamic_state
|
|
||||||
vk::DynamicState::eCullModeEXT,
|
|
||||||
vk::DynamicState::eDepthCompareOpEXT,
|
|
||||||
vk::DynamicState::eDepthTestEnableEXT,
|
|
||||||
vk::DynamicState::eDepthWriteEnableEXT,
|
|
||||||
vk::DynamicState::eFrontFaceEXT,
|
|
||||||
vk::DynamicState::ePrimitiveTopologyEXT,
|
|
||||||
vk::DynamicState::eStencilOpEXT,
|
|
||||||
vk::DynamicState::eStencilTestEnableEXT,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (instance.IsExtendedDynamicStateSupported()) {
|
||||||
|
constexpr std::array extended = {
|
||||||
|
vk::DynamicState::eCullModeEXT, vk::DynamicState::eDepthCompareOpEXT,
|
||||||
|
vk::DynamicState::eDepthTestEnableEXT, vk::DynamicState::eDepthWriteEnableEXT,
|
||||||
|
vk::DynamicState::eFrontFaceEXT, vk::DynamicState::ePrimitiveTopologyEXT,
|
||||||
|
vk::DynamicState::eStencilOpEXT, vk::DynamicState::eStencilTestEnableEXT,
|
||||||
|
};
|
||||||
|
dynamic_states.insert(dynamic_states.end(), extended.begin(), extended.end());
|
||||||
|
}
|
||||||
|
if (instance.IsExtendedDynamicState2Supported()) {
|
||||||
|
dynamic_states.push_back(vk::DynamicState::eLogicOpEXT);
|
||||||
|
}
|
||||||
|
if (instance.IsExtendedDynamicState3LogicOpSupported()) {
|
||||||
|
dynamic_states.push_back(vk::DynamicState::eLogicOpEnableEXT);
|
||||||
|
}
|
||||||
|
if (instance.IsExtendedDynamicState3BlendEnableSupported()) {
|
||||||
|
dynamic_states.push_back(vk::DynamicState::eColorBlendEnableEXT);
|
||||||
|
}
|
||||||
|
if (instance.IsExtendedDynamicState3BlendEqSupported()) {
|
||||||
|
dynamic_states.push_back(vk::DynamicState::eColorBlendEquationEXT);
|
||||||
|
}
|
||||||
|
if (instance.IsExtendedDynamicState3ColorMaskSupported()) {
|
||||||
|
dynamic_states.push_back(vk::DynamicState::eColorWriteMaskEXT);
|
||||||
|
}
|
||||||
|
|
||||||
const vk::PipelineDynamicStateCreateInfo dynamic_info = {
|
const vk::PipelineDynamicStateCreateInfo dynamic_info = {
|
||||||
.dynamicStateCount = extended_dynamic_states ? static_cast<u32>(dynamic_states.size()) : 6u,
|
.dynamicStateCount = static_cast<u32>(dynamic_states.size()),
|
||||||
.pDynamicStates = dynamic_states.data(),
|
.pDynamicStates = dynamic_states.data(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -393,17 +437,14 @@ void PipelineCache::SaveDiskCache() {
|
|||||||
MICROPROFILE_DEFINE(Vulkan_Bind, "Vulkan", "Pipeline Bind", MP_RGB(192, 32, 32));
|
MICROPROFILE_DEFINE(Vulkan_Bind, "Vulkan", "Pipeline Bind", MP_RGB(192, 32, 32));
|
||||||
bool PipelineCache::BindPipeline(const PipelineInfo& info, bool wait_built) {
|
bool PipelineCache::BindPipeline(const PipelineInfo& info, bool wait_built) {
|
||||||
MICROPROFILE_SCOPE(Vulkan_Bind);
|
MICROPROFILE_SCOPE(Vulkan_Bind);
|
||||||
std::size_t shader_hash = 0;
|
|
||||||
|
u64 shader_hash = 0;
|
||||||
for (u32 i = 0; i < MAX_SHADER_STAGES; i++) {
|
for (u32 i = 0; i < MAX_SHADER_STAGES; i++) {
|
||||||
shader_hash = Common::HashCombine(shader_hash, shader_hashes[i]);
|
shader_hash = Common::HashCombine(shader_hash, shader_hashes[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const u64 info_hash_size = instance.IsExtendedDynamicStateSupported()
|
const u64 info_hash = info.Hash(instance);
|
||||||
? offsetof(PipelineInfo, rasterization)
|
const u64 pipeline_hash = Common::HashCombine(shader_hash, info_hash);
|
||||||
: offsetof(PipelineInfo, dynamic);
|
|
||||||
|
|
||||||
u64 info_hash = Common::ComputeHash64(&info, info_hash_size);
|
|
||||||
u64 pipeline_hash = Common::HashCombine(shader_hash, info_hash);
|
|
||||||
|
|
||||||
auto [it, new_pipeline] = graphics_pipelines.try_emplace(pipeline_hash);
|
auto [it, new_pipeline] = graphics_pipelines.try_emplace(pipeline_hash);
|
||||||
if (new_pipeline) {
|
if (new_pipeline) {
|
||||||
@ -611,12 +652,6 @@ void PipelineCache::SetScissor(s32 x, s32 y, u32 width, u32 height) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PipelineCache::ApplyDynamic(const PipelineInfo& info, bool is_dirty) {
|
void PipelineCache::ApplyDynamic(const PipelineInfo& info, bool is_dirty) {
|
||||||
if (!is_dirty && info.dynamic == current_info.dynamic &&
|
|
||||||
info.rasterization.value == current_info.rasterization.value &&
|
|
||||||
info.depth_stencil.value == current_info.depth_stencil.value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler.Record([is_dirty, current_dynamic = current_info.dynamic,
|
scheduler.Record([is_dirty, current_dynamic = current_info.dynamic,
|
||||||
dynamic = info.dynamic](vk::CommandBuffer cmdbuf) {
|
dynamic = info.dynamic](vk::CommandBuffer cmdbuf) {
|
||||||
if (dynamic.stencil_compare_mask != current_dynamic.stencil_compare_mask || is_dirty) {
|
if (dynamic.stencil_compare_mask != current_dynamic.stencil_compare_mask || is_dirty) {
|
||||||
@ -689,6 +724,61 @@ void PipelineCache::ApplyDynamic(const PipelineInfo& info, bool is_dirty) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (instance.IsExtendedDynamicState2Supported()) {
|
||||||
|
scheduler.Record(
|
||||||
|
[is_dirty, logic_op = info.blending.logic_op,
|
||||||
|
current_logic_op = current_info.blending.logic_op](vk::CommandBuffer cmdbuf) {
|
||||||
|
if (logic_op != current_logic_op || is_dirty) {
|
||||||
|
cmdbuf.setLogicOpEXT(PicaToVK::LogicOp(logic_op));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance.IsExtendedDynamicState3LogicOpSupported() && !instance.NeedsLogicOpEmulation()) {
|
||||||
|
scheduler.Record(
|
||||||
|
[is_dirty, blend_enable = info.blending.blend_enable,
|
||||||
|
current_blend_enable = current_info.blending.blend_enable](vk::CommandBuffer cmdbuf) {
|
||||||
|
if (blend_enable != current_blend_enable || is_dirty) {
|
||||||
|
cmdbuf.setLogicOpEnableEXT(!blend_enable);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (instance.IsExtendedDynamicState3BlendEnableSupported()) {
|
||||||
|
scheduler.Record(
|
||||||
|
[is_dirty, blend_enable = info.blending.blend_enable,
|
||||||
|
current_blend_enable = current_info.blending.blend_enable](vk::CommandBuffer cmdbuf) {
|
||||||
|
if (blend_enable != current_blend_enable || is_dirty) {
|
||||||
|
cmdbuf.setColorBlendEnableEXT(0, blend_enable);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (instance.IsExtendedDynamicState3BlendEqSupported()) {
|
||||||
|
scheduler.Record([is_dirty, blending = info.blending,
|
||||||
|
current_blending = current_info.blending](vk::CommandBuffer cmdbuf) {
|
||||||
|
if (blending.value != current_blending.value || is_dirty) {
|
||||||
|
const vk::ColorBlendEquationEXT blend_info = {
|
||||||
|
.srcColorBlendFactor = PicaToVK::BlendFunc(blending.src_color_blend_factor),
|
||||||
|
.dstColorBlendFactor = PicaToVK::BlendFunc(blending.dst_color_blend_factor),
|
||||||
|
.colorBlendOp = PicaToVK::BlendEquation(blending.color_blend_eq),
|
||||||
|
.srcAlphaBlendFactor = PicaToVK::BlendFunc(blending.src_alpha_blend_factor),
|
||||||
|
.dstAlphaBlendFactor = PicaToVK::BlendFunc(blending.dst_alpha_blend_factor),
|
||||||
|
.alphaBlendOp = PicaToVK::BlendEquation(blending.alpha_blend_eq),
|
||||||
|
};
|
||||||
|
|
||||||
|
cmdbuf.setColorBlendEquationEXT(0, blend_info);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (instance.IsExtendedDynamicState3ColorMaskSupported()) {
|
||||||
|
scheduler.Record([is_dirty, color_mask = info.blending.color_write_mask,
|
||||||
|
current_color_mask =
|
||||||
|
current_info.blending.color_write_mask](vk::CommandBuffer cmdbuf) {
|
||||||
|
if (color_mask != current_color_mask || is_dirty) {
|
||||||
|
cmdbuf.setColorWriteMaskEXT(0, static_cast<vk::ColorComponentFlags>(color_mask));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
current_info = info;
|
current_info = info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,17 +45,19 @@ union DepthStencilState {
|
|||||||
BitField<15, 3, Pica::FramebufferRegs::CompareFunc> stencil_compare_op;
|
BitField<15, 3, Pica::FramebufferRegs::CompareFunc> stencil_compare_op;
|
||||||
};
|
};
|
||||||
|
|
||||||
union BlendingState {
|
struct BlendingState {
|
||||||
|
u16 blend_enable;
|
||||||
|
u16 color_write_mask;
|
||||||
|
Pica::FramebufferRegs::LogicOp logic_op;
|
||||||
|
union {
|
||||||
u32 value = 0;
|
u32 value = 0;
|
||||||
BitField<0, 1, u32> blend_enable;
|
BitField<0, 4, Pica::FramebufferRegs::BlendFactor> src_color_blend_factor;
|
||||||
BitField<1, 4, Pica::FramebufferRegs::BlendFactor> src_color_blend_factor;
|
BitField<4, 4, Pica::FramebufferRegs::BlendFactor> dst_color_blend_factor;
|
||||||
BitField<5, 4, Pica::FramebufferRegs::BlendFactor> dst_color_blend_factor;
|
BitField<8, 3, Pica::FramebufferRegs::BlendEquation> color_blend_eq;
|
||||||
BitField<9, 3, Pica::FramebufferRegs::BlendEquation> color_blend_eq;
|
BitField<11, 4, Pica::FramebufferRegs::BlendFactor> src_alpha_blend_factor;
|
||||||
BitField<12, 4, Pica::FramebufferRegs::BlendFactor> src_alpha_blend_factor;
|
BitField<15, 4, Pica::FramebufferRegs::BlendFactor> dst_alpha_blend_factor;
|
||||||
BitField<16, 4, Pica::FramebufferRegs::BlendFactor> dst_alpha_blend_factor;
|
BitField<19, 3, Pica::FramebufferRegs::BlendEquation> alpha_blend_eq;
|
||||||
BitField<20, 3, Pica::FramebufferRegs::BlendEquation> alpha_blend_eq;
|
};
|
||||||
BitField<23, 4, u32> color_write_mask;
|
|
||||||
BitField<27, 4, Pica::FramebufferRegs::LogicOp> logic_op;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DynamicState {
|
struct DynamicState {
|
||||||
@ -90,20 +92,27 @@ struct VertexLayout {
|
|||||||
std::array<VertexAttribute, MAX_VERTEX_ATTRIBUTES> attributes;
|
std::array<VertexAttribute, MAX_VERTEX_ATTRIBUTES> attributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AttachmentInfo {
|
||||||
|
VideoCore::PixelFormat color_format;
|
||||||
|
VideoCore::PixelFormat depth_format;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information about a graphics/compute pipeline
|
* Information about a graphics/compute pipeline
|
||||||
*/
|
*/
|
||||||
struct PipelineInfo {
|
struct PipelineInfo {
|
||||||
VertexLayout vertex_layout{};
|
VertexLayout vertex_layout{};
|
||||||
BlendingState blending{};
|
BlendingState blending{};
|
||||||
VideoCore::PixelFormat color_attachment = VideoCore::PixelFormat::RGBA8;
|
AttachmentInfo attachments{};
|
||||||
VideoCore::PixelFormat depth_attachment = VideoCore::PixelFormat::D24S8;
|
|
||||||
RasterizationState rasterization{};
|
RasterizationState rasterization{};
|
||||||
DepthStencilState depth_stencil{};
|
DepthStencilState depth_stencil{};
|
||||||
DynamicState dynamic;
|
DynamicState dynamic;
|
||||||
|
|
||||||
|
/// Returns the hash of the info structure
|
||||||
|
u64 Hash(const Instance& instance) const;
|
||||||
|
|
||||||
[[nodiscard]] bool IsDepthWriteEnabled() const noexcept {
|
[[nodiscard]] bool IsDepthWriteEnabled() const noexcept {
|
||||||
const bool has_stencil = depth_attachment == VideoCore::PixelFormat::D24S8;
|
const bool has_stencil = attachments.depth_format == VideoCore::PixelFormat::D24S8;
|
||||||
const bool depth_write =
|
const bool depth_write =
|
||||||
depth_stencil.depth_test_enable && depth_stencil.depth_write_enable;
|
depth_stencil.depth_test_enable && depth_stencil.depth_write_enable;
|
||||||
const bool stencil_write =
|
const bool stencil_write =
|
||||||
|
@ -467,7 +467,7 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) {
|
|||||||
const bool shadow_rendering = regs.framebuffer.IsShadowRendering();
|
const bool shadow_rendering = regs.framebuffer.IsShadowRendering();
|
||||||
const bool has_stencil = regs.framebuffer.HasStencil();
|
const bool has_stencil = regs.framebuffer.HasStencil();
|
||||||
|
|
||||||
const bool write_color_fb = shadow_rendering || pipeline_info.blending.color_write_mask.Value();
|
const bool write_color_fb = shadow_rendering || pipeline_info.blending.color_write_mask;
|
||||||
const bool write_depth_fb = pipeline_info.IsDepthWriteEnabled();
|
const bool write_depth_fb = pipeline_info.IsDepthWriteEnabled();
|
||||||
const bool using_color_fb =
|
const bool using_color_fb =
|
||||||
regs.framebuffer.framebuffer.GetColorBufferPhysicalAddress() != 0 && write_color_fb;
|
regs.framebuffer.framebuffer.GetColorBufferPhysicalAddress() != 0 && write_color_fb;
|
||||||
@ -485,9 +485,9 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline_info.color_attachment =
|
pipeline_info.attachments.color_format =
|
||||||
color_surface ? color_surface->pixel_format : VideoCore::PixelFormat::Invalid;
|
color_surface ? color_surface->pixel_format : VideoCore::PixelFormat::Invalid;
|
||||||
pipeline_info.depth_attachment =
|
pipeline_info.attachments.depth_format =
|
||||||
depth_surface ? depth_surface->pixel_format : VideoCore::PixelFormat::Invalid;
|
depth_surface ? depth_surface->pixel_format : VideoCore::PixelFormat::Invalid;
|
||||||
|
|
||||||
const u16 res_scale = color_surface != nullptr
|
const u16 res_scale = color_surface != nullptr
|
||||||
@ -693,8 +693,8 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) {
|
|||||||
const FramebufferInfo framebuffer_info = {
|
const FramebufferInfo framebuffer_info = {
|
||||||
.color = color_surface ? color_surface->GetFramebufferView() : VK_NULL_HANDLE,
|
.color = color_surface ? color_surface->GetFramebufferView() : VK_NULL_HANDLE,
|
||||||
.depth = depth_surface ? depth_surface->GetFramebufferView() : VK_NULL_HANDLE,
|
.depth = depth_surface ? depth_surface->GetFramebufferView() : VK_NULL_HANDLE,
|
||||||
.renderpass = renderpass_cache.GetRenderpass(pipeline_info.color_attachment,
|
.renderpass = renderpass_cache.GetRenderpass(pipeline_info.attachments.color_format,
|
||||||
pipeline_info.depth_attachment, false),
|
pipeline_info.attachments.depth_format, false),
|
||||||
.width = width,
|
.width = width,
|
||||||
.height = height,
|
.height = height,
|
||||||
};
|
};
|
||||||
@ -1149,8 +1149,8 @@ void RasterizerVulkan::SyncCullMode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerVulkan::SyncBlendEnabled() {
|
void RasterizerVulkan::SyncBlendEnabled() {
|
||||||
pipeline_info.blending.blend_enable.Assign(
|
pipeline_info.blending.blend_enable =
|
||||||
Pica::g_state.regs.framebuffer.output_merger.alphablend_enable);
|
Pica::g_state.regs.framebuffer.output_merger.alphablend_enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerVulkan::SyncBlendFuncs() {
|
void RasterizerVulkan::SyncBlendFuncs() {
|
||||||
@ -1182,7 +1182,7 @@ void RasterizerVulkan::SyncLogicOp() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto& regs = Pica::g_state.regs;
|
const auto& regs = Pica::g_state.regs;
|
||||||
pipeline_info.blending.logic_op.Assign(regs.framebuffer.output_merger.logic_op);
|
pipeline_info.blending.logic_op = regs.framebuffer.output_merger.logic_op;
|
||||||
|
|
||||||
const bool is_logic_op_emulated =
|
const bool is_logic_op_emulated =
|
||||||
instance.NeedsLogicOpEmulation() && !regs.framebuffer.output_merger.alphablend_enable;
|
instance.NeedsLogicOpEmulation() && !regs.framebuffer.output_merger.alphablend_enable;
|
||||||
@ -1191,7 +1191,7 @@ void RasterizerVulkan::SyncLogicOp() {
|
|||||||
if (is_logic_op_emulated && is_logic_op_noop) {
|
if (is_logic_op_emulated && is_logic_op_noop) {
|
||||||
// Color output is disabled by logic operation. We use color write mask to skip
|
// Color output is disabled by logic operation. We use color write mask to skip
|
||||||
// color but allow depth write.
|
// color but allow depth write.
|
||||||
pipeline_info.blending.color_write_mask.Assign(0);
|
pipeline_info.blending.color_write_mask = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1211,7 +1211,7 @@ void RasterizerVulkan::SyncColorWriteMask() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline_info.blending.color_write_mask.Assign(color_mask);
|
pipeline_info.blending.color_write_mask = color_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerVulkan::SyncStencilWriteMask() {
|
void RasterizerVulkan::SyncStencilWriteMask() {
|
||||||
|
Reference in New Issue
Block a user