[Vulkan] Add support for user clip planes
This commit is contained in:
@@ -241,6 +241,10 @@ void SpirvShaderTranslator::StartTranslation() {
|
|||||||
type_uint4_, builder_->makeUintConstant(4), sizeof(uint32_t) * 4);
|
type_uint4_, builder_->makeUintConstant(4), sizeof(uint32_t) * 4);
|
||||||
builder_->addDecoration(type_uint4_array_4, spv::DecorationArrayStride,
|
builder_->addDecoration(type_uint4_array_4, spv::DecorationArrayStride,
|
||||||
sizeof(uint32_t) * 4);
|
sizeof(uint32_t) * 4);
|
||||||
|
spv::Id type_float4_array_6 = builder_->makeArrayType(
|
||||||
|
type_float4_, builder_->makeUintConstant(6), sizeof(float) * 4);
|
||||||
|
builder_->addDecoration(type_float4_array_6, spv::DecorationArrayStride,
|
||||||
|
sizeof(float) * 4);
|
||||||
const SystemConstant system_constants[] = {
|
const SystemConstant system_constants[] = {
|
||||||
{"flags", offsetof(SystemConstants, flags), type_uint_},
|
{"flags", offsetof(SystemConstants, flags), type_uint_},
|
||||||
{"vertex_index_load_address",
|
{"vertex_index_load_address",
|
||||||
@@ -1261,6 +1265,51 @@ void SpirvShaderTranslator::StartVertexOrTessEvalShaderBeforeMain() {
|
|||||||
std::vector<spv::Id> struct_per_vertex_members;
|
std::vector<spv::Id> struct_per_vertex_members;
|
||||||
struct_per_vertex_members.reserve(kOutputPerVertexMemberCount);
|
struct_per_vertex_members.reserve(kOutputPerVertexMemberCount);
|
||||||
struct_per_vertex_members.push_back(type_float4_);
|
struct_per_vertex_members.push_back(type_float4_);
|
||||||
|
|
||||||
|
// Only allocate ClipDistance/CullDistance arrays when user clip planes are
|
||||||
|
// actually enabled (count > 0).
|
||||||
|
uint32_t user_clip_plane_count =
|
||||||
|
shader_modification.vertex.user_clip_plane_count;
|
||||||
|
output_per_vertex_clip_distance_member_index_ = 0;
|
||||||
|
output_per_vertex_cull_distance_member_index_ = 0;
|
||||||
|
constexpr uint32_t kMaxUserClipPlanes = 6;
|
||||||
|
if (user_clip_plane_count > 0) {
|
||||||
|
// Create separate uniform buffer for clip planes.
|
||||||
|
spv::Id type_float4_array_6 = builder_->makeArrayType(
|
||||||
|
type_float4_, builder_->makeUintConstant(6), sizeof(float) * 4);
|
||||||
|
builder_->addDecoration(type_float4_array_6, spv::DecorationArrayStride,
|
||||||
|
sizeof(float) * 4);
|
||||||
|
std::vector<spv::Id> clip_plane_struct_members;
|
||||||
|
clip_plane_struct_members.push_back(type_float4_array_6);
|
||||||
|
spv::Id type_clip_plane_constants = builder_->makeStructType(
|
||||||
|
clip_plane_struct_members, "XeClipPlaneConstants");
|
||||||
|
builder_->addMemberDecoration(type_clip_plane_constants, 0,
|
||||||
|
spv::DecorationOffset, 0);
|
||||||
|
builder_->addDecoration(type_clip_plane_constants, spv::DecorationBlock);
|
||||||
|
uniform_clip_plane_constants_ = builder_->createVariable(
|
||||||
|
spv::NoPrecision, spv::StorageClassUniform, type_clip_plane_constants,
|
||||||
|
"xe_uniform_clip_planes");
|
||||||
|
builder_->addDecoration(uniform_clip_plane_constants_,
|
||||||
|
spv::DecorationDescriptorSet,
|
||||||
|
int(kDescriptorSetConstants));
|
||||||
|
builder_->addDecoration(uniform_clip_plane_constants_,
|
||||||
|
spv::DecorationBinding,
|
||||||
|
int(kConstantBufferClipPlanes));
|
||||||
|
if (features_.spirv_version >= spv::Spv_1_4) {
|
||||||
|
main_interface_.push_back(uniform_clip_plane_constants_);
|
||||||
|
}
|
||||||
|
|
||||||
|
output_per_vertex_clip_distance_member_index_ =
|
||||||
|
static_cast<unsigned int>(struct_per_vertex_members.size());
|
||||||
|
struct_per_vertex_members.push_back(builder_->makeArrayType(
|
||||||
|
type_float_, builder_->makeUintConstant(user_clip_plane_count), 0));
|
||||||
|
|
||||||
|
output_per_vertex_cull_distance_member_index_ =
|
||||||
|
static_cast<unsigned int>(struct_per_vertex_members.size());
|
||||||
|
struct_per_vertex_members.push_back(builder_->makeArrayType(
|
||||||
|
type_float_, builder_->makeUintConstant(user_clip_plane_count), 0));
|
||||||
|
}
|
||||||
|
|
||||||
spv::Id type_struct_per_vertex =
|
spv::Id type_struct_per_vertex =
|
||||||
builder_->makeStructType(struct_per_vertex_members, "gl_PerVertex");
|
builder_->makeStructType(struct_per_vertex_members, "gl_PerVertex");
|
||||||
builder_->addMemberName(type_struct_per_vertex,
|
builder_->addMemberName(type_struct_per_vertex,
|
||||||
@@ -1268,6 +1317,24 @@ void SpirvShaderTranslator::StartVertexOrTessEvalShaderBeforeMain() {
|
|||||||
builder_->addMemberDecoration(
|
builder_->addMemberDecoration(
|
||||||
type_struct_per_vertex, kOutputPerVertexMemberPosition,
|
type_struct_per_vertex, kOutputPerVertexMemberPosition,
|
||||||
spv::DecorationBuiltIn, static_cast<int>(spv::BuiltIn::Position));
|
spv::DecorationBuiltIn, static_cast<int>(spv::BuiltIn::Position));
|
||||||
|
|
||||||
|
// Decorate clip/cull arrays only if allocated.
|
||||||
|
if (user_clip_plane_count > 0) {
|
||||||
|
builder_->addMemberName(type_struct_per_vertex,
|
||||||
|
output_per_vertex_clip_distance_member_index_,
|
||||||
|
"gl_ClipDistance");
|
||||||
|
builder_->addMemberDecoration(
|
||||||
|
type_struct_per_vertex, output_per_vertex_clip_distance_member_index_,
|
||||||
|
spv::DecorationBuiltIn, static_cast<int>(spv::BuiltIn::ClipDistance));
|
||||||
|
|
||||||
|
builder_->addMemberName(type_struct_per_vertex,
|
||||||
|
output_per_vertex_cull_distance_member_index_,
|
||||||
|
"gl_CullDistance");
|
||||||
|
builder_->addMemberDecoration(
|
||||||
|
type_struct_per_vertex, output_per_vertex_cull_distance_member_index_,
|
||||||
|
spv::DecorationBuiltIn, static_cast<int>(spv::BuiltIn::CullDistance));
|
||||||
|
}
|
||||||
|
|
||||||
builder_->addDecoration(type_struct_per_vertex, spv::DecorationBlock);
|
builder_->addDecoration(type_struct_per_vertex, spv::DecorationBlock);
|
||||||
output_per_vertex_ = builder_->createVariable(
|
output_per_vertex_ = builder_->createVariable(
|
||||||
spv::NoPrecision, spv::StorageClassOutput, type_struct_per_vertex, "");
|
spv::NoPrecision, spv::StorageClassOutput, type_struct_per_vertex, "");
|
||||||
@@ -1519,6 +1586,8 @@ void SpirvShaderTranslator::StartVertexOrTessEvalShaderInMain() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() {
|
void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() {
|
||||||
|
Modification shader_modification = GetSpirvShaderModification();
|
||||||
|
|
||||||
id_vector_temp_.clear();
|
id_vector_temp_.clear();
|
||||||
id_vector_temp_.push_back(
|
id_vector_temp_.push_back(
|
||||||
builder_->makeIntConstant(kOutputPerVertexMemberPosition));
|
builder_->makeIntConstant(kOutputPerVertexMemberPosition));
|
||||||
@@ -1600,6 +1669,61 @@ void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute user clip/cull distances BEFORE NDC transform.
|
||||||
|
// Clip planes must operate on the original clip-space position.
|
||||||
|
uint32_t user_clip_plane_count =
|
||||||
|
shader_modification.vertex.user_clip_plane_count;
|
||||||
|
if (user_clip_plane_count > 0) {
|
||||||
|
// Reconstruct the original clip-space position (x, y, z, w) for dot
|
||||||
|
// product. Use the untransformed position_xyz and corrected position_w.
|
||||||
|
spv::Id clip_space_position;
|
||||||
|
{
|
||||||
|
std::unique_ptr<spv::Instruction> composite_construct_op =
|
||||||
|
std::make_unique<spv::Instruction>(
|
||||||
|
builder_->getUniqueId(), type_float4_, spv::OpCompositeConstruct);
|
||||||
|
composite_construct_op->addIdOperand(position_xyz);
|
||||||
|
composite_construct_op->addIdOperand(position_w);
|
||||||
|
clip_space_position = composite_construct_op->getResultId();
|
||||||
|
builder_->getBuildPoint()->addInstruction(
|
||||||
|
std::move(composite_construct_op));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine which member index to use based on whether we're using
|
||||||
|
// ClipDistance or CullDistance.
|
||||||
|
bool user_clip_plane_cull = shader_modification.vertex.user_clip_plane_cull;
|
||||||
|
unsigned int clip_cull_distance_member_index =
|
||||||
|
user_clip_plane_cull ? output_per_vertex_cull_distance_member_index_
|
||||||
|
: output_per_vertex_clip_distance_member_index_;
|
||||||
|
|
||||||
|
// Compute distance to each enabled user clip plane via dot product.
|
||||||
|
for (uint32_t i = 0; i < user_clip_plane_count; ++i) {
|
||||||
|
// Load user clip plane from separate clip plane constants buffer.
|
||||||
|
id_vector_temp_.clear();
|
||||||
|
id_vector_temp_.push_back(
|
||||||
|
builder_->makeIntConstant(0)); // Struct member 0
|
||||||
|
id_vector_temp_.push_back(
|
||||||
|
builder_->makeIntConstant(int(i))); // Array index
|
||||||
|
spv::Id clip_plane = builder_->createLoad(
|
||||||
|
builder_->createAccessChain(spv::StorageClassUniform,
|
||||||
|
uniform_clip_plane_constants_,
|
||||||
|
id_vector_temp_),
|
||||||
|
spv::NoPrecision);
|
||||||
|
|
||||||
|
// Compute dot product: distance = dot(clip_space_position, clip_plane).
|
||||||
|
spv::Id distance = builder_->createBinOp(spv::OpDot, type_float_,
|
||||||
|
clip_space_position, clip_plane);
|
||||||
|
|
||||||
|
// Store to gl_ClipDistance[i] or gl_CullDistance[i].
|
||||||
|
id_vector_temp_.clear();
|
||||||
|
id_vector_temp_.push_back(
|
||||||
|
builder_->makeIntConstant(clip_cull_distance_member_index));
|
||||||
|
id_vector_temp_.push_back(builder_->makeIntConstant(int(i)));
|
||||||
|
spv::Id distance_ptr = builder_->createAccessChain(
|
||||||
|
spv::StorageClassOutput, output_per_vertex_, id_vector_temp_);
|
||||||
|
builder_->createStore(distance, distance_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Apply the NDC scale and offset for guest to host viewport transformation.
|
// Apply the NDC scale and offset for guest to host viewport transformation.
|
||||||
id_vector_temp_.clear();
|
id_vector_temp_.clear();
|
||||||
id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantNdcScale));
|
id_vector_temp_.push_back(builder_->makeIntConstant(kSystemConstantNdcScale));
|
||||||
@@ -1641,8 +1765,6 @@ void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() {
|
|||||||
builder_->createStore(point_size, output_point_size_);
|
builder_->createStore(point_size, output_point_size_);
|
||||||
}
|
}
|
||||||
|
|
||||||
Modification shader_modification = GetSpirvShaderModification();
|
|
||||||
|
|
||||||
// Expand the point sprite.
|
// Expand the point sprite.
|
||||||
if (shader_modification.vertex.host_vertex_shader_type ==
|
if (shader_modification.vertex.host_vertex_shader_type ==
|
||||||
Shader::HostVertexShaderType::kPointListAsTriangleStrip) {
|
Shader::HostVertexShaderType::kPointListAsTriangleStrip) {
|
||||||
|
|||||||
@@ -60,6 +60,11 @@ class SpirvShaderTranslator : public ShaderTranslator {
|
|||||||
// Pipeline stage and input configuration.
|
// Pipeline stage and input configuration.
|
||||||
Shader::HostVertexShaderType host_vertex_shader_type
|
Shader::HostVertexShaderType host_vertex_shader_type
|
||||||
: Shader::kHostVertexShaderTypeBitCount;
|
: Shader::kHostVertexShaderTypeBitCount;
|
||||||
|
// User clip plane count, number of clip planes enabled (0-6).
|
||||||
|
uint32_t user_clip_plane_count : 3;
|
||||||
|
// If user_clip_plane_count is non-zero, whether they should be cull
|
||||||
|
// distances instead of clip distances.
|
||||||
|
uint32_t user_clip_plane_cull : 1;
|
||||||
} vertex;
|
} vertex;
|
||||||
struct PixelShaderModification {
|
struct PixelShaderModification {
|
||||||
// uint32_t 0.
|
// uint32_t 0.
|
||||||
@@ -258,12 +263,18 @@ class SpirvShaderTranslator : public ShaderTranslator {
|
|||||||
float edram_blend_constant[4];
|
float edram_blend_constant[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Separate constant buffer for user clip planes
|
||||||
|
struct ClipPlaneConstants {
|
||||||
|
float user_clip_planes[6][4];
|
||||||
|
};
|
||||||
|
|
||||||
enum ConstantBuffer : uint32_t {
|
enum ConstantBuffer : uint32_t {
|
||||||
kConstantBufferSystem,
|
kConstantBufferSystem,
|
||||||
kConstantBufferFloatVertex,
|
kConstantBufferFloatVertex,
|
||||||
kConstantBufferFloatPixel,
|
kConstantBufferFloatPixel,
|
||||||
kConstantBufferBoolLoop,
|
kConstantBufferBoolLoop,
|
||||||
kConstantBufferFetch,
|
kConstantBufferFetch,
|
||||||
|
kConstantBufferClipPlanes,
|
||||||
|
|
||||||
kConstantBufferCount,
|
kConstantBufferCount,
|
||||||
};
|
};
|
||||||
@@ -846,6 +857,7 @@ class SpirvShaderTranslator : public ShaderTranslator {
|
|||||||
kSystemConstantEdramBlendConstant,
|
kSystemConstantEdramBlendConstant,
|
||||||
};
|
};
|
||||||
spv::Id uniform_system_constants_;
|
spv::Id uniform_system_constants_;
|
||||||
|
spv::Id uniform_clip_plane_constants_;
|
||||||
spv::Id uniform_float_constants_;
|
spv::Id uniform_float_constants_;
|
||||||
spv::Id uniform_bool_loop_constants_;
|
spv::Id uniform_bool_loop_constants_;
|
||||||
spv::Id uniform_fetch_constants_;
|
spv::Id uniform_fetch_constants_;
|
||||||
@@ -895,6 +907,8 @@ class SpirvShaderTranslator : public ShaderTranslator {
|
|||||||
kOutputPerVertexMemberCount,
|
kOutputPerVertexMemberCount,
|
||||||
};
|
};
|
||||||
spv::Id output_per_vertex_;
|
spv::Id output_per_vertex_;
|
||||||
|
unsigned int output_per_vertex_clip_distance_member_index_ = 0;
|
||||||
|
unsigned int output_per_vertex_cull_distance_member_index_ = 0;
|
||||||
|
|
||||||
// With fragment shader interlock, variables in the main function.
|
// With fragment shader interlock, variables in the main function.
|
||||||
// Otherwise, framebuffer color attachment outputs.
|
// Otherwise, framebuffer color attachment outputs.
|
||||||
|
|||||||
@@ -4064,6 +4064,34 @@ void VulkanCommandProcessor::UpdateSystemConstantValues(
|
|||||||
system_constants_.ndc_offset[i] = viewport_info.ndc_offset[i];
|
system_constants_.ndc_offset[i] = viewport_info.ndc_offset[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// User clip planes (for vertex shaders)
|
||||||
|
auto pa_cl_clip_cntl = regs.Get<reg::PA_CL_CLIP_CNTL>();
|
||||||
|
if (!pa_cl_clip_cntl.clip_disable && pa_cl_clip_cntl.ucp_ena) {
|
||||||
|
float* user_clip_plane_write_ptr =
|
||||||
|
clip_plane_constants_.user_clip_planes[0];
|
||||||
|
uint32_t user_clip_planes_remaining = pa_cl_clip_cntl.ucp_ena;
|
||||||
|
uint32_t user_clip_plane_index;
|
||||||
|
while (xe::bit_scan_forward(user_clip_planes_remaining,
|
||||||
|
&user_clip_plane_index)) {
|
||||||
|
user_clip_planes_remaining =
|
||||||
|
xe::clear_lowest_bit(user_clip_planes_remaining);
|
||||||
|
// Validate plane index is within bounds (0-5).
|
||||||
|
assert(user_clip_plane_index < 6);
|
||||||
|
if (user_clip_plane_index >= 6) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const void* user_clip_plane_regs =
|
||||||
|
®s[XE_GPU_REG_PA_CL_UCP_0_X + user_clip_plane_index * 4];
|
||||||
|
if (std::memcmp(user_clip_plane_write_ptr, user_clip_plane_regs,
|
||||||
|
4 * sizeof(float))) {
|
||||||
|
dirty = true;
|
||||||
|
std::memcpy(user_clip_plane_write_ptr, user_clip_plane_regs,
|
||||||
|
4 * sizeof(float));
|
||||||
|
}
|
||||||
|
user_clip_plane_write_ptr += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Point size.
|
// Point size.
|
||||||
if (vgt_draw_initiator.prim_type == xenos::PrimitiveType::kPointList) {
|
if (vgt_draw_initiator.prim_type == xenos::PrimitiveType::kPointList) {
|
||||||
auto pa_su_point_minmax = regs.Get<reg::PA_SU_POINT_MINMAX>();
|
auto pa_su_point_minmax = regs.Get<reg::PA_SU_POINT_MINMAX>();
|
||||||
@@ -4446,6 +4474,29 @@ bool VulkanCommandProcessor::UpdateBindings(const VulkanShader* vertex_shader,
|
|||||||
current_constant_buffers_up_to_date_ |=
|
current_constant_buffers_up_to_date_ |=
|
||||||
UINT32_C(1) << SpirvShaderTranslator::kConstantBufferSystem;
|
UINT32_C(1) << SpirvShaderTranslator::kConstantBufferSystem;
|
||||||
}
|
}
|
||||||
|
// Clip plane constants.
|
||||||
|
auto pa_cl_clip_cntl = regs.Get<reg::PA_CL_CLIP_CNTL>();
|
||||||
|
bool clip_planes_enabled =
|
||||||
|
!pa_cl_clip_cntl.clip_disable && pa_cl_clip_cntl.ucp_ena;
|
||||||
|
if (clip_planes_enabled) {
|
||||||
|
if (!(current_constant_buffers_up_to_date_ &
|
||||||
|
(UINT32_C(1)
|
||||||
|
<< SpirvShaderTranslator::kConstantBufferClipPlanes))) {
|
||||||
|
VkDescriptorBufferInfo& buffer_info = current_constant_buffer_infos_
|
||||||
|
[SpirvShaderTranslator::kConstantBufferClipPlanes];
|
||||||
|
uint8_t* mapping = uniform_buffer_pool_->Request(
|
||||||
|
frame_current_, sizeof(SpirvShaderTranslator::ClipPlaneConstants),
|
||||||
|
uniform_buffer_alignment, buffer_info.buffer, buffer_info.offset);
|
||||||
|
if (!mapping) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
buffer_info.range = sizeof(SpirvShaderTranslator::ClipPlaneConstants);
|
||||||
|
std::memcpy(mapping, &clip_plane_constants_,
|
||||||
|
sizeof(SpirvShaderTranslator::ClipPlaneConstants));
|
||||||
|
current_constant_buffers_up_to_date_ |=
|
||||||
|
UINT32_C(1) << SpirvShaderTranslator::kConstantBufferClipPlanes;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Vertex shader float constants.
|
// Vertex shader float constants.
|
||||||
if (!(current_constant_buffers_up_to_date_ &
|
if (!(current_constant_buffers_up_to_date_ &
|
||||||
(UINT32_C(1) << SpirvShaderTranslator::kConstantBufferFloatVertex))) {
|
(UINT32_C(1) << SpirvShaderTranslator::kConstantBufferFloatVertex))) {
|
||||||
|
|||||||
@@ -753,6 +753,9 @@ class VulkanCommandProcessor final : public CommandProcessor {
|
|||||||
// System shader constants.
|
// System shader constants.
|
||||||
SpirvShaderTranslator::SystemConstants system_constants_;
|
SpirvShaderTranslator::SystemConstants system_constants_;
|
||||||
|
|
||||||
|
// Clip plane constants.
|
||||||
|
SpirvShaderTranslator::ClipPlaneConstants clip_plane_constants_;
|
||||||
|
|
||||||
// Temporary storage for memexport stream constants used in the draw.
|
// Temporary storage for memexport stream constants used in the draw.
|
||||||
std::vector<draw_util::MemExportRange> memexport_ranges_;
|
std::vector<draw_util::MemExportRange> memexport_ranges_;
|
||||||
|
|
||||||
|
|||||||
@@ -175,6 +175,14 @@ VulkanPipelineCache::GetCurrentVertexShaderModification(
|
|||||||
|
|
||||||
modification.vertex.interpolator_mask = interpolator_mask;
|
modification.vertex.interpolator_mask = interpolator_mask;
|
||||||
|
|
||||||
|
// User clip planes.
|
||||||
|
auto pa_cl_clip_cntl = regs.Get<reg::PA_CL_CLIP_CNTL>();
|
||||||
|
uint32_t user_clip_planes =
|
||||||
|
pa_cl_clip_cntl.clip_disable ? 0 : pa_cl_clip_cntl.ucp_ena;
|
||||||
|
modification.vertex.user_clip_plane_count = xe::bit_count(user_clip_planes);
|
||||||
|
modification.vertex.user_clip_plane_cull =
|
||||||
|
uint32_t(user_clip_planes && pa_cl_clip_cntl.ucp_cull_only_ena);
|
||||||
|
|
||||||
if (host_vertex_shader_type ==
|
if (host_vertex_shader_type ==
|
||||||
Shader::HostVertexShaderType::kPointListAsTriangleStrip) {
|
Shader::HostVertexShaderType::kPointListAsTriangleStrip) {
|
||||||
modification.vertex.output_point_parameters = uint32_t(ps_param_gen_used);
|
modification.vertex.output_point_parameters = uint32_t(ps_param_gen_used);
|
||||||
@@ -805,15 +813,14 @@ bool VulkanPipelineCache::GetGeometryShaderKey(
|
|||||||
// real counts here.
|
// real counts here.
|
||||||
key.interpolator_count =
|
key.interpolator_count =
|
||||||
xe::bit_count(vertex_shader_modification.vertex.interpolator_mask);
|
xe::bit_count(vertex_shader_modification.vertex.interpolator_mask);
|
||||||
key.user_clip_plane_count =
|
|
||||||
/* vertex_shader_modification.vertex.user_clip_plane_count */ 0;
|
|
||||||
key.user_clip_plane_cull =
|
|
||||||
/* vertex_shader_modification.vertex.user_clip_plane_cull */ 0;
|
|
||||||
key.has_vertex_kill_and =
|
key.has_vertex_kill_and =
|
||||||
/* vertex_shader_modification.vertex.vertex_kill_and */ 0;
|
/* vertex_shader_modification.vertex.vertex_kill_and */ 0;
|
||||||
key.has_point_size =
|
key.has_point_size =
|
||||||
vertex_shader_modification.vertex.output_point_parameters;
|
vertex_shader_modification.vertex.output_point_parameters;
|
||||||
key.has_point_coordinates = pixel_shader_modification.pixel.param_gen_point;
|
key.has_point_coordinates = pixel_shader_modification.pixel.param_gen_point;
|
||||||
|
// Single bit to indicate if clip planes are enabled.
|
||||||
|
key.has_user_clip_planes =
|
||||||
|
uint32_t(vertex_shader_modification.vertex.user_clip_plane_count > 0);
|
||||||
key_out = key;
|
key_out = key;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -858,10 +865,12 @@ VkShaderModule VulkanPipelineCache::GetGeometryShader(GeometryShaderKey key) {
|
|||||||
assert_unhandled_case(key.type);
|
assert_unhandled_case(key.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When enabled, use max size to reduce variants from different counts.
|
||||||
|
constexpr uint32_t kMaxUserClipPlanes = 6;
|
||||||
uint32_t clip_distance_count =
|
uint32_t clip_distance_count =
|
||||||
key.user_clip_plane_cull ? 0 : key.user_clip_plane_count;
|
key.has_user_clip_planes ? kMaxUserClipPlanes : 0;
|
||||||
uint32_t cull_distance_count =
|
uint32_t cull_distance_count =
|
||||||
(key.user_clip_plane_cull ? key.user_clip_plane_count : 0) +
|
(key.has_user_clip_planes ? kMaxUserClipPlanes : 0) +
|
||||||
key.has_vertex_kill_and;
|
key.has_vertex_kill_and;
|
||||||
|
|
||||||
SpirvBuilder builder(spv::Spv_1_5,
|
SpirvBuilder builder(spv::Spv_1_5,
|
||||||
|
|||||||
@@ -224,8 +224,7 @@ class VulkanPipelineCache {
|
|||||||
struct {
|
struct {
|
||||||
PipelineGeometryShader type : 2;
|
PipelineGeometryShader type : 2;
|
||||||
uint32_t interpolator_count : 5;
|
uint32_t interpolator_count : 5;
|
||||||
uint32_t user_clip_plane_count : 3;
|
uint32_t has_user_clip_planes : 1;
|
||||||
uint32_t user_clip_plane_cull : 1;
|
|
||||||
uint32_t has_vertex_kill_and : 1;
|
uint32_t has_vertex_kill_and : 1;
|
||||||
uint32_t has_point_size : 1;
|
uint32_t has_point_size : 1;
|
||||||
uint32_t has_point_coordinates : 1;
|
uint32_t has_point_coordinates : 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user