Browse Source

shader compiler: Ensure all clip distances are initialized when used

Thank you to Ryujinx (riperiperi specifically) for the pointer towards clip distances
Huge thanks to crueter for finding where the code works and Camille for giving pointers along the way.
nce_cpp
JPikachu 8 months ago
committed by swurl
parent
commit
fc1a3b6310
  1. 17
      src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
  2. 2
      src/shader_recompiler/backend/spirv/spirv_emit_context.h
  3. 13
      src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp

17
src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp

@ -53,6 +53,15 @@ std::optional<OutAttr> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) {
return OutputAccessChain(ctx, ctx.output_f32, info.id, index_id); return OutputAccessChain(ctx, ctx.output_f32, info.id, index_id);
} }
} }
for (u32 i = 0; i < ctx.profile.max_user_clip_distances; ++i) {
if (!clip_distance_written.test(i)) {
const Id idx = ctx.Const(i);
const Id element = OutputAccessChain(ctx, ctx.output_f32, ctx.clip_distances, idx);
ctx.OpStore(element, ctx.Const(0.0f));
}
}
switch (attr) { switch (attr) {
case IR::Attribute::PointSize: case IR::Attribute::PointSize:
return ctx.output_point_size; return ctx.output_point_size;
@ -421,6 +430,14 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value, [[maybe_un
if (Sirit::ValidId(output->type)) { if (Sirit::ValidId(output->type)) {
value = ctx.OpBitcast(output->type, value); value = ctx.OpBitcast(output->type, value);
} }
static constexpr IR::Attribute cd0 = IR::Attribute::ClipDistance0;
static constexpr IR::Attribute cd7 = IR::Attribute::ClipDistance7;
if (attr >= cd0 && attr <= cd7) {
const u32 idx = (u32) attr - (u32) cd0;
clip_distance_written.set(idx);
}
ctx.OpStore(output->pointer, value); ctx.OpStore(output->pointer, value);
} }

2
src/shader_recompiler/backend/spirv/spirv_emit_context.h

@ -15,6 +15,8 @@
namespace Shader::Backend::SPIRV { namespace Shader::Backend::SPIRV {
std::bitset<8> clip_distance_written;
using Sirit::Id; using Sirit::Id;
class VectorTypes { class VectorTypes {

13
src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp

@ -375,7 +375,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
views[view_index++] = { views[view_index++] = {
.index = handle.first, .index = handle.first,
.blacklist = blacklist, .blacklist = blacklist,
.id = {},
.id = {}
}; };
} }
}}; }};
@ -740,6 +740,12 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
? VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT ? VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT
: VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT, : VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT,
}; };
VkPipelineRasterizationDepthClipStateCreateInfoEXT depth_clip{
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT,
.pNext = nullptr,
.flags = 0,
.depthClipEnable = VK_TRUE,
};
if (IsLine(input_assembly_topology) && device.IsExtLineRasterizationSupported()) { if (IsLine(input_assembly_topology) && device.IsExtLineRasterizationSupported()) {
line_state.pNext = std::exchange(rasterization_ci.pNext, &line_state); line_state.pNext = std::exchange(rasterization_ci.pNext, &line_state);
} }
@ -749,6 +755,9 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
if (device.IsExtProvokingVertexSupported()) { if (device.IsExtProvokingVertexSupported()) {
provoking_vertex.pNext = std::exchange(rasterization_ci.pNext, &provoking_vertex); provoking_vertex.pNext = std::exchange(rasterization_ci.pNext, &provoking_vertex);
} }
if (device.IsExtDepthClipControlSupported()) {
depth_clip.pNext = std::exchange(rasterization_ci.pNext, &depth_clip);
}
const VkPipelineMultisampleStateCreateInfo multisample_ci{ const VkPipelineMultisampleStateCreateInfo multisample_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
@ -814,7 +823,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
.logicOp = static_cast<VkLogicOp>(dynamic.logic_op.Value()), .logicOp = static_cast<VkLogicOp>(dynamic.logic_op.Value()),
.attachmentCount = static_cast<u32>(cb_attachments.size()), .attachmentCount = static_cast<u32>(cb_attachments.size()),
.pAttachments = cb_attachments.data(), .pAttachments = cb_attachments.data(),
.blendConstants = {},
.blendConstants = {}
}; };
static_vector<VkDynamicState, 28> dynamic_states{ static_vector<VkDynamicState, 28> dynamic_states{
VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR,

Loading…
Cancel
Save