2019-12-23 02:48:43 +01:00
|
|
|
// Copyright 2019 yuzu Emulator Project
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
2020-05-04 23:31:17 +02:00
|
|
|
#include <algorithm>
|
2020-04-18 09:03:29 +02:00
|
|
|
#include <cstring>
|
2019-12-23 02:48:43 +01:00
|
|
|
#include <tuple>
|
|
|
|
|
|
|
|
#include <boost/functional/hash.hpp>
|
|
|
|
|
2020-11-25 06:33:20 +01:00
|
|
|
#include "common/bit_cast.h"
|
2020-04-17 23:37:27 +02:00
|
|
|
#include "common/cityhash.h"
|
2019-12-23 02:48:43 +01:00
|
|
|
#include "common/common_types.h"
|
|
|
|
#include "video_core/renderer_vulkan/fixed_pipeline_state.h"
|
2021-01-19 06:04:27 +01:00
|
|
|
#include "video_core/renderer_vulkan/vk_state_tracker.h"
|
2019-12-23 02:48:43 +01:00
|
|
|
|
|
|
|
namespace Vulkan {
|
2020-04-18 09:03:29 +02:00
|
|
|
namespace {
|
2021-01-19 06:04:27 +01:00
|
|
|
constexpr size_t POINT = 0;
|
|
|
|
constexpr size_t LINE = 1;
|
|
|
|
constexpr size_t POLYGON = 2;
|
2020-04-18 09:03:29 +02:00
|
|
|
constexpr std::array POLYGON_OFFSET_ENABLE_LUT = {
|
|
|
|
POINT, // Points
|
|
|
|
LINE, // Lines
|
|
|
|
LINE, // LineLoop
|
|
|
|
LINE, // LineStrip
|
|
|
|
POLYGON, // Triangles
|
|
|
|
POLYGON, // TriangleStrip
|
|
|
|
POLYGON, // TriangleFan
|
|
|
|
POLYGON, // Quads
|
|
|
|
POLYGON, // QuadStrip
|
|
|
|
POLYGON, // Polygon
|
|
|
|
LINE, // LinesAdjacency
|
|
|
|
LINE, // LineStripAdjacency
|
|
|
|
POLYGON, // TrianglesAdjacency
|
|
|
|
POLYGON, // TriangleStripAdjacency
|
|
|
|
POLYGON, // Patches
|
|
|
|
};
|
|
|
|
|
2021-05-21 22:19:35 +02:00
|
|
|
void RefreshXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& regs) {
|
|
|
|
std::ranges::transform(regs.tfb_layouts, state.layouts.begin(), [](const auto& layout) {
|
|
|
|
return VideoCommon::TransformFeedbackState::Layout{
|
|
|
|
.stream = layout.stream,
|
|
|
|
.varying_count = layout.varying_count,
|
|
|
|
.stride = layout.stride,
|
|
|
|
};
|
|
|
|
});
|
|
|
|
state.varyings = regs.tfb_varying_locs;
|
|
|
|
}
|
2020-04-18 09:03:29 +02:00
|
|
|
} // Anonymous namespace
|
|
|
|
|
2021-01-19 06:04:27 +01:00
|
|
|
void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d,
|
2021-06-12 10:07:52 +02:00
|
|
|
bool has_extended_dynamic_state, bool has_dynamic_vertex_input) {
|
2021-01-19 06:04:27 +01:00
|
|
|
const Maxwell& regs = maxwell3d.regs;
|
|
|
|
const std::array enabled_lut{
|
|
|
|
regs.polygon_offset_point_enable,
|
|
|
|
regs.polygon_offset_line_enable,
|
|
|
|
regs.polygon_offset_fill_enable,
|
|
|
|
};
|
2020-04-18 09:03:29 +02:00
|
|
|
const u32 topology_index = static_cast<u32>(regs.draw.topology.Value());
|
|
|
|
|
2020-11-26 20:49:20 +01:00
|
|
|
raw1 = 0;
|
2021-06-12 10:07:52 +02:00
|
|
|
extended_dynamic_state.Assign(has_extended_dynamic_state ? 1 : 0);
|
|
|
|
dynamic_vertex_input.Assign(has_dynamic_vertex_input ? 1 : 0);
|
2021-04-14 06:04:59 +02:00
|
|
|
xfb_enabled.Assign(regs.tfb_enabled != 0);
|
2020-04-18 09:03:29 +02:00
|
|
|
primitive_restart_enable.Assign(regs.primitive_restart.enabled != 0 ? 1 : 0);
|
|
|
|
depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0);
|
2020-04-28 01:50:14 +02:00
|
|
|
depth_clamp_disabled.Assign(regs.view_volume_clip_control.depth_clamp_disabled.Value());
|
2020-04-18 09:03:29 +02:00
|
|
|
ndc_minus_one_to_one.Assign(regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1 : 0);
|
|
|
|
polygon_mode.Assign(PackPolygonMode(regs.polygon_mode_front));
|
|
|
|
patch_control_points_minus_one.Assign(regs.patch_vertices - 1);
|
|
|
|
tessellation_primitive.Assign(static_cast<u32>(regs.tess_mode.prim.Value()));
|
|
|
|
tessellation_spacing.Assign(static_cast<u32>(regs.tess_mode.spacing.Value()));
|
|
|
|
tessellation_clockwise.Assign(regs.tess_mode.cw.Value());
|
|
|
|
logic_op_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0);
|
|
|
|
logic_op.Assign(PackLogicOp(regs.logic_op.operation));
|
2020-10-13 02:33:27 +02:00
|
|
|
topology.Assign(regs.draw.topology);
|
2020-12-30 06:25:23 +01:00
|
|
|
msaa_mode.Assign(regs.multisample_mode);
|
2020-06-22 09:01:37 +02:00
|
|
|
|
2020-11-26 20:49:20 +01:00
|
|
|
raw2 = 0;
|
2021-06-12 10:07:52 +02:00
|
|
|
rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0);
|
2020-11-19 08:25:37 +01:00
|
|
|
const auto test_func =
|
2021-01-19 06:04:27 +01:00
|
|
|
regs.alpha_test_enabled != 0 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always;
|
2020-11-19 08:25:37 +01:00
|
|
|
alpha_test_func.Assign(PackComparisonOp(test_func));
|
2020-11-26 20:49:20 +01:00
|
|
|
early_z.Assign(regs.force_early_fragment_tests != 0 ? 1 : 0);
|
2021-03-19 23:28:31 +01:00
|
|
|
depth_enabled.Assign(regs.zeta_enable != 0 ? 1 : 0);
|
|
|
|
depth_format.Assign(static_cast<u32>(regs.zeta.format));
|
2021-06-12 02:52:04 +02:00
|
|
|
y_negate.Assign(regs.screen_y_control.y_negate != 0 ? 1 : 0);
|
|
|
|
provoking_vertex_last.Assign(regs.provoking_vertex_last != 0 ? 1 : 0);
|
2021-06-23 08:32:41 +02:00
|
|
|
conservative_raster_enable.Assign(regs.conservative_raster_enable != 0 ? 1 : 0);
|
2021-06-25 10:25:19 +02:00
|
|
|
smooth_lines.Assign(regs.line_smooth_enable != 0 ? 1 : 0);
|
2020-11-19 02:08:51 +01:00
|
|
|
|
2021-06-02 01:37:45 +02:00
|
|
|
for (size_t i = 0; i < regs.rt.size(); ++i) {
|
|
|
|
color_formats[i] = static_cast<u8>(regs.rt[i].format);
|
|
|
|
}
|
2020-11-26 20:49:20 +01:00
|
|
|
alpha_test_ref = Common::BitCast<u32>(regs.alpha_test_ref);
|
2020-11-25 06:33:20 +01:00
|
|
|
point_size = Common::BitCast<u32>(regs.point_size);
|
2019-12-23 02:48:43 +01:00
|
|
|
|
2021-06-12 10:07:52 +02:00
|
|
|
if (maxwell3d.dirty.flags[Dirty::VertexInput]) {
|
|
|
|
if (has_dynamic_vertex_input) {
|
|
|
|
// Dirty flag will be reset by the command buffer update
|
|
|
|
static constexpr std::array LUT{
|
|
|
|
0u, // Invalid
|
|
|
|
1u, // SignedNorm
|
|
|
|
1u, // UnsignedNorm
|
|
|
|
2u, // SignedInt
|
|
|
|
3u, // UnsignedInt
|
|
|
|
1u, // UnsignedScaled
|
|
|
|
1u, // SignedScaled
|
|
|
|
1u, // Float
|
|
|
|
};
|
|
|
|
const auto& attrs = regs.vertex_attrib_format;
|
|
|
|
attribute_types = 0;
|
|
|
|
for (size_t i = 0; i < Maxwell::NumVertexAttributes; ++i) {
|
|
|
|
const u32 mask = attrs[i].constant != 0 ? 0 : 3;
|
|
|
|
const u32 type = LUT[static_cast<size_t>(attrs[i].type.Value())];
|
|
|
|
attribute_types |= static_cast<u64>(type & mask) << (i * 2);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
maxwell3d.dirty.flags[Dirty::VertexInput] = false;
|
|
|
|
enabled_divisors = 0;
|
|
|
|
for (size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
|
|
|
|
const bool is_enabled = regs.instanced_arrays.IsInstancingEnabled(index);
|
|
|
|
binding_divisors[index] = is_enabled ? regs.vertex_array[index].divisor : 0;
|
|
|
|
enabled_divisors |= (is_enabled ? u64{1} : 0) << index;
|
|
|
|
}
|
|
|
|
for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
|
|
|
|
const auto& input = regs.vertex_attrib_format[index];
|
|
|
|
auto& attribute = attributes[index];
|
|
|
|
attribute.raw = 0;
|
|
|
|
attribute.enabled.Assign(input.IsConstant() ? 0 : 1);
|
|
|
|
attribute.buffer.Assign(input.buffer);
|
|
|
|
attribute.offset.Assign(input.offset);
|
|
|
|
attribute.type.Assign(static_cast<u32>(input.type.Value()));
|
|
|
|
attribute.size.Assign(static_cast<u32>(input.size.Value()));
|
|
|
|
}
|
2021-01-19 06:04:27 +01:00
|
|
|
}
|
2020-06-22 09:01:37 +02:00
|
|
|
}
|
2021-01-19 06:04:27 +01:00
|
|
|
if (maxwell3d.dirty.flags[Dirty::Blending]) {
|
|
|
|
maxwell3d.dirty.flags[Dirty::Blending] = false;
|
|
|
|
for (size_t index = 0; index < attachments.size(); ++index) {
|
|
|
|
attachments[index].Refresh(regs, index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (maxwell3d.dirty.flags[Dirty::ViewportSwizzles]) {
|
|
|
|
maxwell3d.dirty.flags[Dirty::ViewportSwizzles] = false;
|
|
|
|
const auto& transform = regs.viewport_transform;
|
|
|
|
std::ranges::transform(transform, viewport_swizzles.begin(), [](const auto& viewport) {
|
|
|
|
return static_cast<u16>(viewport.swizzle.raw);
|
|
|
|
});
|
2019-12-23 02:48:43 +01:00
|
|
|
}
|
2021-06-12 10:07:52 +02:00
|
|
|
if (!extended_dynamic_state) {
|
2021-01-19 06:04:27 +01:00
|
|
|
dynamic_state.Refresh(regs);
|
2020-06-23 00:07:04 +02:00
|
|
|
}
|
2021-06-12 10:07:52 +02:00
|
|
|
if (xfb_enabled) {
|
2021-05-21 22:19:35 +02:00
|
|
|
RefreshXfbState(xfb_state, regs);
|
2021-04-14 06:04:59 +02:00
|
|
|
}
|
2020-05-04 23:31:17 +02:00
|
|
|
}
|
|
|
|
|
2021-01-19 06:04:27 +01:00
|
|
|
void FixedPipelineState::BlendingAttachment::Refresh(const Maxwell& regs, size_t index) {
|
2020-04-18 10:41:56 +02:00
|
|
|
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
|
2019-12-23 02:48:43 +01:00
|
|
|
|
|
|
|
if (!regs.independent_blend_enable) {
|
|
|
|
const auto& src = regs.blend;
|
2020-04-18 10:41:56 +02:00
|
|
|
if (!src.enable[index]) {
|
|
|
|
return;
|
2019-12-23 02:48:43 +01:00
|
|
|
}
|
2020-04-18 10:41:56 +02:00
|
|
|
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;
|
2019-12-23 02:48:43 +01:00
|
|
|
}
|
|
|
|
|
2020-04-18 10:41:56 +02:00
|
|
|
if (!regs.blend.enable[index]) {
|
|
|
|
return;
|
2019-12-23 02:48:43 +01:00
|
|
|
}
|
2020-04-18 10:41:56 +02:00
|
|
|
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);
|
2019-12-23 02:48:43 +01:00
|
|
|
}
|
|
|
|
|
2021-01-19 06:04:27 +01:00
|
|
|
void FixedPipelineState::DynamicState::Refresh(const Maxwell& regs) {
|
2020-06-22 00:30:23 +02:00
|
|
|
u32 packed_front_face = PackFrontFace(regs.front_face);
|
|
|
|
if (regs.screen_y_control.triangle_rast_flip != 0) {
|
|
|
|
// Flip front face
|
|
|
|
packed_front_face = 1 - packed_front_face;
|
|
|
|
}
|
|
|
|
|
|
|
|
raw1 = 0;
|
|
|
|
raw2 = 0;
|
|
|
|
front.action_stencil_fail.Assign(PackStencilOp(regs.stencil_front_op_fail));
|
|
|
|
front.action_depth_fail.Assign(PackStencilOp(regs.stencil_front_op_zfail));
|
|
|
|
front.action_depth_pass.Assign(PackStencilOp(regs.stencil_front_op_zpass));
|
|
|
|
front.test_func.Assign(PackComparisonOp(regs.stencil_front_func_func));
|
|
|
|
if (regs.stencil_two_side_enable) {
|
|
|
|
back.action_stencil_fail.Assign(PackStencilOp(regs.stencil_back_op_fail));
|
|
|
|
back.action_depth_fail.Assign(PackStencilOp(regs.stencil_back_op_zfail));
|
|
|
|
back.action_depth_pass.Assign(PackStencilOp(regs.stencil_back_op_zpass));
|
|
|
|
back.test_func.Assign(PackComparisonOp(regs.stencil_back_func_func));
|
|
|
|
} else {
|
|
|
|
back.action_stencil_fail.Assign(front.action_stencil_fail);
|
|
|
|
back.action_depth_fail.Assign(front.action_depth_fail);
|
|
|
|
back.action_depth_pass.Assign(front.action_depth_pass);
|
|
|
|
back.test_func.Assign(front.test_func);
|
|
|
|
}
|
|
|
|
stencil_enable.Assign(regs.stencil_enable);
|
|
|
|
depth_write_enable.Assign(regs.depth_write_enabled);
|
|
|
|
depth_bounds_enable.Assign(regs.depth_bounds_enable);
|
|
|
|
depth_test_enable.Assign(regs.depth_test_enable);
|
|
|
|
front_face.Assign(packed_front_face);
|
|
|
|
depth_test_func.Assign(PackComparisonOp(regs.depth_test_func));
|
|
|
|
cull_face.Assign(PackCullFace(regs.cull_face));
|
|
|
|
cull_enable.Assign(regs.cull_test_enabled != 0 ? 1 : 0);
|
2020-12-26 03:34:38 +01:00
|
|
|
std::ranges::transform(regs.vertex_array, vertex_strides.begin(), [](const auto& array) {
|
|
|
|
return static_cast<u16>(array.stride.Value());
|
|
|
|
});
|
2020-06-22 00:30:23 +02:00
|
|
|
}
|
|
|
|
|
2021-01-19 06:04:27 +01:00
|
|
|
size_t FixedPipelineState::Hash() const noexcept {
|
2020-06-23 00:07:04 +02:00
|
|
|
const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), Size());
|
2021-01-19 06:04:27 +01:00
|
|
|
return static_cast<size_t>(hash);
|
2019-12-23 02:48:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool FixedPipelineState::operator==(const FixedPipelineState& rhs) const noexcept {
|
2020-06-23 00:07:04 +02:00
|
|
|
return std::memcmp(this, &rhs, Size()) == 0;
|
2019-12-23 02:48:43 +01:00
|
|
|
}
|
|
|
|
|
2020-04-18 05:05:41 +02:00
|
|
|
u32 FixedPipelineState::PackComparisonOp(Maxwell::ComparisonOp op) noexcept {
|
|
|
|
// OpenGL enums go from 0x200 to 0x207 and the others from 1 to 8
|
|
|
|
// If we substract 0x200 to OpenGL enums and 1 to the others we get a 0-7 range.
|
|
|
|
// Perfect for a hash.
|
|
|
|
const u32 value = static_cast<u32>(op);
|
|
|
|
return value - (value >= 0x200 ? 0x200 : 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
Maxwell::ComparisonOp FixedPipelineState::UnpackComparisonOp(u32 packed) noexcept {
|
|
|
|
// Read PackComparisonOp for the logic behind this.
|
|
|
|
return static_cast<Maxwell::ComparisonOp>(packed + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 FixedPipelineState::PackStencilOp(Maxwell::StencilOp op) noexcept {
|
|
|
|
switch (op) {
|
|
|
|
case Maxwell::StencilOp::Keep:
|
|
|
|
case Maxwell::StencilOp::KeepOGL:
|
|
|
|
return 0;
|
|
|
|
case Maxwell::StencilOp::Zero:
|
|
|
|
case Maxwell::StencilOp::ZeroOGL:
|
|
|
|
return 1;
|
|
|
|
case Maxwell::StencilOp::Replace:
|
|
|
|
case Maxwell::StencilOp::ReplaceOGL:
|
|
|
|
return 2;
|
|
|
|
case Maxwell::StencilOp::Incr:
|
|
|
|
case Maxwell::StencilOp::IncrOGL:
|
|
|
|
return 3;
|
|
|
|
case Maxwell::StencilOp::Decr:
|
|
|
|
case Maxwell::StencilOp::DecrOGL:
|
|
|
|
return 4;
|
|
|
|
case Maxwell::StencilOp::Invert:
|
|
|
|
case Maxwell::StencilOp::InvertOGL:
|
|
|
|
return 5;
|
|
|
|
case Maxwell::StencilOp::IncrWrap:
|
|
|
|
case Maxwell::StencilOp::IncrWrapOGL:
|
|
|
|
return 6;
|
|
|
|
case Maxwell::StencilOp::DecrWrap:
|
|
|
|
case Maxwell::StencilOp::DecrWrapOGL:
|
|
|
|
return 7;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Maxwell::StencilOp FixedPipelineState::UnpackStencilOp(u32 packed) noexcept {
|
|
|
|
static constexpr std::array LUT = {Maxwell::StencilOp::Keep, Maxwell::StencilOp::Zero,
|
|
|
|
Maxwell::StencilOp::Replace, Maxwell::StencilOp::Incr,
|
|
|
|
Maxwell::StencilOp::Decr, Maxwell::StencilOp::Invert,
|
|
|
|
Maxwell::StencilOp::IncrWrap, Maxwell::StencilOp::DecrWrap};
|
|
|
|
return LUT[packed];
|
|
|
|
}
|
|
|
|
|
2020-04-18 09:03:29 +02:00
|
|
|
u32 FixedPipelineState::PackCullFace(Maxwell::CullFace cull) noexcept {
|
|
|
|
// FrontAndBack is 0x408, by substracting 0x406 in it we get 2.
|
|
|
|
// Individual cull faces are in 0x404 and 0x405, substracting 0x404 we get 0 and 1.
|
|
|
|
const u32 value = static_cast<u32>(cull);
|
|
|
|
return value - (value == 0x408 ? 0x406 : 0x404);
|
|
|
|
}
|
|
|
|
|
|
|
|
Maxwell::CullFace FixedPipelineState::UnpackCullFace(u32 packed) noexcept {
|
|
|
|
static constexpr std::array LUT = {Maxwell::CullFace::Front, Maxwell::CullFace::Back,
|
|
|
|
Maxwell::CullFace::FrontAndBack};
|
|
|
|
return LUT[packed];
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 FixedPipelineState::PackFrontFace(Maxwell::FrontFace face) noexcept {
|
|
|
|
return static_cast<u32>(face) - 0x900;
|
|
|
|
}
|
|
|
|
|
|
|
|
Maxwell::FrontFace FixedPipelineState::UnpackFrontFace(u32 packed) noexcept {
|
|
|
|
return static_cast<Maxwell::FrontFace>(packed + 0x900);
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 FixedPipelineState::PackPolygonMode(Maxwell::PolygonMode mode) noexcept {
|
|
|
|
return static_cast<u32>(mode) - 0x1B00;
|
|
|
|
}
|
|
|
|
|
|
|
|
Maxwell::PolygonMode FixedPipelineState::UnpackPolygonMode(u32 packed) noexcept {
|
|
|
|
return static_cast<Maxwell::PolygonMode>(packed + 0x1B00);
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 FixedPipelineState::PackLogicOp(Maxwell::LogicOperation op) noexcept {
|
|
|
|
return static_cast<u32>(op) - 0x1500;
|
|
|
|
}
|
|
|
|
|
|
|
|
Maxwell::LogicOperation FixedPipelineState::UnpackLogicOp(u32 packed) noexcept {
|
|
|
|
return static_cast<Maxwell::LogicOperation>(packed + 0x1500);
|
|
|
|
}
|
|
|
|
|
2020-04-18 10:41:56 +02:00
|
|
|
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];
|
|
|
|
}
|
|
|
|
|
2019-12-23 02:48:43 +01:00
|
|
|
} // namespace Vulkan
|