Path: blob/main/contrib/llvm-project/llvm/lib/MC/DXContainerRootSignature.cpp
213766 views
//===- llvm/MC/DXContainerRootSignature.cpp - RootSignature -*- C++ -*-=======//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/MC/DXContainerRootSignature.h"9#include "llvm/ADT/SmallString.h"10#include "llvm/Support/EndianStream.h"1112using namespace llvm;13using namespace llvm::mcdxbc;1415static uint32_t writePlaceholder(raw_svector_ostream &Stream) {16const uint32_t DummyValue = std::numeric_limits<uint32_t>::max();17uint32_t Offset = Stream.tell();18support::endian::write(Stream, DummyValue, llvm::endianness::little);19return Offset;20}2122static void rewriteOffsetToCurrentByte(raw_svector_ostream &Stream,23uint32_t Offset) {24uint32_t Value =25support::endian::byte_swap<uint32_t, llvm::endianness::little>(26Stream.tell());27Stream.pwrite(reinterpret_cast<const char *>(&Value), sizeof(Value), Offset);28}2930size_t RootSignatureDesc::getSize() const {31size_t Size =32sizeof(dxbc::RTS0::v1::RootSignatureHeader) +33ParametersContainer.size() * sizeof(dxbc::RTS0::v1::RootParameterHeader) +34StaticSamplers.size() * sizeof(dxbc::RTS0::v1::StaticSampler);3536for (const RootParameterInfo &I : ParametersContainer) {37switch (I.Header.ParameterType) {38case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit):39Size += sizeof(dxbc::RTS0::v1::RootConstants);40break;41case llvm::to_underlying(dxbc::RootParameterType::CBV):42case llvm::to_underlying(dxbc::RootParameterType::SRV):43case llvm::to_underlying(dxbc::RootParameterType::UAV):44if (Version == 1)45Size += sizeof(dxbc::RTS0::v1::RootDescriptor);46else47Size += sizeof(dxbc::RTS0::v2::RootDescriptor);4849break;50case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable):51const DescriptorTable &Table =52ParametersContainer.getDescriptorTable(I.Location);5354// 4 bytes for the number of ranges in table and55// 4 bytes for the ranges offset56Size += 2 * sizeof(uint32_t);57if (Version == 1)58Size += sizeof(dxbc::RTS0::v1::DescriptorRange) * Table.Ranges.size();59else60Size += sizeof(dxbc::RTS0::v2::DescriptorRange) * Table.Ranges.size();61break;62}63}64return Size;65}6667void RootSignatureDesc::write(raw_ostream &OS) const {68SmallString<256> Storage;69raw_svector_ostream BOS(Storage);70BOS.reserveExtraSpace(getSize());7172const uint32_t NumParameters = ParametersContainer.size();73const uint32_t NumSamplers = StaticSamplers.size();74support::endian::write(BOS, Version, llvm::endianness::little);75support::endian::write(BOS, NumParameters, llvm::endianness::little);76support::endian::write(BOS, RootParameterOffset, llvm::endianness::little);77support::endian::write(BOS, NumSamplers, llvm::endianness::little);78uint32_t SSO = StaticSamplersOffset;79if (NumSamplers > 0)80SSO = writePlaceholder(BOS);81else82support::endian::write(BOS, SSO, llvm::endianness::little);83support::endian::write(BOS, Flags, llvm::endianness::little);8485SmallVector<uint32_t> ParamsOffsets;86for (const RootParameterInfo &P : ParametersContainer) {87support::endian::write(BOS, P.Header.ParameterType,88llvm::endianness::little);89support::endian::write(BOS, P.Header.ShaderVisibility,90llvm::endianness::little);9192ParamsOffsets.push_back(writePlaceholder(BOS));93}9495assert(NumParameters == ParamsOffsets.size());96for (size_t I = 0; I < NumParameters; ++I) {97rewriteOffsetToCurrentByte(BOS, ParamsOffsets[I]);98const auto &[Type, Loc] = ParametersContainer.getTypeAndLocForParameter(I);99switch (Type) {100case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit): {101const dxbc::RTS0::v1::RootConstants &Constants =102ParametersContainer.getConstant(Loc);103support::endian::write(BOS, Constants.ShaderRegister,104llvm::endianness::little);105support::endian::write(BOS, Constants.RegisterSpace,106llvm::endianness::little);107support::endian::write(BOS, Constants.Num32BitValues,108llvm::endianness::little);109break;110}111case llvm::to_underlying(dxbc::RootParameterType::CBV):112case llvm::to_underlying(dxbc::RootParameterType::SRV):113case llvm::to_underlying(dxbc::RootParameterType::UAV): {114const dxbc::RTS0::v2::RootDescriptor &Descriptor =115ParametersContainer.getRootDescriptor(Loc);116117support::endian::write(BOS, Descriptor.ShaderRegister,118llvm::endianness::little);119support::endian::write(BOS, Descriptor.RegisterSpace,120llvm::endianness::little);121if (Version > 1)122support::endian::write(BOS, Descriptor.Flags, llvm::endianness::little);123break;124}125case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {126const DescriptorTable &Table =127ParametersContainer.getDescriptorTable(Loc);128support::endian::write(BOS, (uint32_t)Table.Ranges.size(),129llvm::endianness::little);130rewriteOffsetToCurrentByte(BOS, writePlaceholder(BOS));131for (const auto &Range : Table) {132support::endian::write(BOS, Range.RangeType, llvm::endianness::little);133support::endian::write(BOS, Range.NumDescriptors,134llvm::endianness::little);135support::endian::write(BOS, Range.BaseShaderRegister,136llvm::endianness::little);137support::endian::write(BOS, Range.RegisterSpace,138llvm::endianness::little);139if (Version > 1)140support::endian::write(BOS, Range.Flags, llvm::endianness::little);141support::endian::write(BOS, Range.OffsetInDescriptorsFromTableStart,142llvm::endianness::little);143}144break;145}146}147}148if (NumSamplers > 0) {149rewriteOffsetToCurrentByte(BOS, SSO);150for (const auto &S : StaticSamplers) {151support::endian::write(BOS, S.Filter, llvm::endianness::little);152support::endian::write(BOS, S.AddressU, llvm::endianness::little);153support::endian::write(BOS, S.AddressV, llvm::endianness::little);154support::endian::write(BOS, S.AddressW, llvm::endianness::little);155support::endian::write(BOS, S.MipLODBias, llvm::endianness::little);156support::endian::write(BOS, S.MaxAnisotropy, llvm::endianness::little);157support::endian::write(BOS, S.ComparisonFunc, llvm::endianness::little);158support::endian::write(BOS, S.BorderColor, llvm::endianness::little);159support::endian::write(BOS, S.MinLOD, llvm::endianness::little);160support::endian::write(BOS, S.MaxLOD, llvm::endianness::little);161support::endian::write(BOS, S.ShaderRegister, llvm::endianness::little);162support::endian::write(BOS, S.RegisterSpace, llvm::endianness::little);163support::endian::write(BOS, S.ShaderVisibility, llvm::endianness::little);164}165}166assert(Storage.size() == getSize());167OS.write(Storage.data(), Storage.size());168}169170171