359 строки
9.8 KiB
C++
359 строки
9.8 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// DxilCompType.cpp //
|
|
// Copyright (C) Microsoft Corporation. All rights reserved. //
|
|
// This file is distributed under the University of Illinois Open Source //
|
|
// License. See LICENSE.TXT for details. //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "dxc/DXIL/DxilCompType.h"
|
|
#include "dxc/Support/Global.h"
|
|
|
|
#include "llvm/IR/DerivedTypes.h"
|
|
#include "llvm/IR/LLVMContext.h"
|
|
#include "llvm/IR/Type.h"
|
|
|
|
using namespace llvm;
|
|
|
|
namespace hlsl {
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
// CompType class methods.
|
|
//
|
|
CompType::CompType() : m_Kind(Kind::Invalid) {}
|
|
|
|
CompType::CompType(Kind K) : m_Kind(K) {
|
|
DXASSERT(m_Kind >= Kind::Invalid && m_Kind < Kind::LastEntry,
|
|
"otherwise the caller passed out-of-range value");
|
|
}
|
|
|
|
CompType::CompType(unsigned int K) : CompType((Kind)K) {}
|
|
|
|
bool CompType::operator==(const CompType &o) const {
|
|
return m_Kind == o.m_Kind;
|
|
}
|
|
|
|
CompType::Kind CompType::GetKind() const { return m_Kind; }
|
|
|
|
uint8_t CompType::GetSizeInBits() const {
|
|
switch (m_Kind) {
|
|
case Kind::Invalid:
|
|
return 0;
|
|
case Kind::I1:
|
|
return 1;
|
|
case Kind::SNormF16:
|
|
case Kind::UNormF16:
|
|
case Kind::I16:
|
|
case Kind::F16:
|
|
case Kind::U16:
|
|
return 16;
|
|
case Kind::SNormF32:
|
|
case Kind::UNormF32:
|
|
case Kind::I32:
|
|
case Kind::U32:
|
|
case Kind::F32:
|
|
case Kind::PackedS8x32:
|
|
case Kind::PackedU8x32:
|
|
return 32;
|
|
case Kind::I64:
|
|
case Kind::U64:
|
|
case Kind::SNormF64:
|
|
case Kind::UNormF64:
|
|
case Kind::F64:
|
|
return 64;
|
|
default:
|
|
DXASSERT(false, "invalid type kind");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
CompType CompType::getInvalid() { return CompType(); }
|
|
|
|
CompType CompType::getF16() { return CompType(Kind::F16); }
|
|
|
|
CompType CompType::getF32() { return CompType(Kind::F32); }
|
|
|
|
CompType CompType::getF64() { return CompType(Kind::F64); }
|
|
|
|
CompType CompType::getI16() { return CompType(Kind::I16); }
|
|
|
|
CompType CompType::getI32() { return CompType(Kind::I32); }
|
|
|
|
CompType CompType::getI64() { return CompType(Kind::I64); }
|
|
|
|
CompType CompType::getU16() { return CompType(Kind::U16); }
|
|
|
|
CompType CompType::getU32() { return CompType(Kind::U32); }
|
|
|
|
CompType CompType::getU64() { return CompType(Kind::U64); }
|
|
|
|
CompType CompType::getI1() { return CompType(Kind::I1); }
|
|
|
|
CompType CompType::getSNormF16() { return CompType(Kind::SNormF16); }
|
|
|
|
CompType CompType::getUNormF16() { return CompType(Kind::UNormF16); }
|
|
|
|
CompType CompType::getSNormF32() { return CompType(Kind::SNormF32); }
|
|
|
|
CompType CompType::getUNormF32() { return CompType(Kind::UNormF32); }
|
|
|
|
CompType CompType::getSNormF64() { return CompType(Kind::SNormF64); }
|
|
|
|
CompType CompType::getUNormF64() { return CompType(Kind::UNormF64); }
|
|
|
|
bool CompType::IsInvalid() const { return m_Kind == Kind::Invalid; }
|
|
|
|
bool CompType::IsFloatTy() const {
|
|
return m_Kind == Kind::F16 || m_Kind == Kind::F32 || m_Kind == Kind::F64;
|
|
}
|
|
|
|
bool CompType::IsIntTy() const { return IsSIntTy() || IsUIntTy(); }
|
|
|
|
bool CompType::IsSIntTy() const {
|
|
return m_Kind == Kind::I16 || m_Kind == Kind::I32 || m_Kind == Kind::I64;
|
|
}
|
|
|
|
bool CompType::IsUIntTy() const {
|
|
return m_Kind == Kind::U16 || m_Kind == Kind::U32 || m_Kind == Kind::U64 ||
|
|
m_Kind == Kind::PackedS8x32 || m_Kind == Kind::PackedU8x32;
|
|
}
|
|
|
|
bool CompType::IsBoolTy() const { return m_Kind == Kind::I1; }
|
|
|
|
bool CompType::IsSNorm() const {
|
|
return m_Kind == Kind::SNormF16 || m_Kind == Kind::SNormF32 ||
|
|
m_Kind == Kind::SNormF64;
|
|
}
|
|
|
|
bool CompType::IsUNorm() const {
|
|
return m_Kind == Kind::UNormF16 || m_Kind == Kind::UNormF32 ||
|
|
m_Kind == Kind::UNormF64;
|
|
}
|
|
|
|
bool CompType::Is64Bit() const {
|
|
switch (m_Kind) {
|
|
case DXIL::ComponentType::F64:
|
|
case DXIL::ComponentType::SNormF64:
|
|
case DXIL::ComponentType::UNormF64:
|
|
case DXIL::ComponentType::I64:
|
|
case DXIL::ComponentType::U64:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool CompType::Is16Bit() const {
|
|
switch (m_Kind) {
|
|
case DXIL::ComponentType::F16:
|
|
case DXIL::ComponentType::I16:
|
|
case DXIL::ComponentType::SNormF16:
|
|
case DXIL::ComponentType::UNormF16:
|
|
case DXIL::ComponentType::U16:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
CompType CompType::GetBaseCompType() const {
|
|
switch (m_Kind) {
|
|
case Kind::I1:
|
|
return CompType(Kind::I1);
|
|
case Kind::I16:
|
|
LLVM_FALLTHROUGH;
|
|
case Kind::PackedS8x32:
|
|
LLVM_FALLTHROUGH;
|
|
case Kind::PackedU8x32:
|
|
LLVM_FALLTHROUGH;
|
|
case Kind::I32:
|
|
return CompType(Kind::I32);
|
|
case Kind::I64:
|
|
return CompType(Kind::I64);
|
|
case Kind::U16:
|
|
LLVM_FALLTHROUGH;
|
|
case Kind::U32:
|
|
return CompType(Kind::U32);
|
|
case Kind::U64:
|
|
return CompType(Kind::U64);
|
|
case Kind::SNormF16:
|
|
LLVM_FALLTHROUGH;
|
|
case Kind::UNormF16:
|
|
LLVM_FALLTHROUGH;
|
|
case Kind::F16:
|
|
LLVM_FALLTHROUGH;
|
|
case Kind::SNormF32:
|
|
LLVM_FALLTHROUGH;
|
|
case Kind::UNormF32:
|
|
LLVM_FALLTHROUGH;
|
|
case Kind::F32:
|
|
return CompType(Kind::F32);
|
|
case Kind::SNormF64:
|
|
LLVM_FALLTHROUGH;
|
|
case Kind::UNormF64:
|
|
LLVM_FALLTHROUGH;
|
|
case Kind::F64:
|
|
return CompType(Kind::F64);
|
|
default:
|
|
DXASSERT(false, "invalid type kind");
|
|
}
|
|
return CompType();
|
|
}
|
|
|
|
bool CompType::HasMinPrec() const {
|
|
switch (m_Kind) {
|
|
case Kind::I16:
|
|
case Kind::U16:
|
|
case Kind::F16:
|
|
case Kind::SNormF16:
|
|
case Kind::UNormF16:
|
|
return true;
|
|
case Kind::I1:
|
|
case Kind::PackedS8x32:
|
|
case Kind::PackedU8x32:
|
|
case Kind::I32:
|
|
case Kind::U32:
|
|
case Kind::I64:
|
|
case Kind::U64:
|
|
case Kind::F32:
|
|
case Kind::F64:
|
|
case Kind::SNormF32:
|
|
case Kind::UNormF32:
|
|
case Kind::SNormF64:
|
|
case Kind::UNormF64:
|
|
break;
|
|
default:
|
|
DXASSERT(false, "invalid comp type");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
Type *CompType::GetLLVMType(LLVMContext &Ctx) const {
|
|
switch (m_Kind) {
|
|
case Kind::I1:
|
|
return (Type *)Type::getInt1Ty(Ctx);
|
|
case Kind::I16:
|
|
case Kind::U16:
|
|
return (Type *)Type::getInt16Ty(Ctx);
|
|
case Kind::PackedS8x32:
|
|
case Kind::PackedU8x32:
|
|
case Kind::I32:
|
|
case Kind::U32:
|
|
return (Type *)Type::getInt32Ty(Ctx);
|
|
case Kind::I64:
|
|
case Kind::U64:
|
|
return (Type *)Type::getInt64Ty(Ctx);
|
|
case Kind::SNormF16:
|
|
case Kind::UNormF16:
|
|
case Kind::F16:
|
|
return Type::getHalfTy(Ctx);
|
|
case Kind::SNormF32:
|
|
case Kind::UNormF32:
|
|
case Kind::F32:
|
|
return Type::getFloatTy(Ctx);
|
|
case Kind::SNormF64:
|
|
case Kind::UNormF64:
|
|
case Kind::F64:
|
|
return Type::getDoubleTy(Ctx);
|
|
default:
|
|
DXASSERT(false, "invalid type kind");
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
PointerType *CompType::GetLLVMPtrType(LLVMContext &Ctx,
|
|
const unsigned AddrSpace) const {
|
|
switch (m_Kind) {
|
|
case Kind::I1:
|
|
return Type::getInt1PtrTy(Ctx, AddrSpace);
|
|
case Kind::I16:
|
|
case Kind::U16:
|
|
return Type::getInt16PtrTy(Ctx, AddrSpace);
|
|
case Kind::PackedS8x32:
|
|
case Kind::PackedU8x32:
|
|
case Kind::I32:
|
|
case Kind::U32:
|
|
return Type::getInt32PtrTy(Ctx, AddrSpace);
|
|
case Kind::I64:
|
|
case Kind::U64:
|
|
return Type::getInt64PtrTy(Ctx, AddrSpace);
|
|
case Kind::SNormF16:
|
|
case Kind::UNormF16:
|
|
case Kind::F16:
|
|
return Type::getHalfPtrTy(Ctx, AddrSpace);
|
|
case Kind::SNormF32:
|
|
case Kind::UNormF32:
|
|
case Kind::F32:
|
|
return Type::getFloatPtrTy(Ctx, AddrSpace);
|
|
case Kind::SNormF64:
|
|
case Kind::UNormF64:
|
|
case Kind::F64:
|
|
return Type::getDoublePtrTy(Ctx, AddrSpace);
|
|
default:
|
|
DXASSERT(false, "invalid type kind");
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
Type *CompType::GetLLVMBaseType(llvm::LLVMContext &Ctx) const {
|
|
return GetBaseCompType().GetLLVMType(Ctx);
|
|
}
|
|
|
|
CompType CompType::GetCompType(Type *type) {
|
|
LLVMContext &Ctx = type->getContext();
|
|
if (type == Type::getInt1Ty(Ctx))
|
|
return CompType(Kind::I1);
|
|
if (type == Type::getInt16Ty(Ctx))
|
|
return CompType(Kind::I16);
|
|
if (type == Type::getInt32Ty(Ctx))
|
|
return CompType(Kind::I32);
|
|
if (type == Type::getInt64Ty(Ctx))
|
|
return CompType(Kind::I64);
|
|
if (type == Type::getHalfTy(Ctx))
|
|
return CompType(Kind::F16);
|
|
if (type == Type::getFloatTy(Ctx))
|
|
return CompType(Kind::F32);
|
|
if (type == Type::getDoubleTy(Ctx))
|
|
return CompType(Kind::F64);
|
|
|
|
DXASSERT(false, "invalid type kind");
|
|
return CompType();
|
|
}
|
|
|
|
static const char *s_TypeKindNames[(unsigned)CompType::Kind::LastEntry] = {
|
|
"invalid", "i1", "i16", "u16", "i32",
|
|
"u32", "i64", "u64", "f16", "f32",
|
|
"f64", "snorm_f16", "unorm_f16", "snorm_f32", "unorm_f32",
|
|
"snorm_f64", "unorm_f64", "p32i8", "p32u8",
|
|
};
|
|
|
|
const char *CompType::GetName() const {
|
|
return s_TypeKindNames[(unsigned)m_Kind];
|
|
}
|
|
|
|
static const char *s_TypeKindHLSLNames[(unsigned)CompType::Kind::LastEntry] = {
|
|
"unknown", "bool", "int16_t", "uint16_t",
|
|
"int", "uint", "int64_t", "uint64_t",
|
|
"half", "float", "double", "snorm_half",
|
|
"unorm_half", "snorm_float", "unorm_float", "snorm_double",
|
|
"unorm_double", "int8_t_packed", "uint8_t_packed",
|
|
};
|
|
|
|
static const char
|
|
*s_TypeKindHLSLNamesMinPrecision[(unsigned)CompType::Kind::LastEntry] = {
|
|
"unknown", "bool", "min16i", "min16ui",
|
|
"int", "uint", "int64_t", "uint64_t",
|
|
"min16float", "float", "double", "snorm_min16f",
|
|
"unorm_min16f", "snorm_float", "unorm_float", "snorm_double",
|
|
"unorm_double", "int8_t_packed", "uint8_t_packed",
|
|
};
|
|
|
|
const char *CompType::GetHLSLName(bool MinPrecision) const {
|
|
return MinPrecision ? s_TypeKindHLSLNamesMinPrecision[(unsigned)m_Kind]
|
|
: s_TypeKindHLSLNames[(unsigned)m_Kind];
|
|
}
|
|
|
|
} // namespace hlsl
|