1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-11-29 19:24:10 +01:00

[dxbc] Added highly experimental shader input/output interface code

This commit is contained in:
Philip Rebohle 2017-12-07 16:29:34 +01:00
parent 04f8c6d306
commit b7e263fc73
11 changed files with 144 additions and 32 deletions

View File

@ -3,8 +3,10 @@
namespace dxvk {
DxbcCompiler::DxbcCompiler(
const DxbcProgramVersion& version)
: m_gen(DxbcCodeGen::create(version)) { }
const DxbcProgramVersion& version,
const Rc<DxbcIsgn>& isgn,
const Rc<DxbcIsgn>& osgn)
: m_gen(DxbcCodeGen::create(version, isgn, osgn)) { }
DxbcCompiler::~DxbcCompiler() {

View File

@ -15,11 +15,13 @@ namespace dxvk {
public:
DxbcCompiler(
const DxbcProgramVersion& version);
const DxbcProgramVersion& version,
const Rc<DxbcIsgn>& isgn,
const Rc<DxbcIsgn>& osgn);
~DxbcCompiler();
void processInstruction(
const DxbcInstruction& ins);
const DxbcInstruction& ins);
SpirvCodeBuffer finalize();

View File

@ -44,7 +44,10 @@ namespace dxvk {
if (m_shexChunk == nullptr)
throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk");
DxbcCompiler compiler(m_shexChunk->version());
DxbcCompiler compiler(
m_shexChunk->version(),
m_isgnChunk, m_osgnChunk);
for (auto ins : *m_shexChunk)
compiler.processInstruction(ins);
return compiler.finalize();

View File

@ -329,13 +329,15 @@ namespace dxvk {
Rc<DxbcCodeGen> DxbcCodeGen::create(
const DxbcProgramVersion& version) {
const DxbcProgramVersion& version,
const Rc<DxbcIsgn>& isgn,
const Rc<DxbcIsgn>& osgn) {
switch (version.type()) {
case DxbcProgramType::PixelShader:
return new DxbcPsCodeGen();
return new DxbcPsCodeGen(osgn);
case DxbcProgramType::VertexShader:
return new DxbcVsCodeGen();
return new DxbcVsCodeGen(isgn);
default:
throw DxvkError(str::format(

View File

@ -1,5 +1,6 @@
#pragma once
#include "../dxbc_chunk_isgn.h"
#include "../dxbc_common.h"
#include "../dxbc_decoder.h"
#include "../dxbc_type.h"
@ -112,7 +113,9 @@ namespace dxvk {
virtual SpirvCodeBuffer finalize() = 0;
static Rc<DxbcCodeGen> create(
const DxbcProgramVersion& version);
const DxbcProgramVersion& version,
const Rc<DxbcIsgn>& isgn,
const Rc<DxbcIsgn>& osgn);
protected:

View File

@ -2,7 +2,8 @@
namespace dxvk {
DxbcPsCodeGen::DxbcPsCodeGen() {
DxbcPsCodeGen::DxbcPsCodeGen(
const Rc<DxbcIsgn>& osgn) {
m_module.enableCapability(spv::CapabilityShader);
m_module.enableCapability(spv::CapabilityCullDistance);
m_module.enableCapability(spv::CapabilityClipDistance);
@ -17,6 +18,22 @@ namespace dxvk {
m_module.defVoidType(), 0, nullptr),
spv::FunctionControlMaskNone);
m_module.opLabel(m_module.allocateId());
// Declare outputs based on the input signature
for (auto e = osgn->begin(); e != osgn->end(); e++) {
if (e->systemValue == DxbcSystemValue::None) {
m_psOut.at(e->registerId) = this->defVar(
DxbcValueType(e->componentType, e->componentMask.componentCount()),
spv::StorageClassOutput);
m_module.decorateLocation(
m_psOut.at(e->registerId).valueId,
e->registerId);
m_module.setDebugName(m_psOut.at(e->registerId).valueId,
str::format("ps_out", e->registerId).c_str());
m_entryPointInterfaces.push_back(
m_psOut.at(e->registerId).valueId);
}
}
}
@ -142,7 +159,17 @@ namespace dxvk {
void DxbcPsCodeGen::prepareSvOutputs() {
// TODO properly re-implement this
std::array<uint32_t, 5> masks = { 0x0, 0x1, 0x3, 0x7, 0xF };
for (uint32_t i = 0; i < m_psOut.size(); i++) {
if ((m_psOut.at(i).valueId != 0) && (m_oRegs.at(i).valueId != 0)) {
DxbcValue srcValue = this->regLoad(m_oRegs.at(i));
srcValue = this->regCast(srcValue, m_psOut.at(i).type.valueType);
this->regStore(m_psOut.at(i), srcValue, DxbcComponentMask(
masks.at(m_psOut.at(i).type.valueType.componentCount)));
}
}
}
}

View File

@ -11,7 +11,8 @@ namespace dxvk {
public:
DxbcPsCodeGen();
DxbcPsCodeGen(
const Rc<DxbcIsgn>& osgn);
~DxbcPsCodeGen();
void dclInterfaceVar(
@ -41,6 +42,7 @@ namespace dxvk {
std::array<DxbcPointer, 32> m_vRegs;
std::array<DxbcPointer, 8> m_oRegs;
std::array<DxbcPointer, 8> m_psOut;
void dclSvInputReg(DxbcSystemValue sv);

View File

@ -2,7 +2,7 @@
namespace dxvk {
DxbcVsCodeGen::DxbcVsCodeGen() {
DxbcVsCodeGen::DxbcVsCodeGen(const Rc<DxbcIsgn>& isgn) {
m_module.enableCapability(spv::CapabilityShader);
m_module.enableCapability(spv::CapabilityCullDistance);
m_module.enableCapability(spv::CapabilityClipDistance);
@ -24,6 +24,22 @@ namespace dxvk {
spv::StorageClassOutput);
m_entryPointInterfaces.push_back(m_vsPerVertex);
m_module.setDebugName(m_vsPerVertex, "vs_per_vertex");
// Declare vertex inputs based on the input signature
for (auto e = isgn->begin(); e != isgn->end(); e++) {
if (e->systemValue == DxbcSystemValue::None) {
m_vsIn.at(e->registerId) = this->defVar(
DxbcValueType(e->componentType, 4),
spv::StorageClassInput);
m_module.decorateLocation(
m_vsIn.at(e->registerId).valueId,
e->registerId);
m_module.setDebugName(m_vsIn.at(e->registerId).valueId,
str::format("vs_in", e->registerId).c_str());
m_entryPointInterfaces.push_back(
m_vsIn.at(e->registerId).valueId);
}
}
}
@ -47,6 +63,11 @@ namespace dxvk {
m_module.setDebugName(m_vRegs.at(regId).valueId,
str::format("v", regId).c_str());
}
if (sv != DxbcSystemValue::None) {
m_svIn.push_back(DxbcSvMapping {
regId, regMask, sv });
}
} break;
case DxbcOperandType::Output: {
@ -57,6 +78,11 @@ namespace dxvk {
m_module.setDebugName(m_oRegs.at(regId).valueId,
str::format("o", regId).c_str());
}
if (sv != DxbcSystemValue::None) {
m_svOut.push_back(DxbcSvMapping {
regId, regMask, sv });
}
} break;
default:
@ -129,12 +155,35 @@ namespace dxvk {
void DxbcVsCodeGen::prepareSvInputs() {
DxbcValueType targetType(DxbcScalarType::Float32, 4);
// Copy vertex inputs to the actual shader input registers
for (uint32_t i = 0; i < m_vsIn.size(); i++) {
if ((m_vsIn.at(i).valueId != 0) && (m_vRegs.at(i).valueId != 0)) {
DxbcValue srcValue = this->regLoad(m_vsIn.at(i));
srcValue = this->regCast(srcValue, targetType);
this->regStore(m_vRegs.at(i), srcValue,
DxbcComponentMask(true, true, true, true));
}
}
// TODO system values
}
void DxbcVsCodeGen::prepareSvOutputs() {
// TODO add user-defined shader outputs
for (const auto& mapping : m_svOut) {
DxbcValue srcValue = this->regLoad(m_oRegs.at(mapping.regId));
switch (mapping.sv) {
case DxbcSystemValue::Position: {
this->regStore(this->ptrBuiltInPosition(), srcValue,
DxbcComponentMask(true, true, true, true));
} break;
}
}
}

View File

@ -11,7 +11,8 @@ namespace dxvk {
public:
DxbcVsCodeGen();
DxbcVsCodeGen(
const Rc<DxbcIsgn>& isgn);
~DxbcVsCodeGen();
void dclInterfaceVar(
@ -42,6 +43,9 @@ namespace dxvk {
std::array<DxbcPointer, 32> m_vRegs;
std::array<DxbcPointer, 32> m_oRegs;
std::vector<DxbcSvMapping> m_svIn;
std::vector<DxbcSvMapping> m_svOut;
void dclSvInputReg(DxbcSystemValue sv);
void prepareSvInputs();

View File

@ -184,54 +184,72 @@ namespace dxvk {
AddFormat(
DXGI_FORMAT_R8G8B8A8_UINT,
VK_FORMAT_R8G8B8A8_UINT, {},
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT |
VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT |
VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT |
VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT |
VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT |
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
AddFormat(
DXGI_FORMAT_R8G8B8A8_UNORM,
VK_FORMAT_R8G8B8A8_UNORM, {},
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT |
VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT |
VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT |
VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT |
VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT |
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT);
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT);
AddFormat(
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
VK_FORMAT_R8G8B8A8_SRGB, {},
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT);
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT);
AddFormat(
DXGI_FORMAT_R8G8B8A8_SINT,
VK_FORMAT_R8G8B8A8_SINT, {},
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT |
VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT |
VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT |
VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT |
VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT |
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
AddFormat(
DXGI_FORMAT_R8G8B8A8_SNORM,
VK_FORMAT_R8G8B8A8_SNORM, {},
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT |
VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT |
VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT |
VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT |
VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT |
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT);
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT);
AddFormat(
DXGI_FORMAT_R32G32B32_FLOAT,
VK_FORMAT_R32G32B32_SFLOAT, {},
VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT |
VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT);
AddFormat(
DXGI_FORMAT_R32G32B32A32_FLOAT,
VK_FORMAT_R32G32B32A32_SFLOAT, {},
VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT |
VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT |
VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT |
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT);
AddFormat(
DXGI_FORMAT_D24_UNORM_S8_UINT,

View File

@ -1,6 +1,6 @@
lib_d3d11 = dxvk_compiler.find_library('d3d11')
lib_dxgi = dxvk_compiler.find_library('dxgi')
lib_d3dcompiler_47 = dxvk_compiler.find_library('d3dcompiler')
lib_d3dcompiler_47 = dxvk_compiler.find_library('d3dcompiler_47')
subdir('d3d11')
subdir('dxbc')