brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.5 KiB · 713aa3d Raw
182 lines · cpp
1//===- llvm/MC/DXContainerRootSignature.cpp - RootSignature -*- C++ -*-=======//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/MC/DXContainerRootSignature.h"10#include "llvm/ADT/SmallString.h"11#include "llvm/Support/EndianStream.h"12 13using namespace llvm;14using namespace llvm::mcdxbc;15 16static uint32_t writePlaceholder(raw_svector_ostream &Stream) {17  const uint32_t DummyValue = std::numeric_limits<uint32_t>::max();18  uint32_t Offset = Stream.tell();19  support::endian::write(Stream, DummyValue, llvm::endianness::little);20  return Offset;21}22 23static uint32_t rewriteOffsetToCurrentByte(raw_svector_ostream &Stream,24                                           uint32_t Offset) {25  uint32_t ByteOffset = Stream.tell();26  uint32_t Value = support::endian::byte_swap<uint32_t>(27      ByteOffset, llvm::endianness::little);28  Stream.pwrite(reinterpret_cast<const char *>(&Value), sizeof(Value), Offset);29  return ByteOffset;30}31 32size_t RootSignatureDesc::getSize() const {33  uint32_t StaticSamplersOffset = computeStaticSamplersOffset();34  size_t StaticSamplersSize = sizeof(dxbc::RTS0::v1::StaticSampler);35  if (Version > 2)36    StaticSamplersSize = sizeof(dxbc::RTS0::v3::StaticSampler);37 38  return size_t(StaticSamplersOffset) +39         (StaticSamplersSize * StaticSamplers.size());40}41 42uint32_t RootSignatureDesc::computeRootParametersOffset() const {43  return sizeof(dxbc::RTS0::v1::RootSignatureHeader);44}45 46uint32_t RootSignatureDesc::computeStaticSamplersOffset() const {47  uint32_t Offset = computeRootParametersOffset();48 49  for (const RootParameterInfo &I : ParametersContainer) {50    Offset += sizeof(dxbc::RTS0::v1::RootParameterHeader);51    switch (I.Type) {52    case dxbc::RootParameterType::Constants32Bit:53      Offset += sizeof(dxbc::RTS0::v1::RootConstants);54      break;55    case dxbc::RootParameterType::CBV:56    case dxbc::RootParameterType::SRV:57    case dxbc::RootParameterType::UAV:58      if (Version == 1)59        Offset += sizeof(dxbc::RTS0::v1::RootDescriptor);60      else61        Offset += sizeof(dxbc::RTS0::v2::RootDescriptor);62 63      break;64    case dxbc::RootParameterType::DescriptorTable:65      const DescriptorTable &Table =66          ParametersContainer.getDescriptorTable(I.Location);67 68      // 4 bytes for the number of ranges in table and69      // 4 bytes for the ranges offset70      Offset += 2 * sizeof(uint32_t);71      if (Version == 1)72        Offset += sizeof(dxbc::RTS0::v1::DescriptorRange) * Table.Ranges.size();73      else74        Offset += sizeof(dxbc::RTS0::v2::DescriptorRange) * Table.Ranges.size();75      break;76    }77  }78 79  return Offset;80}81 82void RootSignatureDesc::write(raw_ostream &OS) const {83  SmallString<256> Storage;84  raw_svector_ostream BOS(Storage);85  BOS.reserveExtraSpace(getSize());86 87  const uint32_t NumParameters = ParametersContainer.size();88  const uint32_t NumSamplers = StaticSamplers.size();89  support::endian::write(BOS, Version, llvm::endianness::little);90  support::endian::write(BOS, NumParameters, llvm::endianness::little);91  support::endian::write(BOS, RootParameterOffset, llvm::endianness::little);92  support::endian::write(BOS, NumSamplers, llvm::endianness::little);93  uint32_t SSO = writePlaceholder(BOS);94  support::endian::write(BOS, Flags, llvm::endianness::little);95 96  SmallVector<uint32_t> ParamsOffsets;97  for (const RootParameterInfo &I : ParametersContainer) {98    support::endian::write(BOS, I.Type, llvm::endianness::little);99    support::endian::write(BOS, I.Visibility, llvm::endianness::little);100 101    ParamsOffsets.push_back(writePlaceholder(BOS));102  }103 104  assert(NumParameters == ParamsOffsets.size());105  for (size_t I = 0; I < NumParameters; ++I) {106    rewriteOffsetToCurrentByte(BOS, ParamsOffsets[I]);107    const RootParameterInfo &Info = ParametersContainer.getInfo(I);108    switch (Info.Type) {109    case dxbc::RootParameterType::Constants32Bit: {110      const mcdxbc::RootConstants &Constants =111          ParametersContainer.getConstant(Info.Location);112      support::endian::write(BOS, Constants.ShaderRegister,113                             llvm::endianness::little);114      support::endian::write(BOS, Constants.RegisterSpace,115                             llvm::endianness::little);116      support::endian::write(BOS, Constants.Num32BitValues,117                             llvm::endianness::little);118      break;119    }120    case dxbc::RootParameterType::CBV:121    case dxbc::RootParameterType::SRV:122    case dxbc::RootParameterType::UAV: {123      const mcdxbc::RootDescriptor &Descriptor =124          ParametersContainer.getRootDescriptor(Info.Location);125 126      support::endian::write(BOS, Descriptor.ShaderRegister,127                             llvm::endianness::little);128      support::endian::write(BOS, Descriptor.RegisterSpace,129                             llvm::endianness::little);130      if (Version > 1)131        support::endian::write(BOS, Descriptor.Flags, llvm::endianness::little);132      break;133    }134    case dxbc::RootParameterType::DescriptorTable: {135      const DescriptorTable &Table =136          ParametersContainer.getDescriptorTable(Info.Location);137      support::endian::write(BOS, (uint32_t)Table.Ranges.size(),138                             llvm::endianness::little);139      rewriteOffsetToCurrentByte(BOS, writePlaceholder(BOS));140      for (const auto &Range : Table) {141        support::endian::write(BOS, static_cast<uint32_t>(Range.RangeType),142                               llvm::endianness::little);143        support::endian::write(BOS, Range.NumDescriptors,144                               llvm::endianness::little);145        support::endian::write(BOS, Range.BaseShaderRegister,146                               llvm::endianness::little);147        support::endian::write(BOS, Range.RegisterSpace,148                               llvm::endianness::little);149        if (Version > 1)150          support::endian::write(BOS, Range.Flags, llvm::endianness::little);151        support::endian::write(BOS, Range.OffsetInDescriptorsFromTableStart,152                               llvm::endianness::little);153      }154      break;155    }156    }157  }158  [[maybe_unused]] uint32_t Offset = rewriteOffsetToCurrentByte(BOS, SSO);159  assert(Offset == computeStaticSamplersOffset() &&160         "Computed offset does not match written offset");161  for (const auto &S : StaticSamplers) {162    support::endian::write(BOS, S.Filter, llvm::endianness::little);163    support::endian::write(BOS, S.AddressU, llvm::endianness::little);164    support::endian::write(BOS, S.AddressV, llvm::endianness::little);165    support::endian::write(BOS, S.AddressW, llvm::endianness::little);166    support::endian::write(BOS, S.MipLODBias, llvm::endianness::little);167    support::endian::write(BOS, S.MaxAnisotropy, llvm::endianness::little);168    support::endian::write(BOS, S.ComparisonFunc, llvm::endianness::little);169    support::endian::write(BOS, S.BorderColor, llvm::endianness::little);170    support::endian::write(BOS, S.MinLOD, llvm::endianness::little);171    support::endian::write(BOS, S.MaxLOD, llvm::endianness::little);172    support::endian::write(BOS, S.ShaderRegister, llvm::endianness::little);173    support::endian::write(BOS, S.RegisterSpace, llvm::endianness::little);174    support::endian::write(BOS, S.ShaderVisibility, llvm::endianness::little);175 176    if (Version > 2)177      support::endian::write(BOS, S.Flags, llvm::endianness::little);178  }179  assert(Storage.size() == getSize());180  OS.write(Storage.data(), Storage.size());181}182