|
|
|
@ -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);
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // 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
|
|
|
|
|