mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 10:54:16 +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('util')
|
||||||
subdir('dxvk')
|
subdir('dxvk')
|
||||||
subdir('dxgi')
|
subdir('dxgi')
|
||||||
|
subdir('dxbc')
|
||||||
subdir('d3d11')
|
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
|
#pragma once
|
||||||
|
|
||||||
|
#include <locale>
|
||||||
|
#include <codecvt>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
@ -20,4 +22,8 @@ namespace dxvk::str {
|
|||||||
return stream.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…
x
Reference in New Issue
Block a user