shader_recompiler: respect clip distance limits in indexed store

This commit is contained in:
Liam 2023-12-26 19:10:25 -05:00
parent 12178c694a
commit 6697b665ca
1 changed files with 28 additions and 18 deletions

View File

@ -811,11 +811,15 @@ void EmitContext::DefineAttributeMemAccess(const Info& info) {
labels.push_back(OpLabel()); labels.push_back(OpLabel());
} }
if (info.stores.ClipDistances()) { if (info.stores.ClipDistances()) {
if (profile.max_user_clip_distances >= 4) {
literals.push_back(static_cast<u32>(IR::Attribute::ClipDistance0) >> 2); literals.push_back(static_cast<u32>(IR::Attribute::ClipDistance0) >> 2);
labels.push_back(OpLabel()); labels.push_back(OpLabel());
}
if (profile.max_user_clip_distances >= 8) {
literals.push_back(static_cast<u32>(IR::Attribute::ClipDistance4) >> 2); literals.push_back(static_cast<u32>(IR::Attribute::ClipDistance4) >> 2);
labels.push_back(OpLabel()); labels.push_back(OpLabel());
} }
}
OpSelectionMerge(end_block, spv::SelectionControlMask::MaskNone); OpSelectionMerge(end_block, spv::SelectionControlMask::MaskNone);
OpSwitch(compare_index, default_label, literals, labels); OpSwitch(compare_index, default_label, literals, labels);
AddLabel(default_label); AddLabel(default_label);
@ -843,18 +847,22 @@ void EmitContext::DefineAttributeMemAccess(const Info& info) {
++label_index; ++label_index;
} }
if (info.stores.ClipDistances()) { if (info.stores.ClipDistances()) {
if (profile.max_user_clip_distances >= 4) {
AddLabel(labels[label_index]); AddLabel(labels[label_index]);
const Id pointer{OpAccessChain(output_f32, clip_distances, masked_index)}; const Id pointer{OpAccessChain(output_f32, clip_distances, masked_index)};
OpStore(pointer, store_value); OpStore(pointer, store_value);
OpReturn(); OpReturn();
++label_index; ++label_index;
}
if (profile.max_user_clip_distances >= 8) {
AddLabel(labels[label_index]); AddLabel(labels[label_index]);
const Id fixed_index{OpIAdd(U32[1], masked_index, Const(4U))}; const Id fixed_index{OpIAdd(U32[1], masked_index, Const(4U))};
const Id pointer2{OpAccessChain(output_f32, clip_distances, fixed_index)}; const Id pointer{OpAccessChain(output_f32, clip_distances, fixed_index)};
OpStore(pointer2, store_value); OpStore(pointer, store_value);
OpReturn(); OpReturn();
++label_index; ++label_index;
} }
}
AddLabel(end_block); AddLabel(end_block);
OpUnreachable(); OpUnreachable();
OpFunctionEnd(); OpFunctionEnd();
@ -1532,10 +1540,12 @@ void EmitContext::DefineOutputs(const IR::Program& program) {
if (stage == Stage::Fragment) { if (stage == Stage::Fragment) {
throw NotImplementedException("Storing ClipDistance in fragment stage"); throw NotImplementedException("Storing ClipDistance in fragment stage");
} }
const Id type{TypeArray( if (profile.max_user_clip_distances > 0) {
F32[1], Const(std::min(info.used_clip_distances, profile.max_user_clip_distances)))}; const Id type{TypeArray(F32[1], Const(std::min(info.used_clip_distances,
profile.max_user_clip_distances)))};
clip_distances = DefineOutput(*this, type, invocations, spv::BuiltIn::ClipDistance); clip_distances = DefineOutput(*this, type, invocations, spv::BuiltIn::ClipDistance);
} }
}
if (info.stores[IR::Attribute::Layer] && if (info.stores[IR::Attribute::Layer] &&
(profile.support_viewport_index_layer_non_geometry || stage == Stage::Geometry)) { (profile.support_viewport_index_layer_non_geometry || stage == Stage::Geometry)) {
if (stage == Stage::Fragment) { if (stage == Stage::Fragment) {