mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
[dxbc] Added pixel shader code generator stub
This commit is contained in:
parent
5d26f0fb0c
commit
cded7726a7
@ -112,7 +112,6 @@ namespace dxvk {
|
|||||||
void DxbcCompiler::opMov(const DxbcInstruction& ins) {
|
void DxbcCompiler::opMov(const DxbcInstruction& ins) {
|
||||||
auto dstOp = ins.operand(0);
|
auto dstOp = ins.operand(0);
|
||||||
auto srcOp = ins.operand(dstOp.length());
|
auto srcOp = ins.operand(dstOp.length());
|
||||||
|
|
||||||
DxbcComponentMask mask = this->getDstOperandMask(dstOp);
|
DxbcComponentMask mask = this->getDstOperandMask(dstOp);
|
||||||
|
|
||||||
DxbcValue value = this->loadOperand(srcOp, mask, DxbcScalarType::Float32);
|
DxbcValue value = this->loadOperand(srcOp, mask, DxbcScalarType::Float32);
|
||||||
@ -229,9 +228,13 @@ namespace dxvk {
|
|||||||
return m_gen->regExtract(opValue,
|
return m_gen->regExtract(opValue,
|
||||||
opToken.componentSelection());
|
opToken.componentSelection());
|
||||||
|
|
||||||
|
case DxbcComponentSelectionMode::Mask:
|
||||||
|
return m_gen->regExtract(opValue,
|
||||||
|
opToken.componentMask());
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw DxvkError(str::format(
|
throw DxvkError(str::format(
|
||||||
"DxbcCompiler::loadOperand: Invalid component selection mode: ",
|
"DxbcCompiler::selectOperandComponents: Invalid selection mode: ",
|
||||||
opToken.selectionMode()));
|
opToken.selectionMode()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -257,38 +260,35 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxbcValue result;
|
DxbcValue result;
|
||||||
|
|
||||||
switch (token.type()) {
|
if (token.type() == DxbcOperandType::Imm32) {
|
||||||
case DxbcOperandType::Imm32: {
|
if (token.numComponents() == 1) {
|
||||||
if (token.numComponents() == 1) {
|
result = m_gen->defConstScalar(operand.imm32(0));
|
||||||
result = m_gen->defConstScalar(operand.imm32(0));
|
} else if (token.numComponents() == 4) {
|
||||||
} else if (token.numComponents() == 4) {
|
result = m_gen->defConstVector(
|
||||||
result = m_gen->defConstVector(
|
operand.imm32(0), operand.imm32(1),
|
||||||
operand.imm32(0), operand.imm32(1),
|
operand.imm32(2), operand.imm32(3));
|
||||||
operand.imm32(2), operand.imm32(3));
|
} else {
|
||||||
} else {
|
throw DxvkError(str::format(
|
||||||
throw DxvkError(str::format(
|
"DxbcCompiler::loadOperand [imm32]: Invalid number of components: ",
|
||||||
"DxbcCompiler::loadOperand [imm32]: Invalid number of components: ",
|
token.numComponents()));
|
||||||
token.numComponents()));
|
}
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default: {
|
result = m_gen->regExtract(result, dstMask);
|
||||||
result = m_gen->regLoad(
|
} else {
|
||||||
this->getOperandPtr(operand));
|
result = m_gen->regLoad(this->getOperandPtr(operand));
|
||||||
};
|
|
||||||
}
|
// Apply the source operand swizzle
|
||||||
|
if (token.numComponents() == 4)
|
||||||
// Apply the source operand swizzle
|
result = this->selectOperandComponents(token, result, dstMask);
|
||||||
if (token.numComponents() == 4)
|
|
||||||
result = this->selectOperandComponents(token, result, dstMask);
|
// Apply source operand modifiers, if any
|
||||||
|
auto operandModifiers = operand.queryOperandExt(
|
||||||
// Apply source operand modifiers, if any
|
DxbcOperandExt::OperandModifier);
|
||||||
auto operandModifiers = operand.queryOperandExt(
|
|
||||||
DxbcOperandExt::OperandModifier);
|
if (operandModifiers) {
|
||||||
|
result = this->applyOperandModifiers(
|
||||||
if (operandModifiers) {
|
result, operandModifiers->data());
|
||||||
result = this->applyOperandModifiers(
|
}
|
||||||
result, operandModifiers->data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "dxbc_gen_common.h"
|
#include "dxbc_gen_common.h"
|
||||||
|
#include "dxbc_gen_pixel.h"
|
||||||
#include "dxbc_gen_vertex.h"
|
#include "dxbc_gen_vertex.h"
|
||||||
|
|
||||||
#include "../dxbc_names.h"
|
#include "../dxbc_names.h"
|
||||||
@ -145,7 +146,8 @@ namespace dxvk {
|
|||||||
DxbcValue DxbcCodeGen::regExtract(
|
DxbcValue DxbcCodeGen::regExtract(
|
||||||
const DxbcValue& src,
|
const DxbcValue& src,
|
||||||
DxbcComponentMask mask) {
|
DxbcComponentMask mask) {
|
||||||
// TODO implement
|
return this->regSwizzle(src,
|
||||||
|
DxbcComponentSwizzle(), mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -263,6 +265,9 @@ namespace dxvk {
|
|||||||
Rc<DxbcCodeGen> DxbcCodeGen::create(
|
Rc<DxbcCodeGen> DxbcCodeGen::create(
|
||||||
const DxbcProgramVersion& version) {
|
const DxbcProgramVersion& version) {
|
||||||
switch (version.type()) {
|
switch (version.type()) {
|
||||||
|
case DxbcProgramType::PixelShader:
|
||||||
|
return new DxbcPsCodeGen();
|
||||||
|
|
||||||
case DxbcProgramType::VertexShader:
|
case DxbcProgramType::VertexShader:
|
||||||
return new DxbcVsCodeGen();
|
return new DxbcVsCodeGen();
|
||||||
|
|
||||||
|
155
src/dxbc/gen/dxbc_gen_pixel.cpp
Normal file
155
src/dxbc/gen/dxbc_gen_pixel.cpp
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
#include "dxbc_gen_pixel.h"
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
DxbcPsCodeGen::DxbcPsCodeGen() {
|
||||||
|
m_module.enableCapability(spv::CapabilityShader);
|
||||||
|
m_module.enableCapability(spv::CapabilityCullDistance);
|
||||||
|
m_module.enableCapability(spv::CapabilityClipDistance);
|
||||||
|
|
||||||
|
m_function = m_module.allocateId();
|
||||||
|
m_module.setDebugName(m_function, "ps_main");
|
||||||
|
|
||||||
|
m_module.functionBegin(
|
||||||
|
m_module.defVoidType(),
|
||||||
|
m_function,
|
||||||
|
m_module.defFunctionType(
|
||||||
|
m_module.defVoidType(), 0, nullptr),
|
||||||
|
spv::FunctionControlMaskNone);
|
||||||
|
m_module.opLabel(m_module.allocateId());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxbcPsCodeGen::~DxbcPsCodeGen() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxbcPsCodeGen::dclInterfaceVar(
|
||||||
|
DxbcOperandType regType,
|
||||||
|
uint32_t regId,
|
||||||
|
uint32_t regDim,
|
||||||
|
DxbcComponentMask regMask,
|
||||||
|
DxbcSystemValue sv) {
|
||||||
|
switch (regType) {
|
||||||
|
case DxbcOperandType::Input: {
|
||||||
|
if (sv == DxbcSystemValue::None) {
|
||||||
|
if (m_vRegs.at(regId).valueId == 0) {
|
||||||
|
m_vRegs.at(regId) = this->defVar(
|
||||||
|
DxbcValueType(DxbcScalarType::Float32, 4),
|
||||||
|
spv::StorageClassInput);
|
||||||
|
m_module.setDebugName(m_vRegs.at(regId).valueId,
|
||||||
|
str::format("v", regId).c_str());
|
||||||
|
m_module.decorateLocation(
|
||||||
|
m_vRegs.at(regId).valueId, regId);
|
||||||
|
m_entryPointInterfaces.push_back(
|
||||||
|
m_vRegs.at(regId).valueId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (m_vRegsSv.at(regId).valueId == 0) {
|
||||||
|
m_vRegsSv.at(regId) = this->defVar(
|
||||||
|
DxbcValueType(DxbcScalarType::Float32, 4),
|
||||||
|
spv::StorageClassPrivate);
|
||||||
|
m_module.setDebugName(m_vRegsSv.at(regId).valueId,
|
||||||
|
str::format("sv", regId).c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case DxbcOperandType::Output: {
|
||||||
|
if (sv != DxbcSystemValue::None) {
|
||||||
|
throw DxvkError(str::format(
|
||||||
|
"DxbcPsCodeGen::dclInterfaceVar: Cannot map output register to system value: ",
|
||||||
|
sv));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_oRegs.at(regId).valueId == 0) {
|
||||||
|
m_oRegs.at(regId) = this->defVar(
|
||||||
|
DxbcValueType(DxbcScalarType::Float32, 4),
|
||||||
|
spv::StorageClassOutput);
|
||||||
|
m_module.setDebugName(m_oRegs.at(regId).valueId,
|
||||||
|
str::format("o", regId).c_str());
|
||||||
|
m_module.decorateLocation(
|
||||||
|
m_oRegs.at(regId).valueId, regId);
|
||||||
|
m_entryPointInterfaces.push_back(
|
||||||
|
m_oRegs.at(regId).valueId);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw DxvkError(str::format(
|
||||||
|
"DxbcPsCodeGen::dclInterfaceVar: Unhandled operand type: ",
|
||||||
|
regType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxbcPointer DxbcPsCodeGen::ptrInterfaceVar(
|
||||||
|
DxbcOperandType regType,
|
||||||
|
uint32_t regId) {
|
||||||
|
switch (regType) {
|
||||||
|
case DxbcOperandType::Input:
|
||||||
|
return m_vRegsSv.at(regId).valueId != 0
|
||||||
|
? m_vRegsSv.at(regId)
|
||||||
|
: m_vRegs .at(regId);
|
||||||
|
|
||||||
|
case DxbcOperandType::Output:
|
||||||
|
return m_oRegs.at(regId);
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw DxvkError(str::format(
|
||||||
|
"DxbcPsCodeGen::ptrInterfaceVar: Unhandled operand type: ",
|
||||||
|
regType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxbcPointer DxbcPsCodeGen::ptrInterfaceVarIndexed(
|
||||||
|
DxbcOperandType regType,
|
||||||
|
uint32_t regId,
|
||||||
|
const DxbcValue& index) {
|
||||||
|
throw DxvkError(str::format(
|
||||||
|
"DxbcPsCodeGen::ptrInterfaceVarIndexed:\n",
|
||||||
|
"Pixel shaders do not support indexed interface variables"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Rc<DxvkShader> DxbcPsCodeGen::finalize() {
|
||||||
|
m_module.functionBegin(
|
||||||
|
m_module.defVoidType(),
|
||||||
|
m_entryPointId,
|
||||||
|
m_module.defFunctionType(
|
||||||
|
m_module.defVoidType(), 0, nullptr),
|
||||||
|
spv::FunctionControlMaskNone);
|
||||||
|
m_module.opLabel(m_module.allocateId());
|
||||||
|
|
||||||
|
this->prepareSvInputs();
|
||||||
|
m_module.opFunctionCall(
|
||||||
|
m_module.defVoidType(),
|
||||||
|
m_function, 0, nullptr);
|
||||||
|
this->prepareSvOutputs();
|
||||||
|
|
||||||
|
m_module.opReturn();
|
||||||
|
m_module.functionEnd();
|
||||||
|
|
||||||
|
m_module.addEntryPoint(m_entryPointId,
|
||||||
|
spv::ExecutionModelFragment, "main",
|
||||||
|
m_entryPointInterfaces.size(),
|
||||||
|
m_entryPointInterfaces.data());
|
||||||
|
m_module.setDebugName(m_entryPointId, "main");
|
||||||
|
|
||||||
|
return new DxvkShader(VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||||
|
m_module.compile(), 0, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxbcPsCodeGen::prepareSvInputs() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxbcPsCodeGen::prepareSvOutputs() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
52
src/dxbc/gen/dxbc_gen_pixel.h
Normal file
52
src/dxbc/gen/dxbc_gen_pixel.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dxbc_gen_common.h"
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Pixel shader code generator
|
||||||
|
*/
|
||||||
|
class DxbcPsCodeGen : public DxbcCodeGen {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DxbcPsCodeGen();
|
||||||
|
~DxbcPsCodeGen();
|
||||||
|
|
||||||
|
void dclInterfaceVar(
|
||||||
|
DxbcOperandType regType,
|
||||||
|
uint32_t regId,
|
||||||
|
uint32_t regDim,
|
||||||
|
DxbcComponentMask regMask,
|
||||||
|
DxbcSystemValue sv);
|
||||||
|
|
||||||
|
DxbcPointer ptrInterfaceVar(
|
||||||
|
DxbcOperandType regType,
|
||||||
|
uint32_t regId);
|
||||||
|
|
||||||
|
DxbcPointer ptrInterfaceVarIndexed(
|
||||||
|
DxbcOperandType regType,
|
||||||
|
uint32_t regId,
|
||||||
|
const DxbcValue& index);
|
||||||
|
|
||||||
|
Rc<DxvkShader> finalize() final;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
uint32_t m_function = 0;
|
||||||
|
|
||||||
|
DxbcPointer m_svPosition;
|
||||||
|
|
||||||
|
std::array<DxbcPointer, 32> m_vRegs;
|
||||||
|
std::array<DxbcPointer, 32> m_vRegsSv;
|
||||||
|
std::array<DxbcPointer, 32> m_oRegs;
|
||||||
|
|
||||||
|
std::vector<DxbcSvMapping> m_svInputs;
|
||||||
|
|
||||||
|
void prepareSvInputs();
|
||||||
|
void prepareSvOutputs();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -11,6 +11,7 @@ dxbc_src = files([
|
|||||||
'dxbc_type.cpp',
|
'dxbc_type.cpp',
|
||||||
|
|
||||||
'gen/dxbc_gen_common.cpp',
|
'gen/dxbc_gen_common.cpp',
|
||||||
|
'gen/dxbc_gen_pixel.cpp',
|
||||||
'gen/dxbc_gen_vertex.cpp',
|
'gen/dxbc_gen_vertex.cpp',
|
||||||
])
|
])
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user