DirectXShaderCompiler/lib/DXIL/DxilCompType.cpp

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