|
|
|
@ -95,71 +95,58 @@ void FixedPipelineState::Rasterizer::Fill(const Maxwell& regs) noexcept { |
|
|
|
std::memcpy(&point_size, ®s.point_size, sizeof(point_size)); // TODO: C++20 std::bit_cast
|
|
|
|
} |
|
|
|
|
|
|
|
namespace { |
|
|
|
|
|
|
|
constexpr FixedPipelineState::BlendingAttachment GetBlendingAttachmentState( |
|
|
|
const Maxwell& regs, std::size_t render_target) { |
|
|
|
const auto& mask = regs.color_mask[regs.color_mask_common ? 0 : render_target]; |
|
|
|
const std::array components = {mask.R != 0, mask.G != 0, mask.B != 0, mask.A != 0}; |
|
|
|
|
|
|
|
const FixedPipelineState::BlendingAttachment default_blending( |
|
|
|
false, Maxwell::Blend::Equation::Add, Maxwell::Blend::Factor::One, |
|
|
|
Maxwell::Blend::Factor::Zero, Maxwell::Blend::Equation::Add, Maxwell::Blend::Factor::One, |
|
|
|
Maxwell::Blend::Factor::Zero, components); |
|
|
|
if (render_target >= regs.rt_control.count) { |
|
|
|
return default_blending; |
|
|
|
void FixedPipelineState::ColorBlending::Fill(const Maxwell& regs) noexcept { |
|
|
|
for (std::size_t index = 0; index < std::size(attachments); ++index) { |
|
|
|
attachments[index].Fill(regs, index); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void FixedPipelineState::BlendingAttachment::Fill(const Maxwell& regs, std::size_t index) { |
|
|
|
const auto& mask = regs.color_mask[regs.color_mask_common ? 0 : index]; |
|
|
|
|
|
|
|
raw = 0; |
|
|
|
mask_r.Assign(mask.R); |
|
|
|
mask_g.Assign(mask.G); |
|
|
|
mask_b.Assign(mask.B); |
|
|
|
mask_a.Assign(mask.A); |
|
|
|
|
|
|
|
// TODO: C++20 Use templated lambda to deduplicate code
|
|
|
|
|
|
|
|
if (!regs.independent_blend_enable) { |
|
|
|
const auto& src = regs.blend; |
|
|
|
if (!src.enable[render_target]) { |
|
|
|
return default_blending; |
|
|
|
if (!src.enable[index]) { |
|
|
|
return; |
|
|
|
} |
|
|
|
return FixedPipelineState::BlendingAttachment( |
|
|
|
true, src.equation_rgb, src.factor_source_rgb, src.factor_dest_rgb, src.equation_a, |
|
|
|
src.factor_source_a, src.factor_dest_a, components); |
|
|
|
equation_rgb.Assign(PackBlendEquation(src.equation_rgb)); |
|
|
|
equation_a.Assign(PackBlendEquation(src.equation_a)); |
|
|
|
factor_source_rgb.Assign(PackBlendFactor(src.factor_source_rgb)); |
|
|
|
factor_dest_rgb.Assign(PackBlendFactor(src.factor_dest_rgb)); |
|
|
|
factor_source_a.Assign(PackBlendFactor(src.factor_source_a)); |
|
|
|
factor_dest_a.Assign(PackBlendFactor(src.factor_dest_a)); |
|
|
|
enable.Assign(1); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (!regs.blend.enable[render_target]) { |
|
|
|
return default_blending; |
|
|
|
if (!regs.blend.enable[index]) { |
|
|
|
return; |
|
|
|
} |
|
|
|
const auto& src = regs.independent_blend[render_target]; |
|
|
|
return FixedPipelineState::BlendingAttachment( |
|
|
|
true, src.equation_rgb, src.factor_source_rgb, src.factor_dest_rgb, src.equation_a, |
|
|
|
src.factor_source_a, src.factor_dest_a, components); |
|
|
|
} |
|
|
|
|
|
|
|
constexpr FixedPipelineState::ColorBlending GetColorBlendingState(const Maxwell& regs) { |
|
|
|
return FixedPipelineState::ColorBlending( |
|
|
|
{regs.blend_color.r, regs.blend_color.g, regs.blend_color.b, regs.blend_color.a}, |
|
|
|
regs.rt_control.count, |
|
|
|
{GetBlendingAttachmentState(regs, 0), GetBlendingAttachmentState(regs, 1), |
|
|
|
GetBlendingAttachmentState(regs, 2), GetBlendingAttachmentState(regs, 3), |
|
|
|
GetBlendingAttachmentState(regs, 4), GetBlendingAttachmentState(regs, 5), |
|
|
|
GetBlendingAttachmentState(regs, 6), GetBlendingAttachmentState(regs, 7)}); |
|
|
|
const auto& src = regs.independent_blend[index]; |
|
|
|
equation_rgb.Assign(PackBlendEquation(src.equation_rgb)); |
|
|
|
equation_a.Assign(PackBlendEquation(src.equation_a)); |
|
|
|
factor_source_rgb.Assign(PackBlendFactor(src.factor_source_rgb)); |
|
|
|
factor_dest_rgb.Assign(PackBlendFactor(src.factor_dest_rgb)); |
|
|
|
factor_source_a.Assign(PackBlendFactor(src.factor_source_a)); |
|
|
|
factor_dest_a.Assign(PackBlendFactor(src.factor_dest_a)); |
|
|
|
enable.Assign(1); |
|
|
|
} |
|
|
|
|
|
|
|
} // Anonymous namespace
|
|
|
|
|
|
|
|
std::size_t FixedPipelineState::BlendingAttachment::Hash() const noexcept { |
|
|
|
return static_cast<std::size_t>(enable) ^ (static_cast<std::size_t>(rgb_equation) << 5) ^ |
|
|
|
(static_cast<std::size_t>(src_rgb_func) << 10) ^ |
|
|
|
(static_cast<std::size_t>(dst_rgb_func) << 15) ^ |
|
|
|
(static_cast<std::size_t>(a_equation) << 20) ^ |
|
|
|
(static_cast<std::size_t>(src_a_func) << 25) ^ |
|
|
|
(static_cast<std::size_t>(dst_a_func) << 30) ^ |
|
|
|
(static_cast<std::size_t>(components[0]) << 35) ^ |
|
|
|
(static_cast<std::size_t>(components[1]) << 36) ^ |
|
|
|
(static_cast<std::size_t>(components[2]) << 37) ^ |
|
|
|
(static_cast<std::size_t>(components[3]) << 38); |
|
|
|
return raw; |
|
|
|
} |
|
|
|
|
|
|
|
bool FixedPipelineState::BlendingAttachment::operator==(const BlendingAttachment& rhs) const |
|
|
|
noexcept { |
|
|
|
return std::tie(enable, rgb_equation, src_rgb_func, dst_rgb_func, a_equation, src_a_func, |
|
|
|
dst_a_func, components) == |
|
|
|
std::tie(rhs.enable, rhs.rgb_equation, rhs.src_rgb_func, rhs.dst_rgb_func, |
|
|
|
rhs.a_equation, rhs.src_a_func, rhs.dst_a_func, rhs.components); |
|
|
|
return raw == rhs.raw; |
|
|
|
} |
|
|
|
|
|
|
|
std::size_t FixedPipelineState::VertexInput::Hash() const noexcept { |
|
|
|
@ -190,16 +177,15 @@ bool FixedPipelineState::DepthStencil::operator==(const DepthStencil& rhs) const |
|
|
|
} |
|
|
|
|
|
|
|
std::size_t FixedPipelineState::ColorBlending::Hash() const noexcept { |
|
|
|
std::size_t hash = attachments_count << 13; |
|
|
|
for (std::size_t rt = 0; rt < static_cast<std::size_t>(attachments_count); ++rt) { |
|
|
|
std::size_t hash = 0; |
|
|
|
for (std::size_t rt = 0; rt < std::size(attachments); ++rt) { |
|
|
|
boost::hash_combine(hash, attachments[rt].Hash()); |
|
|
|
} |
|
|
|
return hash; |
|
|
|
} |
|
|
|
|
|
|
|
bool FixedPipelineState::ColorBlending::operator==(const ColorBlending& rhs) const noexcept { |
|
|
|
return std::equal(attachments.begin(), attachments.begin() + attachments_count, |
|
|
|
rhs.attachments.begin(), rhs.attachments.begin() + rhs.attachments_count); |
|
|
|
return attachments == rhs.attachments; |
|
|
|
} |
|
|
|
|
|
|
|
std::size_t FixedPipelineState::Hash() const noexcept { |
|
|
|
@ -220,7 +206,7 @@ FixedPipelineState GetFixedPipelineState(const Maxwell& regs) { |
|
|
|
FixedPipelineState fixed_state; |
|
|
|
fixed_state.rasterizer.Fill(regs); |
|
|
|
fixed_state.depth_stencil.Fill(regs); |
|
|
|
fixed_state.color_blending = GetColorBlendingState(regs); |
|
|
|
fixed_state.color_blending.Fill(regs); |
|
|
|
return fixed_state; |
|
|
|
} |
|
|
|
|
|
|
|
@ -312,4 +298,121 @@ Maxwell::LogicOperation FixedPipelineState::UnpackLogicOp(u32 packed) noexcept { |
|
|
|
return static_cast<Maxwell::LogicOperation>(packed + 0x1500); |
|
|
|
} |
|
|
|
|
|
|
|
u32 FixedPipelineState::PackBlendEquation(Maxwell::Blend::Equation equation) noexcept { |
|
|
|
switch (equation) { |
|
|
|
case Maxwell::Blend::Equation::Add: |
|
|
|
case Maxwell::Blend::Equation::AddGL: |
|
|
|
return 0; |
|
|
|
case Maxwell::Blend::Equation::Subtract: |
|
|
|
case Maxwell::Blend::Equation::SubtractGL: |
|
|
|
return 1; |
|
|
|
case Maxwell::Blend::Equation::ReverseSubtract: |
|
|
|
case Maxwell::Blend::Equation::ReverseSubtractGL: |
|
|
|
return 2; |
|
|
|
case Maxwell::Blend::Equation::Min: |
|
|
|
case Maxwell::Blend::Equation::MinGL: |
|
|
|
return 3; |
|
|
|
case Maxwell::Blend::Equation::Max: |
|
|
|
case Maxwell::Blend::Equation::MaxGL: |
|
|
|
return 4; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
Maxwell::Blend::Equation FixedPipelineState::UnpackBlendEquation(u32 packed) noexcept { |
|
|
|
static constexpr std::array LUT = { |
|
|
|
Maxwell::Blend::Equation::Add, Maxwell::Blend::Equation::Subtract, |
|
|
|
Maxwell::Blend::Equation::ReverseSubtract, Maxwell::Blend::Equation::Min, |
|
|
|
Maxwell::Blend::Equation::Max}; |
|
|
|
return LUT[packed]; |
|
|
|
} |
|
|
|
|
|
|
|
u32 FixedPipelineState::PackBlendFactor(Maxwell::Blend::Factor factor) noexcept { |
|
|
|
switch (factor) { |
|
|
|
case Maxwell::Blend::Factor::Zero: |
|
|
|
case Maxwell::Blend::Factor::ZeroGL: |
|
|
|
return 0; |
|
|
|
case Maxwell::Blend::Factor::One: |
|
|
|
case Maxwell::Blend::Factor::OneGL: |
|
|
|
return 1; |
|
|
|
case Maxwell::Blend::Factor::SourceColor: |
|
|
|
case Maxwell::Blend::Factor::SourceColorGL: |
|
|
|
return 2; |
|
|
|
case Maxwell::Blend::Factor::OneMinusSourceColor: |
|
|
|
case Maxwell::Blend::Factor::OneMinusSourceColorGL: |
|
|
|
return 3; |
|
|
|
case Maxwell::Blend::Factor::SourceAlpha: |
|
|
|
case Maxwell::Blend::Factor::SourceAlphaGL: |
|
|
|
return 4; |
|
|
|
case Maxwell::Blend::Factor::OneMinusSourceAlpha: |
|
|
|
case Maxwell::Blend::Factor::OneMinusSourceAlphaGL: |
|
|
|
return 5; |
|
|
|
case Maxwell::Blend::Factor::DestAlpha: |
|
|
|
case Maxwell::Blend::Factor::DestAlphaGL: |
|
|
|
return 6; |
|
|
|
case Maxwell::Blend::Factor::OneMinusDestAlpha: |
|
|
|
case Maxwell::Blend::Factor::OneMinusDestAlphaGL: |
|
|
|
return 7; |
|
|
|
case Maxwell::Blend::Factor::DestColor: |
|
|
|
case Maxwell::Blend::Factor::DestColorGL: |
|
|
|
return 8; |
|
|
|
case Maxwell::Blend::Factor::OneMinusDestColor: |
|
|
|
case Maxwell::Blend::Factor::OneMinusDestColorGL: |
|
|
|
return 9; |
|
|
|
case Maxwell::Blend::Factor::SourceAlphaSaturate: |
|
|
|
case Maxwell::Blend::Factor::SourceAlphaSaturateGL: |
|
|
|
return 10; |
|
|
|
case Maxwell::Blend::Factor::Source1Color: |
|
|
|
case Maxwell::Blend::Factor::Source1ColorGL: |
|
|
|
return 11; |
|
|
|
case Maxwell::Blend::Factor::OneMinusSource1Color: |
|
|
|
case Maxwell::Blend::Factor::OneMinusSource1ColorGL: |
|
|
|
return 12; |
|
|
|
case Maxwell::Blend::Factor::Source1Alpha: |
|
|
|
case Maxwell::Blend::Factor::Source1AlphaGL: |
|
|
|
return 13; |
|
|
|
case Maxwell::Blend::Factor::OneMinusSource1Alpha: |
|
|
|
case Maxwell::Blend::Factor::OneMinusSource1AlphaGL: |
|
|
|
return 14; |
|
|
|
case Maxwell::Blend::Factor::ConstantColor: |
|
|
|
case Maxwell::Blend::Factor::ConstantColorGL: |
|
|
|
return 15; |
|
|
|
case Maxwell::Blend::Factor::OneMinusConstantColor: |
|
|
|
case Maxwell::Blend::Factor::OneMinusConstantColorGL: |
|
|
|
return 16; |
|
|
|
case Maxwell::Blend::Factor::ConstantAlpha: |
|
|
|
case Maxwell::Blend::Factor::ConstantAlphaGL: |
|
|
|
return 17; |
|
|
|
case Maxwell::Blend::Factor::OneMinusConstantAlpha: |
|
|
|
case Maxwell::Blend::Factor::OneMinusConstantAlphaGL: |
|
|
|
return 18; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
Maxwell::Blend::Factor FixedPipelineState::UnpackBlendFactor(u32 packed) noexcept { |
|
|
|
static constexpr std::array LUT = { |
|
|
|
Maxwell::Blend::Factor::Zero, |
|
|
|
Maxwell::Blend::Factor::One, |
|
|
|
Maxwell::Blend::Factor::SourceColor, |
|
|
|
Maxwell::Blend::Factor::OneMinusSourceColor, |
|
|
|
Maxwell::Blend::Factor::SourceAlpha, |
|
|
|
Maxwell::Blend::Factor::OneMinusSourceAlpha, |
|
|
|
Maxwell::Blend::Factor::DestAlpha, |
|
|
|
Maxwell::Blend::Factor::OneMinusDestAlpha, |
|
|
|
Maxwell::Blend::Factor::DestColor, |
|
|
|
Maxwell::Blend::Factor::OneMinusDestColor, |
|
|
|
Maxwell::Blend::Factor::SourceAlphaSaturate, |
|
|
|
Maxwell::Blend::Factor::Source1Color, |
|
|
|
Maxwell::Blend::Factor::OneMinusSource1Color, |
|
|
|
Maxwell::Blend::Factor::Source1Alpha, |
|
|
|
Maxwell::Blend::Factor::OneMinusSource1Alpha, |
|
|
|
Maxwell::Blend::Factor::ConstantColor, |
|
|
|
Maxwell::Blend::Factor::OneMinusConstantColor, |
|
|
|
Maxwell::Blend::Factor::ConstantAlpha, |
|
|
|
Maxwell::Blend::Factor::OneMinusConstantAlpha, |
|
|
|
}; |
|
|
|
return LUT[packed]; |
|
|
|
} |
|
|
|
|
|
|
|
} // namespace Vulkan
|