mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 05:52:11 +01:00
[dxbc] Added result modifiers, simple add instruction
This commit is contained in:
parent
4c0404d3c6
commit
abc0e98761
@ -33,6 +33,9 @@ namespace dxvk {
|
|||||||
case DxbcOpcode::DclTemps:
|
case DxbcOpcode::DclTemps:
|
||||||
return this->dclTemps(ins);
|
return this->dclTemps(ins);
|
||||||
|
|
||||||
|
case DxbcOpcode::Add:
|
||||||
|
return this->opAdd(ins);
|
||||||
|
|
||||||
case DxbcOpcode::Mov:
|
case DxbcOpcode::Mov:
|
||||||
return this->opMov(ins);
|
return this->opMov(ins);
|
||||||
|
|
||||||
@ -109,13 +112,27 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxbcCompiler::opAdd(const DxbcInstruction& ins) {
|
||||||
|
auto dstOp = ins.operand(0);
|
||||||
|
auto srcOp1 = ins.operand(dstOp.length());
|
||||||
|
auto srcOp2 = ins.operand(dstOp.length() + srcOp1.length());
|
||||||
|
DxbcComponentMask mask = this->getDstOperandMask(dstOp);
|
||||||
|
|
||||||
|
DxbcValue src1 = this->loadOperand(srcOp1, mask, DxbcScalarType::Float32);
|
||||||
|
DxbcValue src2 = this->loadOperand(srcOp2, mask, DxbcScalarType::Float32);
|
||||||
|
DxbcValue val = m_gen->opAdd(src1, src2);
|
||||||
|
val = this->applyResultModifiers(val, ins.token().control());
|
||||||
|
this->storeOperand(dstOp, val, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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);
|
||||||
|
value = this->applyResultModifiers(value, ins.token().control());
|
||||||
this->storeOperand(dstOp, value, mask);
|
this->storeOperand(dstOp, value, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,6 +269,15 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxbcValue DxbcCompiler::applyResultModifiers(
|
||||||
|
DxbcValue value,
|
||||||
|
DxbcOpcodeControl control) {
|
||||||
|
if (control.saturateBit())
|
||||||
|
value = m_gen->opSaturate(value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DxbcValue DxbcCompiler::loadOperand(
|
DxbcValue DxbcCompiler::loadOperand(
|
||||||
const DxbcOperand& operand,
|
const DxbcOperand& operand,
|
||||||
DxbcComponentMask dstMask,
|
DxbcComponentMask dstMask,
|
||||||
@ -267,16 +293,22 @@ namespace dxvk {
|
|||||||
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));
|
||||||
|
result = m_gen->regExtract(result, dstMask);
|
||||||
} 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()));
|
||||||
}
|
}
|
||||||
|
|
||||||
result = m_gen->regExtract(result, dstMask);
|
result = m_gen->regCast(result, DxbcValueType(
|
||||||
|
dstType, result.type.componentCount));
|
||||||
} else {
|
} else {
|
||||||
result = m_gen->regLoad(this->getOperandPtr(operand));
|
result = m_gen->regLoad(this->getOperandPtr(operand));
|
||||||
|
|
||||||
|
// Cast register to requested type
|
||||||
|
result = m_gen->regCast(result, DxbcValueType(
|
||||||
|
dstType, result.type.componentCount));
|
||||||
|
|
||||||
// Apply the source operand swizzle
|
// Apply the source operand swizzle
|
||||||
if (token.numComponents() == 4)
|
if (token.numComponents() == 4)
|
||||||
result = this->selectOperandComponents(token, result, dstMask);
|
result = this->selectOperandComponents(token, result, dstMask);
|
||||||
|
@ -36,6 +36,9 @@ namespace dxvk {
|
|||||||
void dclTemps(
|
void dclTemps(
|
||||||
const DxbcInstruction& ins);
|
const DxbcInstruction& ins);
|
||||||
|
|
||||||
|
void opAdd(
|
||||||
|
const DxbcInstruction& ins);
|
||||||
|
|
||||||
void opMov(
|
void opMov(
|
||||||
const DxbcInstruction& ins);
|
const DxbcInstruction& ins);
|
||||||
|
|
||||||
@ -63,6 +66,10 @@ namespace dxvk {
|
|||||||
DxbcValue value,
|
DxbcValue value,
|
||||||
DxbcOperandModifiers modifiers);
|
DxbcOperandModifiers modifiers);
|
||||||
|
|
||||||
|
DxbcValue applyResultModifiers(
|
||||||
|
DxbcValue value,
|
||||||
|
DxbcOpcodeControl control);
|
||||||
|
|
||||||
DxbcValue loadOperand(
|
DxbcValue loadOperand(
|
||||||
const DxbcOperand& operand,
|
const DxbcOperand& operand,
|
||||||
DxbcComponentMask dstMask,
|
DxbcComponentMask dstMask,
|
||||||
|
@ -11,6 +11,77 @@ namespace dxvk {
|
|||||||
|
|
||||||
class DxbcOperand;
|
class DxbcOperand;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Basic control info
|
||||||
|
*
|
||||||
|
* Parses instruction-specific control bits. Whether
|
||||||
|
* these are well defined depends on the instruction.
|
||||||
|
*/
|
||||||
|
class DxbcOpcodeControl {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DxbcOpcodeControl() { }
|
||||||
|
DxbcOpcodeControl(uint32_t control)
|
||||||
|
: m_control(control) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Saturation hint
|
||||||
|
*
|
||||||
|
* If set, the result of the given instruction
|
||||||
|
* is clamped to the [0..1] range.
|
||||||
|
*/
|
||||||
|
bool saturateBit() const {
|
||||||
|
return bit::extract(m_control, 2, 2) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Precision hint
|
||||||
|
*/
|
||||||
|
bool preciseBit() const {
|
||||||
|
return bit::extract(m_control, 8, 11) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Zero test
|
||||||
|
*
|
||||||
|
* For conditional instructions, this defines
|
||||||
|
* whether the test shall pass when the given
|
||||||
|
* operand is zero or non-zero.
|
||||||
|
*/
|
||||||
|
DxbcZeroTest zeroTest() const {
|
||||||
|
return static_cast<DxbcZeroTest>(
|
||||||
|
bit::extract(m_control, 7, 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Resinfo return type
|
||||||
|
*
|
||||||
|
* Control bits specifically for
|
||||||
|
* the \c resinfo instruction.
|
||||||
|
*/
|
||||||
|
DxbcResinfoType resinfoType() const {
|
||||||
|
return static_cast<DxbcResinfoType>(
|
||||||
|
bit::extract(m_control, 0, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sync flags
|
||||||
|
*
|
||||||
|
* Defines the exact operation of sync
|
||||||
|
* instructions in compute shaders.
|
||||||
|
*/
|
||||||
|
DxbcSyncFlags syncFlags() const {
|
||||||
|
return bit::extract(m_control, 0, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
uint32_t m_control = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief DXBC instruction token
|
* \brief DXBC instruction token
|
||||||
*
|
*
|
||||||
|
@ -432,4 +432,24 @@ namespace dxvk {
|
|||||||
|
|
||||||
using DxbcOperandModifiers = Flags<DxbcOperandModifier>;
|
using DxbcOperandModifiers = Flags<DxbcOperandModifier>;
|
||||||
|
|
||||||
|
enum class DxbcZeroTest : uint32_t {
|
||||||
|
TestZ = 0,
|
||||||
|
TestNz = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class DxbcResinfoType : uint32_t {
|
||||||
|
Float = 0,
|
||||||
|
RcpFloat = 1, // ?
|
||||||
|
Uint = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class DxbcSyncFlag : uint32_t {
|
||||||
|
ThreadsInGroup = 0,
|
||||||
|
ThreadGroupSharedMemory = 1,
|
||||||
|
UavMemoryGroup = 2,
|
||||||
|
UavMemoryGlobal = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
using DxbcSyncFlags = Flags<DxbcSyncFlag>;
|
||||||
|
|
||||||
}
|
}
|
@ -565,6 +565,55 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t SpirvModule::opIAdd(
|
||||||
|
uint32_t resultType,
|
||||||
|
uint32_t a,
|
||||||
|
uint32_t b) {
|
||||||
|
uint32_t resultId = this->allocateId();
|
||||||
|
|
||||||
|
m_code.putIns (spv::OpIAdd, 5);
|
||||||
|
m_code.putWord(resultType);
|
||||||
|
m_code.putWord(resultId);
|
||||||
|
m_code.putWord(a);
|
||||||
|
m_code.putWord(b);
|
||||||
|
return resultId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t SpirvModule::opFAdd(
|
||||||
|
uint32_t resultType,
|
||||||
|
uint32_t a,
|
||||||
|
uint32_t b) {
|
||||||
|
uint32_t resultId = this->allocateId();
|
||||||
|
|
||||||
|
m_code.putIns (spv::OpFAdd, 5);
|
||||||
|
m_code.putWord(resultType);
|
||||||
|
m_code.putWord(resultId);
|
||||||
|
m_code.putWord(a);
|
||||||
|
m_code.putWord(b);
|
||||||
|
return resultId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t SpirvModule::opFClamp(
|
||||||
|
uint32_t resultType,
|
||||||
|
uint32_t x,
|
||||||
|
uint32_t minVal,
|
||||||
|
uint32_t maxVal) {
|
||||||
|
uint32_t resultId = this->allocateId();
|
||||||
|
|
||||||
|
m_code.putIns (spv::OpExtInst, 8);
|
||||||
|
m_code.putWord(resultType);
|
||||||
|
m_code.putWord(resultId);
|
||||||
|
m_code.putWord(m_instExtGlsl450);
|
||||||
|
m_code.putWord(spv::GLSLstd450FClamp);
|
||||||
|
m_code.putWord(x);
|
||||||
|
m_code.putWord(minVal);
|
||||||
|
m_code.putWord(maxVal);
|
||||||
|
return resultId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t SpirvModule::opFunctionCall(
|
uint32_t SpirvModule::opFunctionCall(
|
||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t functionId,
|
uint32_t functionId,
|
||||||
|
@ -201,6 +201,22 @@ namespace dxvk {
|
|||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t operand);
|
uint32_t operand);
|
||||||
|
|
||||||
|
uint32_t opIAdd(
|
||||||
|
uint32_t resultType,
|
||||||
|
uint32_t a,
|
||||||
|
uint32_t b);
|
||||||
|
|
||||||
|
uint32_t opFAdd(
|
||||||
|
uint32_t resultType,
|
||||||
|
uint32_t a,
|
||||||
|
uint32_t b);
|
||||||
|
|
||||||
|
uint32_t opFClamp(
|
||||||
|
uint32_t resultType,
|
||||||
|
uint32_t x,
|
||||||
|
uint32_t minVal,
|
||||||
|
uint32_t maxVal);
|
||||||
|
|
||||||
uint32_t opFunctionCall(
|
uint32_t opFunctionCall(
|
||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t functionId,
|
uint32_t functionId,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user