DXBC to DXIL Converter + unit tests (#2685)
Includes dxilconv-specific DXIL optimization passes added to opt.exe tool.
This commit is contained in:
Родитель
76e34cc27d
Коммит
a42ffbf491
|
@ -203,6 +203,8 @@ inline void OutputDebugFormatA(_In_ _Printf_format_string_ _Null_terminated_ con
|
|||
|
||||
#define DXASSERT_LOCALVAR(local, exp, msg) DXASSERT(exp, msg)
|
||||
|
||||
#define DXASSERT_LOCALVAR_NOMSG(local, exp) DXASSERT_LOCALVAR(local, exp, "")
|
||||
|
||||
#define DXASSERT_NOMSG(exp) DXASSERT(exp, "")
|
||||
|
||||
#define DXVERIFY_NOMSG(exp) DXASSERT(exp, "")
|
||||
|
@ -214,6 +216,8 @@ inline void OutputDebugFormatA(_In_ _Printf_format_string_ _Null_terminated_ con
|
|||
|
||||
#define DXASSERT_LOCALVAR(local, exp, msg) DXASSERT(exp, msg)
|
||||
|
||||
#define DXASSERT_LOCALVAR_NOMSG(local, exp) DXASSERT_LOCALVAR(local, exp, "")
|
||||
|
||||
#define DXVERIFY_NOMSG assert
|
||||
|
||||
#define DXASSERT_ARGS(expr, fmt, ...) do { if (!(expr)) { fprintf(stderr, fmt, __VA_ARGS__); assert(false); } } while (0);
|
||||
|
@ -232,6 +236,7 @@ inline void OutputDebugFormatA(_In_ _Printf_format_string_ _Null_terminated_ con
|
|||
|
||||
// DXASSERT_LOCALVAR is disabled in free builds, but we keep the local referenced to avoid a warning.
|
||||
#define DXASSERT_LOCALVAR(local, exp, msg) do { (void)(local); _Analysis_assume_(exp); } while (0)
|
||||
#define DXASSERT_LOCALVAR_NOMSG(local, exp) DXASSERT_LOCALVAR(local, exp, "")
|
||||
|
||||
// DXASSERT_NOMSG is disabled in free builds.
|
||||
#define DXASSERT_NOMSG(exp) _Analysis_assume_(exp)
|
||||
|
|
|
@ -13,4 +13,4 @@
|
|||
type = Library
|
||||
name = HLSL
|
||||
parent = Libraries
|
||||
required_libraries = BitReader Core DxcSupport IPA Support
|
||||
required_libraries = BitReader Core DxcSupport IPA Support DXIL
|
||||
|
|
|
@ -1,34 +1,3 @@
|
|||
# Discover the projects that use CMake in the subdirectories.
|
||||
# Note that explicit cmake invocation is required every time a new project is
|
||||
# added or removed.
|
||||
file(GLOB entries *)
|
||||
foreach(entry ${entries})
|
||||
if(IS_DIRECTORY ${entry} AND EXISTS ${entry}/CMakeLists.txt)
|
||||
if((NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/compiler-rt) AND
|
||||
(NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/dragonegg) AND
|
||||
(NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/libcxx) AND
|
||||
(NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/libcxxabi) AND
|
||||
(NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/libunwind))
|
||||
add_subdirectory(${entry})
|
||||
endif()
|
||||
endif()
|
||||
endforeach(entry)
|
||||
|
||||
# Also add in libc++ and compiler-rt trees if present (and we have
|
||||
# a sufficiently recent version of CMake where required).
|
||||
if(${LLVM_BUILD_RUNTIME})
|
||||
# MSVC isn't quite working with libc++ yet, disable it until issues are
|
||||
# fixed.
|
||||
if(NOT MSVC)
|
||||
# libc++ uses the libc++abi target names so libc++abi should be added
|
||||
# first.
|
||||
add_llvm_external_project(libcxxabi)
|
||||
add_llvm_external_project(libcxx)
|
||||
add_llvm_external_project(libunwind)
|
||||
endif()
|
||||
if(NOT LLVM_BUILD_EXTERNAL_COMPILER_RT)
|
||||
add_llvm_external_project(compiler-rt)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_llvm_external_project(dragonegg)
|
||||
if(WIN32)
|
||||
add_subdirectory(dxilconv)
|
||||
endif (WIN32)
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
set(DXILCONV_PROJECT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(DXILCONV_PROJECT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
include_directories(
|
||||
${LLVM_MAIN_INCLUDE_DIR}
|
||||
${DXILCONV_PROJECT_SOURCE_DIR}/include
|
||||
${DXILCONV_PROJECT_BINARY_DIR}/include
|
||||
)
|
||||
|
||||
macro(add_dxilconv_project_library name)
|
||||
add_llvm_library(${name} ${ARGN})
|
||||
# add_definitions(/D_ITERATOR_DEBUG_LEVEL=0)
|
||||
set_output_directory(${name} ${LLVM_RUNTIME_OUTPUT_INTDIR} ${LLVM_LIBRARY_OUTPUT_INTDIR})
|
||||
set_target_properties(${name} PROPERTIES FOLDER "Dxilconv libraries")
|
||||
endmacro(add_dxilconv_project_library)
|
||||
|
||||
macro(add_dxilconv_project_executable name)
|
||||
add_llvm_executable(${name} ${ARGN})
|
||||
set_target_properties(${name} PROPERTIES FOLDER "Dxilconv executables")
|
||||
endmacro(add_dxilconv_project_executable)
|
||||
|
||||
macro(add_dxilconv_project_test_library name)
|
||||
add_dxilconv_project_library(${name} ${ARGN})
|
||||
set_target_properties(${name} PROPERTIES FOLDER "Dxilconv tests")
|
||||
endmacro(add_dxilconv_project_test_library)
|
||||
|
||||
|
||||
if(WIN32)
|
||||
add_subdirectory(lib)
|
||||
add_subdirectory(tools)
|
||||
add_subdirectory(unittests)
|
||||
add_subdirectory(include/Tracing)
|
||||
endif()
|
|
@ -0,0 +1,68 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// DxbcConverter.h //
|
||||
// Copyright (C) Microsoft. All rights reserved. //
|
||||
// This file is distributed under the University of Illinois Open Source //
|
||||
// License. See LICENSE.TXT for details. //
|
||||
// //
|
||||
// Provides declarations for the DirectX DXBC to DXIL converter component. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __DXBC_CONVERTER__H__
|
||||
#define __DXBC_CONVERTER__H__
|
||||
|
||||
#ifndef _MSC_VER
|
||||
extern "C"
|
||||
#endif
|
||||
DXC_API_IMPORT HRESULT __stdcall DxcCreateInstance(
|
||||
_In_ REFCLSID rclsid,
|
||||
_In_ REFIID riid,
|
||||
_Out_ LPVOID* ppv
|
||||
);
|
||||
|
||||
#ifndef _MSC_VER
|
||||
extern "C"
|
||||
#endif
|
||||
DXC_API_IMPORT HRESULT __stdcall DxcCreateInstance2(
|
||||
_In_ IMalloc *pMalloc,
|
||||
_In_ REFCLSID rclsid,
|
||||
_In_ REFIID riid,
|
||||
_Out_ LPVOID* ppv
|
||||
);
|
||||
|
||||
struct __declspec(uuid("5F956ED5-78D1-4B15-8247-F7187614A041"))
|
||||
IDxbcConverter : public IUnknown {
|
||||
/// Create DXIL container out of DXBC shader blob.
|
||||
virtual HRESULT STDMETHODCALLTYPE Convert(
|
||||
_In_reads_bytes_(DxbcSize) LPCVOID pDxbc,
|
||||
_In_ UINT32 DxbcSize,
|
||||
_In_opt_z_ LPCWSTR pExtraOptions,
|
||||
_Outptr_result_bytebuffer_maybenull_(*pDxilSize) LPVOID *ppDxil,
|
||||
_Out_ UINT32 *pDxilSize,
|
||||
_Outptr_result_maybenull_z_ LPWSTR *ppDiag) = 0;
|
||||
|
||||
/// Create DXIL LLVM module out of DXBC bytecode and DDI I/O signatures.
|
||||
/// This is for driver consumption only.
|
||||
virtual HRESULT STDMETHODCALLTYPE ConvertInDriver(
|
||||
_In_reads_bytes_(pBytecode[1]) const UINT32 *pBytecode,
|
||||
_In_opt_z_ LPCVOID pInputSignature,
|
||||
_In_ UINT32 NumInputSignatureElements,
|
||||
_In_opt_z_ LPCVOID pOutputSignature,
|
||||
_In_ UINT32 NumOutputSignatureElements,
|
||||
_In_opt_z_ LPCVOID pPatchConstantSignature,
|
||||
_In_ UINT32 NumPatchConstantSignatureElements,
|
||||
_In_opt_z_ LPCWSTR pExtraOptions,
|
||||
_Out_ IDxcBlob **ppDxilModule,
|
||||
_Outptr_result_maybenull_z_ LPWSTR *ppDiag) = 0;
|
||||
};
|
||||
|
||||
__declspec(selectany)
|
||||
extern const CLSID CLSID_DxbcConverter = { /* 4900391E-B752-4EDD-A885-6FB76E25ADDB */
|
||||
0x4900391e,
|
||||
0xb752,
|
||||
0x4edd,
|
||||
{ 0xa8, 0x85, 0x6f, 0xb7, 0x6e, 0x25, 0xad, 0xdb }
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,24 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// DxilCleanup.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. //
|
||||
// //
|
||||
// Optimization of DXIL after conversion from DXBC. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace llvm {
|
||||
class PassRegistry;
|
||||
class ModulePass;
|
||||
|
||||
extern char &DxilCleanupID;
|
||||
|
||||
llvm::ModulePass *createDxilCleanupPass();
|
||||
|
||||
void initializeDxilCleanupPass(llvm::PassRegistry&);
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// NormalizeDxil.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. //
|
||||
// //
|
||||
// Normalize DXIL transformation. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
#include "llvm/Pass.h"
|
||||
|
||||
|
||||
namespace llvm {
|
||||
class Function;
|
||||
class PassRegistry;
|
||||
class FunctionPass;
|
||||
|
||||
|
||||
llvm::FunctionPass *createNormalizeDxilPass();
|
||||
void initializeNormalizeDxilPassPass(llvm::PassRegistry&);
|
||||
|
||||
// The legacy pass manager's analysis pass to normalize dxil ir.
|
||||
class NormalizeDxilPass : public FunctionPass {
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
|
||||
NormalizeDxilPass() : FunctionPass(ID) {
|
||||
initializeNormalizeDxilPassPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
// Normalize incoming dxil ir.
|
||||
bool runOnFunction(Function &F) override;
|
||||
|
||||
virtual const char *getPassName() const override { return "Normalize Dxil"; }
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// ScopeNest.h //
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. //
|
||||
// This file is distributed under the University of Illinois Open Source //
|
||||
// License. See LICENSE.TXT for details. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This file holds the type used to represent a scope nest. The
|
||||
// ScopeNestEvent is the type used by the iterator to represent the nesting
|
||||
// structure in the cfg.
|
||||
//
|
||||
// The iterator returns tokens of type ScopeNestEvent that describe the
|
||||
// structure. A ScopeNestEvent is a pair of a basic block and a scope type.
|
||||
// The block may be null depending on the scope type so it should always be
|
||||
// checked for null before using.
|
||||
//
|
||||
// See @ScopeNestIterator.h for more details on the iteration.
|
||||
//
|
||||
// The element types represent the major "events" that occur when walking a
|
||||
// scope nest. The block field corresponds to the basic block where the
|
||||
// event occurs. There may not always be a block associated with the event
|
||||
// because some events are used just to indicate transitions. For example,
|
||||
// with the If_Else and Switch_Case events, the actual else and case blocks
|
||||
// will be returned with the next event, which will have its own type indicating
|
||||
// the event caused by that block.
|
||||
//
|
||||
// The event location in the block depends on the scope type. For scope-opening
|
||||
// events, the location is at the end of the block. For example, the @If_Begin
|
||||
// event occurs an the end of the A block. For scope closing events the event
|
||||
// occurs at the top of the block. For example, the @If_End event occurs at
|
||||
// the entry to the X block. For events that do not open or close scopes
|
||||
// the events generally occur at the bottom of the block. For example, the
|
||||
// @Loop_Continue event occurs with the branch at the end of the block.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace llvm {
|
||||
|
||||
struct ScopeNestEvent {
|
||||
enum class Type {
|
||||
Invalid, // Not a valid event.
|
||||
TopLevel_Begin, // Before the first block. Block will be null.
|
||||
Body, // In the body of a scope. No interesting event.
|
||||
Switch_Begin, // Begin a switch scope. Block has multi-way branch.
|
||||
Switch_Break, // Break out of a switch scope. Block may be null.
|
||||
Switch_Case, // A case will start at the next event. Block will be null.
|
||||
Switch_End, // End a switch scope. Block is after all switch exits.
|
||||
Loop_Begin, // Begin a loop scope. Block has one branch leading to loop header.
|
||||
Loop_Continue, // A "continue" inside a loop. Block has one branch leading to loop latch.
|
||||
Loop_Break, // A "break" inside a loop. Block has one branch leading to Loop_End block.
|
||||
Loop_End, // End of loop marker. Block is after the loop (the post loop footer).
|
||||
If_Begin, // Start of if. Block has branch leading to the two sides of the if.
|
||||
If_Else, // The else body starts at the next event. Block will be null.
|
||||
If_End, // The end if marker. Block may be null.
|
||||
TopLevel_End, // After the last block. Block will be null.
|
||||
};
|
||||
|
||||
typedef const BasicBlock BlockTy; // TODO: make this a template so we can have const and non-const iterators.
|
||||
Type ElementType;
|
||||
BlockTy *Block;
|
||||
|
||||
ScopeNestEvent(BlockTy *B, Type T) : Block(B), ElementType(T) {}
|
||||
static ScopeNestEvent Invalid() { return ScopeNestEvent(nullptr, Type::Invalid); }
|
||||
|
||||
const bool IsBeginScope() const {
|
||||
switch (ElementType) {
|
||||
case Type::TopLevel_Begin: return "TopLevel_Begin";
|
||||
case Type::Switch_Begin: return "Switch_Begin";
|
||||
case Type::Loop_Begin: return "Loop_Begin";
|
||||
case Type::If_Begin: return "If_Begin";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool IsEndScope() const {
|
||||
switch (ElementType) {
|
||||
case Type::If_End:
|
||||
case Type::Switch_End:
|
||||
case Type::Loop_End:
|
||||
case Type::TopLevel_End:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *GetElementTypeName() const {
|
||||
switch (ElementType) {
|
||||
case Type::Invalid: return "Invalid";
|
||||
case Type::TopLevel_Begin: return "TopLevel_Begin";
|
||||
case Type::Body: return "Body";
|
||||
case Type::Switch_Begin: return "Switch_Begin";
|
||||
case Type::Switch_Case: return "Switch_Case";
|
||||
case Type::Switch_Break: return "Switch_Break";
|
||||
case Type::Switch_End: return "Switch_End";
|
||||
case Type::Loop_Begin: return "Loop_Begin";
|
||||
case Type::Loop_Continue: return "Loop_Continue";
|
||||
case Type::Loop_Break: return "Loop_Break";
|
||||
case Type::Loop_End: return "Loop_End";
|
||||
case Type::If_Begin: return "If_Begin";
|
||||
case Type::If_Else: return "If_Else";
|
||||
case Type::If_End: return "If_End";
|
||||
case Type::TopLevel_End: return "TopLevel_End";
|
||||
}
|
||||
assert(false && "unreachable");
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
bool operator==(const ScopeNestEvent &other) const {
|
||||
return Block == other.Block && ElementType == other.ElementType;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// ScopeNestInfo.h //
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. //
|
||||
// This file is distributed under the University of Illinois Open Source //
|
||||
// License. See LICENSE.TXT for details. //
|
||||
// //
|
||||
// Implementation of ScopeNestInfo class and related transformation pass. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Pass to read the scope nest annotations in a cfg and provide a high-level
|
||||
// view of the scope nesting structure.
|
||||
//
|
||||
// The pass follows the same usage patter as the LLVM LoopInfo pass. We have
|
||||
// a ScopeNestInfo class that contains the results of the scope info
|
||||
// analysis. The ScopeNestInfoWrapperPass class is the pass implementation
|
||||
// that runs the analysis and saves the results so it can be queried by
|
||||
// a later pass.
|
||||
//
|
||||
// This pass requires the the -scopenestedcfg pass has been run prior to
|
||||
// running this pass because we rely on the cfg annotations added by the
|
||||
// scopenestedcfg pass.
|
||||
//
|
||||
// This pass is itself a thin wrapper around the ScopeNestIterator pass. The
|
||||
// iterator does the heavy lifting and we just cache the results of the
|
||||
// iteration here. We keep the iterator separate so that it can be easily
|
||||
// run outside the llvm pass infrastructure.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
#include "llvm/Pass.h"
|
||||
#include "DxilConvPasses/ScopeNest.h"
|
||||
|
||||
|
||||
namespace llvm {
|
||||
class Function;
|
||||
class PassRegistry;
|
||||
class FunctionPass;
|
||||
|
||||
|
||||
llvm::FunctionPass *createScopeNestInfoWrapperPass();
|
||||
void initializeScopeNestInfoWrapperPassPass(llvm::PassRegistry&);
|
||||
|
||||
// Class to hold the results of the scope nest analysis.
|
||||
//
|
||||
// Provides an iterator to examine the sequence of ScopeNestElements.
|
||||
// We could provide a higher-level view of the scope nesting if needed,
|
||||
// but that would probably build on the stream of elements anyway.
|
||||
//
|
||||
// This class is modeled after llvm LoopInfo.
|
||||
class ScopeNestInfo {
|
||||
public:
|
||||
typedef std::vector<ScopeNestEvent>::const_iterator elements_iterator;
|
||||
typedef iterator_range<elements_iterator> elements_iterator_range;
|
||||
|
||||
elements_iterator elements_begin() { return m_scopeElements.begin(); }
|
||||
elements_iterator elements_end() { return m_scopeElements.end(); }
|
||||
elements_iterator_range elements(){ return elements_iterator_range(elements_begin(), elements_end()); }
|
||||
|
||||
void Analyze(Function &F);
|
||||
void print(raw_ostream &O) const;
|
||||
void releaseMemory();
|
||||
|
||||
private:
|
||||
std::vector<ScopeNestEvent> m_scopeElements;
|
||||
|
||||
raw_ostream &indent(raw_ostream &O, int level, StringRef str) const;
|
||||
};
|
||||
|
||||
// The legacy pass manager's analysis pass to read scope nest annotation information.
|
||||
//
|
||||
// This class is modeled after the llvm LoopInfoWrapperPass.
|
||||
class ScopeNestInfoWrapperPass : public FunctionPass {
|
||||
ScopeNestInfo SI;
|
||||
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
|
||||
ScopeNestInfoWrapperPass() : FunctionPass(ID) {
|
||||
initializeScopeNestInfoWrapperPassPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
ScopeNestInfo &getScopeNestedInfo() { return SI; }
|
||||
const ScopeNestInfo &getScopeNestedInfo() const { return SI; }
|
||||
|
||||
// Read the scope nest annotation information for a given function.
|
||||
bool runOnFunction(Function &F) override;
|
||||
|
||||
void releaseMemory() override;
|
||||
|
||||
void print(raw_ostream &O, const Module *M = nullptr) const override;
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
};
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,53 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// ScopeNestedCFG.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. //
|
||||
// //
|
||||
// Pass that converts a reducible CFG into scope-nested CFG. //
|
||||
// The pass expects that the following passes have been run //
|
||||
// right before the pass is invoked: //
|
||||
// -simplifycfg //
|
||||
// -loop-simplify //
|
||||
// -reg2mem_hlsl //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace llvm {
|
||||
class Module;
|
||||
class Function;
|
||||
class PassRegistry;
|
||||
class FunctionPass;
|
||||
|
||||
|
||||
llvm::FunctionPass *createScopeNestedCFGPass();
|
||||
void initializeScopeNestedCFGPass(llvm::PassRegistry&);
|
||||
|
||||
llvm::FunctionPass *createLoopSimplifyFunctionPass();
|
||||
void initializeLoopSimplifyFunctionPass(llvm::PassRegistry&);
|
||||
|
||||
enum class BranchKind {
|
||||
Invalid = 0,
|
||||
|
||||
IfBegin,
|
||||
IfEnd,
|
||||
IfNoEnd,
|
||||
|
||||
SwitchBegin,
|
||||
SwitchEnd,
|
||||
SwitchNoEnd,
|
||||
SwitchBreak,
|
||||
|
||||
LoopBegin,
|
||||
LoopExit,
|
||||
LoopNoEnd,
|
||||
LoopBreak,
|
||||
LoopContinue,
|
||||
LoopBackEdge,
|
||||
};
|
||||
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,35 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// DXIncludes.h //
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. //
|
||||
// This file is distributed under the University of Illinois Open Source //
|
||||
// License. See LICENSE.TXT for details. //
|
||||
// //
|
||||
// This is a common include for DXBC/Windows related things. //
|
||||
// //
|
||||
// IMPORTANT: do not add LLVM/Clang or DXIL files to this file. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
// This is a platform-specific file.
|
||||
// Do not add LLVM/Clang or DXIL files to this file.
|
||||
|
||||
#define NOMINMAX 1
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#define VC_EXTRALEAN 1
|
||||
#include <windows.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
#include <dxgitype.h>
|
||||
#include <d3dcommon.h>
|
||||
#include <d3d11.h>
|
||||
#include <d3d12.h>
|
||||
#include "dxc/Support/d3dx12.h"
|
||||
#include "DxbcSignatures.h"
|
||||
#include <d3dcompiler.h>
|
||||
#include <wincrypt.h>
|
||||
#include <d3d12TokenizedProgramFormat.hpp>
|
||||
#include <ShaderBinary/ShaderBinary.h>
|
|
@ -0,0 +1,141 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// DxbcSignatures.h //
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. //
|
||||
// This file is distributed under the University of Illinois Open Source //
|
||||
// License. See LICENSE.TXT for details. //
|
||||
// //
|
||||
// Declaration of shader parameter structs in DXBC container. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef D3D_NAME D3D10_NAME;
|
||||
typedef D3D_REGISTER_COMPONENT_TYPE D3D10_REGISTER_COMPONENT_TYPE;
|
||||
|
||||
|
||||
typedef struct _D3D11_INTERNALSHADER_PARAMETER_FOR_GS
|
||||
{
|
||||
UINT Stream; // Stream index (parameters must appear in non-decreasing stream order)
|
||||
UINT SemanticName; // Offset to LPCSTR
|
||||
UINT SemanticIndex; // Semantic Index
|
||||
D3D10_NAME SystemValue; // Internally defined enumeration
|
||||
D3D10_REGISTER_COMPONENT_TYPE ComponentType; // Type of of bits
|
||||
UINT Register; // Register Index
|
||||
BYTE Mask; // Combination of D3D10_COMPONENT_MASK values
|
||||
|
||||
// The following unioned fields, NeverWrites_Mask and AlwaysReads_Mask, are exclusively used for
|
||||
// output signatures or input signatures, respectively.
|
||||
//
|
||||
// For an output signature, NeverWrites_Mask indicates that the shader the signature belongs to never
|
||||
// writes to the masked components of the output register. Meaningful bits are the ones set in Mask above.
|
||||
//
|
||||
// For an input signature, AlwaysReads_Mask indicates that the shader the signature belongs to always
|
||||
// reads the masked components of the input register. Meaningful bits are the ones set in the Mask above.
|
||||
//
|
||||
// This allows many shaders to share similar signatures even though some of them may not happen to use
|
||||
// all of the inputs/outputs - something which may not be obvious when authored. The NeverWrites_Mask
|
||||
// and AlwaysReads_Mask can be checked in a debug layer at runtime for the one interesting case: that a
|
||||
// shader that always reads a value is fed by a shader that always writes it. Cases where shaders may
|
||||
// read values or may not cannot be validated unfortunately.
|
||||
//
|
||||
// In scenarios where a signature is being passed around standalone (so it isn't tied to input or output
|
||||
// of a given shader), this union can be zeroed out in the absence of more information. This effectively
|
||||
// forces off linkage validation errors with the signature, since if interpreted as a input or output signature
|
||||
// somehow, since the meaning on output would be "everything is always written" and on input it would be
|
||||
// "nothing is always read".
|
||||
union
|
||||
{
|
||||
BYTE NeverWrites_Mask; // For an output signature, the shader the signature belongs to never
|
||||
// writes the masked components of the output register.
|
||||
BYTE AlwaysReads_Mask; // For an input signature, the shader the signature belongs to always
|
||||
// reads the masked components of the input register.
|
||||
};
|
||||
} D3D11_INTERNALSHADER_PARAMETER_FOR_GS, *LPD3D11_INTERNALSHADER_PARAMETER_FOR_GS;
|
||||
|
||||
typedef struct _D3D11_INTERNALSHADER_PARAMETER_11_1
|
||||
{
|
||||
UINT Stream; // Stream index (parameters must appear in non-decreasing stream order)
|
||||
UINT SemanticName; // Offset to LPCSTR
|
||||
UINT SemanticIndex; // Semantic Index
|
||||
D3D10_NAME SystemValue; // Internally defined enumeration
|
||||
D3D10_REGISTER_COMPONENT_TYPE ComponentType; // Type of of bits
|
||||
UINT Register; // Register Index
|
||||
BYTE Mask; // Combination of D3D10_COMPONENT_MASK values
|
||||
|
||||
// The following unioned fields, NeverWrites_Mask and AlwaysReads_Mask, are exclusively used for
|
||||
// output signatures or input signatures, respectively.
|
||||
//
|
||||
// For an output signature, NeverWrites_Mask indicates that the shader the signature belongs to never
|
||||
// writes to the masked components of the output register. Meaningful bits are the ones set in Mask above.
|
||||
//
|
||||
// For an input signature, AlwaysReads_Mask indicates that the shader the signature belongs to always
|
||||
// reads the masked components of the input register. Meaningful bits are the ones set in the Mask above.
|
||||
//
|
||||
// This allows many shaders to share similar signatures even though some of them may not happen to use
|
||||
// all of the inputs/outputs - something which may not be obvious when authored. The NeverWrites_Mask
|
||||
// and AlwaysReads_Mask can be checked in a debug layer at runtime for the one interesting case: that a
|
||||
// shader that always reads a value is fed by a shader that always writes it. Cases where shaders may
|
||||
// read values or may not cannot be validated unfortunately.
|
||||
//
|
||||
// In scenarios where a signature is being passed around standalone (so it isn't tied to input or output
|
||||
// of a given shader), this union can be zeroed out in the absence of more information. This effectively
|
||||
// forces off linkage validation errors with the signature, since if interpreted as a input or output signature
|
||||
// somehow, since the meaning on output would be "everything is always written" and on input it would be
|
||||
// "nothing is always read".
|
||||
union
|
||||
{
|
||||
BYTE NeverWrites_Mask; // For an output signature, the shader the signature belongs to never
|
||||
// writes the masked components of the output register.
|
||||
BYTE AlwaysReads_Mask; // For an input signature, the shader the signature belongs to always
|
||||
// reads the masked components of the input register.
|
||||
};
|
||||
|
||||
D3D_MIN_PRECISION MinPrecision; // Minimum precision of input/output data
|
||||
} D3D11_INTERNALSHADER_PARAMETER_11_1, *LPD3D11_INTERNALSHADER_PARAMETER_11_1;
|
||||
|
||||
|
||||
typedef struct _D3D10_INTERNALSHADER_SIGNATURE
|
||||
{
|
||||
UINT Parameters; // Number of parameters
|
||||
UINT ParameterInfo; // Offset to D3D10_INTERNALSHADER_PARAMETER[Parameters]
|
||||
} D3D10_INTERNALSHADER_SIGNATURE, *LPD3D10_INTERNALSHADER_SIGNATURE;
|
||||
|
||||
typedef struct _D3D10_INTERNALSHADER_PARAMETER
|
||||
{
|
||||
UINT SemanticName; // Offset to LPCSTR
|
||||
UINT SemanticIndex; // Semantic Index
|
||||
D3D10_NAME SystemValue; // Internally defined enumeration
|
||||
D3D10_REGISTER_COMPONENT_TYPE ComponentType; // Type of of bits
|
||||
UINT Register; // Register Index
|
||||
BYTE Mask; // Combination of D3D10_COMPONENT_MASK values
|
||||
|
||||
// The following unioned fields, NeverWrites_Mask and AlwaysReads_Mask, are exclusively used for
|
||||
// output signatures or input signatures, respectively.
|
||||
//
|
||||
// For an output signature, NeverWrites_Mask indicates that the shader the signature belongs to never
|
||||
// writes to the masked components of the output register. Meaningful bits are the ones set in Mask above.
|
||||
//
|
||||
// For an input signature, AlwaysReads_Mask indicates that the shader the signature belongs to always
|
||||
// reads the masked components of the input register. Meaningful bits are the ones set in the Mask above.
|
||||
//
|
||||
// This allows many shaders to share similar signatures even though some of them may not happen to use
|
||||
// all of the inputs/outputs - something which may not be obvious when authored. The NeverWrites_Mask
|
||||
// and AlwaysReads_Mask can be checked in a debug layer at runtime for the one interesting case: that a
|
||||
// shader that always reads a value is fed by a shader that always writes it. Cases where shaders may
|
||||
// read values or may not cannot be validated unfortunately.
|
||||
//
|
||||
// In scenarios where a signature is being passed around standalone (so it isn't tied to input or output
|
||||
// of a given shader), this union can be zeroed out in the absence of more information. This effectively
|
||||
// forces off linkage validation errors with the signature, since if interpreted as a input or output signature
|
||||
// somehow, since the meaning on output would be "everything is always written" and on input it would be
|
||||
// "nothing is always read".
|
||||
union
|
||||
{
|
||||
BYTE NeverWrites_Mask; // For an output signature, the shader the signature belongs to never
|
||||
// writes the masked components of the output register.
|
||||
BYTE AlwaysReads_Mask; // For an input signature, the shader the signature belongs to always
|
||||
// reads the masked components of the input register.
|
||||
};
|
||||
} D3D10_INTERNALSHADER_PARAMETER, *LPD3D10_INTERNALSHADER_PARAMETER;
|
|
@ -0,0 +1,42 @@
|
|||
# Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
# This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
# Generate ETW instrumentation.
|
||||
|
||||
# Create the header in a temporary file and only update when necessary,
|
||||
# to avoid invalidating targets that depend on it.
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/dxc/Tracing/tmpdxcruntimeetw.h
|
||||
COMMAND mc -r ${CMAKE_CURRENT_BINARY_DIR} -h ${CMAKE_CURRENT_BINARY_DIR} -p DxcRuntimeEtw_ -um -z tmpdxcruntimeetw ${CMAKE_CURRENT_SOURCE_DIR}/DxcRuntime.man
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/DxcRuntime.man
|
||||
COMMENT "Building instrumentation manifest ..."
|
||||
)
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/dxc/Tracing/DxcRuntimeEtw.h
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tmpdxcruntimeetw.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/DxcRuntimeEtw.h
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tmpdxcruntimeetw.rc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/DxcRuntimeEtw.rc
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tmpdxcruntimeetwTEMP.bin
|
||||
${CMAKE_CURRENT_BINARY_DIR}/DxcRuntimeEtwtemp.BIN
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tmpdxcruntimeetw_msg00001.bin
|
||||
${CMAKE_CURRENT_BINARY_DIR}/DxcRuntimeEtw_msg00001.bin
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/dxc/Tracing/tmpdxcruntimeetw.h
|
||||
COMMENT "Updating instrumentation manifest ..."
|
||||
)
|
||||
|
||||
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/DxcRuntimeEtw.h PROPERTIES GENERATED 1)
|
||||
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/DxcRuntimeEtw.rc PROPERTIES GENERATED 1)
|
||||
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/DxcRuntimeEtwtemp.bin PROPERTIES GENERATED 1)
|
||||
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/DxcRuntimeEtw_msg00001.bin PROPERTIES GENERATED 1)
|
||||
|
||||
add_custom_target(DxcRuntimeEtw
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/dxc/Tracing/DxcRuntimeEtw.h
|
||||
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/DxcRuntime.man
|
||||
)
|
||||
|
||||
# Not quite library, but close enough.
|
||||
set_target_properties(DxcRuntimeEtw PROPERTIES FOLDER "Dxilconv libraries")
|
|
@ -0,0 +1,154 @@
|
|||
<?xml version='1.0' encoding='utf-8' standalone='yes'?>
|
||||
<instrumentationManifest xmlns="http://schemas.microsoft.com/win/2004/08/events">
|
||||
<instrumentation
|
||||
xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
>
|
||||
<events xmlns="http://schemas.microsoft.com/win/2004/08/events">
|
||||
<provider
|
||||
guid="{af2ca688-62aa-48e9-8bf6-a0ca0cae2354}"
|
||||
message="$(string.eventProviderName)"
|
||||
messageFileName="%SystemRoot%\system32\dxcompilerp.dll"
|
||||
name="Microsoft-Windows-DxcRuntime-API"
|
||||
resourceFileName="%SystemRoot%\system32\dxcompilerp.dll"
|
||||
symbol="MICROSOFT_WINDOWS_DXCRUNTIME_PROVIDER"
|
||||
>
|
||||
<channels>
|
||||
<channel
|
||||
chid="DxcRuntimeAnalytic"
|
||||
name="Microsoft-Windows-DxcRuntime-API/Analytic"
|
||||
type="Analytic"
|
||||
/>
|
||||
</channels>
|
||||
<tasks>
|
||||
<task
|
||||
name="DxcRuntimeInitialization"
|
||||
value="1"
|
||||
/>
|
||||
<task
|
||||
name="DxcRuntimeShutdown"
|
||||
value="2"
|
||||
/>
|
||||
<task
|
||||
name="DxcTranslate"
|
||||
value="3"
|
||||
>
|
||||
<opcodes>
|
||||
<opcode
|
||||
message="$(string.Task.DxcTranslate.TranslateStats)"
|
||||
name="TranslateStats"
|
||||
symbol="TranslateStats"
|
||||
value="100"
|
||||
/>
|
||||
</opcodes>
|
||||
</task>
|
||||
</tasks>
|
||||
<events>
|
||||
<event
|
||||
channel="DxcRuntimeAnalytic"
|
||||
level="win:Informational"
|
||||
opcode="win:Start"
|
||||
symbol="DxcRuntimeInitialization_Start"
|
||||
task="DxcRuntimeInitialization"
|
||||
value="0"
|
||||
/>
|
||||
<event
|
||||
channel="DxcRuntimeAnalytic"
|
||||
level="win:Informational"
|
||||
opcode="win:Stop"
|
||||
symbol="DxcRuntimeInitialization_Stop"
|
||||
task="DxcRuntimeInitialization"
|
||||
template="OperationResultTemplate"
|
||||
value="1"
|
||||
/>
|
||||
<event
|
||||
channel="DxcRuntimeAnalytic"
|
||||
level="win:Informational"
|
||||
opcode="win:Start"
|
||||
symbol="DxcRuntimeShutdown_Start"
|
||||
task="DxcRuntimeShutdown"
|
||||
value="2"
|
||||
/>
|
||||
<event
|
||||
channel="DxcRuntimeAnalytic"
|
||||
level="win:Informational"
|
||||
opcode="win:Stop"
|
||||
symbol="DxcRuntimeShutdown_Stop"
|
||||
task="DxcRuntimeShutdown"
|
||||
template="OperationResultTemplate"
|
||||
value="3"
|
||||
/>
|
||||
<event
|
||||
channel="DxcRuntimeAnalytic"
|
||||
level="win:Informational"
|
||||
opcode="win:Start"
|
||||
symbol="DxcTranslate_Start"
|
||||
task="DxcTranslate"
|
||||
value="4"
|
||||
/>
|
||||
<event
|
||||
channel="DxcRuntimeAnalytic"
|
||||
level="win:Informational"
|
||||
opcode="win:Stop"
|
||||
symbol="DxcTranslate_Stop"
|
||||
task="DxcTranslate"
|
||||
template="OperationResultTemplate"
|
||||
value="5"
|
||||
/>
|
||||
<event
|
||||
channel="DxcRuntimeAnalytic"
|
||||
level="win:Informational"
|
||||
opcode="TranslateStats"
|
||||
symbol="DxcTranslate_TranslateStats"
|
||||
task="DxcTranslate"
|
||||
template="TranslateStatsTemplate"
|
||||
value="6"
|
||||
/>
|
||||
</events>
|
||||
<templates>
|
||||
<template tid="OperationResultTemplate">
|
||||
<data
|
||||
inType="win:Int32"
|
||||
name="errorCode"
|
||||
outType="win:HResult"
|
||||
/>
|
||||
</template>
|
||||
<template tid="TranslateStatsTemplate">
|
||||
<data
|
||||
inType="win:UInt32"
|
||||
name="inputByteCount"
|
||||
/>
|
||||
<data
|
||||
inType="win:UInt32"
|
||||
name="inputShaderSize"
|
||||
/>
|
||||
<data
|
||||
inType="win:Binary"
|
||||
length="inputShaderSize"
|
||||
name="inputShader"
|
||||
/>
|
||||
<data
|
||||
inType="win:UInt32"
|
||||
name="outputByteCount"
|
||||
/>
|
||||
</template>
|
||||
</templates>
|
||||
</provider>
|
||||
</events>
|
||||
</instrumentation>
|
||||
<localization>
|
||||
<resources culture="en-US">
|
||||
<stringTable>
|
||||
<string
|
||||
id="eventProviderName"
|
||||
value="Microsoft-Windows-DxcRuntime-API"
|
||||
/>
|
||||
<string
|
||||
id="Task.DxcTranslate.TranslateStats"
|
||||
value="Translation statistics."
|
||||
/>
|
||||
</stringTable>
|
||||
</resources>
|
||||
</localization>
|
||||
</instrumentationManifest>
|
|
@ -0,0 +1,4 @@
|
|||
add_subdirectory(DxilConvPasses)
|
||||
add_subdirectory(DxbcConverter)
|
||||
add_subdirectory(ShaderBinary)
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# Build DxbcConverter.lib.
|
||||
|
||||
find_package(D3D12 REQUIRED)
|
||||
|
||||
add_dxilconv_project_library(DxbcConverter
|
||||
DxbcConverter.cpp
|
||||
DxbcUtil.cpp
|
||||
)
|
||||
|
||||
add_dependencies(DxbcConverter intrinsics_gen DxcRuntimeEtw)
|
||||
|
||||
include_directories(
|
||||
${D3D12_INCLUDE_DIRS}
|
||||
)
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,634 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// DxbcConverterImpl.h //
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved. //
|
||||
// This file is distributed under the University of Illinois Open Source //
|
||||
// License. See LICENSE.TXT for details. //
|
||||
// //
|
||||
// Utilities to convert from DXBC to DXIL. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "dxc/DXIL/DXIL.h"
|
||||
#include "dxc/DxilContainer/DxilContainer.h"
|
||||
#include "dxc/DxilContainer/DxilContainerReader.h"
|
||||
#include "llvm/Analysis/ReducibilityAnalysis.h"
|
||||
#include "dxc/Support/Global.h"
|
||||
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "llvm/Support/PrettyStackTrace.h"
|
||||
#include "llvm/Support/Signals.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/Host.h"
|
||||
#include "llvm/Support/FileOutputBuffer.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/GlobalVariable.h"
|
||||
#include "llvm/IR/CFG.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/InstVisitor.h"
|
||||
#include "llvm/Bitcode/ReaderWriter.h"
|
||||
#include "llvm/Bitcode/BitstreamWriter.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
||||
|
||||
#include <atlbase.h>
|
||||
#include "dxc/Support/microcom.h"
|
||||
#include "Support/DXIncludes.h"
|
||||
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/MSFileSystem.h"
|
||||
#include "dxc/Support/FileIOHelper.h"
|
||||
#include "dxc/dxcapi.h"
|
||||
|
||||
#include "DxbcUtil.h"
|
||||
#include "DxbcConverter.h"
|
||||
|
||||
#include "dxc/DxilContainer/DxilPipelineStateValidation.h"
|
||||
|
||||
#include "Tracing/DxcRuntimeEtw.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
#pragma once
|
||||
namespace llvm {
|
||||
using legacy::PassManagerBase;
|
||||
using legacy::PassManager;
|
||||
using legacy::FunctionPassManager;
|
||||
}
|
||||
|
||||
using namespace llvm;
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
using std::pair;
|
||||
using std::vector;
|
||||
using std::map;
|
||||
using std::unique_ptr;
|
||||
|
||||
|
||||
struct D3D12DDIARG_SIGNATURE_ENTRY_0012 {
|
||||
D3D10_SB_NAME SystemValue;
|
||||
UINT Register;
|
||||
BYTE Mask;
|
||||
BYTE Stream;
|
||||
D3D10_SB_REGISTER_COMPONENT_TYPE RegisterComponentType;
|
||||
D3D11_SB_OPERAND_MIN_PRECISION MinPrecision;
|
||||
};
|
||||
|
||||
|
||||
namespace hlsl {
|
||||
|
||||
#define DXBC_FOURCC(ch0, ch1, ch2, ch3) \
|
||||
((UINT)(BYTE)(ch0) | ((UINT)(BYTE)(ch1) << 8) | \
|
||||
((UINT)(BYTE)(ch2) << 16) | ((UINT)(BYTE)(ch3) << 24 ))
|
||||
|
||||
enum DXBCFourCC {
|
||||
DXBC_GenericShader = DXBC_FOURCC('S', 'H', 'D', 'R'),
|
||||
DXBC_GenericShaderEx = DXBC_FOURCC('S', 'H', 'E', 'X'),
|
||||
DXBC_InputSignature = DXBC_FOURCC('I', 'S', 'G', 'N'),
|
||||
DXBC_InputSignature11_1 = DXBC_FOURCC('I', 'S', 'G', '1'), // == DFCC_InputSignature
|
||||
DXBC_PatchConstantSignature = DXBC_FOURCC('P', 'C', 'S', 'G'),
|
||||
DXBC_PatchConstantSignature11_1 = DXBC_FOURCC('P', 'S', 'G', '1'), // == DFCC_PatchConstantSignature
|
||||
DXBC_OutputSignature = DXBC_FOURCC('O', 'S', 'G', 'N'),
|
||||
DXBC_OutputSignature5 = DXBC_FOURCC('O', 'S', 'G', '5'),
|
||||
DXBC_OutputSignature11_1 = DXBC_FOURCC('O', 'S', 'G', '1'), // == DFCC_OutputSignature
|
||||
DXBC_ShaderFeatureInfo = DXBC_FOURCC('S', 'F', 'I', '0'), // == DFCC_FeatureInfo
|
||||
DXBC_RootSignature = DXBC_FOURCC('R', 'T', 'S', '0'), // == DFCC_RootSignature
|
||||
DXBC_DXIL = DXBC_FOURCC('D', 'X', 'I', 'L'), // == DFCC_DXIL
|
||||
DXBC_PipelineStateValidation = DXBC_FOURCC('P', 'S', 'V', '0'), // == DFCC_PipelineStateValidation
|
||||
};
|
||||
#undef DXBC_FOURCC
|
||||
|
||||
|
||||
/// Use this class to parse DXBC signatures.
|
||||
class SignatureHelper {
|
||||
public:
|
||||
// Signature elements.
|
||||
DxilSignature m_Signature;
|
||||
|
||||
// Use this to represent signature element record that comes from either:
|
||||
// (1) DXBC signature blob, or (2) DDI signature vector.
|
||||
struct ElementRecord {
|
||||
string SemanticName;
|
||||
unsigned SemanticIndex;
|
||||
unsigned StartRow;
|
||||
unsigned StartCol;
|
||||
unsigned Rows;
|
||||
unsigned Cols;
|
||||
unsigned Stream;
|
||||
CompType ComponentType;
|
||||
};
|
||||
vector<ElementRecord> m_ElementRecords;
|
||||
|
||||
// Use this to represent register range declaration.
|
||||
struct Range {
|
||||
unsigned StartRow;
|
||||
unsigned StartCol;
|
||||
unsigned Rows;
|
||||
unsigned Cols;
|
||||
BYTE OutputStream;
|
||||
|
||||
Range() : StartRow(UINT_MAX), StartCol(UINT_MAX), Rows(0), Cols(0), OutputStream(0) {}
|
||||
|
||||
unsigned GetStartRow() const { return StartRow; }
|
||||
unsigned GetStartCol() const { return StartCol; }
|
||||
unsigned GetEndRow() const { return StartRow + Rows - 1; }
|
||||
unsigned GetEndCol() const { return StartCol + Cols - 1; }
|
||||
|
||||
struct LTRangeByStreamAndStartRowAndStartCol {
|
||||
bool operator()(const Range &e1, const Range &e2) const {
|
||||
if (e1.OutputStream < e2.OutputStream)
|
||||
return true;
|
||||
else if (e1.OutputStream == e2.OutputStream) {
|
||||
if (e1.StartRow < e2.StartRow)
|
||||
return true;
|
||||
else if (e1.StartRow == e2.StartRow)
|
||||
return e1.StartCol < e2.StartCol;
|
||||
else
|
||||
return false; // e1.StartRow > e2.StartRow
|
||||
} else
|
||||
return false; // e1.OutputStream > e2.OutputStream
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
vector<Range> m_Ranges;
|
||||
|
||||
// Use this to represent input/output/tessellation register declaration.
|
||||
struct UsedElement {
|
||||
unsigned Row;
|
||||
unsigned StartCol;
|
||||
unsigned Cols;
|
||||
D3D_INTERPOLATION_MODE InterpolationMode;
|
||||
D3D11_SB_OPERAND_MIN_PRECISION MinPrecision;
|
||||
unsigned NumUnits;
|
||||
BYTE OutputStream;
|
||||
|
||||
UsedElement() : Row(UINT_MAX), StartCol(UINT_MAX), Cols(0),
|
||||
InterpolationMode(D3D_INTERPOLATION_UNDEFINED), MinPrecision(D3D11_SB_OPERAND_MIN_PRECISION_DEFAULT),
|
||||
NumUnits(0), OutputStream(0) {}
|
||||
|
||||
struct LTByStreamAndStartRowAndStartCol {
|
||||
bool operator()(const UsedElement &e1, const UsedElement &e2) const {
|
||||
if (e1.OutputStream < e2.OutputStream)
|
||||
return true;
|
||||
else if (e1.OutputStream == e2.OutputStream) {
|
||||
if (e1.Row < e2.Row)
|
||||
return true;
|
||||
else if (e1.Row == e2.Row)
|
||||
return e1.StartCol < e2.StartCol;
|
||||
else
|
||||
return false; // e1.Row > e2.Row
|
||||
} else
|
||||
return false; // e1.OutputStream > e2.OutputStream
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Assume the vector is sorted by <stream,row,col>.
|
||||
vector<UsedElement> m_UsedElements;
|
||||
|
||||
// Elements with stream, register and component.
|
||||
struct RegAndCompAndStream {
|
||||
unsigned Reg;
|
||||
unsigned Comp;
|
||||
unsigned Stream;
|
||||
RegAndCompAndStream(unsigned r, unsigned c, unsigned s) : Reg(r), Comp(c), Stream(s) {}
|
||||
bool operator<(const RegAndCompAndStream &o) const {
|
||||
if (Stream < o.Stream)
|
||||
return true;
|
||||
else if (Stream == o.Stream) {
|
||||
if (Reg < o.Reg)
|
||||
return true;
|
||||
else if (Reg == o.Reg)
|
||||
return Comp < o.Comp;
|
||||
else
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
};
|
||||
map<RegAndCompAndStream, unsigned> m_DxbcRegisterToSignatureElement;
|
||||
|
||||
const DxilSignatureElement *GetElement(unsigned Reg, unsigned Comp) const {
|
||||
const unsigned Stream = 0;
|
||||
return GetElementWithStream(Reg, Comp, Stream);
|
||||
}
|
||||
const DxilSignatureElement *GetElementWithStream(unsigned Reg, unsigned Comp, unsigned Stream) const {
|
||||
RegAndCompAndStream Key(Reg, Comp, Stream);
|
||||
auto it = m_DxbcRegisterToSignatureElement.find(Key);
|
||||
if (it == m_DxbcRegisterToSignatureElement.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
unsigned ElemIdx = it->second;
|
||||
const DxilSignatureElement *E = &m_Signature.GetElement(ElemIdx);
|
||||
DXASSERT(E->IsAllocated(), "otherwise signature elements were not set correctly");
|
||||
DXASSERT(E->GetStartRow() <= (int)Reg && (int)Reg < E->GetStartRow()+E->GetRows(), "otherwise signature elements were not set correctly");
|
||||
DXASSERT(E->GetStartCol() <= (int)Comp && (int)Comp < E->GetStartCol()+E->GetCols(), "otherwise signature elements were not set correctly");
|
||||
return E;
|
||||
}
|
||||
|
||||
// Elements that are System Generated Values (SVGs), without register.
|
||||
map<D3D10_SB_OPERAND_TYPE, unsigned> m_DxbcSgvToSignatureElement;
|
||||
|
||||
const DxilSignatureElement *GetElement(D3D10_SB_OPERAND_TYPE SgvRegType) const {
|
||||
DXASSERT(m_DxbcSgvToSignatureElement.find(SgvRegType) != m_DxbcSgvToSignatureElement.end(), "otherwise the element has not been added to the map");
|
||||
unsigned ElemIdx = m_DxbcSgvToSignatureElement.find(SgvRegType)->second;
|
||||
const DxilSignatureElement *E = &m_Signature.GetElement(ElemIdx);
|
||||
DXASSERT(!E->IsAllocated(), "otherwise signature elements were not set correctly");
|
||||
return E;
|
||||
}
|
||||
|
||||
bool IsInput() const { return m_Signature.IsInput(); }
|
||||
bool IsOutput() const { return m_Signature.IsOutput(); }
|
||||
|
||||
// Special case SGVs that are not in the signature.
|
||||
bool m_bHasInputCoverage;
|
||||
bool m_bHasInnerInputCoverage;
|
||||
|
||||
SignatureHelper(DXIL::ShaderKind shaderKind, DXIL::SignatureKind sigKind)
|
||||
: m_Signature(shaderKind, sigKind, /*useMinPrecision*/false)
|
||||
, m_bHasInputCoverage(false)
|
||||
, m_bHasInnerInputCoverage(false) {}
|
||||
};
|
||||
|
||||
|
||||
/// Use this class to implement the IDxbcConverter inteface for DXBC to DXIL translation.
|
||||
class DxbcConverter : public IDxbcConverter {
|
||||
protected:
|
||||
DXC_MICROCOM_TM_REF_FIELDS();
|
||||
public:
|
||||
DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) {
|
||||
return DoBasicQueryInterface<IDxbcConverter>(this, iid, ppv);
|
||||
}
|
||||
|
||||
DxbcConverter();
|
||||
DxbcConverter(IMalloc *pMalloc) : DxbcConverter() { m_pMalloc = pMalloc; }
|
||||
DXC_MICROCOM_TM_ALLOC(DxbcConverter);
|
||||
|
||||
~DxbcConverter();
|
||||
|
||||
__override HRESULT STDMETHODCALLTYPE Convert(_In_reads_bytes_(DxbcSize) LPCVOID pDxbc,
|
||||
_In_ UINT32 DxbcSize,
|
||||
_In_opt_z_ LPCWSTR pExtraOptions,
|
||||
_Outptr_result_bytebuffer_maybenull_(*pDxilSize) LPVOID *ppDxil,
|
||||
_Out_ UINT32 *pDxilSize,
|
||||
_Outptr_result_maybenull_z_ LPWSTR *ppDiag);
|
||||
|
||||
__override HRESULT STDMETHODCALLTYPE ConvertInDriver(_In_reads_bytes_(8) const UINT32 *pBytecode,
|
||||
_In_opt_z_ LPCVOID pInputSignature,
|
||||
_In_ UINT32 NumInputSignatureElements,
|
||||
_In_opt_z_ LPCVOID pOutputSignature,
|
||||
_In_ UINT32 NumOutputSignatureElements,
|
||||
_In_opt_z_ LPCVOID pPatchConstantSignature,
|
||||
_In_ UINT32 NumPatchConstantSignatureElements,
|
||||
_In_opt_z_ LPCWSTR pExtraOptions,
|
||||
_Out_ IDxcBlob **ppDxilModule,
|
||||
_Outptr_result_maybenull_z_ LPWSTR *ppDiag);
|
||||
|
||||
protected:
|
||||
LLVMContext m_Ctx;
|
||||
DxilModule *m_pPR;
|
||||
std::unique_ptr<Module> m_pModule;
|
||||
OP *m_pOP;
|
||||
const ShaderModel *m_pSM;
|
||||
unsigned m_DxbcMajor;
|
||||
unsigned m_DxbcMinor;
|
||||
bool IsSM51Plus() const { return m_DxbcMajor > 5 || (m_DxbcMajor == 5 && m_DxbcMinor >= 1); }
|
||||
std::unique_ptr< IRBuilder<> > m_pBuilder;
|
||||
|
||||
bool m_bDisableHashCheck;
|
||||
bool m_bRunDxilCleanup;
|
||||
|
||||
bool m_bLegacyCBufferLoad;
|
||||
|
||||
unique_ptr<SignatureHelper> m_pInputSignature;
|
||||
unique_ptr<SignatureHelper> m_pOutputSignature;
|
||||
unique_ptr<SignatureHelper> m_pPatchConstantSignature;
|
||||
D3D10_SB_OPERAND_TYPE m_DepthRegType;
|
||||
bool m_bHasStencilRef;
|
||||
bool m_bHasCoverageOut;
|
||||
|
||||
const unsigned kRegCompAlignment = 4;
|
||||
const unsigned kLegacyCBufferRegSizeInBytes = 16;
|
||||
|
||||
Value *m_pUnusedF32;
|
||||
Value *m_pUnusedI32;
|
||||
|
||||
// Temporary r-registers.
|
||||
unsigned m_NumTempRegs;
|
||||
|
||||
// Indexable temporary registers.
|
||||
struct IndexableReg {
|
||||
Value *pValue32;
|
||||
Value *pValue16;
|
||||
unsigned NumRegs;
|
||||
unsigned NumComps;
|
||||
bool bIsAlloca;
|
||||
};
|
||||
map<unsigned, IndexableReg> m_IndexableRegs;
|
||||
map<unsigned, IndexableReg> m_PatchConstantIndexableRegs;
|
||||
|
||||
// Shader resource register/rangeID maps.
|
||||
map<unsigned, unsigned> m_SRVRangeMap;
|
||||
map<unsigned, unsigned> m_UAVRangeMap;
|
||||
map<unsigned, unsigned> m_CBufferRangeMap;
|
||||
map<unsigned, unsigned> m_SamplerRangeMap;
|
||||
|
||||
// Immediate constant buffer.
|
||||
GlobalVariable *m_pIcbGV;
|
||||
|
||||
// Control flow.
|
||||
struct Scope {
|
||||
enum Kind : unsigned { Function, If, Loop, Switch, HullLoop, LastKind };
|
||||
|
||||
enum Kind Kind;
|
||||
BasicBlock *pPreScopeBB;
|
||||
BasicBlock *pPostScopeBB;
|
||||
unsigned NameIndex;
|
||||
|
||||
union {
|
||||
// If
|
||||
struct {
|
||||
BasicBlock *pThenBB;
|
||||
BasicBlock *pElseBB;
|
||||
Value *pCond;
|
||||
};
|
||||
|
||||
// Loop
|
||||
struct {
|
||||
BasicBlock *pLoopBB;
|
||||
unsigned ContinueIndex;
|
||||
unsigned LoopBreakIndex;
|
||||
};
|
||||
|
||||
// Switch
|
||||
struct {
|
||||
BasicBlock *pDefaultBB;
|
||||
Value *pSelector;
|
||||
unsigned CaseGroupIndex;
|
||||
unsigned SwitchBreakIndex;
|
||||
};
|
||||
|
||||
// Function
|
||||
struct {
|
||||
unsigned LabelIdx;
|
||||
unsigned CallIdx;
|
||||
unsigned ReturnTokenOffset;
|
||||
unsigned ReturnIndex;
|
||||
bool bEntryFunc;
|
||||
};
|
||||
|
||||
// HullLoop
|
||||
struct {
|
||||
BasicBlock *pHullLoopBB;
|
||||
unsigned HullLoopBreakIndex;
|
||||
Value *pInductionVar;
|
||||
unsigned HullLoopTripCount;
|
||||
};
|
||||
};
|
||||
vector<pair<unsigned, BasicBlock*> > SwitchCases; // Switch
|
||||
|
||||
Scope() : Kind(Kind::Function), pPreScopeBB(nullptr), pPostScopeBB(nullptr), NameIndex(0),
|
||||
pThenBB(nullptr), pElseBB(nullptr), pCond(nullptr),
|
||||
pLoopBB(nullptr), ContinueIndex(0), LoopBreakIndex(0),
|
||||
pDefaultBB(nullptr), pSelector(nullptr), CaseGroupIndex(0), SwitchBreakIndex(0),
|
||||
LabelIdx(0), CallIdx(0), ReturnTokenOffset(0), ReturnIndex(0), bEntryFunc(false),
|
||||
pHullLoopBB(nullptr), HullLoopBreakIndex(0), pInductionVar(nullptr), HullLoopTripCount(0) {}
|
||||
|
||||
void SetEntry(bool b = true) { DXASSERT_NOMSG(Kind==Function); bEntryFunc = b; }
|
||||
bool IsEntry() const { DXASSERT_NOMSG(Kind==Function); return bEntryFunc; }
|
||||
};
|
||||
|
||||
class ScopeStack {
|
||||
public:
|
||||
ScopeStack();
|
||||
Scope &Top();
|
||||
Scope &Push(enum Scope::Kind Kind, BasicBlock *pPreScopeBB);
|
||||
void Pop();
|
||||
bool IsEmpty() const;
|
||||
Scope &FindParentLoop();
|
||||
Scope &FindParentLoopOrSwitch();
|
||||
Scope &FindParentFunction();
|
||||
Scope &FindParentHullLoop();
|
||||
|
||||
private:
|
||||
vector<Scope> m_Scopes;
|
||||
unsigned m_FuncCount;
|
||||
unsigned m_IfCount;
|
||||
unsigned m_LoopCount;
|
||||
unsigned m_SwitchCount;
|
||||
unsigned m_HullLoopCount;
|
||||
};
|
||||
ScopeStack m_ScopeStack;
|
||||
|
||||
struct LabelEntry {
|
||||
Function *pFunc;
|
||||
};
|
||||
map<unsigned, LabelEntry> m_Labels;
|
||||
map<unsigned, LabelEntry> m_InterfaceFunctionBodies;
|
||||
bool HasLabels() { return !m_Labels.empty() || !m_InterfaceFunctionBodies.empty(); }
|
||||
|
||||
// Shared memory.
|
||||
struct TGSMEntry {
|
||||
GlobalVariable *pVar;
|
||||
unsigned Stride;
|
||||
unsigned Count;
|
||||
unsigned Id;
|
||||
};
|
||||
map<unsigned, TGSMEntry> m_TGSMMap;
|
||||
unsigned m_TGSMCount;
|
||||
|
||||
// Geometry shader.
|
||||
unsigned GetGSTempRegForOutputReg(unsigned OutputReg) const;
|
||||
|
||||
// Hull shader.
|
||||
bool m_bControlPointPhase;
|
||||
bool m_bPatchConstantPhase;
|
||||
vector<unsigned> m_PatchConstantPhaseInstanceCounts;
|
||||
|
||||
CMask m_PreciseMask;
|
||||
|
||||
// Interfaces
|
||||
DxilCBuffer* m_pInterfaceDataBuffer;
|
||||
DxilCBuffer* m_pClassInstanceCBuffers;
|
||||
DxilSampler* m_pClassInstanceSamplers;
|
||||
DxilSampler* m_pClassInstanceComparisonSamplers;
|
||||
|
||||
struct InterfaceShaderResourceKey {
|
||||
DxilResource::Kind Kind;
|
||||
union {
|
||||
DXIL::ComponentType TypedSRVRet;
|
||||
unsigned StructureByteStride;
|
||||
};
|
||||
bool operator<(const InterfaceShaderResourceKey &o) const {
|
||||
if (Kind != o.Kind)
|
||||
return Kind < o.Kind;
|
||||
if (Kind == DxilResource::Kind::StructuredBuffer)
|
||||
return StructureByteStride < o.StructureByteStride;
|
||||
if (Kind != DxilResource::Kind::RawBuffer)
|
||||
return TypedSRVRet < o.TypedSRVRet;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
map<InterfaceShaderResourceKey, unsigned> m_ClassInstanceSRVs;
|
||||
map<unsigned, vector<unsigned>> m_FunctionTables;
|
||||
struct Interface {
|
||||
vector<unsigned> Tables;
|
||||
bool bDynamicallyIndexed;
|
||||
unsigned NumArrayEntries;
|
||||
};
|
||||
map<unsigned, Interface> m_Interfaces;
|
||||
unsigned m_NumIfaces;
|
||||
unsigned m_FcallCount;
|
||||
|
||||
protected:
|
||||
virtual void ConvertImpl(_In_reads_bytes_(DxbcSize) LPCVOID pDxbc,
|
||||
_In_ UINT32 DxbcSize,
|
||||
_In_opt_z_ LPCWSTR pExtraOptions,
|
||||
_Outptr_result_bytebuffer_maybenull_(*pDxilSize) LPVOID *ppDxil,
|
||||
_Out_ UINT32 *pDxilSize,
|
||||
_Outptr_result_maybenull_z_ LPWSTR *ppDiag);
|
||||
|
||||
virtual void ConvertInDriverImpl(_In_reads_bytes_(8) const UINT32 *pByteCode,
|
||||
_In_opt_ const D3D12DDIARG_SIGNATURE_ENTRY_0012 *pInputSignature,
|
||||
_In_ UINT32 NumInputSignatureElements,
|
||||
_In_opt_ const D3D12DDIARG_SIGNATURE_ENTRY_0012 *pOutputSignature,
|
||||
_In_ UINT32 NumOutputSignatureElements,
|
||||
_In_opt_ const D3D12DDIARG_SIGNATURE_ENTRY_0012 *pPatchConstantSignature,
|
||||
_In_ UINT32 NumPatchConstantSignatureElements,
|
||||
_In_opt_z_ LPCWSTR pExtraOptions,
|
||||
_Out_ IDxcBlob **ppDxcBlob,
|
||||
_Outptr_result_maybenull_z_ LPWSTR *ppDiag);
|
||||
|
||||
virtual void LogConvertResult(bool InDriver,
|
||||
_In_ const LARGE_INTEGER *pQPCConvertStart,
|
||||
_In_ const LARGE_INTEGER *pQPCConvertEnd,
|
||||
_In_reads_bytes_(DxbcSize) LPCVOID pDxbc,
|
||||
_In_ UINT32 DxbcSize,
|
||||
_In_opt_z_ LPCWSTR pExtraOptions,
|
||||
_In_reads_bytes_(ConvertedSize) LPCVOID pConverted,
|
||||
_In_opt_ UINT32 ConvertedSize,
|
||||
HRESULT hr);
|
||||
|
||||
|
||||
// Callbacks added to support conversion of custom intrinsics.
|
||||
virtual void HandleUnknownInstruction(D3D10ShaderBinary::CInstruction &Inst);
|
||||
virtual unsigned GetResourceSlot(D3D10ShaderBinary::CInstruction &Inst);
|
||||
|
||||
protected:
|
||||
void ParseExtraOptions(const wchar_t *pStr);
|
||||
|
||||
void AnalyzeShader(D3D10ShaderBinary::CShaderCodeParser &Parser);
|
||||
|
||||
void ExtractInputSignatureFromDXBC(DxilContainerReader &dxbcReader, const void *pMaxPtr);
|
||||
void ExtractOutputSignatureFromDXBC(DxilContainerReader &dxbcReader, const void *pMaxPtr);
|
||||
void ExtractPatchConstantSignatureFromDXBC(DxilContainerReader &dxbcReader, const void *pMaxPtr);
|
||||
void ExtractSignatureFromDXBC(const D3D10_INTERNALSHADER_SIGNATURE *pSig, UINT uElemSize,
|
||||
const void *pMaxPtr, SignatureHelper &SigHelper);
|
||||
void ExtractSignatureFromDDI(const D3D12DDIARG_SIGNATURE_ENTRY_0012 *pElements, unsigned NumElements, SignatureHelper &SigHelper);
|
||||
/// Correlates information from decls and signature element records to create DXIL signature element.
|
||||
void ConvertSignature(SignatureHelper &SigHelper, DxilSignature &Sig);
|
||||
|
||||
void ConvertInstructions(D3D10ShaderBinary::CShaderCodeParser &Parser);
|
||||
void AdvanceDxbcInstructionStream(D3D10ShaderBinary::CShaderCodeParser &Parser,
|
||||
D3D10ShaderBinary::CInstruction &Inst,
|
||||
bool &bDoneParsing);
|
||||
bool GetNextDxbcInstruction(D3D10ShaderBinary::CShaderCodeParser &Parser, D3D10ShaderBinary::CInstruction &NextInst);
|
||||
void InsertSM50ResourceHandles();
|
||||
void InsertInterfacesResourceDecls();
|
||||
const DxilResource& GetInterfacesSRVDecl(D3D10ShaderBinary::CInstruction &Inst);
|
||||
void DeclareIndexableRegisters();
|
||||
void CleanupIndexableRegisterDecls(map<unsigned, IndexableReg> &IdxRegMap);
|
||||
void RemoveUnreachableBasicBlocks();
|
||||
void CleanupGEP();
|
||||
|
||||
void ConvertUnary(OP::OpCode OpCode, const CompType &ElementType, D3D10ShaderBinary::CInstruction &Inst,
|
||||
const unsigned DstIdx = 0, const unsigned SrcIdx = 1);
|
||||
void ConvertBinary(OP::OpCode OpCode, const CompType &ElementType, D3D10ShaderBinary::CInstruction &Inst,
|
||||
const unsigned DstIdx = 0, const unsigned SrcIdx1 = 1, const unsigned SrcIdx2 = 2);
|
||||
void ConvertBinary(Instruction::BinaryOps OpCode, const CompType &ElementType, D3D10ShaderBinary::CInstruction &Inst,
|
||||
const unsigned DstIdx = 0, const unsigned SrcIdx1 = 1, const unsigned SrcIdx2 = 2);
|
||||
void ConvertBinaryWithTwoOuts(OP::OpCode OpCode, D3D10ShaderBinary::CInstruction &Inst,
|
||||
const unsigned DstIdx1 = 0, const unsigned DstIdx2 = 1,
|
||||
const unsigned SrcIdx1 = 2, const unsigned SrcIdx2 = 3);
|
||||
void ConvertBinaryWithCarry(OP::OpCode OpCode, D3D10ShaderBinary::CInstruction &Inst,
|
||||
const unsigned DstIdx1 = 0, const unsigned DstIdx2 = 1,
|
||||
const unsigned SrcIdx1 = 2, const unsigned SrcIdx2 = 3);
|
||||
void ConvertTertiary(OP::OpCode OpCode, const CompType &ElementType, D3D10ShaderBinary::CInstruction &Inst,
|
||||
const unsigned DstIdx = 0,
|
||||
const unsigned SrcIdx1 = 1, const unsigned SrcIdx2 = 2, const unsigned SrcIdx3 = 3);
|
||||
void ConvertQuaternary(OP::OpCode OpCode, const CompType &ElementType, D3D10ShaderBinary::CInstruction &Inst,
|
||||
const unsigned DstIdx = 0,
|
||||
const unsigned SrcIdx1 = 1, const unsigned SrcIdx2 = 2,
|
||||
const unsigned SrcIdx3 = 3, const unsigned SrcIdx4 = 4);
|
||||
void ConvertComparison(CmpInst::Predicate Predicate, const CompType &ElementType, D3D10ShaderBinary::CInstruction &Inst,
|
||||
const unsigned DstIdx = 0, const unsigned SrcIdx1 = 1, const unsigned SrcIdx2 = 2);
|
||||
void ConvertDotProduct(OP::OpCode OpCode, const BYTE NumComps, const CMask &LoadMask, D3D10ShaderBinary::CInstruction &Inst);
|
||||
void ConvertCast(const CompType &SrcElementType, const CompType &DstElementType, D3D10ShaderBinary::CInstruction &Inst,
|
||||
const unsigned DstIdx = 0, const unsigned SrcIdx = 1);
|
||||
void ConvertToDouble(const CompType &SrcElementType, D3D10ShaderBinary::CInstruction &Inst);
|
||||
void ConvertFromDouble(const CompType &DstElementType, D3D10ShaderBinary::CInstruction &Inst);
|
||||
void LoadCommonSampleInputs(D3D10ShaderBinary::CInstruction &Inst, Value *pArgs[], bool bSetOffsets = true);
|
||||
void StoreResRetOutputAndStatus(D3D10ShaderBinary::CInstruction &Inst, Value *pResRet, CompType DstType);
|
||||
void StoreGetDimensionsOutput(D3D10ShaderBinary::CInstruction &Inst, Value *pGetDimRet);
|
||||
void StoreSamplePosOutput(D3D10ShaderBinary::CInstruction &Inst, Value *pSamplePosVal);
|
||||
void StoreBroadcastOutput(D3D10ShaderBinary::CInstruction &Inst, Value *pValue, CompType DstType);
|
||||
Value *GetCoordValue(D3D10ShaderBinary::CInstruction &Inst, const unsigned uCoordIdx);
|
||||
Value *GetByteOffset(D3D10ShaderBinary::CInstruction &Inst, const unsigned Idx1, const unsigned Idx2, const unsigned Stride);
|
||||
void ConvertLoadTGSM(D3D10ShaderBinary::CInstruction &Inst, const unsigned uOpTGSM, const unsigned uOpOutput, CompType SrcType, Value *pByteOffset);
|
||||
void ConvertStoreTGSM(D3D10ShaderBinary::CInstruction &Inst, const unsigned uOpTGSM, const unsigned uOpValue, CompType BaseValueType, Value *pByteOffset);
|
||||
|
||||
void EmitGSOutputRegisterStore(unsigned StreamId);
|
||||
|
||||
void SetShaderGlobalFlags(unsigned GlobalFlags);
|
||||
Value *CreateHandle(DxilResourceBase::Class Class, unsigned RangeID, Value *pIndex, bool bNonUniformIndex);
|
||||
|
||||
void Optimize();
|
||||
void AddOptimizationPasses(PassManagerBase &PassManager, unsigned OptLevel);
|
||||
|
||||
void CheckDxbcString(const char *pStr, const void *pMaxPtrInclusive);
|
||||
|
||||
Value *LoadConstFloat(float& fVal);
|
||||
void LoadOperand(OperandValue &SrcVal, D3D10ShaderBinary::CInstruction &Inst, const unsigned OpIdx, const CMask &Mask, const CompType &ValueType);
|
||||
const DxilResource& LoadSRVOperand(OperandValue &SrcVal, D3D10ShaderBinary::CInstruction &Inst, const unsigned OpIdx, const CMask &Mask, const CompType &ValueType);
|
||||
const DxilResource& GetSRVFromOperand(D3D10ShaderBinary::CInstruction &Inst, const unsigned OpIdx);
|
||||
void StoreOperand(OperandValue &DstVal, const D3D10ShaderBinary::CInstruction &Inst, const unsigned OpIdx, const CMask &Mask, const CompType &ValueType);
|
||||
Value *LoadOperandIndex(const D3D10ShaderBinary::COperandIndex &OpIndex, const D3D10_SB_OPERAND_INDEX_REPRESENTATION IndexType);
|
||||
Value *LoadOperandIndexRelative(const D3D10ShaderBinary::COperandIndex &OpIndex);
|
||||
/// Implicit casts of a value.
|
||||
Value *CastDxbcValue(Value *pValue, const CompType &SrcType, const CompType &DstType);
|
||||
Value *CreateBitCast(Value *pValue, const CompType &SrcType, const CompType &DstType);
|
||||
Value *ApplyOperandModifiers(Value *pValue, const D3D10ShaderBinary::COperandBase &O);
|
||||
void ApplyInstructionModifiers(OperandValue &DstVal, const D3D10ShaderBinary::CInstruction &Inst);
|
||||
CompType InferOperandType(const D3D10ShaderBinary::CInstruction &Inst, const unsigned OpIdx, const CMask &Mask);
|
||||
|
||||
void CreateBranchIfNeeded(BasicBlock *pBB, BasicBlock *pTargetBB);
|
||||
Value *LoadZNZCondition(D3D10ShaderBinary::CInstruction &Inst, const unsigned OpIdx);
|
||||
D3D11_SB_OPERAND_MIN_PRECISION GetHigherPrecision(D3D11_SB_OPERAND_MIN_PRECISION p1, D3D11_SB_OPERAND_MIN_PRECISION p2);
|
||||
|
||||
string SynthesizeResGVName(const char *pNamePrefix, unsigned ID);
|
||||
StructType *GetStructResElemType(unsigned StructSizeInBytes);
|
||||
StructType *GetTypedResElemType(CompType CT);
|
||||
UndefValue *DeclareUndefPtr(Type *pType, unsigned AddrSpace);
|
||||
Value *MarkPrecise(Value *pVal, BYTE Comp = BYTE(-1));
|
||||
|
||||
void SerializeDxil(SmallVectorImpl<char> &DxilBitcode);
|
||||
|
||||
};
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,191 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// DxbcUtil.h //
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved. //
|
||||
// This file is distributed under the University of Illinois Open Source //
|
||||
// License. See LICENSE.TXT for details. //
|
||||
// //
|
||||
// Utilities to convert from DXBC to DXIL. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "dxc/DXIL/DxilShaderModel.h"
|
||||
#include "dxc/DXIL/DxilSemantic.h"
|
||||
#include "dxc/DXIL/DxilInterpolationMode.h"
|
||||
#include "dxc/DXIL/DxilCompType.h"
|
||||
#include "dxc/DXIL/DxilSampler.h"
|
||||
#include "dxc/DXIL/DxilResource.h"
|
||||
#include "dxc/DXIL/DxilConstants.h"
|
||||
|
||||
namespace llvm {
|
||||
class Type;
|
||||
class LLVMContext;
|
||||
class Value;
|
||||
class AtomicRMWInst;
|
||||
enum AtomicRMWInst::BinOp;
|
||||
}
|
||||
|
||||
#define DXASSERT_DXBC(__exp) DXASSERT(__exp, "otherwise incorrect assumption about DXBC")
|
||||
|
||||
|
||||
namespace hlsl {
|
||||
|
||||
namespace DXBC {
|
||||
|
||||
// Width of DXBC vector operand.
|
||||
const BYTE kWidth = 4;
|
||||
// DXBC mask with all active components.
|
||||
const BYTE kAllCompMask = 0x0F;
|
||||
|
||||
ShaderModel::Kind GetShaderModelKind(D3D10_SB_TOKENIZED_PROGRAM_TYPE Type);
|
||||
|
||||
// Query DXBC shader flags.
|
||||
bool IsFlagDisableOptimizations(unsigned Flags);
|
||||
bool IsFlagDisableMathRefactoring(unsigned Flags);
|
||||
bool IsFlagEnableDoublePrecision(unsigned Flags);
|
||||
bool IsFlagForceEarlyDepthStencil(unsigned Flags);
|
||||
bool IsFlagEnableRawAndStructuredBuffers(unsigned Flags);
|
||||
bool IsFlagEnableMinPrecision(unsigned Flags);
|
||||
bool IsFlagEnableDoubleExtensions(unsigned Flags);
|
||||
bool IsFlagEnableMSAD(unsigned Flags);
|
||||
bool IsFlagAllResourcesBound(unsigned Flags);
|
||||
|
||||
InterpolationMode::Kind GetInterpolationModeKind(D3D_INTERPOLATION_MODE Mode);
|
||||
|
||||
D3D10_SB_OPERAND_TYPE GetOperandRegType(Semantic::Kind Kind, bool IsOutput);
|
||||
|
||||
DxilResource::Kind GetResourceKind(D3D10_SB_RESOURCE_DIMENSION ResType);
|
||||
BYTE GetNumResCoords(DxilResource::Kind ResKind);
|
||||
BYTE GetNumResOffsets(DxilResource::Kind ResKind);
|
||||
|
||||
CompType GetCompType(D3D_REGISTER_COMPONENT_TYPE CompTy);
|
||||
CompType GetCompTypeWithMinPrec(D3D_REGISTER_COMPONENT_TYPE BaseCompTy, D3D11_SB_OPERAND_MIN_PRECISION MinPrec);
|
||||
CompType GetCompTypeWithMinPrec(CompType BaseCompTy, D3D11_SB_OPERAND_MIN_PRECISION MinPrec);
|
||||
CompType GetCompTypeFromMinPrec(D3D11_SB_OPERAND_MIN_PRECISION MinPrec, CompType DefaultPrecCompType);
|
||||
|
||||
CompType GetResCompType(D3D10_SB_RESOURCE_RETURN_TYPE CompTy);
|
||||
CompType GetDeclResCompType(D3D10_SB_RESOURCE_RETURN_TYPE CompTy);
|
||||
|
||||
char GetCompName(BYTE c);
|
||||
|
||||
DxilSampler::SamplerKind GetSamplerKind(D3D10_SB_SAMPLER_MODE Mode);
|
||||
|
||||
unsigned GetRegIndex(unsigned Reg, unsigned Comp);
|
||||
|
||||
DXIL::AtomicBinOpCode GetAtomicBinOp(D3D10_SB_OPCODE_TYPE DxbcOpCode);
|
||||
llvm::AtomicRMWInst::BinOp GetLlvmAtomicBinOp(D3D10_SB_OPCODE_TYPE DxbcOpCode);
|
||||
bool AtomicBinOpHasReturn(D3D10_SB_OPCODE_TYPE DxbcOpCode);
|
||||
bool IsCompareExchAtomicBinOp(D3D10_SB_OPCODE_TYPE DxbcOpCode);
|
||||
|
||||
bool HasFeedback(D3D10_SB_OPCODE_TYPE OpCode);
|
||||
unsigned GetResourceSlot(D3D10_SB_OPCODE_TYPE OpCode);
|
||||
|
||||
DXIL::BarrierMode GetBarrierMode(bool bSyncThreadGroup, bool bUAVFenceGlobal,
|
||||
bool bUAVFenceThreadGroup, bool bTGSMFence);
|
||||
|
||||
DXIL::InputPrimitive GetInputPrimitive(D3D10_SB_PRIMITIVE Primitive);
|
||||
DXIL::PrimitiveTopology GetPrimitiveTopology(D3D10_SB_PRIMITIVE_TOPOLOGY Topology);
|
||||
|
||||
const char *GetD3D10SBName(D3D10_SB_NAME D3DName);
|
||||
unsigned GetD3D10SBSemanticIndex(D3D10_SB_NAME D3DName);
|
||||
D3D_REGISTER_COMPONENT_TYPE GetD3DRegCompType(D3D10_SB_NAME D3DName);
|
||||
const char *GetSemanticNameFromD3DName(D3D_NAME D3DName);
|
||||
unsigned GetSemanticIndexFromD3DName(D3D_NAME D3DName);
|
||||
|
||||
DXIL::TessellatorDomain GetTessellatorDomain(D3D11_SB_TESSELLATOR_DOMAIN TessDomain);
|
||||
DXIL::TessellatorPartitioning GetTessellatorPartitioning(D3D11_SB_TESSELLATOR_PARTITIONING TessPartitioning);
|
||||
DXIL::TessellatorOutputPrimitive GetTessellatorOutputPrimitive(D3D11_SB_TESSELLATOR_OUTPUT_PRIMITIVE TessOutputPrimitive);
|
||||
|
||||
} // namespace DXBC
|
||||
|
||||
|
||||
/// Use this class to represent DXBC register component mask.
|
||||
class CMask {
|
||||
public:
|
||||
CMask();
|
||||
CMask(BYTE Mask);
|
||||
CMask(BYTE c0, BYTE c1, BYTE c2, BYTE c3);
|
||||
CMask(BYTE StartComp, BYTE NumComp);
|
||||
|
||||
BYTE ToByte() const;
|
||||
|
||||
static bool IsSet(BYTE Mask, BYTE c);
|
||||
bool IsSet(BYTE c) const;
|
||||
void Set(BYTE c);
|
||||
|
||||
CMask operator|(const CMask &o);
|
||||
|
||||
BYTE GetNumActiveComps() const;
|
||||
BYTE GetNumActiveRangeComps() const;
|
||||
bool IsZero() const { return GetNumActiveComps() == 0; }
|
||||
|
||||
BYTE GetFirstActiveComp() const;
|
||||
|
||||
static BYTE MakeMask(BYTE c0, BYTE c1, BYTE c2, BYTE c3);
|
||||
static CMask MakeXYZWMask();
|
||||
static CMask MakeFirstNCompMask(BYTE n);
|
||||
static CMask MakeCompMask(BYTE Component);
|
||||
static CMask MakeXMask();
|
||||
|
||||
static bool IsValidDoubleMask(const CMask &Mask);
|
||||
static CMask GetMaskForDoubleOperation(const CMask &Mask);
|
||||
|
||||
static CMask FromDXBC(const unsigned DxbcMask);
|
||||
|
||||
protected:
|
||||
BYTE m_Mask;
|
||||
};
|
||||
|
||||
|
||||
/// Use this class to pass around DXBC register component values.
|
||||
class OperandValue {
|
||||
friend class OperandValueHelper;
|
||||
typedef llvm::Value * PValue;
|
||||
PValue m_pVal[DXBC::kWidth];
|
||||
public:
|
||||
OperandValue();
|
||||
PValue &operator[](BYTE c);
|
||||
const PValue &operator[](BYTE c) const;
|
||||
};
|
||||
|
||||
|
||||
/// \brief Use this one-time-iterator class to set up component values of input operands,
|
||||
/// replicating the same value to all components with the same swizzled name.
|
||||
///
|
||||
/// After creation an instance serves as an iterator to iterate through
|
||||
/// uniques components and set their values in the OperandValue instance.
|
||||
/// After the iterator is done, the instance is not usable anymore.
|
||||
///
|
||||
/// Usage:
|
||||
/// OperandValueHelper OVH(OpVal, Mask, Swizzle);
|
||||
/// for (; !OVH.IsDone(); OVH.Advance()) {
|
||||
/// BYTE Comp = OVH.GetComp();
|
||||
/// ... // Create llvm::Value *pVal
|
||||
/// OHV.SetValue(pVal); // for all components with the same swizzle name
|
||||
/// }
|
||||
class OperandValueHelper {
|
||||
public:
|
||||
OperandValueHelper();
|
||||
OperandValueHelper(OperandValue &OpValue, const CMask &Mask, const D3D10ShaderBinary::COperandBase &O);
|
||||
|
||||
/// Returns the value of the current active wrt to Mask component.
|
||||
BYTE GetComp() const;
|
||||
/// Returns true is there are no more active components.
|
||||
bool IsDone() const;
|
||||
/// Advances the iterator to the next unique, active component.
|
||||
void Advance();
|
||||
/// Sets the value of all active components with the same swizzle name in OperandValue OpValue.
|
||||
void SetValue(llvm::Value *pValue);
|
||||
|
||||
private:
|
||||
static const BYTE kBadComp = 0xFF;
|
||||
OperandValue *m_pOpValue;
|
||||
BYTE m_Components[DXBC::kWidth];
|
||||
BYTE m_Index;
|
||||
|
||||
void Initialize(const CMask &Mask, const BYTE CompSwizzle[DXBC::kWidth]);
|
||||
};
|
||||
|
||||
} // namespace hlsl
|
|
@ -0,0 +1,9 @@
|
|||
# Build DxilConvPasses.lib.
|
||||
|
||||
add_dxilconv_project_library(DxilConvPasses
|
||||
NormalizeDxil.cpp
|
||||
ScopeNestedCFG.cpp
|
||||
InitializePasses.cpp
|
||||
ScopeNestInfo.cpp
|
||||
DxilCleanup.cpp
|
||||
)
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,43 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// InitializePasses.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. //
|
||||
// //
|
||||
// Initialization of transformation passes used in DirectX DXBC to DXIL //
|
||||
// converter. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "DxilConvPasses/ScopeNestInfo.h"
|
||||
#include "DxilConvPasses/ScopeNestedCFG.h"
|
||||
#include "DxilConvPasses/NormalizeDxil.h"
|
||||
#include "DxilConvPasses/DxilCleanup.h"
|
||||
#include "dxc/Support/WinIncludes.h"
|
||||
#include "dxc/Support/Global.h"
|
||||
|
||||
#include "llvm/PassRegistry.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
|
||||
// Place to put our private pass initialization for opt.exe.
|
||||
void __cdecl initializeDxilConvPasses(PassRegistry &Registry) {
|
||||
initializeScopeNestedCFGPass(Registry);
|
||||
initializeScopeNestInfoWrapperPassPass(Registry);
|
||||
initializeNormalizeDxilPassPass(Registry);
|
||||
initializeDxilCleanupPass(Registry);
|
||||
}
|
||||
|
||||
namespace hlsl {
|
||||
HRESULT SetupRegistryPassForDxilConvPasses() {
|
||||
try
|
||||
{
|
||||
PassRegistry &Registry = *PassRegistry::getPassRegistry();
|
||||
initializeDxilConvPasses(Registry);
|
||||
}
|
||||
CATCH_CPP_RETURN_HRESULT();
|
||||
return S_OK;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// NormalizeDxil.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. //
|
||||
// //
|
||||
// Normalize DXIL transformation. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "DxilConvPasses/NormalizeDxil.h"
|
||||
#include "dxc/Support/Global.h"
|
||||
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/Constant.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
|
||||
#include "dxc/DXIL/DXILOperations.h"
|
||||
#include "dxc/DXIL/DxilInstructions.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
//----------------------- Normalize Implementation ------------------------//
|
||||
|
||||
// Look for resource handles that were moved to the stack by reg2mem and
|
||||
// move them back to registers.
|
||||
//
|
||||
// We make this change so the dxil will have an actual resource handle as
|
||||
// the argument to a load/store resource instruction instead of being
|
||||
// indirected through the stack.
|
||||
class NormalizeResourceHandle {
|
||||
public:
|
||||
bool Run(Function &F, DominatorTree &DT);
|
||||
private:
|
||||
struct ResourceHandleCandidate {
|
||||
Instruction *Alloca;
|
||||
Instruction *CreateHandle;
|
||||
};
|
||||
Instruction *IsResourceHandleAllocaCandidate(BasicBlock *entryBlock, AllocaInst *allocaInst, DominatorTree &DT);
|
||||
void FindCandidates(BasicBlock &entry, std::vector<ResourceHandleCandidate> &candidates, DominatorTree &DT);
|
||||
void ReplaceResourceHandleUsage(const std::vector<ResourceHandleCandidate> &candidates, std::vector<Instruction*> &trash);
|
||||
void Cleanup(std::vector<Instruction *> &trash);
|
||||
};
|
||||
|
||||
// Check to see if this is a valid resource handle location for replacement:
|
||||
// 1. Only used in load/store.
|
||||
// 2. Only stored to once.
|
||||
// 3. Store value is create handle inst.
|
||||
// 4. Create handle dominates all uses of alloca.
|
||||
//
|
||||
// The check is strict to limit the replacement candidates to those allocas that
|
||||
// were inserted by mem2reg and make the replacement trivial.
|
||||
Instruction *NormalizeResourceHandle::IsResourceHandleAllocaCandidate(BasicBlock *entryBlock, AllocaInst *allocaInst, DominatorTree &DT) {
|
||||
Instruction *createHandleInst = nullptr;
|
||||
Instruction *const NOT_A_CANDIDATE = nullptr;
|
||||
|
||||
for (User *use : allocaInst->users()) {
|
||||
if (StoreInst *store = dyn_cast<StoreInst>(use)) {
|
||||
if (store->getPointerOperand() != allocaInst) // In case it is used in gep expression.
|
||||
return NOT_A_CANDIDATE;
|
||||
|
||||
Instruction *storedValue = dyn_cast<Instruction>(store->getValueOperand());
|
||||
if (!storedValue)
|
||||
return NOT_A_CANDIDATE;
|
||||
|
||||
hlsl::DxilInst_CreateHandle createHandle(storedValue);
|
||||
if (!createHandle)
|
||||
return NOT_A_CANDIDATE;
|
||||
|
||||
if (createHandleInst && createHandleInst != storedValue)
|
||||
return NOT_A_CANDIDATE;
|
||||
|
||||
createHandleInst = storedValue;
|
||||
}
|
||||
else if (!(isa<LoadInst>(use))) {
|
||||
return NOT_A_CANDIDATE;
|
||||
}
|
||||
}
|
||||
|
||||
for (Use &use : allocaInst->uses()) {
|
||||
if (!DT.dominates(createHandleInst, use))
|
||||
return NOT_A_CANDIDATE;
|
||||
}
|
||||
|
||||
return createHandleInst;
|
||||
}
|
||||
|
||||
void NormalizeResourceHandle::FindCandidates(BasicBlock &BBEntry, std::vector<ResourceHandleCandidate> &candidates, DominatorTree &DT) {
|
||||
DXASSERT_NOMSG(BBEntry.getTerminator());
|
||||
|
||||
BasicBlock::iterator I = BBEntry.begin();
|
||||
while (isa<AllocaInst>(I)) {
|
||||
if (Instruction *createHandle = IsResourceHandleAllocaCandidate(&BBEntry, cast<AllocaInst>(I), DT))
|
||||
{
|
||||
candidates.push_back({ I, createHandle });
|
||||
}
|
||||
++I;
|
||||
}
|
||||
}
|
||||
|
||||
void NormalizeResourceHandle::ReplaceResourceHandleUsage(const std::vector<ResourceHandleCandidate> &candidates, std::vector<Instruction *> &trash) {
|
||||
for (const ResourceHandleCandidate &candidate : candidates) {
|
||||
for (User *use : candidate.Alloca->users()) {
|
||||
if (LoadInst *load = dyn_cast<LoadInst>(use)) {
|
||||
load->replaceAllUsesWith(candidate.CreateHandle);
|
||||
trash.push_back(load);
|
||||
}
|
||||
else if (StoreInst *store = dyn_cast<StoreInst>(use)) {
|
||||
trash.push_back(store);
|
||||
}
|
||||
else {
|
||||
DXASSERT(false, "should only have load and store insts");
|
||||
}
|
||||
}
|
||||
|
||||
trash.push_back(candidate.Alloca);
|
||||
}
|
||||
}
|
||||
|
||||
void NormalizeResourceHandle::Cleanup(std::vector<Instruction*> &trash) {
|
||||
for (Instruction *inst : trash) {
|
||||
inst->eraseFromParent();
|
||||
}
|
||||
|
||||
trash.clear();
|
||||
}
|
||||
|
||||
bool NormalizeResourceHandle::Run(Function &function, DominatorTree &DT) {
|
||||
std::vector<ResourceHandleCandidate> candidates;
|
||||
std::vector<Instruction *> trash;
|
||||
|
||||
FindCandidates(function.getEntryBlock(), candidates, DT);
|
||||
ReplaceResourceHandleUsage(candidates, trash);
|
||||
Cleanup(trash);
|
||||
|
||||
return candidates.size() > 0;
|
||||
}
|
||||
|
||||
class NormalizeDxil {
|
||||
public:
|
||||
NormalizeDxil(Function &F, DominatorTree &DT) : m_function(F), m_dominatorTree(DT) {}
|
||||
|
||||
bool Run();
|
||||
|
||||
private:
|
||||
Function &m_function;
|
||||
DominatorTree &m_dominatorTree;
|
||||
};
|
||||
|
||||
|
||||
bool NormalizeDxil::Run() {
|
||||
return NormalizeResourceHandle().Run(m_function, m_dominatorTree);
|
||||
}
|
||||
|
||||
|
||||
//----------------------- Pass Implementation ------------------------//
|
||||
char NormalizeDxilPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(NormalizeDxilPass, "normalizedxil", "Normalize dxil pass", false, false)
|
||||
INITIALIZE_PASS_END(NormalizeDxilPass, "normalizedxil", "Normalize dxil pass", false, false)
|
||||
|
||||
|
||||
FunctionPass *llvm::createNormalizeDxilPass() {
|
||||
return new NormalizeDxilPass();
|
||||
}
|
||||
|
||||
bool NormalizeDxilPass::runOnFunction(Function &F) {
|
||||
DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
NormalizeDxil normalizer(F, DT);
|
||||
return normalizer.Run();
|
||||
}
|
||||
|
||||
void NormalizeDxilPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesCFG();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// ScopeNestInfo.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. //
|
||||
// //
|
||||
// Implements ScopeNestInfo class to hold the results of the scope //
|
||||
// nest analysis. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "DxilConvPasses/ScopeNestInfo.h"
|
||||
#include "DxilConvPasses/ScopeNestIterator.h"
|
||||
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
|
||||
//----------------------- Scope Nest Info Implementation ---------------------//
|
||||
void ScopeNestInfo::print(raw_ostream &out) const
|
||||
{
|
||||
out << "ScopeNestInfo:\n";
|
||||
int level = 0;
|
||||
for (const ScopeNestEvent &element : m_scopeElements) {
|
||||
if (element.IsEndScope())
|
||||
--level;
|
||||
|
||||
if (element.IsBeginScope()) {
|
||||
if (element.Block)
|
||||
indent(out, level, element.Block->getName()) << "\n";
|
||||
indent(out, level, "@") << element.GetElementTypeName() << "\n";
|
||||
}
|
||||
else if (element.IsEndScope()) {
|
||||
indent(out, level, "@") << element.GetElementTypeName() << "\n";
|
||||
if (element.Block)
|
||||
indent(out, level, element.Block->getName()) << "\n";
|
||||
}
|
||||
else {
|
||||
if (element.Block)
|
||||
indent(out, level, element.Block->getName()) << "\n";
|
||||
|
||||
if (element.ElementType == ScopeNestEvent::Type::If_Else ||
|
||||
element.ElementType == ScopeNestEvent::Type::Switch_Case)
|
||||
indent(out, level-1, "@") << element.GetElementTypeName() << "\n";
|
||||
else if (element.ElementType != ScopeNestEvent::Type::Body)
|
||||
indent(out, level, "@") << element.GetElementTypeName() << "\n";
|
||||
}
|
||||
|
||||
if (element.IsBeginScope())
|
||||
++level;
|
||||
}
|
||||
}
|
||||
|
||||
raw_ostream &ScopeNestInfo::indent(raw_ostream &out, int level, StringRef str) const {
|
||||
for (int i = 0; i < level; ++i)
|
||||
out << " ";
|
||||
out << str;
|
||||
return out;
|
||||
}
|
||||
|
||||
void ScopeNestInfo::releaseMemory() {
|
||||
m_scopeElements.clear();
|
||||
}
|
||||
|
||||
void ScopeNestInfo::Analyze(Function &F) {
|
||||
for (ScopeNestIterator I = ScopeNestIterator::begin(F), E = ScopeNestIterator::end(); I != E; ++I) {
|
||||
ScopeNestEvent element = *I;
|
||||
m_scopeElements.push_back(element);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------- Wrapper Pass Implementation ------------------------//
|
||||
char ScopeNestInfoWrapperPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(ScopeNestInfoWrapperPass, "scopenestinfo", "Scope nest info pass", true, true)
|
||||
INITIALIZE_PASS_END(ScopeNestInfoWrapperPass, "scopenestinfo", "Scope nest info pass", true, true)
|
||||
|
||||
|
||||
FunctionPass *llvm::createScopeNestInfoWrapperPass() {
|
||||
return new ScopeNestInfoWrapperPass();
|
||||
}
|
||||
|
||||
bool ScopeNestInfoWrapperPass::runOnFunction(Function &F) {
|
||||
releaseMemory();
|
||||
SI.Analyze(F);
|
||||
return false;
|
||||
}
|
||||
|
||||
void ScopeNestInfoWrapperPass::releaseMemory() {
|
||||
SI.releaseMemory();
|
||||
}
|
||||
|
||||
void ScopeNestInfoWrapperPass::print(raw_ostream &O, const Module *M) const {
|
||||
SI.print(O);
|
||||
}
|
||||
|
||||
void ScopeNestInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesAll();
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,11 @@
|
|||
# Build ShaderBinary.lib.
|
||||
|
||||
find_package(D3D12 REQUIRED)
|
||||
|
||||
add_dxilconv_project_library(ShaderBinary
|
||||
ShaderBinary.cpp
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${D3D12_INCLUDE_DIRS}
|
||||
)
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,24 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// ShaderBinaryIncludes.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. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
#include "windows.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#include <strsafe.h>
|
||||
#include <intsafe.h>
|
||||
#include <dxgiformat.h>
|
||||
#include <d3d12.h>
|
||||
#define D3DX12_NO_STATE_OBJECT_HELPERS
|
||||
#include "dxc/Support/d3dx12.h"
|
||||
#include "D3D12TokenizedProgramFormat.hpp"
|
||||
#include "ShaderBinary/ShaderBinary.h"
|
||||
|
||||
#define ASSUME( _exp ) { assert( _exp ); __analysis_assume( _exp ); __assume( _exp ); }
|
|
@ -0,0 +1,13 @@
|
|||
@echo off
|
||||
|
||||
set TESTASM=%_NTTREE%\nttest\Windowstest\graphics\d3d\support\testasm.exe
|
||||
|
||||
FOR %%f IN (call2.asm cs3.asm cyclecounter.asm hs3.asm indexabletemp4.asm) DO (
|
||||
%TESTASM% %%f /Fo %%~nf.dxbc
|
||||
)
|
||||
|
||||
FOR %%f IN (indexabletemp6.asm) DO (
|
||||
%TESTASM% %%f /allowMinimumPrecision /Fo %%~nf.dxbc
|
||||
)
|
||||
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*// RUN: %testasm %s /Fo %t.dxbc*/
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
ps_5_0
|
||||
dcl_globalFlags refactoringAllowed
|
||||
dcl_input_ps linear v0.x
|
||||
dcl_input_ps constant v1.xyz
|
||||
dcl_output o0.x
|
||||
dcl_temps 1
|
||||
mov r0.xyz, v1.xyz
|
||||
call l0
|
||||
callc_nz r0.x, l0
|
||||
switch v1.x
|
||||
case 1
|
||||
call l2
|
||||
callc_nz r0.y, l1
|
||||
break
|
||||
default
|
||||
callc_nz r0.z, l2
|
||||
break
|
||||
case 2
|
||||
break
|
||||
endswitch
|
||||
add o0.x, r0.x, l(1.000000)
|
||||
ret
|
||||
label l0
|
||||
mov r0.x, l(5.000000)
|
||||
ret
|
||||
label l1
|
||||
mov r0.x, v0.x
|
||||
ret
|
||||
label l2
|
||||
mov r0.x, l(3.000000)
|
||||
ret
|
Двоичный файл не отображается.
|
@ -0,0 +1,129 @@
|
|||
|
||||
@dx.v32.r0 = internal global i32 undef, align 4
|
||||
|
||||
define internal void @dx.label.0() {
|
||||
entry:
|
||||
store i32 1084227584, i32* @dx.v32.r0
|
||||
ret void
|
||||
}
|
||||
|
||||
define internal void @dx.label.1() {
|
||||
entry:
|
||||
%0 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%1 = call i32 @dx.op.bitcastF32toI32(i32 127, float %0)
|
||||
store i32 %1, i32* @dx.v32.r0
|
||||
ret void
|
||||
}
|
||||
|
||||
define internal void @dx.label.2() {
|
||||
entry:
|
||||
store i32 1077936128, i32* @dx.v32.r0
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call i32 @dx.op.loadInput.i32(i32 4, i32 1, i32 0, i8 0, i32 undef)
|
||||
%1 = call i32 @dx.op.loadInput.i32(i32 4, i32 1, i32 0, i8 1, i32 undef)
|
||||
%2 = call i32 @dx.op.loadInput.i32(i32 4, i32 1, i32 0, i8 2, i32 undef)
|
||||
store i32 %0, i32* @dx.v32.r0
|
||||
call void @dx.label.0()
|
||||
%3 = load i32, i32* @dx.v32.r0
|
||||
%4 = icmp ne i32 %3, 0
|
||||
br i1 %4, label %label0.callc, label %label0.callc.1
|
||||
|
||||
label0.callc: ; preds = %entry
|
||||
call void @dx.label.0()
|
||||
br label %label0.callc.1
|
||||
|
||||
label0.callc.1: ; preds = %label0.callc, %entry
|
||||
%5 = call i32 @dx.op.loadInput.i32(i32 4, i32 1, i32 0, i8 0, i32 undef)
|
||||
switch i32 %5, label %switch0.default [
|
||||
i32 1, label %switch0.casegroup0
|
||||
i32 2, label %switch0.casegroup1
|
||||
]
|
||||
|
||||
switch0.casegroup0: ; preds = %label0.callc.1
|
||||
call void @dx.label.2()
|
||||
%6 = icmp ne i32 %1, 0
|
||||
br i1 %6, label %label1.callc, label %label1.callc.2
|
||||
|
||||
label1.callc: ; preds = %switch0.casegroup0
|
||||
call void @dx.label.1()
|
||||
br label %label1.callc.2
|
||||
|
||||
label1.callc.2: ; preds = %label1.callc, %switch0.casegroup0
|
||||
br label %switch0.end
|
||||
|
||||
switch0.default: ; preds = %label0.callc.1
|
||||
%7 = icmp ne i32 %2, 0
|
||||
br i1 %7, label %label2.callc, label %label2.callc.3
|
||||
|
||||
label2.callc: ; preds = %switch0.default
|
||||
call void @dx.label.2()
|
||||
br label %label2.callc.3
|
||||
|
||||
label2.callc.3: ; preds = %label2.callc, %switch0.default
|
||||
br label %switch0.end
|
||||
|
||||
switch0.casegroup1: ; preds = %label0.callc.1
|
||||
br label %switch0.end
|
||||
|
||||
switch0.end: ; preds = %switch0.casegroup1, %label2.callc.3, %label1.callc.2
|
||||
%8 = load i32, i32* @dx.v32.r0
|
||||
%9 = call float @dx.op.bitcastI32toF32(i32 126, i32 %8)
|
||||
%10 = fadd fast float %9, 1.000000e+00
|
||||
%11 = call i32 @dx.op.bitcastF32toI32(i32 127, float %10)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 0, i32 %11)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.loadInput.i32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.i32(i32, i32, i32) #1
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare i32 @dx.op.tempRegLoad.i32(i32, i32) #2
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare float @dx.op.tempRegLoad.f32(i32, i32) #2
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.bitcastF32toI32(i32, float) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.i32(i32, i32, i32, i8, i32) #1
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.f32(i32, i32, float) #1
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.bitcastI32toF32(i32, i32) #0
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #1 = { nounwind }
|
||||
attributes #2 = { nounwind readonly }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!11}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !10}
|
||||
!3 = !{!4, !8, null}
|
||||
!4 = !{!5, !7}
|
||||
!5 = !{i32 0, !"0_", i8 9, i8 0, !6, i8 2, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{i32 1, !"1_", i8 5, i8 0, !6, i8 1, i32 1, i8 3, i32 1, i8 0, null}
|
||||
!8 = !{!9}
|
||||
!9 = !{i32 0, !"SV_Target", i8 5, i8 16, !6, i8 0, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!10 = !{i32 0, i64 256}
|
||||
!11 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,35 @@
|
|||
/*// RUN: %testasm %s /Fo %t.dxbc*/
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
cs_5_0
|
||||
dcl_globalFlags refactoringAllowed
|
||||
dcl_constantbuffer cb0[1], immediateIndexed
|
||||
dcl_input vThreadIDInGroup.xyz
|
||||
dcl_temps 3
|
||||
dcl_tgsm_raw g0, 1024
|
||||
dcl_thread_group 4, 2, 3
|
||||
|
||||
ishl r0.x, vThreadIDInGroup.z, l(2)
|
||||
store_raw g0.xy, r0.x, cb0[0].wzyx
|
||||
|
||||
sync_g
|
||||
sync_ugroup
|
||||
sync_uglobal
|
||||
sync_g_t
|
||||
sync_ugroup_t
|
||||
sync_uglobal_t
|
||||
sync_ugroup_g
|
||||
sync_uglobal_g
|
||||
sync_ugroup_g_t
|
||||
sync_uglobal_g_t
|
||||
|
||||
ld_raw r0.xz, r0.x, g0.zxwy
|
||||
|
||||
imm_atomic_iadd r2.x, g0, r1.xyxx, vThreadIDInGroup.x
|
||||
atomic_or g0, r1.xyxx, vThreadIDInGroup.x
|
||||
|
||||
atomic_cmp_store g0, r1.xyxx, vThreadIDInGroup.y, vThreadIDInGroup.x
|
||||
imm_atomic_cmp_exch r1.x, g0, r1.xyxx, vThreadIDInGroup.y, vThreadIDInGroup.x
|
||||
|
||||
ret
|
Двоичный файл не отображается.
|
@ -0,0 +1,102 @@
|
|||
|
||||
%dx.types.Handle = type { i8* }
|
||||
%dx.types.CBufRet.i32 = type { i32, i32, i32, i32 }
|
||||
%dx.types.i8x16 = type { [16 x i8] }
|
||||
|
||||
@TGSM0 = internal addrspace(3) global [1024 x i8] undef, align 4
|
||||
@llvm.used = appending global [1 x i8*] [i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([1024 x i8], [1024 x i8] addrspace(3)* @TGSM0, i32 0, i32 0) to i8*)], section "llvm.metadata"
|
||||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 0, i32 0, i1 false)
|
||||
%1 = call i32 @dx.op.threadIdInGroup.i32(i32 95, i32 2)
|
||||
%2 = shl i32 %1, 2
|
||||
%3 = call %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32 59, %dx.types.Handle %0, i32 0)
|
||||
%4 = extractvalue %dx.types.CBufRet.i32 %3, 3
|
||||
%5 = extractvalue %dx.types.CBufRet.i32 %3, 2
|
||||
%6 = getelementptr [1024 x i8], [1024 x i8] addrspace(3)* @TGSM0, i32 0, i32 %2
|
||||
%7 = bitcast i8 addrspace(3)* %6 to i32 addrspace(3)*
|
||||
store i32 %4, i32 addrspace(3)* %7, align 4
|
||||
%8 = add i32 %2, 4
|
||||
%9 = getelementptr [1024 x i8], [1024 x i8] addrspace(3)* @TGSM0, i32 0, i32 %8
|
||||
%10 = bitcast i8 addrspace(3)* %9 to i32 addrspace(3)*
|
||||
store i32 %5, i32 addrspace(3)* %10, align 4
|
||||
call void @dx.op.barrier(i32 80, i32 8)
|
||||
call void @dx.op.barrier(i32 80, i32 4)
|
||||
call void @dx.op.barrier(i32 80, i32 2)
|
||||
call void @dx.op.barrier(i32 80, i32 9)
|
||||
call void @dx.op.barrier(i32 80, i32 5)
|
||||
call void @dx.op.barrier(i32 80, i32 3)
|
||||
call void @dx.op.barrier(i32 80, i32 12)
|
||||
call void @dx.op.barrier(i32 80, i32 10)
|
||||
call void @dx.op.barrier(i32 80, i32 13)
|
||||
call void @dx.op.barrier(i32 80, i32 11)
|
||||
%11 = call i32 @dx.op.threadIdInGroup.i32(i32 95, i32 0)
|
||||
%12 = getelementptr [1024 x i8], [1024 x i8] addrspace(3)* @TGSM0, i32 0, i32 undef
|
||||
%13 = bitcast i8 addrspace(3)* %12 to i32 addrspace(3)*
|
||||
%14 = atomicrmw add i32 addrspace(3)* %13, i32 %11 monotonic
|
||||
%15 = call i32 @dx.op.threadIdInGroup.i32(i32 95, i32 0)
|
||||
%16 = getelementptr [1024 x i8], [1024 x i8] addrspace(3)* @TGSM0, i32 0, i32 undef
|
||||
%17 = bitcast i8 addrspace(3)* %16 to i32 addrspace(3)*
|
||||
%18 = atomicrmw or i32 addrspace(3)* %17, i32 %15 monotonic
|
||||
%19 = call i32 @dx.op.threadIdInGroup.i32(i32 95, i32 1)
|
||||
%20 = call i32 @dx.op.threadIdInGroup.i32(i32 95, i32 0)
|
||||
%21 = getelementptr [1024 x i8], [1024 x i8] addrspace(3)* @TGSM0, i32 0, i32 undef
|
||||
%22 = bitcast i8 addrspace(3)* %21 to i32 addrspace(3)*
|
||||
%23 = cmpxchg i32 addrspace(3)* %22, i32 %19, i32 %20 monotonic monotonic
|
||||
%24 = call i32 @dx.op.threadIdInGroup.i32(i32 95, i32 1)
|
||||
%25 = call i32 @dx.op.threadIdInGroup.i32(i32 95, i32 0)
|
||||
%26 = getelementptr [1024 x i8], [1024 x i8] addrspace(3)* @TGSM0, i32 0, i32 undef
|
||||
%27 = bitcast i8 addrspace(3)* %26 to i32 addrspace(3)*
|
||||
%28 = cmpxchg i32 addrspace(3)* %27, i32 %24, i32 %25 monotonic monotonic
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #0
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.threadIdInGroup.i32(i32, i32) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.i32(i32, i32, i32) #2
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare i32 @dx.op.tempRegLoad.i32(i32, i32) #0
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32, %dx.types.Handle, i32) #0
|
||||
|
||||
; Function Attrs: noduplicate nounwind
|
||||
declare void @dx.op.barrier(i32, i32) #3
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.bitcastI32toF32(i32, i32) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.f32(i32, i32, float) #2
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.bitcastF32toI32(i32, float) #1
|
||||
|
||||
attributes #0 = { nounwind readonly }
|
||||
attributes #1 = { nounwind readnone }
|
||||
attributes #2 = { nounwind }
|
||||
attributes #3 = { noduplicate nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.resources = !{!2}
|
||||
!dx.entryPoints = !{!5}
|
||||
!llvm.ident = !{!8}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"cs", i32 6, i32 0}
|
||||
!2 = !{null, null, !3, null}
|
||||
!3 = !{!4}
|
||||
!4 = !{i32 0, %dx.types.i8x16 addrspace(2)* undef, !"CB0", i32 0, i32 0, i32 1, i32 16, null}
|
||||
!5 = !{void ()* @main, !"main", null, !2, !6}
|
||||
!6 = !{i32 0, i64 256, i32 4, !7}
|
||||
!7 = !{i32 4, i32 2, i32 3}
|
||||
!8 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,11 @@
|
|||
/*// RUN: %testasm %s /Fo %t.dxbc*/
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
ps_5_0
|
||||
dcl_temps 1
|
||||
dcl_output o0.xyzw
|
||||
dcl_input vCycleCounter.x
|
||||
mov r0, l(0,0,0,0)
|
||||
mov r0.z, vCycleCounter.x
|
||||
mov o0, r0
|
Двоичный файл не отображается.
|
@ -0,0 +1,44 @@
|
|||
|
||||
%dx.types.twoi32 = type { i32, i32 }
|
||||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call %dx.types.twoi32 @dx.op.cycleCounterLegacy(i32 109)
|
||||
%1 = extractvalue %dx.types.twoi32 %0, 0
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 0, i32 0)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 1, i32 0)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 2, i32 %1)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 3, i32 0)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.i32(i32, i32, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare %dx.types.twoi32 @dx.op.cycleCounterLegacy(i32) #0
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare i32 @dx.op.tempRegLoad.i32(i32, i32) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.i32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
attributes #0 = { nounwind }
|
||||
attributes #1 = { nounwind readonly }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!8}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !7}
|
||||
!3 = !{null, !4, null}
|
||||
!4 = !{!5}
|
||||
!5 = !{i32 0, !"SV_Target", i8 5, i8 16, !6, i8 0, i32 1, i8 4, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{i32 0, i64 258}
|
||||
!8 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,93 @@
|
|||
/*// RUN: %testasm %s /Fo %t.dxbc*/
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
hs_5_0
|
||||
hs_decls
|
||||
dcl_input_control_point_count 4
|
||||
dcl_output_control_point_count 32
|
||||
dcl_tessellator_domain domain_quad
|
||||
dcl_tessellator_partitioning partitioning_fractional_odd
|
||||
dcl_tessellator_output_primitive output_triangle_cw
|
||||
dcl_hs_max_tessfactor 64.f
|
||||
hs_control_point_phase
|
||||
dcl_input v[4][0].xyzw
|
||||
dcl_input v[4][1].xy
|
||||
dcl_input v[4][2].xyz
|
||||
dcl_input vOutputControlPointID
|
||||
dcl_input vPrim
|
||||
dcl_output o0.xyzw
|
||||
dcl_output o1.xy
|
||||
dcl_output o2.xyz
|
||||
dcl_temps 1
|
||||
udiv NULL, r0.x, vOutputControlPointID, 4
|
||||
mov o0.xyzw, v[r0.x][0].xyzw
|
||||
mov o1.xy, v[r0.x][1].xyxx
|
||||
mov o2.xyz, v[r0.x][2].xyzx
|
||||
hs_fork_phase
|
||||
dcl_input vcp[4][0].xyzw
|
||||
dcl_input vcp[4][1].xy
|
||||
dcl_input vcp[4][2].xyz
|
||||
dcl_input vocp[32][0].xyzw
|
||||
dcl_input vocp[32][1].xy
|
||||
dcl_input vocp[32][2].xyz
|
||||
dcl_hs_fork_phase_instance_count 4
|
||||
dcl_input vForkInstanceID
|
||||
dcl_input vPrim
|
||||
dcl_indexRange o[0], o[3]
|
||||
dcl_temps 1
|
||||
dcl_indexableTemp x0[4], 1
|
||||
dcl_output_sv o0.x, finalQuadUeq0EdgeTessFactor
|
||||
dcl_output_sv o1.x, finalQuadVeq0EdgeTessFactor
|
||||
dcl_output_sv o2.x, finalQuadUeq1EdgeTessFactor
|
||||
dcl_output_sv o3.x, finalQuadVeq1EdgeTessFactor
|
||||
mov x0[0].x, 2.0f
|
||||
mov x0[1].x, 4.0f
|
||||
mov x0[2].x, 15.0f
|
||||
mov x0[3].x, 6.0f
|
||||
mov r0.x, vForkInstanceID
|
||||
mov o[r0.x].x, x0[r0.x].x
|
||||
hs_fork_phase
|
||||
dcl_input vcp[4][0].xyzw
|
||||
dcl_input vcp[4][1].xy
|
||||
dcl_input vcp[4][2].xyz
|
||||
dcl_input vocp[32][0].xyzw
|
||||
dcl_input vocp[32][1].xy
|
||||
dcl_input vocp[32][2].xyz
|
||||
dcl_hs_fork_phase_instance_count 4
|
||||
dcl_input vForkInstanceID
|
||||
dcl_input vPrim
|
||||
dcl_indexRange o[0], o[3]
|
||||
dcl_temps 1
|
||||
dcl_indexableTemp x0[4], 1
|
||||
dcl_output o0.y
|
||||
dcl_output o1.y
|
||||
dcl_output o2.y
|
||||
dcl_output o3.y
|
||||
mov x0[0].x, 12.0f
|
||||
mov x0[1].x, 32.0f
|
||||
mov x0[2].x, 15.0f
|
||||
mov x0[3].x, 5.0f
|
||||
mov r0.x, vForkInstanceID
|
||||
mov o[r0.x].y, x0[r0.x].x
|
||||
hs_join_phase
|
||||
dcl_input vcp[4][0].xyzw
|
||||
dcl_input vcp[4][1].xy
|
||||
dcl_input vcp[4][2].xyz
|
||||
dcl_input vocp[32][0].xyzw
|
||||
dcl_input vocp[32][1].xy
|
||||
dcl_input vocp[32][2].xyz
|
||||
dcl_input vpc[0].xy
|
||||
dcl_input vpc[1].xy
|
||||
dcl_input vpc[2].xy
|
||||
dcl_input vpc[3].xy
|
||||
dcl_indexRange vpc[0], vpc[3]
|
||||
dcl_output_sv o4.x, finalQuadUInsideTessFactor
|
||||
dcl_output_sv o5.x, finalQuadVInsideTessFactor
|
||||
dcl_output o4.y
|
||||
dcl_output o5.y
|
||||
dcl_input vPrim
|
||||
mov o4.x, 12.0f
|
||||
mov o5.x, 6.0f
|
||||
mov o4.y, 0.0f
|
||||
mov o5.y, 0.0f
|
Двоичный файл не отображается.
|
@ -0,0 +1,159 @@
|
|||
|
||||
%dx.types.twoi32 = type { i32, i32 }
|
||||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call i32 @dx.op.outputControlPointID.i32(i32 107)
|
||||
%1 = call %dx.types.twoi32 @dx.op.binaryWithTwoOuts.i32(i32 43, i32 %0, i32 4)
|
||||
%2 = extractvalue %dx.types.twoi32 %1, 1
|
||||
%3 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 %2)
|
||||
%4 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 1, i32 %2)
|
||||
%5 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 %2)
|
||||
%6 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 3, i32 %2)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 0, i32 %3)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 1, i32 %4)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 2, i32 %5)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 3, i32 %6)
|
||||
%7 = call i32 @dx.op.loadInput.i32(i32 4, i32 1, i32 0, i8 0, i32 %2)
|
||||
%8 = call i32 @dx.op.loadInput.i32(i32 4, i32 1, i32 0, i8 1, i32 %2)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 1, i32 0, i8 0, i32 %7)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 1, i32 0, i8 1, i32 %8)
|
||||
%9 = call i32 @dx.op.loadInput.i32(i32 4, i32 2, i32 0, i8 0, i32 %2)
|
||||
%10 = call i32 @dx.op.loadInput.i32(i32 4, i32 2, i32 0, i8 1, i32 %2)
|
||||
%11 = call i32 @dx.op.loadInput.i32(i32 4, i32 2, i32 0, i8 2, i32 %2)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 2, i32 0, i8 0, i32 %9)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 2, i32 0, i8 1, i32 %10)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 2, i32 0, i8 2, i32 %11)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare %dx.types.twoi32 @dx.op.binaryWithTwoOuts.i32(i32, i32, i32) #0
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.outputControlPointID.i32(i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.i32(i32, i32, i32) #1
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare i32 @dx.op.tempRegLoad.i32(i32, i32) #2
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.loadInput.i32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.i32(i32, i32, i32, i8, i32) #1
|
||||
|
||||
define void @pc_main() {
|
||||
entry:
|
||||
%dx.v32.x01 = alloca [16 x i32], align 4
|
||||
br label %hullloop0
|
||||
|
||||
hullloop0: ; preds = %hullloop0, %entry
|
||||
%InstanceID.0 = phi i32 [ 0, %entry ], [ %10, %hullloop0 ]
|
||||
%0 = getelementptr [16 x i32], [16 x i32]* %dx.v32.x01, i32 0, i32 0
|
||||
store i32 1073741824, i32* %0, align 4
|
||||
%1 = getelementptr [16 x i32], [16 x i32]* %dx.v32.x01, i32 0, i32 4
|
||||
store i32 1082130432, i32* %1, align 4
|
||||
%2 = getelementptr [16 x i32], [16 x i32]* %dx.v32.x01, i32 0, i32 8
|
||||
store i32 1097859072, i32* %2, align 4
|
||||
%3 = getelementptr [16 x i32], [16 x i32]* %dx.v32.x01, i32 0, i32 12
|
||||
store i32 1086324736, i32* %3, align 4
|
||||
%4 = mul i32 %InstanceID.0, 4
|
||||
%5 = add i32 %4, 0
|
||||
%6 = getelementptr [16 x i32], [16 x i32]* %dx.v32.x01, i32 0, i32 %5
|
||||
%7 = load i32, i32* %6, align 4
|
||||
%8 = call float @dx.op.bitcastI32toF32(i32 126, i32 %7)
|
||||
%9 = sub i32 %InstanceID.0, 0
|
||||
call void @dx.op.storePatchConstant.f32(i32 106, i32 0, i32 %9, i8 0, float %8)
|
||||
%10 = add i32 %InstanceID.0, 1
|
||||
%11 = icmp ult i32 %10, 4
|
||||
br i1 %11, label %hullloop0, label %hullloop0.end
|
||||
|
||||
hullloop0.end: ; preds = %hullloop0
|
||||
br label %hullloop1
|
||||
|
||||
hullloop1: ; preds = %hullloop1, %hullloop0.end
|
||||
%InstanceID.1 = phi i32 [ 0, %hullloop0.end ], [ %21, %hullloop1 ]
|
||||
%12 = getelementptr [16 x i32], [16 x i32]* %dx.v32.x01, i32 0, i32 0
|
||||
store i32 1094713344, i32* %12, align 4
|
||||
%13 = getelementptr [16 x i32], [16 x i32]* %dx.v32.x01, i32 0, i32 4
|
||||
store i32 1107296256, i32* %13, align 4
|
||||
%14 = getelementptr [16 x i32], [16 x i32]* %dx.v32.x01, i32 0, i32 8
|
||||
store i32 1097859072, i32* %14, align 4
|
||||
%15 = getelementptr [16 x i32], [16 x i32]* %dx.v32.x01, i32 0, i32 12
|
||||
store i32 1084227584, i32* %15, align 4
|
||||
%16 = mul i32 %InstanceID.1, 4
|
||||
%17 = add i32 %16, 0
|
||||
%18 = getelementptr [16 x i32], [16 x i32]* %dx.v32.x01, i32 0, i32 %17
|
||||
%19 = load i32, i32* %18, align 4
|
||||
%20 = sub i32 %InstanceID.1, 0
|
||||
call void @dx.op.storePatchConstant.i32(i32 106, i32 1, i32 %20, i8 0, i32 %19)
|
||||
%21 = add i32 %InstanceID.1, 1
|
||||
%22 = icmp ult i32 %21, 4
|
||||
br i1 %22, label %hullloop1, label %hullloop1.end
|
||||
|
||||
hullloop1.end: ; preds = %hullloop1
|
||||
br label %hullloop2
|
||||
|
||||
hullloop2: ; preds = %hullloop2, %hullloop1.end
|
||||
%InstanceID.2 = phi i32 [ 0, %hullloop1.end ], [ %23, %hullloop2 ]
|
||||
call void @dx.op.storePatchConstant.f32(i32 106, i32 5, i32 0, i8 0, float 1.200000e+01)
|
||||
call void @dx.op.storePatchConstant.f32(i32 106, i32 7, i32 0, i8 0, float 6.000000e+00)
|
||||
call void @dx.op.storePatchConstant.i32(i32 106, i32 6, i32 0, i8 0, i32 0)
|
||||
call void @dx.op.storePatchConstant.i32(i32 106, i32 8, i32 0, i8 0, i32 0)
|
||||
%23 = add i32 %InstanceID.2, 1
|
||||
%24 = icmp ult i32 %23, 1
|
||||
br i1 %24, label %hullloop2, label %hullloop2.end
|
||||
|
||||
hullloop2.end: ; preds = %hullloop2
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.bitcastI32toF32(i32, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storePatchConstant.f32(i32, i32, i32, i8, float) #1
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.bitcastF32toI32(i32, float) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storePatchConstant.i32(i32, i32, i32, i8, i32) #1
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #1 = { nounwind }
|
||||
attributes #2 = { nounwind readonly }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!23}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"hs", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !21}
|
||||
!3 = !{!4, !4, !9}
|
||||
!4 = !{!5, !7, !8}
|
||||
!5 = !{i32 0, !"0_", i8 5, i8 0, !6, i8 0, i32 1, i8 4, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{i32 1, !"1_", i8 5, i8 0, !6, i8 0, i32 1, i8 2, i32 1, i8 0, null}
|
||||
!8 = !{i32 2, !"2_", i8 5, i8 0, !6, i8 0, i32 1, i8 3, i32 2, i8 0, null}
|
||||
!9 = !{!10, !12, !13, !14, !15, !16, !17, !18, !20}
|
||||
!10 = !{i32 0, !"SV_TessFactor", i8 9, i8 25, !11, i8 0, i32 4, i8 1, i32 0, i8 0, null}
|
||||
!11 = !{i32 0, i32 1, i32 2, i32 3}
|
||||
!12 = !{i32 1, !"0_", i8 5, i8 0, !6, i8 0, i32 1, i8 1, i32 0, i8 1, null}
|
||||
!13 = !{i32 2, !"1_", i8 5, i8 0, !6, i8 0, i32 1, i8 1, i32 1, i8 1, null}
|
||||
!14 = !{i32 3, !"2_", i8 5, i8 0, !6, i8 0, i32 1, i8 1, i32 2, i8 1, null}
|
||||
!15 = !{i32 4, !"3_", i8 5, i8 0, !6, i8 0, i32 1, i8 1, i32 3, i8 1, null}
|
||||
!16 = !{i32 5, !"SV_InsideTessFactor", i8 9, i8 26, !6, i8 0, i32 1, i8 1, i32 4, i8 0, null}
|
||||
!17 = !{i32 6, !"4_", i8 5, i8 0, !6, i8 0, i32 1, i8 1, i32 4, i8 1, null}
|
||||
!18 = !{i32 7, !"SV_InsideTessFactor", i8 9, i8 26, !19, i8 0, i32 1, i8 1, i32 5, i8 0, null}
|
||||
!19 = !{i32 1}
|
||||
!20 = !{i32 8, !"5_", i8 5, i8 0, !6, i8 0, i32 1, i8 1, i32 5, i8 1, null}
|
||||
!21 = !{i32 0, i64 258, i32 3, !22}
|
||||
!22 = !{void ()* @pc_main, i32 4, i32 32, i32 3, i32 3, i32 3, float 6.400000e+01}
|
||||
!23 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,19 @@
|
|||
/*// RUN: %testasm %s /Fo %t.dxbc*/
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
ps_5_0
|
||||
dcl_globalFlags refactoringAllowed
|
||||
dcl_constantbuffer cb0[12], dynamicIndexed
|
||||
dcl_input_ps constant v1.x
|
||||
dcl_input_ps constant v1.y
|
||||
dcl_output o0.x
|
||||
dcl_temps 1
|
||||
dcl_indexableTemp x0[4], 2
|
||||
mov r0.x, v1.x
|
||||
mov x0[0].x, cb0[r0.x + 0].x
|
||||
mov x0[1].x, cb0[r0.x + 4].x
|
||||
mov r0.x, v1.y
|
||||
mov x0[1].y, r0.x
|
||||
mov o0.x, x0[ x0[1].y + 77 ].x
|
||||
ret
|
Двоичный файл не отображается.
|
@ -0,0 +1,82 @@
|
|||
|
||||
%dx.types.Handle = type { i8* }
|
||||
%dx.types.CBufRet.i32 = type { i32, i32, i32, i32 }
|
||||
%dx.types.i8x192 = type { [192 x i8] }
|
||||
|
||||
define void @main() {
|
||||
entry:
|
||||
%dx.v32.x01 = alloca [8 x i32], align 4
|
||||
%0 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 0, i32 0, i1 false)
|
||||
%1 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%2 = call %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32 59, %dx.types.Handle %0, i32 %1)
|
||||
%3 = extractvalue %dx.types.CBufRet.i32 %2, 0
|
||||
%4 = getelementptr [8 x i32], [8 x i32]* %dx.v32.x01, i32 0, i32 0
|
||||
store i32 %3, i32* %4, align 4
|
||||
%5 = add i32 %1, 4
|
||||
%6 = call %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32 59, %dx.types.Handle %0, i32 %5)
|
||||
%7 = extractvalue %dx.types.CBufRet.i32 %6, 0
|
||||
%8 = getelementptr [8 x i32], [8 x i32]* %dx.v32.x01, i32 0, i32 2
|
||||
store i32 %7, i32* %8, align 4
|
||||
%9 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 1, i32 undef)
|
||||
%10 = getelementptr [8 x i32], [8 x i32]* %dx.v32.x01, i32 0, i32 3
|
||||
store i32 %9, i32* %10, align 4
|
||||
%11 = getelementptr [8 x i32], [8 x i32]* %dx.v32.x01, i32 0, i32 3
|
||||
%12 = load i32, i32* %11, align 4
|
||||
%13 = add i32 %12, 77
|
||||
%14 = mul i32 %13, 2
|
||||
%15 = add i32 %14, 0
|
||||
%16 = getelementptr [8 x i32], [8 x i32]* %dx.v32.x01, i32 0, i32 %15
|
||||
%17 = load i32, i32* %16, align 4
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 0, i32 %17)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #0
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.loadInput.i32(i32, i32, i32, i8, i32) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.i32(i32, i32, i32) #2
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare i32 @dx.op.tempRegLoad.i32(i32, i32) #0
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32, %dx.types.Handle, i32) #0
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.bitcastI32toF32(i32, i32) #1
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.bitcastF32toI32(i32, float) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.i32(i32, i32, i32, i8, i32) #2
|
||||
|
||||
attributes #0 = { nounwind readonly }
|
||||
attributes #1 = { nounwind readnone }
|
||||
attributes #2 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.resources = !{!2}
|
||||
!dx.entryPoints = !{!5}
|
||||
!llvm.ident = !{!13}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{null, null, !3, null}
|
||||
!3 = !{!4}
|
||||
!4 = !{i32 0, %dx.types.i8x192 addrspace(2)* undef, !"CB0", i32 0, i32 0, i32 1, i32 192, null}
|
||||
!5 = !{void ()* @main, !"main", !6, !2, !12}
|
||||
!6 = !{!7, !10, null}
|
||||
!7 = !{!8}
|
||||
!8 = !{i32 0, !"1_", i8 5, i8 0, !9, i8 1, i32 1, i8 2, i32 1, i8 0, null}
|
||||
!9 = !{i32 0}
|
||||
!10 = !{!11}
|
||||
!11 = !{i32 0, !"SV_Target", i8 5, i8 16, !9, i8 0, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!12 = !{i32 0, i64 256}
|
||||
!13 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,63 @@
|
|||
/*// RUN: %testasm %s /allowMinimumPrecision /Fo %t.dxbc*/
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
//
|
||||
// Generated by Microsoft (R) HLSL Shader Compiler 10.1 INTERNAL
|
||||
//
|
||||
//
|
||||
// Note: shader requires additional functionality:
|
||||
// Minimum-precision data types
|
||||
//
|
||||
//
|
||||
// Buffer Definitions:
|
||||
//
|
||||
// cbuffer $Globals
|
||||
// {
|
||||
//
|
||||
// min16float g1[4]; // Offset: 0 Size: 52
|
||||
// min16float g2[8]; // Offset: 64 Size: 116
|
||||
//
|
||||
// }
|
||||
//
|
||||
//
|
||||
// Resource Bindings:
|
||||
//
|
||||
// Name Type Format Dim HLSL Bind Count
|
||||
// ------------------------------ ---------- ------- ----------- -------------- ------
|
||||
// $Globals cbuffer NA NA cb0 1
|
||||
//
|
||||
//
|
||||
//
|
||||
// Input signature:
|
||||
//
|
||||
// Name Index Mask Register SysValue Format Used
|
||||
// -------------------- ----- ------ -------- -------- ------- ------
|
||||
// A 0 xyzw 0 NONE min16f
|
||||
// B 0 x 1 NONE int x
|
||||
// C 0 y 1 NONE int y
|
||||
//
|
||||
//
|
||||
// Output signature:
|
||||
//
|
||||
// Name Index Mask Register SysValue Format Used
|
||||
// -------------------- ----- ------ -------- -------- ------- ------
|
||||
// SV_TARGET 0 x 0 TARGET min16f x
|
||||
//
|
||||
ps_5_0
|
||||
dcl_globalFlags refactoringAllowed | enableMinimumPrecision
|
||||
dcl_constantbuffer cb0[12], dynamicIndexed
|
||||
dcl_input_ps constant v1.x
|
||||
dcl_input_ps constant v1.y
|
||||
dcl_output o0.x {min16f}
|
||||
dcl_temps 1
|
||||
dcl_indexableTemp x0[4], 4
|
||||
mov r0.x, v1.x
|
||||
mov x0[0].x, cb0[r0.x + 4].x
|
||||
mov r0.y, x0[0].x
|
||||
mov x0[0].x {min16f}, cb0[r0.x + 0].x {min16f}
|
||||
mov x0[1].x {min16f}, cb0[r0.x + 4].x {min16f}
|
||||
mov r0.x, v1.y
|
||||
add x0[r0.x + 0].x {min16f}, x0[r0.x + 0].x {min16f}, r0.y {min16f}
|
||||
mov o0.x {min16f}, x0[r0.x + 0].x {min16f}
|
||||
ret
|
Двоичный файл не отображается.
|
@ -0,0 +1,103 @@
|
|||
|
||||
%dx.types.Handle = type { i8* }
|
||||
%dx.types.CBufRet.i32 = type { i32, i32, i32, i32 }
|
||||
%dx.types.CBufRet.f32 = type { float, float, float, float }
|
||||
%dx.types.i8x192 = type { [192 x i8] }
|
||||
|
||||
define void @main() {
|
||||
entry:
|
||||
%dx.v32.x01 = alloca [16 x i32], align 4
|
||||
%dx.v16.x0 = alloca [16 x half], align 4
|
||||
%0 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 0, i32 0, i1 false)
|
||||
%1 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%2 = add i32 %1, 4
|
||||
%3 = call %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32 59, %dx.types.Handle %0, i32 %2)
|
||||
%4 = extractvalue %dx.types.CBufRet.i32 %3, 0
|
||||
%5 = getelementptr [16 x i32], [16 x i32]* %dx.v32.x01, i32 0, i32 0
|
||||
store i32 %4, i32* %5, align 4
|
||||
%6 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %0, i32 %1)
|
||||
%7 = extractvalue %dx.types.CBufRet.f32 %6, 0
|
||||
%8 = getelementptr [16 x half], [16 x half]* %dx.v16.x0, i32 0, i32 0
|
||||
%9 = fptrunc float %7 to half
|
||||
store half %9, half* %8, align 2
|
||||
%10 = add i32 %1, 4
|
||||
%11 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %0, i32 %10)
|
||||
%12 = extractvalue %dx.types.CBufRet.f32 %11, 0
|
||||
%13 = getelementptr [16 x half], [16 x half]* %dx.v16.x0, i32 0, i32 4
|
||||
%14 = fptrunc float %12 to half
|
||||
store half %14, half* %13, align 2
|
||||
%15 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 1, i32 undef)
|
||||
%16 = mul i32 %15, 4
|
||||
%17 = add i32 %16, 0
|
||||
%18 = getelementptr [16 x half], [16 x half]* %dx.v16.x0, i32 0, i32 %17
|
||||
%19 = load half, half* %18, align 2
|
||||
%20 = fadd fast half %19, undef
|
||||
%21 = mul i32 %15, 4
|
||||
%22 = add i32 %21, 0
|
||||
%23 = getelementptr [16 x half], [16 x half]* %dx.v16.x0, i32 0, i32 %22
|
||||
store half %20, half* %23, align 2
|
||||
%24 = mul i32 %15, 4
|
||||
%25 = add i32 %24, 0
|
||||
%26 = getelementptr [16 x half], [16 x half]* %dx.v16.x0, i32 0, i32 %25
|
||||
%27 = load half, half* %26, align 2
|
||||
%28 = fpext half %27 to float
|
||||
%29 = call i32 @dx.op.bitcastF32toI32(i32 127, float %28)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 0, i32 %29)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #0
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.loadInput.i32(i32, i32, i32, i8, i32) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.i32(i32, i32, i32) #2
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare i32 @dx.op.tempRegLoad.i32(i32, i32) #0
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32, %dx.types.Handle, i32) #0
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.bitcastI32toF32(i32, i32) #1
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.bitcastF32toI32(i32, float) #1
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32, %dx.types.Handle, i32) #0
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare half @dx.op.tempRegLoad.f16(i32, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.i32(i32, i32, i32, i8, i32) #2
|
||||
|
||||
attributes #0 = { nounwind readonly }
|
||||
attributes #1 = { nounwind readnone }
|
||||
attributes #2 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.resources = !{!2}
|
||||
!dx.entryPoints = !{!5}
|
||||
!llvm.ident = !{!13}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{null, null, !3, null}
|
||||
!3 = !{!4}
|
||||
!4 = !{i32 0, %dx.types.i8x192 addrspace(2)* undef, !"CB0", i32 0, i32 0, i32 1, i32 192, null}
|
||||
!5 = !{void ()* @main, !"main", !6, !2, !12}
|
||||
!6 = !{!7, !10, null}
|
||||
!7 = !{!8}
|
||||
!8 = !{i32 0, !"1_", i8 5, i8 0, !9, i8 1, i32 1, i8 2, i32 1, i8 0, null}
|
||||
!9 = !{i32 0}
|
||||
!10 = !{!11}
|
||||
!11 = !{i32 0, !"SV_Target", i8 5, i8 16, !9, i8 0, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!12 = !{i32 0, i64 288}
|
||||
!13 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,11 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
float4 main(float4 a : A) : SV_TARGET
|
||||
{
|
||||
return abs(a.yxxx);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 1, i32 undef)
|
||||
%1 = call float @dx.op.unary.f32(i32 6, float %0)
|
||||
%2 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%3 = call float @dx.op.unary.f32(i32 6, float %2)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %1)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %3)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %3)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float %3)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.unary.f32(i32, float) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #1 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!10}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !9}
|
||||
!3 = !{!4, !7, null}
|
||||
!4 = !{!5}
|
||||
!5 = !{i32 0, !"A", i8 9, i8 0, !6, i8 2, i32 1, i8 4, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{!8}
|
||||
!8 = !{i32 0, !"SV_Target", i8 9, i8 16, !6, i8 0, i32 1, i8 4, i32 0, i8 0, null}
|
||||
!9 = !{i32 0, i64 256}
|
||||
!10 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,11 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
int4 main(int4 a : A) : SV_TARGET
|
||||
{
|
||||
return abs(a.yxxx);
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 1, i32 undef)
|
||||
%1 = sub i32 0, %0
|
||||
%2 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%3 = sub i32 0, %2
|
||||
%4 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 1, i32 undef)
|
||||
%5 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%6 = call i32 @dx.op.binary.i32(i32 37, i32 %1, i32 %4)
|
||||
%7 = call i32 @dx.op.binary.i32(i32 37, i32 %3, i32 %5)
|
||||
%8 = call i32 @dx.op.binary.i32(i32 37, i32 %3, i32 %5)
|
||||
%9 = call i32 @dx.op.binary.i32(i32 37, i32 %3, i32 %5)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 0, i32 %6)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 1, i32 %7)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 2, i32 %8)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 3, i32 %9)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.binary.i32(i32, i32, i32) #0
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.loadInput.i32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.i32(i32, i32, i32, i8, i32) #1
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #1 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!10}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !9}
|
||||
!3 = !{!4, !7, null}
|
||||
!4 = !{!5}
|
||||
!5 = !{i32 0, !"A", i8 4, i8 0, !6, i8 1, i32 1, i8 4, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{!8}
|
||||
!8 = !{i32 0, !"SV_Target", i8 4, i8 16, !6, i8 0, i32 1, i8 4, i32 0, i8 0, null}
|
||||
!9 = !{i32 0, i64 256}
|
||||
!10 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,61 @@
|
|||
// RUN: %fxc /T ps_5_1 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
RWBuffer<uint> buf0;
|
||||
RWByteAddressBuffer buf1;
|
||||
RWByteAddressBuffer buf2[4][7];
|
||||
RWTexture2D<uint> tex0;
|
||||
RWTexture3D<uint> tex1;
|
||||
RWTexture2DArray<uint> tex2;
|
||||
RWTexture3D<uint> tex3[8][4];
|
||||
|
||||
#define RS "DescriptorTable(" \
|
||||
"UAV(u0), "\
|
||||
"UAV(u1), "\
|
||||
"UAV(u2, numDescriptors=28), "\
|
||||
"UAV(u30), "\
|
||||
"UAV(u31), "\
|
||||
"UAV(u32), "\
|
||||
"UAV(u33, numDescriptors=32) "\
|
||||
")"\
|
||||
|
||||
[RootSignature( RS )]
|
||||
|
||||
float4 main(uint4 a : A, float4 b : B) : SV_Target
|
||||
{
|
||||
uint4 r = a;
|
||||
uint comparevalue = r.w;
|
||||
uint newvalue = r.z;
|
||||
uint origvalue;
|
||||
|
||||
InterlockedAdd(buf0[r.z], newvalue);
|
||||
InterlockedMin(buf0[r.z], newvalue);
|
||||
InterlockedMax(buf0[r.z], newvalue);
|
||||
InterlockedAnd(buf0[r.z], newvalue);
|
||||
InterlockedOr (buf0[r.z], newvalue);
|
||||
InterlockedXor(buf0[r.z], newvalue);
|
||||
|
||||
InterlockedAdd(buf0[r.z], newvalue, origvalue); newvalue += origvalue;
|
||||
InterlockedAdd(tex0[r.xy], newvalue);
|
||||
InterlockedAdd(tex1[r.ywz], newvalue);
|
||||
InterlockedAdd(tex2[r.xyz], newvalue);
|
||||
InterlockedAdd(tex3[r.x][1][r.xyz], newvalue);
|
||||
|
||||
InterlockedCompareExchange(buf0[r.z], comparevalue, newvalue, origvalue); newvalue += origvalue;
|
||||
|
||||
buf1.InterlockedAdd(r.x, r.z, newvalue); // coord, newvalue, original
|
||||
buf2[2][r.y].InterlockedAdd(r.x, r.z, newvalue);
|
||||
buf1.InterlockedMin(r.x, r.z, newvalue);
|
||||
buf1.InterlockedMax(r.x, r.z, newvalue);
|
||||
buf1.InterlockedAnd(r.x, r.z, newvalue);
|
||||
buf1.InterlockedOr (r.x, r.z, newvalue);
|
||||
buf1.InterlockedXor(r.x, r.z, newvalue);
|
||||
buf1.InterlockedExchange(r.z, newvalue, origvalue); newvalue += origvalue;
|
||||
buf1.InterlockedCompareExchange(r.z, comparevalue, newvalue, origvalue); newvalue += origvalue;
|
||||
|
||||
return newvalue;
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
|
||||
%dx.types.Handle = type { i8* }
|
||||
%dx.types.u32 = type { i32 }
|
||||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 0, i1 false)
|
||||
%1 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%2 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%3 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %0, i32 0, i32 %1, i32 undef, i32 undef, i32 %2)
|
||||
%4 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 0, i1 false)
|
||||
%5 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%6 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%7 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %4, i32 6, i32 %5, i32 undef, i32 undef, i32 %6)
|
||||
%8 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 0, i1 false)
|
||||
%9 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%10 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%11 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %8, i32 7, i32 %9, i32 undef, i32 undef, i32 %10)
|
||||
%12 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 0, i1 false)
|
||||
%13 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%14 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%15 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %12, i32 1, i32 %13, i32 undef, i32 undef, i32 %14)
|
||||
%16 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 0, i1 false)
|
||||
%17 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%18 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%19 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %16, i32 2, i32 %17, i32 undef, i32 undef, i32 %18)
|
||||
%20 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 0, i1 false)
|
||||
%21 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%22 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%23 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %20, i32 3, i32 %21, i32 undef, i32 undef, i32 %22)
|
||||
%24 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 0, i1 false)
|
||||
%25 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%26 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%27 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %24, i32 0, i32 %25, i32 undef, i32 undef, i32 %26)
|
||||
%28 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%29 = add i32 %27, %28
|
||||
%30 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 3, i32 30, i1 false)
|
||||
%31 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%32 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 1, i32 undef)
|
||||
%33 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %30, i32 0, i32 %31, i32 %32, i32 undef, i32 %29)
|
||||
%34 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 4, i32 31, i1 false)
|
||||
%35 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 1, i32 undef)
|
||||
%36 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 3, i32 undef)
|
||||
%37 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%38 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %34, i32 0, i32 %35, i32 %36, i32 %37, i32 %29)
|
||||
%39 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 5, i32 32, i1 false)
|
||||
%40 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%41 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 1, i32 undef)
|
||||
%42 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%43 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %39, i32 0, i32 %40, i32 %41, i32 %42, i32 %29)
|
||||
%44 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%45 = call i32 @dx.op.quaternary.i32(i32 53, i32 30, i32 2, i32 %44, i32 1)
|
||||
%46 = add i32 %45, 33
|
||||
%47 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 6, i32 %46, i1 false)
|
||||
%48 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%49 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 1, i32 undef)
|
||||
%50 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%51 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %47, i32 0, i32 %48, i32 %49, i32 %50, i32 %29)
|
||||
%52 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 0, i1 false)
|
||||
%53 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%54 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 3, i32 undef)
|
||||
%55 = call i32 @dx.op.atomicCompareExchange.i32(i32 79, %dx.types.Handle %52, i32 %53, i32 undef, i32 undef, i32 %54, i32 %29)
|
||||
%56 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 1, i32 1, i1 false)
|
||||
%57 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%58 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%59 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %56, i32 0, i32 %57, i32 undef, i32 undef, i32 %58)
|
||||
%60 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 1, i32 undef)
|
||||
%61 = add i32 %60, 14
|
||||
%62 = add i32 %61, 2
|
||||
%63 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 2, i32 %62, i1 false)
|
||||
%64 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%65 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%66 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %63, i32 0, i32 %64, i32 undef, i32 undef, i32 %65)
|
||||
%67 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 1, i32 1, i1 false)
|
||||
%68 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%69 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%70 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %67, i32 6, i32 %68, i32 undef, i32 undef, i32 %69)
|
||||
%71 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 1, i32 1, i1 false)
|
||||
%72 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%73 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%74 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %71, i32 7, i32 %72, i32 undef, i32 undef, i32 %73)
|
||||
%75 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 1, i32 1, i1 false)
|
||||
%76 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%77 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%78 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %75, i32 1, i32 %76, i32 undef, i32 undef, i32 %77)
|
||||
%79 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 1, i32 1, i1 false)
|
||||
%80 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%81 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%82 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %79, i32 2, i32 %80, i32 undef, i32 undef, i32 %81)
|
||||
%83 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 1, i32 1, i1 false)
|
||||
%84 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%85 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%86 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %83, i32 3, i32 %84, i32 undef, i32 undef, i32 %85)
|
||||
%87 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 1, i32 1, i1 false)
|
||||
%88 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%89 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %87, i32 8, i32 %88, i32 undef, i32 undef, i32 %86)
|
||||
%90 = add i32 %86, %89
|
||||
%91 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 1, i32 1, i1 false)
|
||||
%92 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%93 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 3, i32 undef)
|
||||
%94 = call i32 @dx.op.atomicCompareExchange.i32(i32 79, %dx.types.Handle %91, i32 %92, i32 undef, i32 undef, i32 %93, i32 %90)
|
||||
%95 = add i32 %90, %94
|
||||
%96 = uitofp i32 %95 to float
|
||||
%97 = uitofp i32 %95 to float
|
||||
%98 = uitofp i32 %95 to float
|
||||
%99 = uitofp i32 %95 to float
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %96)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %97)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %98)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float %99)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #0
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.loadInput.i32(i32, i32, i32, i8, i32) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i32 @dx.op.atomicBinOp.i32(i32, %dx.types.Handle, i32, i32, i32, i32, i32) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.i32(i32, i32, i32) #2
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare i32 @dx.op.tempRegLoad.i32(i32, i32) #0
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.quaternary.i32(i32, i32, i32, i32, i32) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i32 @dx.op.atomicCompareExchange.i32(i32, %dx.types.Handle, i32, i32, i32, i32, i32) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #2
|
||||
|
||||
attributes #0 = { nounwind readonly }
|
||||
attributes #1 = { nounwind readnone }
|
||||
attributes #2 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.resources = !{!2}
|
||||
!dx.entryPoints = !{!12}
|
||||
!llvm.ident = !{!20}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{null, !3, null, null}
|
||||
!3 = !{!4, !6, !7, !8, !9, !10, !11}
|
||||
!4 = !{i32 0, %dx.types.u32 addrspace(1)* undef, !"U0", i32 0, i32 0, i32 1, i32 10, i1 false, i1 false, i1 false, !5}
|
||||
!5 = !{i32 0, i32 5}
|
||||
!6 = !{i32 1, %dx.types.u32 addrspace(1)* undef, !"U1", i32 0, i32 1, i32 1, i32 11, i1 false, i1 false, i1 false, null}
|
||||
!7 = !{i32 2, %dx.types.u32 addrspace(1)* undef, !"U2", i32 0, i32 2, i32 28, i32 11, i1 false, i1 false, i1 false, null}
|
||||
!8 = !{i32 3, %dx.types.u32 addrspace(1)* undef, !"U3", i32 0, i32 30, i32 1, i32 2, i1 false, i1 false, i1 false, !5}
|
||||
!9 = !{i32 4, %dx.types.u32 addrspace(1)* undef, !"U4", i32 0, i32 31, i32 1, i32 4, i1 false, i1 false, i1 false, !5}
|
||||
!10 = !{i32 5, %dx.types.u32 addrspace(1)* undef, !"U5", i32 0, i32 32, i32 1, i32 7, i1 false, i1 false, i1 false, !5}
|
||||
!11 = !{i32 6, %dx.types.u32 addrspace(1)* undef, !"U6", i32 0, i32 33, i32 32, i32 4, i1 false, i1 false, i1 false, !5}
|
||||
!12 = !{void ()* @main, !"main", !13, !2, null}
|
||||
!13 = !{!14, !18, null}
|
||||
!14 = !{!15, !17}
|
||||
!15 = !{i32 0, !"A", i8 5, i8 0, !16, i8 1, i32 1, i8 4, i32 0, i8 0, null}
|
||||
!16 = !{i32 0}
|
||||
!17 = !{i32 1, !"B", i8 9, i8 0, !16, i8 0, i32 1, i8 4, i32 1, i8 0, null}
|
||||
!18 = !{!19}
|
||||
!19 = !{i32 0, !"SV_Target", i8 9, i8 16, !16, i8 0, i32 1, i8 4, i32 0, i8 0, null}
|
||||
!20 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,32 @@
|
|||
// RUN: %fxc /T vs_5_0 /Od %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
int4 main() : OUTPUT
|
||||
{
|
||||
return int4(340282346638528860000000000000000000000.0,
|
||||
-340282346638528860000000000000000000000.0,
|
||||
asint((uint)340282346638528860000000000000000000000.0),
|
||||
asint((uint)-340282346638528860000000000000000000000.0));
|
||||
}
|
||||
|
||||
// fxc produces:
|
||||
// -> ftou o0.z, l(340282346638528860000000000000000000000.000000)
|
||||
// -> ftou o0.w, l(-340282346638528860000000000000000000000.000000)
|
||||
// -> ftoi o0.xy, l(340282346638528860000000000000000000000.000000, -340282346638528860000000000000000000000.000000, 0.000000, 0.000000)
|
||||
|
||||
// dxbc2dxil used to produce:
|
||||
// -> call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 2, i32 undef)
|
||||
// -> call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 3, i32 undef)
|
||||
// -> call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 0, i32 undef)
|
||||
// -> call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 1, i32 undef)
|
||||
// "i32 undef" is invalid here. It's caused by:
|
||||
// return of opInvalidOp from APFloat::convertToSignExtendedInteger
|
||||
// which llvm::ConstantFoldCastInstruction turns into i32 undef
|
||||
|
||||
// fixed dxbc2dxil produces:
|
||||
// -> call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 2, i32 -1)
|
||||
// -> call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 3, i32 0)
|
||||
// -> call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 0, i32 2147483647)
|
||||
// -> call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 1, i32 -2147483648)
|
||||
// Which is int4(max int, min int, max uint, min uint)
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
define void @main() {
|
||||
entry:
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 2, i32 -1)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 3, i32 0)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 0, i32 2147483647)
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 1, i32 -2147483648)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.i32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
attributes #0 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!8}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"vs", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !7}
|
||||
!3 = !{null, !4, null}
|
||||
!4 = !{!5}
|
||||
!5 = !{i32 0, !"OUTPUT", i8 4, i8 0, !6, i8 0, i32 1, i8 4, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{i32 0, i64 257}
|
||||
!8 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,17 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
float main(float a : A, float b : B, float2 c : C) : SV_Target
|
||||
{
|
||||
float r = a;
|
||||
r += a;
|
||||
r /= a;
|
||||
r *= b;
|
||||
r = max(r, c.x);
|
||||
r = min(r, c.y);
|
||||
return r;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%1 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%2 = fadd fast float %0, %1
|
||||
%3 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%4 = fdiv fast float %2, %3
|
||||
%5 = call float @dx.op.loadInput.f32(i32 4, i32 1, i32 0, i8 0, i32 undef)
|
||||
%6 = fmul fast float %4, %5
|
||||
%7 = call float @dx.op.loadInput.f32(i32 4, i32 2, i32 0, i8 0, i32 undef)
|
||||
%8 = call float @dx.op.binary.f32(i32 35, float %6, float %7)
|
||||
%9 = call float @dx.op.loadInput.f32(i32 4, i32 2, i32 0, i8 1, i32 undef)
|
||||
%10 = call float @dx.op.binary.f32(i32 36, float %8, float %9)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %10)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.f32(i32, i32, float) #1
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare float @dx.op.tempRegLoad.f32(i32, i32) #2
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.binary.f32(i32, float, float) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #1 = { nounwind }
|
||||
attributes #2 = { nounwind readonly }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!12}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !11}
|
||||
!3 = !{!4, !9, null}
|
||||
!4 = !{!5, !7, !8}
|
||||
!5 = !{i32 0, !"A", i8 9, i8 0, !6, i8 2, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{i32 1, !"B", i8 9, i8 0, !6, i8 2, i32 1, i8 1, i32 0, i8 1, null}
|
||||
!8 = !{i32 2, !"C", i8 9, i8 0, !6, i8 2, i32 1, i8 2, i32 0, i8 2, null}
|
||||
!9 = !{!10}
|
||||
!10 = !{i32 0, !"SV_Target", i8 9, i8 16, !6, i8 0, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!11 = !{i32 0, i64 256}
|
||||
!12 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,11 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
int main(uint a : A) : SV_Target
|
||||
{
|
||||
return firstbithigh(a);
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%1 = call i32 @dx.op.unaryBits.i32(i32 33, i32 %0)
|
||||
%2 = sub i32 0, %1
|
||||
%3 = add i32 %2, 31
|
||||
%4 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%5 = icmp ne i32 %4, 0
|
||||
%6 = select i1 %5, i32 %3, i32 -1
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 0, i32 %6)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.unaryBits.i32(i32, i32) #0
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.loadInput.i32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.i32(i32, i32, i32) #1
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare i32 @dx.op.tempRegLoad.i32(i32, i32) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.i32(i32, i32, i32, i8, i32) #1
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #1 = { nounwind }
|
||||
attributes #2 = { nounwind readonly }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!10}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !9}
|
||||
!3 = !{!4, !7, null}
|
||||
!4 = !{!5}
|
||||
!5 = !{i32 0, !"A", i8 5, i8 0, !6, i8 1, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{!8}
|
||||
!8 = !{i32 0, !"SV_Target", i8 4, i8 16, !6, i8 0, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!9 = !{i32 0, i64 256}
|
||||
!10 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,11 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
float main(float a : A, float b : B) : SV_Target
|
||||
{
|
||||
return a < b ? 0 : 1;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%1 = call float @dx.op.loadInput.f32(i32 4, i32 1, i32 0, i8 0, i32 undef)
|
||||
%2 = fcmp fast olt float %0, %1
|
||||
%3 = select i1 %2, float 0.000000e+00, float 1.000000e+00
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %3)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.i32(i32, i32, i32) #1
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare i32 @dx.op.tempRegLoad.i32(i32, i32) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #1 = { nounwind }
|
||||
attributes #2 = { nounwind readonly }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!11}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !10}
|
||||
!3 = !{!4, !8, null}
|
||||
!4 = !{!5, !7}
|
||||
!5 = !{i32 0, !"A", i8 9, i8 0, !6, i8 2, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{i32 1, !"B", i8 9, i8 0, !6, i8 2, i32 1, i8 1, i32 0, i8 1, null}
|
||||
!8 = !{!9}
|
||||
!9 = !{i32 0, !"SV_Target", i8 9, i8 16, !6, i8 0, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!10 = !{i32 0, i64 256}
|
||||
!11 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,34 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
struct Foo
|
||||
{
|
||||
float2 a;
|
||||
float3 b;
|
||||
int2 c[4];
|
||||
};
|
||||
|
||||
StructuredBuffer<Foo> buf1;
|
||||
RWStructuredBuffer<Foo> buf2;
|
||||
|
||||
ByteAddressBuffer buf3;
|
||||
RWByteAddressBuffer buf4;
|
||||
|
||||
Buffer<unorm float2> buf5;
|
||||
RWBuffer<int3> buf6;
|
||||
|
||||
uint main() : SV_Target
|
||||
{
|
||||
uint r = 0, d1, d2;
|
||||
buf1.GetDimensions(d1, d2); r += d1 + d2;
|
||||
buf2.GetDimensions(d1, d2); r += d1 + d2;
|
||||
buf3.GetDimensions(d1); r += d1;
|
||||
buf4.GetDimensions(d1); r += d1;
|
||||
buf5.GetDimensions(d1); r += d1;
|
||||
buf6.GetDimensions(d1); r += d1;
|
||||
return r;
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
|
||||
%dx.types.Handle = type { i8* }
|
||||
%dx.types.Dimensions = type { i32, i32, i32, i32 }
|
||||
%dx.types.i8x52 = type { [52 x i8] }
|
||||
%dx.types.u32 = type { i32 }
|
||||
%dx.types.unorm_f32 = type { float }
|
||||
%dx.types.i32 = type { i32 }
|
||||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 0, i32 0, i1 false)
|
||||
%1 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 1, i32 1, i1 false)
|
||||
%2 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 2, i32 2, i1 false)
|
||||
%3 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 1, i1 false)
|
||||
%4 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 1, i32 2, i1 false)
|
||||
%5 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 2, i32 3, i1 false)
|
||||
%6 = call %dx.types.Dimensions @dx.op.getDimensions(i32 72, %dx.types.Handle %0, i32 undef)
|
||||
%7 = extractvalue %dx.types.Dimensions %6, 0
|
||||
%8 = add i32 %7, 52
|
||||
%9 = call %dx.types.Dimensions @dx.op.getDimensions(i32 72, %dx.types.Handle %3, i32 undef)
|
||||
%10 = extractvalue %dx.types.Dimensions %9, 0
|
||||
%11 = add i32 %8, %10
|
||||
%12 = add i32 %11, 52
|
||||
%13 = call %dx.types.Dimensions @dx.op.getDimensions(i32 72, %dx.types.Handle %1, i32 undef)
|
||||
%14 = extractvalue %dx.types.Dimensions %13, 0
|
||||
%15 = add i32 %14, %12
|
||||
%16 = call %dx.types.Dimensions @dx.op.getDimensions(i32 72, %dx.types.Handle %4, i32 undef)
|
||||
%17 = extractvalue %dx.types.Dimensions %16, 0
|
||||
%18 = add i32 %17, %15
|
||||
%19 = call %dx.types.Dimensions @dx.op.getDimensions(i32 72, %dx.types.Handle %2, i32 undef)
|
||||
%20 = extractvalue %dx.types.Dimensions %19, 0
|
||||
%21 = add i32 %20, %18
|
||||
%22 = call %dx.types.Dimensions @dx.op.getDimensions(i32 72, %dx.types.Handle %5, i32 undef)
|
||||
%23 = extractvalue %dx.types.Dimensions %22, 0
|
||||
%24 = add i32 %23, %21
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 0, i32 %24)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #0
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.Dimensions @dx.op.getDimensions(i32, %dx.types.Handle, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.i32(i32, i32, i32) #1
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare i32 @dx.op.tempRegLoad.i32(i32, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.i32(i32, i32, i32, i8, i32) #1
|
||||
|
||||
attributes #0 = { nounwind readonly }
|
||||
attributes #1 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.resources = !{!2}
|
||||
!dx.typeAnnotations = !{!14}
|
||||
!dx.entryPoints = !{!17}
|
||||
!llvm.ident = !{!23}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{!3, !9, null, null}
|
||||
!3 = !{!4, !6, !7}
|
||||
!4 = !{i32 0, %dx.types.i8x52 addrspace(1)* undef, !"T0", i32 0, i32 0, i32 1, i32 12, i32 0, !5}
|
||||
!5 = !{i32 1, i32 52}
|
||||
!6 = !{i32 1, %dx.types.u32 addrspace(1)* undef, !"T1", i32 0, i32 1, i32 1, i32 11, i32 0, null}
|
||||
!7 = !{i32 2, %dx.types.unorm_f32 addrspace(1)* undef, !"T2", i32 0, i32 2, i32 1, i32 10, i32 0, !8}
|
||||
!8 = !{i32 0, i32 14}
|
||||
!9 = !{!10, !11, !12}
|
||||
!10 = !{i32 0, %dx.types.i8x52 addrspace(1)* undef, !"U0", i32 0, i32 1, i32 1, i32 12, i1 false, i1 false, i1 false, !5}
|
||||
!11 = !{i32 1, %dx.types.u32 addrspace(1)* undef, !"U1", i32 0, i32 2, i32 1, i32 11, i1 false, i1 false, i1 false, null}
|
||||
!12 = !{i32 2, %dx.types.i32 addrspace(1)* undef, !"U2", i32 0, i32 3, i32 1, i32 10, i1 false, i1 false, i1 false, !13}
|
||||
!13 = !{i32 0, i32 4}
|
||||
!14 = !{i32 0, %dx.types.unorm_f32 undef, !15}
|
||||
!15 = !{i32 0, !16}
|
||||
!16 = !{i32 7, i32 14}
|
||||
!17 = !{void ()* @main, !"main", !18, !2, !22}
|
||||
!18 = !{null, !19, null}
|
||||
!19 = !{!20}
|
||||
!20 = !{i32 0, !"SV_Target", i8 5, i8 16, !21, i8 0, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!21 = !{i32 0}
|
||||
!22 = !{i32 0, i64 256}
|
||||
!23 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,22 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
SamplerState samp1;
|
||||
|
||||
Texture2D<float4> tex1;
|
||||
Texture2DArray<float4> tex2;
|
||||
TextureCubeArray<float4> tex3;
|
||||
|
||||
float4 main(float4 a : A) : SV_Target
|
||||
{
|
||||
float4 r = 0;
|
||||
r += tex1.CalculateLevelOfDetail(samp1, a.xy); // sampler, coordinates
|
||||
r += tex2.CalculateLevelOfDetail(samp1, a.xy);
|
||||
r += tex3.CalculateLevelOfDetail(samp1, a.xyz);
|
||||
|
||||
return r;
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
|
||||
%dx.types.Handle = type { i8* }
|
||||
%dx.types.f32 = type { float }
|
||||
%dx.types.Sampler = type opaque
|
||||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 0, i32 0, i1 false)
|
||||
%1 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 1, i32 1, i1 false)
|
||||
%2 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 2, i32 2, i1 false)
|
||||
%3 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 3, i32 0, i32 0, i1 false)
|
||||
%4 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%5 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 1, i32 undef)
|
||||
%6 = call float @dx.op.calculateLOD.f32(i32 81, %dx.types.Handle %0, %dx.types.Handle %3, float %4, float %5, float undef, i1 true)
|
||||
%7 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%8 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 1, i32 undef)
|
||||
%9 = call float @dx.op.calculateLOD.f32(i32 81, %dx.types.Handle %1, %dx.types.Handle %3, float %7, float %8, float undef, i1 true)
|
||||
%10 = fadd fast float %9, %6
|
||||
%11 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%12 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 1, i32 undef)
|
||||
%13 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%14 = call float @dx.op.calculateLOD.f32(i32 81, %dx.types.Handle %2, %dx.types.Handle %3, float %11, float %12, float %13, i1 true)
|
||||
%15 = fadd fast float %14, %10
|
||||
%16 = fadd fast float %14, %10
|
||||
%17 = fadd fast float %14, %10
|
||||
%18 = fadd fast float %14, %10
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %15)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %16)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %17)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float %18)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #0
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #1
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare float @dx.op.calculateLOD.f32(i32, %dx.types.Handle, %dx.types.Handle, float, float, float, i1) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.f32(i32, i32, float) #2
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare float @dx.op.tempRegLoad.f32(i32, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #2
|
||||
|
||||
attributes #0 = { nounwind readonly }
|
||||
attributes #1 = { nounwind readnone }
|
||||
attributes #2 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.resources = !{!2}
|
||||
!dx.entryPoints = !{!10}
|
||||
!llvm.ident = !{!18}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{!3, null, null, !8}
|
||||
!3 = !{!4, !6, !7}
|
||||
!4 = !{i32 0, %dx.types.f32 addrspace(1)* undef, !"T0", i32 0, i32 0, i32 1, i32 2, i32 0, !5}
|
||||
!5 = !{i32 0, i32 9}
|
||||
!6 = !{i32 1, %dx.types.f32 addrspace(1)* undef, !"T1", i32 0, i32 1, i32 1, i32 7, i32 0, !5}
|
||||
!7 = !{i32 2, %dx.types.f32 addrspace(1)* undef, !"T2", i32 0, i32 2, i32 1, i32 9, i32 0, !5}
|
||||
!8 = !{!9}
|
||||
!9 = !{i32 0, %dx.types.Sampler addrspace(1)* undef, !"S0", i32 0, i32 0, i32 1, i32 0, null}
|
||||
!10 = !{void ()* @main, !"main", !11, !2, !17}
|
||||
!11 = !{!12, !15, null}
|
||||
!12 = !{!13}
|
||||
!13 = !{i32 0, !"A", i8 9, i8 0, !14, i8 2, i32 1, i8 4, i32 0, i8 0, null}
|
||||
!14 = !{i32 0}
|
||||
!15 = !{!16}
|
||||
!16 = !{i32 0, !"SV_Target", i8 9, i8 16, !14, i8 0, i32 1, i8 4, i32 0, i8 0, null}
|
||||
!17 = !{i32 0, i64 256}
|
||||
!18 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,25 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
float main(float2 a : A, int3 b : B) : SV_Target
|
||||
{
|
||||
float r;
|
||||
[call]
|
||||
switch(b.x)
|
||||
{
|
||||
case 1:
|
||||
r = 5.f;
|
||||
break;
|
||||
case 2:
|
||||
r = a.x;
|
||||
break;
|
||||
default:
|
||||
r = 3.f;
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
|
||||
@dx.v32.r0 = internal global float undef, align 4
|
||||
|
||||
define internal void @dx.label.0() {
|
||||
entry:
|
||||
%0 = call float @dx.op.bitcastI32toF32(i32 126, i32 1084227584)
|
||||
store float %0, float* @dx.v32.r0
|
||||
ret void
|
||||
}
|
||||
|
||||
define internal void @dx.label.1() {
|
||||
entry:
|
||||
%0 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
store float %0, float* @dx.v32.r0
|
||||
ret void
|
||||
}
|
||||
|
||||
define internal void @dx.label.2() {
|
||||
entry:
|
||||
%0 = call float @dx.op.bitcastI32toF32(i32 126, i32 1077936128)
|
||||
store float %0, float* @dx.v32.r0
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call i32 @dx.op.loadInput.i32(i32 4, i32 1, i32 0, i8 0, i32 undef)
|
||||
switch i32 %0, label %switch0.default [
|
||||
i32 1, label %switch0.casegroup0
|
||||
i32 2, label %switch0.casegroup1
|
||||
]
|
||||
|
||||
switch0.casegroup0: ; preds = %entry
|
||||
call void @dx.label.0()
|
||||
br label %switch0.end
|
||||
|
||||
switch0.casegroup1: ; preds = %entry
|
||||
call void @dx.label.1()
|
||||
br label %switch0.end
|
||||
|
||||
switch0.default: ; preds = %entry
|
||||
call void @dx.label.2()
|
||||
br label %switch0.end
|
||||
|
||||
switch0.end: ; preds = %switch0.default, %switch0.casegroup1, %switch0.casegroup0
|
||||
%1 = load float, float* @dx.v32.r0
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %1)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.loadInput.i32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare float @dx.op.tempRegLoad.f32(i32, i32) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.i32(i32, i32, i32) #2
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.f32(i32, i32, float) #2
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.bitcastI32toF32(i32, i32) #0
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #1 = { nounwind readonly }
|
||||
attributes #2 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!11}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !10}
|
||||
!3 = !{!4, !8, null}
|
||||
!4 = !{!5, !7}
|
||||
!5 = !{i32 0, !"A", i8 9, i8 0, !6, i8 2, i32 1, i8 2, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{i32 1, !"B", i8 4, i8 0, !6, i8 1, i32 1, i8 3, i32 1, i8 0, null}
|
||||
!8 = !{!9}
|
||||
!9 = !{i32 0, !"SV_Target", i8 9, i8 16, !6, i8 0, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!10 = !{i32 0, i64 256}
|
||||
!11 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,32 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
float main(float2 a : A, int3 b : B) : SV_Target
|
||||
{
|
||||
float r;
|
||||
[branch]
|
||||
if (b.y)
|
||||
return a.y;
|
||||
|
||||
[call]
|
||||
switch(b.x)
|
||||
{
|
||||
case 1:
|
||||
[branch]
|
||||
if (b.y)
|
||||
return a.y;
|
||||
r = 5.f;
|
||||
break;
|
||||
case 2:
|
||||
r = a.x;
|
||||
break;
|
||||
default:
|
||||
r = 3.f;
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
|
||||
@dx.v32.r0 = internal global float undef, align 4
|
||||
@dx.v32.r2 = internal global i32 undef, align 4
|
||||
@dx.v32.r1 = internal global float undef, align 4
|
||||
|
||||
define internal void @dx.label.0() {
|
||||
entry:
|
||||
%0 = call i32 @dx.op.loadInput.i32(i32 4, i32 1, i32 0, i8 1, i32 undef)
|
||||
%1 = icmp ne i32 %0, 0
|
||||
br i1 %1, label %if1.then, label %if1.end
|
||||
|
||||
if1.then: ; preds = %entry
|
||||
%2 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 1, i32 undef)
|
||||
store float %2, float* @dx.v32.r0
|
||||
store i32 -1, i32* @dx.v32.r2
|
||||
ret void
|
||||
|
||||
if1.end: ; preds = %entry
|
||||
%3 = call float @dx.op.bitcastI32toF32(i32 126, i32 1084227584)
|
||||
store float %3, float* @dx.v32.r1
|
||||
store i32 0, i32* @dx.v32.r2
|
||||
ret void
|
||||
}
|
||||
|
||||
define internal void @dx.label.1() {
|
||||
entry:
|
||||
%0 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
store float %0, float* @dx.v32.r1
|
||||
store i32 0, i32* @dx.v32.r2
|
||||
ret void
|
||||
}
|
||||
|
||||
define internal void @dx.label.2() {
|
||||
entry:
|
||||
%0 = call float @dx.op.bitcastI32toF32(i32 126, i32 1077936128)
|
||||
store float %0, float* @dx.v32.r1
|
||||
store i32 0, i32* @dx.v32.r2
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call i32 @dx.op.loadInput.i32(i32 4, i32 1, i32 0, i8 1, i32 undef)
|
||||
%1 = icmp ne i32 %0, 0
|
||||
br i1 %1, label %if0.then, label %if0.end
|
||||
|
||||
if0.then: ; preds = %entry
|
||||
%2 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 1, i32 undef)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %2)
|
||||
ret void
|
||||
|
||||
if0.end: ; preds = %entry
|
||||
%3 = call i32 @dx.op.loadInput.i32(i32 4, i32 1, i32 0, i8 0, i32 undef)
|
||||
switch i32 %3, label %switch0.default [
|
||||
i32 1, label %switch0.casegroup0
|
||||
i32 2, label %switch0.casegroup1
|
||||
]
|
||||
|
||||
switch0.casegroup0: ; preds = %if0.end
|
||||
call void @dx.label.0()
|
||||
br label %switch0.end
|
||||
|
||||
switch0.casegroup1: ; preds = %if0.end
|
||||
call void @dx.label.1()
|
||||
br label %switch0.end
|
||||
|
||||
switch0.default: ; preds = %if0.end
|
||||
call void @dx.label.2()
|
||||
br label %switch0.end
|
||||
|
||||
switch0.end: ; preds = %switch0.default, %switch0.casegroup1, %switch0.casegroup0
|
||||
%4 = load float, float* @dx.v32.r0
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %4)
|
||||
%5 = load i32, i32* @dx.v32.r2
|
||||
%6 = icmp ne i32 %5, 0
|
||||
br i1 %6, label %label0.callc0.retc0, label %label0.callc0.afterretc0
|
||||
|
||||
label0.callc0.retc0: ; preds = %switch0.end
|
||||
ret void
|
||||
|
||||
label0.callc0.afterretc0: ; preds = %switch0.end
|
||||
%7 = load float, float* @dx.v32.r1
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %7)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.loadInput.i32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare float @dx.op.tempRegLoad.f32(i32, i32) #2
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare i32 @dx.op.tempRegLoad.i32(i32, i32) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.f32(i32, i32, float) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.i32(i32, i32, i32) #1
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.bitcastI32toF32(i32, i32) #0
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #1 = { nounwind }
|
||||
attributes #2 = { nounwind readonly }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!11}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !10}
|
||||
!3 = !{!4, !8, null}
|
||||
!4 = !{!5, !7}
|
||||
!5 = !{i32 0, !"A", i8 9, i8 0, !6, i8 2, i32 1, i8 2, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{i32 1, !"B", i8 4, i8 0, !6, i8 1, i32 1, i8 3, i32 1, i8 0, null}
|
||||
!8 = !{!9}
|
||||
!9 = !{i32 0, !"SV_Target", i8 9, i8 16, !6, i8 0, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!10 = !{i32 0, i64 256}
|
||||
!11 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,11 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
float main(int a : A) : SV_Target
|
||||
{
|
||||
return a;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%1 = sitofp i32 %0 to float
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %1)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.loadInput.i32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #1 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!10}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !9}
|
||||
!3 = !{!4, !7, null}
|
||||
!4 = !{!5}
|
||||
!5 = !{i32 0, !"A", i8 4, i8 0, !6, i8 1, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{!8}
|
||||
!8 = !{i32 0, !"SV_Target", i8 9, i8 16, !6, i8 0, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!9 = !{i32 0, i64 256}
|
||||
!10 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,11 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
float main(uint a : A) : SV_Target
|
||||
{
|
||||
return a;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%1 = uitofp i32 %0 to float
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %1)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.loadInput.i32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #1 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!10}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !9}
|
||||
!3 = !{!4, !7, null}
|
||||
!4 = !{!5}
|
||||
!5 = !{i32 0, !"A", i8 5, i8 0, !6, i8 1, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{!8}
|
||||
!8 = !{i32 0, !"SV_Target", i8 9, i8 16, !6, i8 0, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!9 = !{i32 0, i64 256}
|
||||
!10 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,11 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
int main(float a : A) : SV_Target
|
||||
{
|
||||
return a;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%1 = fptosi float %0 to i32
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 0, i32 %1)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.i32(i32, i32, i32, i8, i32) #1
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #1 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!10}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !9}
|
||||
!3 = !{!4, !7, null}
|
||||
!4 = !{!5}
|
||||
!5 = !{i32 0, !"A", i8 9, i8 0, !6, i8 2, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{!8}
|
||||
!8 = !{i32 0, !"SV_Target", i8 4, i8 16, !6, i8 0, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!9 = !{i32 0, i64 256}
|
||||
!10 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,11 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
uint main(float a : A) : SV_Target
|
||||
{
|
||||
return a;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%1 = fptoui float %0 to i32
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 0, i32 %1)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.i32(i32, i32, i32, i8, i32) #1
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #1 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!10}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !9}
|
||||
!3 = !{!4, !7, null}
|
||||
!4 = !{!5}
|
||||
!5 = !{i32 0, !"A", i8 9, i8 0, !6, i8 2, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{!8}
|
||||
!8 = !{i32 0, !"SV_Target", i8 5, i8 16, !6, i8 0, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!9 = !{i32 0, i64 256}
|
||||
!10 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,11 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
float main(min16float a : A) : SV_Target
|
||||
{
|
||||
return a;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call half @dx.op.loadInput.f16(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%1 = fpext half %0 to float
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %1)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare half @dx.op.loadInput.f16(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #1 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!10}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !9}
|
||||
!3 = !{!4, !7, null}
|
||||
!4 = !{!5}
|
||||
!5 = !{i32 0, !"A", i8 8, i8 0, !6, i8 2, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{!8}
|
||||
!8 = !{i32 0, !"SV_Target", i8 9, i8 16, !6, i8 0, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!9 = !{i32 0, i64 288}
|
||||
!10 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,11 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
min16float main(float a : A) : SV_Target
|
||||
{
|
||||
return a;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%1 = fptrunc float %0 to half
|
||||
call void @dx.op.storeOutput.f16(i32 5, i32 0, i32 0, i8 0, half %1)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.f16(i32, i32, i32, i8, half) #1
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #1 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!10}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !9}
|
||||
!3 = !{!4, !7, null}
|
||||
!4 = !{!5}
|
||||
!5 = !{i32 0, !"A", i8 9, i8 0, !6, i8 2, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{!8}
|
||||
!8 = !{i32 0, !"SV_Target", i8 8, i8 16, !6, i8 0, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!9 = !{i32 0, i64 288}
|
||||
!10 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,20 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
cbuffer Foo1 : register(b5)
|
||||
{
|
||||
float4 g1;
|
||||
}
|
||||
cbuffer Foo2 : register(b5)
|
||||
{
|
||||
float4 g2;
|
||||
}
|
||||
|
||||
float4 main() : SV_TARGET
|
||||
{
|
||||
return g2;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
|
||||
%dx.types.Handle = type { i8* }
|
||||
%dx.types.CBufRet.f32 = type { float, float, float, float }
|
||||
%dx.types.i8x16 = type { [16 x i8] }
|
||||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 0, i32 5, i1 false)
|
||||
%1 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %0, i32 0)
|
||||
%2 = extractvalue %dx.types.CBufRet.f32 %1, 0
|
||||
%3 = extractvalue %dx.types.CBufRet.f32 %1, 1
|
||||
%4 = extractvalue %dx.types.CBufRet.f32 %1, 2
|
||||
%5 = extractvalue %dx.types.CBufRet.f32 %1, 3
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %2)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %3)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %4)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float %5)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #0
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32, %dx.types.Handle, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
|
||||
|
||||
attributes #0 = { nounwind readonly }
|
||||
attributes #1 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.resources = !{!2}
|
||||
!dx.entryPoints = !{!5}
|
||||
!llvm.ident = !{!11}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{null, null, !3, null}
|
||||
!3 = !{!4}
|
||||
!4 = !{i32 0, %dx.types.i8x16 addrspace(2)* undef, !"CB0", i32 0, i32 5, i32 1, i32 16, null}
|
||||
!5 = !{void ()* @main, !"main", !6, !2, !10}
|
||||
!6 = !{null, !7, null}
|
||||
!7 = !{!8}
|
||||
!8 = !{i32 0, !"SV_Target", i8 9, i8 16, !9, i8 0, i32 1, i8 4, i32 0, i8 0, null}
|
||||
!9 = !{i32 0}
|
||||
!10 = !{i32 0, i64 256}
|
||||
!11 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,21 @@
|
|||
// RUN: %fxc /T ps_5_1 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
cbuffer Foo1 : register(b5)
|
||||
{
|
||||
float4 g1;
|
||||
}
|
||||
cbuffer Foo2 : register(b5)
|
||||
{
|
||||
float4 g2;
|
||||
}
|
||||
|
||||
[RootSignature("DescriptorTable(CBV(b5, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)")]
|
||||
float4 main() : SV_TARGET
|
||||
{
|
||||
return g2;
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
|
||||
%dx.types.Handle = type { i8* }
|
||||
%dx.types.CBufRet.f32 = type { float, float, float, float }
|
||||
%dx.types.i8x16 = type { [16 x i8] }
|
||||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 0, i32 5, i1 false)
|
||||
%1 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %0, i32 0)
|
||||
%2 = extractvalue %dx.types.CBufRet.f32 %1, 0
|
||||
%3 = extractvalue %dx.types.CBufRet.f32 %1, 1
|
||||
%4 = extractvalue %dx.types.CBufRet.f32 %1, 2
|
||||
%5 = extractvalue %dx.types.CBufRet.f32 %1, 3
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %2)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %3)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %4)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float %5)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #0
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32, %dx.types.Handle, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
|
||||
|
||||
attributes #0 = { nounwind readonly }
|
||||
attributes #1 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.resources = !{!2}
|
||||
!dx.entryPoints = !{!5}
|
||||
!llvm.ident = !{!10}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{null, null, !3, null}
|
||||
!3 = !{!4}
|
||||
!4 = !{i32 0, %dx.types.i8x16 addrspace(2)* undef, !"CB0", i32 0, i32 5, i32 1, i32 16, null}
|
||||
!5 = !{void ()* @main, !"main", !6, !2, null}
|
||||
!6 = !{null, !7, null}
|
||||
!7 = !{!8}
|
||||
!8 = !{i32 0, !"SV_Target", i8 9, i8 16, !9, i8 0, i32 1, i8 4, i32 0, i8 0, null}
|
||||
!9 = !{i32 0}
|
||||
!10 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,13 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
float4 g1;
|
||||
|
||||
float4 main() : SV_TARGET
|
||||
{
|
||||
return g1.wyyy;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
|
||||
%dx.types.Handle = type { i8* }
|
||||
%dx.types.CBufRet.f32 = type { float, float, float, float }
|
||||
%dx.types.i8x16 = type { [16 x i8] }
|
||||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 0, i32 0, i1 false)
|
||||
%1 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %0, i32 0)
|
||||
%2 = extractvalue %dx.types.CBufRet.f32 %1, 3
|
||||
%3 = extractvalue %dx.types.CBufRet.f32 %1, 1
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %2)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %3)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %3)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float %3)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #0
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32, %dx.types.Handle, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
|
||||
|
||||
attributes #0 = { nounwind readonly }
|
||||
attributes #1 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.resources = !{!2}
|
||||
!dx.entryPoints = !{!5}
|
||||
!llvm.ident = !{!11}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{null, null, !3, null}
|
||||
!3 = !{!4}
|
||||
!4 = !{i32 0, %dx.types.i8x16 addrspace(2)* undef, !"CB0", i32 0, i32 0, i32 1, i32 16, null}
|
||||
!5 = !{void ()* @main, !"main", !6, !2, !10}
|
||||
!6 = !{null, !7, null}
|
||||
!7 = !{!8}
|
||||
!8 = !{i32 0, !"SV_Target", i8 9, i8 16, !9, i8 0, i32 1, i8 4, i32 0, i8 0, null}
|
||||
!9 = !{i32 0}
|
||||
!10 = !{i32 0, i64 256}
|
||||
!11 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,14 @@
|
|||
// RUN: %fxc /T ps_5_1 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
float4 g1;
|
||||
|
||||
[RootSignature("DescriptorTable(CBV(b0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)")]
|
||||
float4 main() : SV_TARGET
|
||||
{
|
||||
return g1.wyyy;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
%dx.types.Handle = type { i8* }
|
||||
%dx.types.CBufRet.f32 = type { float, float, float, float }
|
||||
%dx.types.i8x16 = type { [16 x i8] }
|
||||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 0, i32 0, i1 false)
|
||||
%1 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %0, i32 0)
|
||||
%2 = extractvalue %dx.types.CBufRet.f32 %1, 3
|
||||
%3 = extractvalue %dx.types.CBufRet.f32 %1, 1
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %2)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %3)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %3)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float %3)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #0
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32, %dx.types.Handle, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
|
||||
|
||||
attributes #0 = { nounwind readonly }
|
||||
attributes #1 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.resources = !{!2}
|
||||
!dx.entryPoints = !{!5}
|
||||
!llvm.ident = !{!10}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{null, null, !3, null}
|
||||
!3 = !{!4}
|
||||
!4 = !{i32 0, %dx.types.i8x16 addrspace(2)* undef, !"CB0", i32 0, i32 0, i32 1, i32 16, null}
|
||||
!5 = !{void ()* @main, !"main", !6, !2, null}
|
||||
!6 = !{null, !7, null}
|
||||
!7 = !{!8}
|
||||
!8 = !{i32 0, !"SV_Target", i8 9, i8 16, !9, i8 0, i32 1, i8 4, i32 0, i8 0, null}
|
||||
!9 = !{i32 0}
|
||||
!10 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,21 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
cbuffer Foo
|
||||
{
|
||||
float4 g1[16];
|
||||
};
|
||||
|
||||
cbuffer Bar
|
||||
{
|
||||
uint3 idx[8];
|
||||
};
|
||||
|
||||
float4 main(int2 a : A) : SV_TARGET
|
||||
{
|
||||
return g1[idx[a.x].z].wyyy;
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
|
||||
%dx.types.Handle = type { i8* }
|
||||
%dx.types.CBufRet.i32 = type { i32, i32, i32, i32 }
|
||||
%dx.types.CBufRet.f32 = type { float, float, float, float }
|
||||
%dx.types.i8x256 = type { [256 x i8] }
|
||||
%dx.types.i8x128 = type { [128 x i8] }
|
||||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 0, i32 0, i1 false)
|
||||
%1 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 1, i32 1, i1 false)
|
||||
%2 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%3 = call %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32 59, %dx.types.Handle %1, i32 %2)
|
||||
%4 = extractvalue %dx.types.CBufRet.i32 %3, 2
|
||||
%5 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %0, i32 %4)
|
||||
%6 = extractvalue %dx.types.CBufRet.f32 %5, 3
|
||||
%7 = extractvalue %dx.types.CBufRet.f32 %5, 1
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %6)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %7)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %7)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float %7)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #0
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.loadInput.i32(i32, i32, i32, i8, i32) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.i32(i32, i32, i32) #2
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare i32 @dx.op.tempRegLoad.i32(i32, i32) #0
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32, %dx.types.Handle, i32) #0
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32, %dx.types.Handle, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #2
|
||||
|
||||
attributes #0 = { nounwind readonly }
|
||||
attributes #1 = { nounwind readnone }
|
||||
attributes #2 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.resources = !{!2}
|
||||
!dx.entryPoints = !{!6}
|
||||
!llvm.ident = !{!14}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{null, null, !3, null}
|
||||
!3 = !{!4, !5}
|
||||
!4 = !{i32 0, %dx.types.i8x256 addrspace(2)* undef, !"CB0", i32 0, i32 0, i32 1, i32 256, null}
|
||||
!5 = !{i32 1, %dx.types.i8x128 addrspace(2)* undef, !"CB1", i32 0, i32 1, i32 1, i32 128, null}
|
||||
!6 = !{void ()* @main, !"main", !7, !2, !13}
|
||||
!7 = !{!8, !11, null}
|
||||
!8 = !{!9}
|
||||
!9 = !{i32 0, !"A", i8 4, i8 0, !10, i8 1, i32 1, i8 2, i32 0, i8 0, null}
|
||||
!10 = !{i32 0}
|
||||
!11 = !{!12}
|
||||
!12 = !{i32 0, !"SV_Target", i8 9, i8 16, !10, i8 0, i32 1, i8 4, i32 0, i8 0, null}
|
||||
!13 = !{i32 0, i64 256}
|
||||
!14 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,26 @@
|
|||
// RUN: %fxc /T ps_5_1 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
struct Foo
|
||||
{
|
||||
float4 g1[16];
|
||||
};
|
||||
|
||||
struct Bar
|
||||
{
|
||||
uint3 idx[16];
|
||||
};
|
||||
|
||||
ConstantBuffer<Foo> buf1[32] : register(b77, space3);
|
||||
ConstantBuffer<Bar> buf2[64] : register(b17);
|
||||
|
||||
[RootSignature("DescriptorTable(CBV(b17, numDescriptors=64, space=0), visibility=SHADER_VISIBILITY_ALL),\
|
||||
DescriptorTable(CBV(b77, numDescriptors=32, space=3), visibility=SHADER_VISIBILITY_ALL)")]
|
||||
float4 main(int3 a : A) : SV_TARGET
|
||||
{
|
||||
return buf1[ buf2[a.x].idx[a.y].z ].g1[a.z + 12].wyyy;
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
|
||||
%dx.types.Handle = type { i8* }
|
||||
%dx.types.CBufRet.i32 = type { i32, i32, i32, i32 }
|
||||
%dx.types.CBufRet.f32 = type { float, float, float, float }
|
||||
%dx.types.i8x256 = type { [256 x i8] }
|
||||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 2, i32 undef)
|
||||
%1 = add i32 %0, 12
|
||||
%2 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 1, i32 undef)
|
||||
%3 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%4 = add i32 %3, 17
|
||||
%5 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 0, i32 %4, i1 false)
|
||||
%6 = call %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32 59, %dx.types.Handle %5, i32 %2)
|
||||
%7 = extractvalue %dx.types.CBufRet.i32 %6, 2
|
||||
%8 = add i32 %7, 77
|
||||
%9 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 1, i32 %8, i1 false)
|
||||
%10 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %9, i32 %1)
|
||||
%11 = extractvalue %dx.types.CBufRet.f32 %10, 3
|
||||
%12 = extractvalue %dx.types.CBufRet.f32 %10, 1
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %11)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %12)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %12)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float %12)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @dx.op.loadInput.i32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.tempRegStore.i32(i32, i32, i32) #1
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare i32 @dx.op.tempRegLoad.i32(i32, i32) #2
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #2
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32, %dx.types.Handle, i32) #2
|
||||
|
||||
; Function Attrs: nounwind readonly
|
||||
declare %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32, %dx.types.Handle, i32) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #1 = { nounwind }
|
||||
attributes #2 = { nounwind readonly }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.resources = !{!2}
|
||||
!dx.entryPoints = !{!6}
|
||||
!llvm.ident = !{!13}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{null, null, !3, null}
|
||||
!3 = !{!4, !5}
|
||||
!4 = !{i32 0, %dx.types.i8x256 addrspace(2)* undef, !"CB0", i32 0, i32 17, i32 64, i32 256, null}
|
||||
!5 = !{i32 1, %dx.types.i8x256 addrspace(2)* undef, !"CB1", i32 3, i32 77, i32 32, i32 256, null}
|
||||
!6 = !{void ()* @main, !"main", !7, !2, null}
|
||||
!7 = !{!8, !11, null}
|
||||
!8 = !{!9}
|
||||
!9 = !{i32 0, !"A", i8 4, i8 0, !10, i8 1, i32 1, i8 3, i32 0, i8 0, null}
|
||||
!10 = !{i32 0}
|
||||
!11 = !{!12}
|
||||
!12 = !{i32 0, !"SV_Target", i8 9, i8 16, !10, i8 0, i32 1, i8 4, i32 0, i8 0, null}
|
||||
!13 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,12 @@
|
|||
// RUN: %fxc /T ps_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
bool main(float a : A, float b : B) : SV_TARGET
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
define void @main() {
|
||||
entry:
|
||||
%0 = call float @dx.op.loadInput.f32(i32 4, i32 1, i32 0, i8 0, i32 undef)
|
||||
%1 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef)
|
||||
%2 = fcmp fast oeq float %0, %1
|
||||
%3 = sext i1 %2 to i32
|
||||
call void @dx.op.storeOutput.i32(i32 5, i32 0, i32 0, i8 0, i32 %3)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.i32(i32, i32, i32, i8, i32) #1
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #1 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!11}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"ps", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !10}
|
||||
!3 = !{!4, !8, null}
|
||||
!4 = !{!5, !7}
|
||||
!5 = !{i32 0, !"A", i8 9, i8 0, !6, i8 2, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{i32 1, !"B", i8 9, i8 0, !6, i8 2, i32 1, i8 1, i32 0, i8 1, null}
|
||||
!8 = !{!9}
|
||||
!9 = !{i32 0, !"SV_Target", i8 5, i8 16, !6, i8 0, i32 1, i8 1, i32 0, i8 0, null}
|
||||
!10 = !{i32 0, i64 256}
|
||||
!11 = !{!"dxbc2dxil 1.2"}
|
|
@ -0,0 +1,11 @@
|
|||
// RUN: %fxc /T vs_5_0 %s /Fo %t.dxbc
|
||||
// RUN: %dxbc2dxil %t.dxbc /emit-llvm /o %t.ll.converted
|
||||
// RUN: fc %b.ref %t.ll.converted
|
||||
|
||||
|
||||
|
||||
|
||||
float4 main() : SV_POSITION
|
||||
{
|
||||
return float4(3,0,0.5,0.12345);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
define void @main() {
|
||||
entry:
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float 3.000000e+00)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float 0.000000e+00)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float 5.000000e-01)
|
||||
call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float 0x3FBF9A6B60000000)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #0
|
||||
|
||||
attributes #0 = { nounwind }
|
||||
|
||||
!dx.version = !{!0}
|
||||
!dx.valver = !{!0}
|
||||
!dx.shaderModel = !{!1}
|
||||
!dx.entryPoints = !{!2}
|
||||
!llvm.ident = !{!8}
|
||||
|
||||
!0 = !{i32 1, i32 0}
|
||||
!1 = !{!"vs", i32 6, i32 0}
|
||||
!2 = !{void ()* @main, !"main", !3, null, !7}
|
||||
!3 = !{null, !4, null}
|
||||
!4 = !{!5}
|
||||
!5 = !{i32 0, !"SV_Position", i8 9, i8 3, !6, i8 0, i32 1, i8 4, i32 0, i8 0, null}
|
||||
!6 = !{i32 0}
|
||||
!7 = !{i32 0, i64 256}
|
||||
!8 = !{!"dxbc2dxil 1.2"}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче