Files
TheRock/compiler/amd-llvm/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

154 lines
5.0 KiB
C++

//===- HLSLRootSignatureValidations.cpp - HLSL Root Signature helpers -----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file This file contains helpers for working with HLSL Root Signatures.
///
//===----------------------------------------------------------------------===//
#include "llvm/Frontend/HLSL/RootSignatureValidations.h"
#include <cmath>
namespace llvm {
namespace hlsl {
namespace rootsig {
bool verifyRootFlag(uint32_t Flags) { return (Flags & ~0xfff) == 0; }
bool verifyVersion(uint32_t Version) {
return (Version == 1 || Version == 2 || Version == 3);
}
bool verifyRegisterValue(uint32_t RegisterValue) {
return RegisterValue != ~0U;
}
// This Range is reserverved, therefore invalid, according to the spec
// https://github.com/llvm/wg-hlsl/blob/main/proposals/0002-root-signature-in-clang.md#all-the-values-should-be-legal
bool verifyRegisterSpace(uint32_t RegisterSpace) {
return !(RegisterSpace >= 0xFFFFFFF0);
}
bool verifyRootDescriptorFlag(uint32_t Version,
dxbc::RootDescriptorFlags FlagsVal) {
using FlagT = dxbc::RootDescriptorFlags;
FlagT Flags = FlagT(FlagsVal);
if (Version == 1)
return Flags == FlagT::DataVolatile;
// The data-specific flags are mutually exclusive.
FlagT DataFlags = FlagT::DataVolatile | FlagT::DataStatic |
FlagT::DataStaticWhileSetAtExecute;
if (popcount(llvm::to_underlying(Flags & DataFlags)) > 1)
return false;
// Only a data flag or no flags is valid
return (Flags | DataFlags) == DataFlags;
}
bool verifyDescriptorRangeFlag(uint32_t Version, dxil::ResourceClass Type,
dxbc::DescriptorRangeFlags Flags) {
using FlagT = dxbc::DescriptorRangeFlags;
const bool IsSampler = (Type == dxil::ResourceClass::Sampler);
if (Version == 1) {
// Since the metadata is unversioned, we expect to explicitly see the values
// that map to the version 1 behaviour here.
if (IsSampler)
return Flags == FlagT::DescriptorsVolatile;
return Flags == (FlagT::DataVolatile | FlagT::DescriptorsVolatile);
}
// The data-specific flags are mutually exclusive.
FlagT DataFlags = FlagT::DataVolatile | FlagT::DataStatic |
FlagT::DataStaticWhileSetAtExecute;
if (popcount(llvm::to_underlying(Flags & DataFlags)) > 1)
return false;
// The descriptor-specific flags are mutually exclusive.
FlagT DescriptorFlags = FlagT::DescriptorsStaticKeepingBufferBoundsChecks |
FlagT::DescriptorsVolatile;
if (popcount(llvm::to_underlying(Flags & DescriptorFlags)) > 1)
return false;
// For volatile descriptors, DATA_is never valid.
if ((Flags & FlagT::DescriptorsVolatile) == FlagT::DescriptorsVolatile) {
FlagT Mask = FlagT::DescriptorsVolatile;
if (!IsSampler) {
Mask |= FlagT::DataVolatile;
Mask |= FlagT::DataStaticWhileSetAtExecute;
}
return (Flags & ~Mask) == FlagT::None;
}
// For "KEEPING_BUFFER_BOUNDS_CHECKS" descriptors,
// the other data-specific flags may all be set.
if ((Flags & FlagT::DescriptorsStaticKeepingBufferBoundsChecks) ==
FlagT::DescriptorsStaticKeepingBufferBoundsChecks) {
FlagT Mask = FlagT::DescriptorsStaticKeepingBufferBoundsChecks;
if (!IsSampler) {
Mask |= FlagT::DataVolatile;
Mask |= FlagT::DataStatic;
Mask |= FlagT::DataStaticWhileSetAtExecute;
}
return (Flags & ~Mask) == FlagT::None;
}
// When no descriptor flag is set, any data flag is allowed.
FlagT Mask = FlagT::None;
if (!IsSampler) {
Mask |= FlagT::DataVolatile;
Mask |= FlagT::DataStaticWhileSetAtExecute;
Mask |= FlagT::DataStatic;
}
return (Flags & ~Mask) == FlagT::None;
}
bool verifyStaticSamplerFlags(uint32_t Version,
dxbc::StaticSamplerFlags Flags) {
if (Version <= 2)
return Flags == dxbc::StaticSamplerFlags::None;
dxbc::StaticSamplerFlags Mask =
dxbc::StaticSamplerFlags::NonNormalizedCoordinates |
dxbc::StaticSamplerFlags::UintBorderColor |
dxbc::StaticSamplerFlags::None;
return (Flags | Mask) == Mask;
}
bool verifyNumDescriptors(uint32_t NumDescriptors) {
return NumDescriptors > 0;
}
bool verifyMipLODBias(float MipLODBias) {
return MipLODBias >= -16.f && MipLODBias <= 15.99f;
}
bool verifyMaxAnisotropy(uint32_t MaxAnisotropy) {
return MaxAnisotropy <= 16u;
}
bool verifyLOD(float LOD) { return !std::isnan(LOD); }
bool verifyNoOverflowedOffset(uint64_t Offset) {
return Offset <= std::numeric_limits<uint32_t>::max();
}
uint64_t computeRangeBound(uint64_t Offset, uint32_t Size) {
assert(0 < Size && "Must be a non-empty range");
if (Size == NumDescriptorsUnbounded)
return NumDescriptorsUnbounded;
return Offset + uint64_t(Size) - 1;
}
} // namespace rootsig
} // namespace hlsl
} // namespace llvm