DXBC to DXIL Converter + unit tests (#2685)

Includes dxilconv-specific DXIL optimization passes added to opt.exe tool.
This commit is contained in:
Helena Kotas 2020-02-11 12:07:26 -08:00 коммит произвёл GitHub
Родитель 76e34cc27d
Коммит a42ffbf491
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
447 изменённых файлов: 45792 добавлений и 54 удалений

Просмотреть файл

@ -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

Двоичные данные
projects/dxilconv/test/dxbc2dxil-asm/call2.dxbc Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -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

Двоичные данные
projects/dxilconv/test/dxbc2dxil-asm/cs3.dxbc Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -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

Двоичные данные
projects/dxilconv/test/dxbc2dxil-asm/cyclecounter.dxbc Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -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

Двоичные данные
projects/dxilconv/test/dxbc2dxil-asm/hs3.dxbc Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -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

Двоичные данные
projects/dxilconv/test/dxbc2dxil-asm/indexabletemp4.dxbc Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -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

Двоичные данные
projects/dxilconv/test/dxbc2dxil-asm/indexabletemp6.dxbc Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -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"}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше