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

View file

@ -811,10 +811,14 @@ void EmitContext::DefineAttributeMemAccess(const Info& info) {
labels.push_back(OpLabel()); labels.push_back(OpLabel());
} }
if (info.stores.ClipDistances()) { if (info.stores.ClipDistances()) {
literals.push_back(static_cast<u32>(IR::Attribute::ClipDistance0) >> 2); if (profile.max_user_clip_distances >= 4) {
labels.push_back(OpLabel()); literals.push_back(static_cast<u32>(IR::Attribute::ClipDistance0) >> 2);
literals.push_back(static_cast<u32>(IR::Attribute::ClipDistance4) >> 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);
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);
@ -843,17 +847,21 @@ void EmitContext::DefineAttributeMemAccess(const Info& info) {
++label_index; ++label_index;
} }
if (info.stores.ClipDistances()) { if (info.stores.ClipDistances()) {
AddLabel(labels[label_index]); if (profile.max_user_clip_distances >= 4) {
const Id pointer{OpAccessChain(output_f32, clip_distances, masked_index)}; AddLabel(labels[label_index]);
OpStore(pointer, store_value); const Id pointer{OpAccessChain(output_f32, clip_distances, masked_index)};
OpReturn(); OpStore(pointer, store_value);
++label_index; OpReturn();
AddLabel(labels[label_index]); ++label_index;
const Id fixed_index{OpIAdd(U32[1], masked_index, Const(4U))}; }
const Id pointer2{OpAccessChain(output_f32, clip_distances, fixed_index)}; if (profile.max_user_clip_distances >= 8) {
OpStore(pointer2, store_value); AddLabel(labels[label_index]);
OpReturn(); const Id fixed_index{OpIAdd(U32[1], masked_index, Const(4U))};
++label_index; const Id pointer{OpAccessChain(output_f32, clip_distances, fixed_index)};
OpStore(pointer, store_value);
OpReturn();
++label_index;
}
} }
AddLabel(end_block); AddLabel(end_block);
OpUnreachable(); OpUnreachable();
@ -1532,9 +1540,11 @@ 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,
clip_distances = DefineOutput(*this, type, invocations, spv::BuiltIn::ClipDistance); profile.max_user_clip_distances)))};
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)) {