mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-29 19:24:10 +01:00
[dxbc] Added DXBC to SPIR-V compiler stub
This commit is contained in:
parent
6e27b7c0cc
commit
bb5b588d23
24
src/dxbc/dxbc_chunk_shex.cpp
Normal file
24
src/dxbc/dxbc_chunk_shex.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
#include "dxbc_chunk_shex.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
DxbcShex::DxbcShex(DxbcReader reader) {
|
||||
// The shader version and type are stored in a 32-bit unit,
|
||||
// where the first byte contains the major and minor version
|
||||
// numbers, and the high word contains the program type.
|
||||
auto pVersion = reader.readu16() & 0xFF;
|
||||
auto pType = reader.readEnum<DxbcProgramType>();
|
||||
m_version = DxbcProgramVersion(pVersion >> 4, pVersion & 0xF, pType);
|
||||
|
||||
// Read the actual shader code as an array of DWORDs.
|
||||
auto codeLength = reader.readu32() - 2;
|
||||
m_code.resize(codeLength);
|
||||
reader.read(m_code.data(), codeLength * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
|
||||
DxbcShex::~DxbcShex() {
|
||||
|
||||
}
|
||||
|
||||
}
|
42
src/dxbc/dxbc_chunk_shex.h
Normal file
42
src/dxbc/dxbc_chunk_shex.h
Normal file
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include "dxbc_common.h"
|
||||
#include "dxbc_instruction.h"
|
||||
#include "dxbc_reader.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief Shader code chunk
|
||||
*
|
||||
* Stores the DXBC shader code itself, as well
|
||||
* as some meta info about the shader, i.e. what
|
||||
* type of shader this is.
|
||||
*/
|
||||
class DxbcShex : public RcObject {
|
||||
|
||||
public:
|
||||
|
||||
DxbcShex(DxbcReader reader);
|
||||
~DxbcShex();
|
||||
|
||||
DxbcProgramVersion version() const {
|
||||
return m_version;
|
||||
}
|
||||
|
||||
DxbcInstructionIterator begin() const {
|
||||
return DxbcInstructionIterator(m_code.data());
|
||||
}
|
||||
|
||||
DxbcInstructionIterator end() const {
|
||||
return DxbcInstructionIterator(m_code.data() + m_code.size());
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
DxbcProgramVersion m_version;
|
||||
std::vector<uint32_t> m_code;
|
||||
|
||||
};
|
||||
|
||||
}
|
70
src/dxbc/dxbc_common.h
Normal file
70
src/dxbc/dxbc_common.h
Normal file
@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include "dxbc_include.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief DXBC Program type
|
||||
*
|
||||
* Defines the shader stage that a DXBC
|
||||
* module has been compiled form.
|
||||
*/
|
||||
enum class DxbcProgramType : uint16_t {
|
||||
PixelShader = 0,
|
||||
VertexShader = 1,
|
||||
GeometryShader = 2,
|
||||
HullShader = 3,
|
||||
DomainShader = 4,
|
||||
ComputeShader = 5,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief DXBC shader version info
|
||||
*
|
||||
* Stores the shader model version
|
||||
* as well as the program type.
|
||||
*/
|
||||
class DxbcProgramVersion {
|
||||
|
||||
public:
|
||||
|
||||
DxbcProgramVersion() { }
|
||||
DxbcProgramVersion(
|
||||
uint8_t major, uint8_t minor, DxbcProgramType type)
|
||||
: m_major(major), m_minor(minor), m_type(type) { }
|
||||
|
||||
/**
|
||||
* \brief Major version
|
||||
* \returns Major version
|
||||
*/
|
||||
uint32_t major() const {
|
||||
return m_major;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Minor version
|
||||
* \returns Minor version
|
||||
*/
|
||||
uint32_t minor() const {
|
||||
return m_minor;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Program type
|
||||
* \returns Program type
|
||||
*/
|
||||
DxbcProgramType type() const {
|
||||
return m_type;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
uint8_t m_major = 0;
|
||||
uint8_t m_minor = 0;
|
||||
DxbcProgramType m_type = DxbcProgramType::PixelShader;
|
||||
|
||||
};
|
||||
|
||||
}
|
26
src/dxbc/dxbc_compiler.cpp
Normal file
26
src/dxbc/dxbc_compiler.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
#include "dxbc_compiler.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
DxbcCompiler::DxbcCompiler(DxbcProgramVersion version) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
DxbcCompiler::~DxbcCompiler() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::processInstruction(DxbcInstruction ins) {
|
||||
Logger::info(str::format(
|
||||
static_cast<uint32_t>(ins.opcode())));
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkShader> DxbcCompiler::finalize() {
|
||||
return new DxvkShader(VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
DxvkSpirvCodeBuffer(), 0, nullptr);
|
||||
}
|
||||
|
||||
}
|
39
src/dxbc/dxbc_compiler.h
Normal file
39
src/dxbc/dxbc_compiler.h
Normal file
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include "../dxvk/dxvk_shader.h"
|
||||
|
||||
#include "dxbc_chunk_shex.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief DXBC to SPIR-V compiler
|
||||
*
|
||||
*
|
||||
*/
|
||||
class DxbcCompiler {
|
||||
|
||||
public:
|
||||
|
||||
DxbcCompiler(DxbcProgramVersion version);
|
||||
~DxbcCompiler();
|
||||
|
||||
/**
|
||||
* \brief Processes a single instruction
|
||||
* \param [in] ins The instruction
|
||||
*/
|
||||
void processInstruction(DxbcInstruction ins);
|
||||
|
||||
/**
|
||||
* \brief Creates actual shader object
|
||||
*
|
||||
* Combines all information gatherd during the
|
||||
* shader compilation into one shader object.
|
||||
*/
|
||||
Rc<DxvkShader> finalize();
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
}
|
30
src/dxbc/dxbc_header.cpp
Normal file
30
src/dxbc/dxbc_header.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include "dxbc_header.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
DxbcHeader::DxbcHeader(DxbcReader& reader) {
|
||||
// FourCC at the start of the file, must be 'DXBC'
|
||||
DxbcTag fourcc = reader.readTag();
|
||||
|
||||
if (fourcc != "DXBC")
|
||||
throw DxvkError("DxbcHeader::DxbcHeader: Invalid fourcc, expected 'DXBC'");
|
||||
|
||||
// Stuff we don't actually need to store
|
||||
reader.skip(4 * sizeof(uint32_t)); // Check sum
|
||||
reader.skip(1 * sizeof(uint32_t)); // Constant 1
|
||||
reader.skip(1 * sizeof(uint32_t)); // Bytecode length
|
||||
|
||||
// Number of chunks in the file
|
||||
uint32_t chunkCount = reader.readu32();
|
||||
|
||||
// Chunk offsets are stored immediately after
|
||||
for (uint32_t i = 0; i < chunkCount; i++)
|
||||
m_chunkOffsets.push_back(reader.readu32());
|
||||
}
|
||||
|
||||
|
||||
DxbcHeader::~DxbcHeader() {
|
||||
|
||||
}
|
||||
|
||||
}
|
48
src/dxbc/dxbc_header.h
Normal file
48
src/dxbc/dxbc_header.h
Normal file
@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "dxbc_reader.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief DXBC header
|
||||
*
|
||||
* Stores information about the shader file itself
|
||||
* and the data chunks stored inside the file.
|
||||
*/
|
||||
class DxbcHeader {
|
||||
|
||||
public:
|
||||
|
||||
DxbcHeader(DxbcReader& reader);
|
||||
~DxbcHeader();
|
||||
|
||||
/**
|
||||
* \brief Number of chunks
|
||||
* \returns Chunk count
|
||||
*/
|
||||
uint32_t numChunks() const {
|
||||
return m_chunkOffsets.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Chunk offset
|
||||
*
|
||||
* Retrieves the offset of a chunk, in
|
||||
* bytes, from the start of the file.
|
||||
* \param [in] chunkId Chunk index
|
||||
* \returns Byte offset of that chunk
|
||||
*/
|
||||
uint32_t chunkOffset(uint32_t chunkId) const {
|
||||
return m_chunkOffsets.at(chunkId);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::vector<uint32_t> m_chunkOffsets;
|
||||
|
||||
};
|
||||
|
||||
}
|
16
src/dxbc/dxbc_include.h
Normal file
16
src/dxbc/dxbc_include.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "../util/com/com_guid.h"
|
||||
#include "../util/com/com_object.h"
|
||||
#include "../util/com/com_pointer.h"
|
||||
|
||||
#include "../util/log/log.h"
|
||||
#include "../util/log/log_debug.h"
|
||||
|
||||
#include "../util/rc/util_rc.h"
|
||||
#include "../util/rc/util_rc_ptr.h"
|
||||
|
||||
#include "../util/util_bit.h"
|
||||
#include "../util/util_enum.h"
|
||||
#include "../util/util_error.h"
|
||||
#include "../util/util_string.h"
|
85
src/dxbc/dxbc_instruction.h
Normal file
85
src/dxbc/dxbc_instruction.h
Normal file
@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
|
||||
#include "dxbc_opcode.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief DXBC instruction
|
||||
*
|
||||
* Provides convenience methods to extract the
|
||||
* opcode, instruction length, and instruction
|
||||
* arguments from an instruction.
|
||||
*/
|
||||
class DxbcInstruction {
|
||||
|
||||
public:
|
||||
|
||||
DxbcInstruction() { }
|
||||
DxbcInstruction(const uint32_t* code)
|
||||
: m_code(code) { }
|
||||
|
||||
/**
|
||||
* \brief Instruction code
|
||||
* \returns The operation code
|
||||
*/
|
||||
DxbcOpcode opcode() const {
|
||||
return static_cast<DxbcOpcode>(
|
||||
bit::extract<uint32_t, 0, 10>(m_code[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Instruction length
|
||||
*
|
||||
* Number of DWORDs for this instruction,
|
||||
* including the initial opcode token.
|
||||
* \returns Instruction length
|
||||
*/
|
||||
uint32_t length() const {
|
||||
return this->opcode() != DxbcOpcode::CustomData
|
||||
? bit::extract<uint32_t, 24, 30>(m_code[0])
|
||||
: m_code[1];
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
const uint32_t* m_code = nullptr;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief DXBC instruction iterator
|
||||
*
|
||||
* Iterator that walks over DXBC instructions.
|
||||
* Instruction boundaries are easy to find as
|
||||
* the length of each instruction is encoded
|
||||
* in the opcode token, much like in SPIR-V.
|
||||
*/
|
||||
class DxbcInstructionIterator {
|
||||
|
||||
public:
|
||||
|
||||
DxbcInstructionIterator() { }
|
||||
DxbcInstructionIterator(const uint32_t* code)
|
||||
: m_code(code) { }
|
||||
|
||||
DxbcInstructionIterator& operator ++ () {
|
||||
m_code += DxbcInstruction(m_code).length();
|
||||
return *this;
|
||||
}
|
||||
|
||||
DxbcInstruction operator * () const {
|
||||
return DxbcInstruction(m_code);
|
||||
}
|
||||
|
||||
bool operator == (const DxbcInstructionIterator& other) const { return m_code == other.m_code; }
|
||||
bool operator != (const DxbcInstructionIterator& other) const { return m_code != other.m_code; }
|
||||
|
||||
private:
|
||||
|
||||
const uint32_t* m_code = nullptr;
|
||||
|
||||
};
|
||||
|
||||
}
|
43
src/dxbc/dxbc_module.cpp
Normal file
43
src/dxbc/dxbc_module.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
#include "dxbc_compiler.h"
|
||||
#include "dxbc_module.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
DxbcModule::DxbcModule(DxbcReader& reader)
|
||||
: m_header(reader) {
|
||||
for (uint32_t i = 0; i < m_header.numChunks(); i++) {
|
||||
|
||||
// The chunk tag is stored at the beginning of each chunk
|
||||
auto chunkReader = reader.clone(m_header.chunkOffset(i));
|
||||
auto tag = chunkReader.readTag();
|
||||
|
||||
// The chunk size follows right after the four-character
|
||||
// code. This does not include the eight bytes that are
|
||||
// consumed by the FourCC and chunk length entry.
|
||||
auto chunkLength = chunkReader.readu32() + 8;
|
||||
chunkReader = chunkReader.resize(chunkLength);
|
||||
|
||||
if ((tag == "SHDR") || (tag == "SHEX"))
|
||||
m_shexChunk = new DxbcShex(chunkReader);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DxbcModule::~DxbcModule() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkShader> DxbcModule::compile() const {
|
||||
if (m_shexChunk == nullptr)
|
||||
throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk");
|
||||
|
||||
DxbcCompiler compiler(m_shexChunk->version());
|
||||
|
||||
for (auto ins : *m_shexChunk)
|
||||
compiler.processInstruction(ins);
|
||||
return compiler.finalize();
|
||||
}
|
||||
|
||||
}
|
43
src/dxbc/dxbc_module.h
Normal file
43
src/dxbc/dxbc_module.h
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include "../dxvk/dxvk_shader.h"
|
||||
|
||||
#include "dxbc_chunk_shex.h"
|
||||
#include "dxbc_header.h"
|
||||
#include "dxbc_reader.h"
|
||||
|
||||
// References used for figuring out DXBC:
|
||||
// - https://github.com/tgjones/slimshader-cpp
|
||||
// - Wine
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief DXBC shader module
|
||||
*
|
||||
* Reads the DXBC byte code and extracts information
|
||||
* about the resource bindings and the instruction
|
||||
* stream. A module can then be compiled to SPIR-V.
|
||||
*/
|
||||
class DxbcModule {
|
||||
|
||||
public:
|
||||
|
||||
DxbcModule(DxbcReader& reader);
|
||||
~DxbcModule();
|
||||
|
||||
/**
|
||||
* \brief Compiles DXBC shader to SPIR-V module
|
||||
* \returns The compiled DXVK shader object
|
||||
*/
|
||||
Rc<DxvkShader> compile() const;
|
||||
|
||||
private:
|
||||
|
||||
DxbcHeader m_header;
|
||||
|
||||
Rc<DxbcShex> m_shexChunk;
|
||||
|
||||
};
|
||||
|
||||
}
|
220
src/dxbc/dxbc_opcode.h
Normal file
220
src/dxbc/dxbc_opcode.h
Normal file
@ -0,0 +1,220 @@
|
||||
#pragma once
|
||||
|
||||
#include "dxbc_include.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief Instruction code listing
|
||||
*/
|
||||
enum class DxbcOpcode : uint32_t {
|
||||
Add = 0,
|
||||
And = 1,
|
||||
Break = 2,
|
||||
Breakc = 3,
|
||||
Call = 4,
|
||||
Callc = 5,
|
||||
Case = 6,
|
||||
Continue = 7,
|
||||
Continuec = 8,
|
||||
Cut = 9,
|
||||
Default = 10,
|
||||
DerivRtx = 11,
|
||||
DerivRty = 12,
|
||||
Discard = 13,
|
||||
Div = 14,
|
||||
Dp2 = 15,
|
||||
Dp3 = 16,
|
||||
Dp4 = 17,
|
||||
Else = 18,
|
||||
Emit = 19,
|
||||
EmitThenCut = 20,
|
||||
EndIf = 21,
|
||||
EndLoop = 22,
|
||||
EndSwitch = 23,
|
||||
Eq = 24,
|
||||
Exp = 25,
|
||||
Frc = 26,
|
||||
FtoI = 27,
|
||||
FtoU = 28,
|
||||
Ge = 29,
|
||||
IAdd = 30,
|
||||
If = 31,
|
||||
IEq = 32,
|
||||
IGe = 33,
|
||||
ILt = 34,
|
||||
IMad = 35,
|
||||
IMax = 36,
|
||||
IMin = 37,
|
||||
IMul = 38,
|
||||
INe = 39,
|
||||
INeg = 40,
|
||||
IShl = 41,
|
||||
IShr = 42,
|
||||
ItoF = 43,
|
||||
Label = 44,
|
||||
Ld = 45,
|
||||
LdMs = 46,
|
||||
Log = 47,
|
||||
Loop = 48,
|
||||
Lt = 49,
|
||||
Mad = 50,
|
||||
Min = 51,
|
||||
Max = 52,
|
||||
CustomData = 53,
|
||||
Mov = 54,
|
||||
Movc = 55,
|
||||
Mul = 56,
|
||||
Ne = 57,
|
||||
Nop = 58,
|
||||
Not = 59,
|
||||
Or = 60,
|
||||
ResInfo = 61,
|
||||
Ret = 62,
|
||||
Retc = 63,
|
||||
RoundNe = 64,
|
||||
RoundNi = 65,
|
||||
RoundPi = 66,
|
||||
RoundZ = 67,
|
||||
Rsq = 68,
|
||||
Sample = 69,
|
||||
SampleC = 70,
|
||||
SampleClz = 71,
|
||||
SampleL = 72,
|
||||
SampleD = 73,
|
||||
SampleB = 74,
|
||||
Sqrt = 75,
|
||||
Switch = 76,
|
||||
SinCos = 77,
|
||||
UDiv = 78,
|
||||
ULt = 79,
|
||||
UGe = 80,
|
||||
UMul = 81,
|
||||
UMad = 82,
|
||||
UMax = 83,
|
||||
UMin = 84,
|
||||
UShr = 85,
|
||||
UtoF = 86,
|
||||
Xor = 87,
|
||||
DclResource = 88,
|
||||
DclConstantBuffer = 89,
|
||||
DclSampler = 90,
|
||||
DclIndexRange = 91,
|
||||
DclGsOutputPrimitiveTopology = 92,
|
||||
DclGsInputPrimitive = 93,
|
||||
DclMaxOutputVertexCount = 94,
|
||||
DclInput = 95,
|
||||
DclInputSgv = 96,
|
||||
DclInputSiv = 97,
|
||||
DclInputPs = 98,
|
||||
DclInputPsSgv = 99,
|
||||
DclInputPsSiv = 100,
|
||||
DclOutput = 101,
|
||||
DclOutputSgv = 102,
|
||||
DclOutputSiv = 103,
|
||||
DclTemps = 104,
|
||||
DclIndexableTemp = 105,
|
||||
DclGlobalFlags = 106,
|
||||
Reserved0 = 107,
|
||||
Lod = 108,
|
||||
Gather4 = 109,
|
||||
SamplePos = 110,
|
||||
SampleInfo = 111,
|
||||
Reserved1 = 112,
|
||||
HsDecls = 113,
|
||||
HsControlPointPhase = 114,
|
||||
HsForkPhase = 115,
|
||||
HsJoinPhase = 116,
|
||||
EmitStream = 117,
|
||||
CutStream = 118,
|
||||
EmitThenCutStream = 119,
|
||||
InterfaceCall = 120,
|
||||
BufInfo = 121,
|
||||
DerivRtxCoarse = 122,
|
||||
DerivRtxFine = 123,
|
||||
DerivRtyCoarse = 124,
|
||||
DerivRtyFine = 125,
|
||||
Gather4C = 126,
|
||||
Gather4Po = 127,
|
||||
Gather4PoC = 128,
|
||||
Rcp = 129,
|
||||
F32toF16 = 130,
|
||||
F16toF32 = 131,
|
||||
UAddc = 132,
|
||||
USubb = 133,
|
||||
CountBits = 134,
|
||||
FirstBitHi = 135,
|
||||
FirstBitLo = 136,
|
||||
FirstBitShi = 137,
|
||||
UBfe = 138,
|
||||
IBfe = 139,
|
||||
Bfi = 140,
|
||||
BfRev = 141,
|
||||
Swapc = 142,
|
||||
DclStream = 143,
|
||||
DclFunctionBody = 144,
|
||||
DclFunctionTable = 145,
|
||||
DclInterface = 146,
|
||||
DclInputControlPointCount = 147,
|
||||
DclOutputControlPointCount = 148,
|
||||
DclTessDomain = 149,
|
||||
DclTessPartitioning = 150,
|
||||
DclTessOutputPrimitive = 151,
|
||||
DclHsMaxTessFactor = 152,
|
||||
DclHsForkPhaseInstanceCount = 153,
|
||||
DclHsJoinPhaseInstanceCount = 154,
|
||||
DclThreadGroup = 155,
|
||||
DclUnorderedAccessViewTyped = 156,
|
||||
DclUnorderedAccessViewRaw = 157,
|
||||
DclUnorderedAccessViewStructured = 158,
|
||||
DclThreadGroupSharedMemoryRaw = 159,
|
||||
DclThreadGroupSharedMemoryStructured = 160,
|
||||
DclResourceRaw = 161,
|
||||
DclResourceStructured = 162,
|
||||
LdUavTyped = 163,
|
||||
StoreUavTyped = 164,
|
||||
LdRaw = 165,
|
||||
StoreRaw = 166,
|
||||
LdStructured = 167,
|
||||
StoreStructured = 168,
|
||||
AtomicAnd = 169,
|
||||
AtomicOr = 170,
|
||||
AtomicXor = 171,
|
||||
AtomicCmpStore = 172,
|
||||
AtomicIAdd = 173,
|
||||
AtomicIMax = 174,
|
||||
AtomicIMin = 175,
|
||||
AtomicUMax = 176,
|
||||
AtomicUMin = 177,
|
||||
ImmAtomicAlloc = 178,
|
||||
ImmAtomicConsume = 179,
|
||||
ImmAtomicIAdd = 180,
|
||||
ImmAtomicAnd = 181,
|
||||
ImmAtomicOr = 182,
|
||||
ImmAtomicXor = 183,
|
||||
ImmAtomicExch = 184,
|
||||
ImmAtomicCmpExch = 185,
|
||||
ImmAtomicImax = 186,
|
||||
ImmAtomicImin = 187,
|
||||
ImmAtomicUmax = 188,
|
||||
ImmAtomicUmin = 189,
|
||||
Sync = 190,
|
||||
DAdd = 191,
|
||||
DMax = 192,
|
||||
DMin = 193,
|
||||
DMul = 194,
|
||||
DEq = 195,
|
||||
DGe = 196,
|
||||
DLt = 197,
|
||||
DNe = 198,
|
||||
DMov = 199,
|
||||
DMovc = 200,
|
||||
DtoF = 201,
|
||||
FtoD = 202,
|
||||
EvalSnapped = 203,
|
||||
EvalSampleIndex = 204,
|
||||
EvalCentroid = 205,
|
||||
DclGsInstanceCount = 206,
|
||||
};
|
||||
|
||||
}
|
53
src/dxbc/dxbc_reader.cpp
Normal file
53
src/dxbc/dxbc_reader.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "dxbc_reader.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
DxbcTag DxbcReader::readTag() {
|
||||
DxbcTag tag;
|
||||
this->read(&tag, 4);
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
std::string DxbcReader::readString() {
|
||||
std::string result;
|
||||
|
||||
while (m_data[m_pos] != '\0')
|
||||
result.push_back(m_data[m_pos++]);
|
||||
|
||||
m_pos++;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void DxbcReader::read(void* dst, size_t n) {
|
||||
if (m_pos + n > m_size)
|
||||
throw DxvkError("DxbcReader::read: Unexpected end of file");
|
||||
std::memcpy(dst, m_data + m_pos, n);
|
||||
m_pos += n;
|
||||
}
|
||||
|
||||
|
||||
void DxbcReader::skip(size_t n) {
|
||||
if (m_pos + n > m_size)
|
||||
throw DxvkError("DxbcReader::skip: Unexpected end of file");
|
||||
m_pos += n;
|
||||
}
|
||||
|
||||
|
||||
DxbcReader DxbcReader::clone(size_t pos) const {
|
||||
if (pos > m_size)
|
||||
throw DxvkError("DxbcReader::clone: Invalid offset");
|
||||
return DxbcReader(m_data + pos, m_size - pos);
|
||||
}
|
||||
|
||||
|
||||
DxbcReader DxbcReader::resize(size_t size) const {
|
||||
if (size > m_size)
|
||||
throw DxvkError("DxbcReader::resize: Invalid size");
|
||||
return DxbcReader(m_data, size, m_pos);
|
||||
}
|
||||
|
||||
}
|
76
src/dxbc/dxbc_reader.h
Normal file
76
src/dxbc/dxbc_reader.h
Normal file
@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
#include "dxbc_tag.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief DXBC bytecode reader
|
||||
*
|
||||
* Holds references to the shader byte code and
|
||||
* provides methods to read
|
||||
*/
|
||||
class DxbcReader {
|
||||
|
||||
public:
|
||||
|
||||
DxbcReader(const char* data, size_t size)
|
||||
: DxbcReader(data, size, 0) { }
|
||||
|
||||
auto readu8 () { return this->readNum<uint8_t> (); }
|
||||
auto readu16() { return this->readNum<uint16_t>(); }
|
||||
auto readu32() { return this->readNum<uint32_t>(); }
|
||||
auto readu64() { return this->readNum<uint64_t>(); }
|
||||
|
||||
auto readi8 () { return this->readNum<int8_t> (); }
|
||||
auto readi16() { return this->readNum<int16_t> (); }
|
||||
auto readi32() { return this->readNum<int32_t> (); }
|
||||
auto readi64() { return this->readNum<int64_t> (); }
|
||||
|
||||
auto readf32() { return this->readNum<float> (); }
|
||||
auto readf64() { return this->readNum<double> (); }
|
||||
|
||||
template<typename T>
|
||||
auto readEnum() {
|
||||
using Tx = std::underlying_type_t<T>;
|
||||
return static_cast<T>(this->readNum<Tx>());
|
||||
}
|
||||
|
||||
DxbcTag readTag();
|
||||
|
||||
std::string readString();
|
||||
|
||||
void read(void* dst, size_t n);
|
||||
|
||||
void skip(size_t n);
|
||||
|
||||
DxbcReader clone(size_t pos) const;
|
||||
|
||||
DxbcReader resize(size_t size) const;
|
||||
|
||||
bool eof() const {
|
||||
return m_pos >= m_size;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
DxbcReader(const char* data, size_t size, size_t pos)
|
||||
: m_data(data), m_size(size), m_pos(pos) { }
|
||||
|
||||
const char* m_data = nullptr;
|
||||
size_t m_size = 0;
|
||||
size_t m_pos = 0;
|
||||
|
||||
template<typename T>
|
||||
T readNum() {
|
||||
T result;
|
||||
this->read(&result, sizeof(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
47
src/dxbc/dxbc_tag.h
Normal file
47
src/dxbc/dxbc_tag.h
Normal file
@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include "dxbc_include.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief Four-character tag
|
||||
*
|
||||
* Used to identify chunks in the
|
||||
* compiled DXBC file by name.
|
||||
*/
|
||||
class DxbcTag {
|
||||
|
||||
public:
|
||||
|
||||
DxbcTag() {
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
m_chars[i] = '\0';
|
||||
}
|
||||
|
||||
DxbcTag(const char* tag) {
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
m_chars[i] = tag[i];
|
||||
}
|
||||
|
||||
bool operator == (const DxbcTag& other) const {
|
||||
bool result = true;
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
result &= m_chars[i] == other.m_chars[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
bool operator != (const DxbcTag& other) const {
|
||||
return !this->operator == (other);
|
||||
}
|
||||
|
||||
const char* operator & () const { return m_chars; }
|
||||
char* operator & () { return m_chars; }
|
||||
|
||||
private:
|
||||
|
||||
char m_chars[4];
|
||||
|
||||
};
|
||||
|
||||
}
|
14
src/dxbc/meson.build
Normal file
14
src/dxbc/meson.build
Normal file
@ -0,0 +1,14 @@
|
||||
dxbc_src = files([
|
||||
'dxbc_chunk_shex.cpp',
|
||||
'dxbc_compiler.cpp',
|
||||
'dxbc_header.cpp',
|
||||
'dxbc_module.cpp',
|
||||
'dxbc_reader.cpp',
|
||||
])
|
||||
|
||||
dxbc_lib = static_library('dxbc', dxbc_src,
|
||||
include_directories : [ dxvk_include_path ])
|
||||
|
||||
dxbc_dep = declare_dependency(
|
||||
link_with : [ dxbc_lib ],
|
||||
include_directories : [ dxvk_include_path, include_directories('.') ])
|
@ -1,4 +1,5 @@
|
||||
subdir('util')
|
||||
subdir('dxvk')
|
||||
subdir('dxgi')
|
||||
subdir('dxbc')
|
||||
subdir('d3d11')
|
10
src/util/util_bit.h
Normal file
10
src/util/util_bit.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
namespace dxvk::bit {
|
||||
|
||||
template<typename T, T Fst, T Lst>
|
||||
constexpr T extract(T value) {
|
||||
return (value >> Fst) & ~(~T(0) << (Lst - Fst + 1));
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
@ -20,4 +22,8 @@ namespace dxvk::str {
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
inline std::string fromws(const std::wstring& ws) {
|
||||
return std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(ws);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user