blob: 90aa71596a51705d43d82804c05de501f2032fe2 [file] [log] [blame] [edit]
///////////////////////////////////////////////////////////////////////////////
// //
// DxilTranslateRawBuffer.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/DxilModule.h"
#include "dxc/DXIL/DxilOperations.h"
#include "dxc/DXIL/DxilUtil.h"
#include "dxc/HLSL/DxilGenerationPass.h"
#include "dxc/Support/Global.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include <vector>
using namespace llvm;
using namespace hlsl;
// Translate RawBufferLoad/RawBufferStore
// This pass is to make sure that we generate correct buffer load for DXIL
// For DXIL < 1.2, rawBufferLoad will be translated to BufferLoad instruction
// without mask.
namespace {
class DxilTranslateRawBuffer : public ModulePass {
public:
static char ID;
explicit DxilTranslateRawBuffer() : ModulePass(ID) {}
bool runOnModule(Module &M) {
unsigned major, minor;
DxilModule &DM = M.GetDxilModule();
DM.GetDxilVersion(major, minor);
OP *hlslOP = DM.GetOP();
// Split 64bit for shader model less than 6.3.
if (major == 1 && minor <= 2) {
for (auto F = M.functions().begin(); F != M.functions().end();) {
Function *func = &*(F++);
DXIL::OpCodeClass opClass;
if (hlslOP->GetOpCodeClass(func, opClass)) {
if (opClass == DXIL::OpCodeClass::RawBufferLoad) {
Type *ETy = OP::GetOverloadType(DXIL::OpCode::RawBufferLoad, func);
bool is64 =
ETy->isDoubleTy() || ETy == Type::getInt64Ty(ETy->getContext());
if (is64) {
ReplaceRawBufferLoad64Bit(func, ETy, M);
func->eraseFromParent();
}
} else if (opClass == DXIL::OpCodeClass::RawBufferStore) {
Type *ETy = OP::GetOverloadType(DXIL::OpCode::RawBufferStore, func);
bool is64 =
ETy->isDoubleTy() || ETy == Type::getInt64Ty(ETy->getContext());
if (is64) {
ReplaceRawBufferStore64Bit(func, ETy, M);
func->eraseFromParent();
}
}
}
}
}
if (major == 1 && minor < 2) {
for (auto F = M.functions().begin(), E = M.functions().end(); F != E;) {
Function *func = &*(F++);
if (func->hasName()) {
if (func->getName().startswith("dx.op.rawBufferLoad")) {
ReplaceRawBufferLoad(func, M);
func->eraseFromParent();
} else if (func->getName().startswith("dx.op.rawBufferStore")) {
ReplaceRawBufferStore(func, M);
func->eraseFromParent();
}
}
}
}
return true;
}
private:
// Replace RawBufferLoad/Store to BufferLoad/Store for DXIL < 1.2
void ReplaceRawBufferLoad(Function *F, Module &M);
void ReplaceRawBufferStore(Function *F, Module &M);
void ReplaceRawBufferLoad64Bit(Function *F, Type *EltTy, Module &M);
void ReplaceRawBufferStore64Bit(Function *F, Type *EltTy, Module &M);
};
} // namespace
void DxilTranslateRawBuffer::ReplaceRawBufferLoad(Function *F, Module &M) {
dxilutil::ReplaceRawBufferLoadWithBufferLoad(F, M.GetDxilModule().GetOP());
}
void DxilTranslateRawBuffer::ReplaceRawBufferLoad64Bit(Function *F, Type *EltTy,
Module &M) {
dxilutil::ReplaceRawBufferLoad64Bit(F, EltTy, M.GetDxilModule().GetOP());
}
void DxilTranslateRawBuffer::ReplaceRawBufferStore(Function *F, Module &M) {
dxilutil::ReplaceRawBufferStoreWithBufferStore(F, M.GetDxilModule().GetOP());
}
void DxilTranslateRawBuffer::ReplaceRawBufferStore64Bit(Function *F, Type *ETy,
Module &M) {
dxilutil::ReplaceRawBufferStore64Bit(F, ETy, M.GetDxilModule().GetOP());
}
char DxilTranslateRawBuffer::ID = 0;
ModulePass *llvm::createDxilTranslateRawBuffer() {
return new DxilTranslateRawBuffer();
}
INITIALIZE_PASS(DxilTranslateRawBuffer, "hlsl-translate-dxil-raw-buffer",
"Translate raw buffer load", false, false)