mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-14 04:29:15 +01:00
[dxbc] Implemented bfi and bfe instructions
This commit is contained in:
parent
1373fe5fcc
commit
f93745adcf
@ -72,6 +72,12 @@ namespace dxvk {
|
||||
case DxbcInstClass::Barrier:
|
||||
return this->emitBarrier(ins);
|
||||
|
||||
case DxbcInstClass::BitExtract:
|
||||
return this->emitBitExtract(ins);
|
||||
|
||||
case DxbcInstClass::BitInsert:
|
||||
return this->emitBitInsert(ins);
|
||||
|
||||
case DxbcInstClass::BufferQuery:
|
||||
return this->emitBufferQuery(ins);
|
||||
|
||||
@ -996,6 +1002,13 @@ namespace dxvk {
|
||||
src.at(0).id, src.at(1).id);
|
||||
break;
|
||||
|
||||
case DxbcOpcode::Rcp: {
|
||||
const std::array<float, 4> ones = {{ 1.0f, 1.0f, 1.0f, 1.0f }};
|
||||
dst.id = m_module.opFDiv(typeId,
|
||||
emitBuildConstVecf32(ones.data(), ins.dst[0].mask).id,
|
||||
src.at(0).id);
|
||||
} break;
|
||||
|
||||
case DxbcOpcode::RoundNe:
|
||||
dst.id = m_module.opRoundEven(
|
||||
typeId, src.at(0).id);
|
||||
@ -1591,6 +1604,53 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::emitBitExtract(const DxbcShaderInstruction& ins) {
|
||||
// ibfe and ubfe take the following arguments:
|
||||
// (dst0) The destination register
|
||||
// (src0) Number of bits to extact
|
||||
// (src1) Offset of the bits to extract
|
||||
// (src2) Register to extract bits from
|
||||
const bool isSigned = ins.op == DxbcOpcode::IBfe;
|
||||
|
||||
const DxbcRegisterValue bitCnt = emitRegisterLoad(ins.src[0], ins.dst[0].mask);
|
||||
const DxbcRegisterValue bitOfs = emitRegisterLoad(ins.src[1], ins.dst[0].mask);
|
||||
|
||||
const DxbcRegisterValue src = emitRegisterLoad(ins.src[2], ins.dst[0].mask);
|
||||
const uint32_t typeId = getVectorTypeId(src.type);
|
||||
|
||||
DxbcRegisterValue result;
|
||||
result.type = src.type;
|
||||
result.id = isSigned
|
||||
? m_module.opBitFieldSExtract(typeId, result.id, bitOfs.id, bitCnt.id)
|
||||
: m_module.opBitFieldUExtract(typeId, result.id, bitOfs.id, bitCnt.id);
|
||||
|
||||
emitRegisterStore(ins.dst[0], result);
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::emitBitInsert(const DxbcShaderInstruction& ins) {
|
||||
// ibfe and ubfe take the following arguments:
|
||||
// (dst0) The destination register
|
||||
// (src0) Number of bits to extact
|
||||
// (src1) Offset of the bits to extract
|
||||
// (src2) Register to take bits from
|
||||
// (src3) Register to replace bits in
|
||||
const DxbcRegisterValue bitCnt = emitRegisterLoad(ins.src[0], ins.dst[0].mask);
|
||||
const DxbcRegisterValue bitOfs = emitRegisterLoad(ins.src[1], ins.dst[0].mask);
|
||||
|
||||
const DxbcRegisterValue insert = emitRegisterLoad(ins.src[2], ins.dst[0].mask);
|
||||
const DxbcRegisterValue base = emitRegisterLoad(ins.src[3], ins.dst[0].mask);
|
||||
|
||||
DxbcRegisterValue result;
|
||||
result.type = base.type;
|
||||
result.id = m_module.opBitFieldInsert(
|
||||
getVectorTypeId(result.type),
|
||||
base.id, insert.id, bitOfs.id, bitCnt.id);
|
||||
|
||||
emitRegisterStore(ins.dst[0], result);
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::emitBufferQuery(const DxbcShaderInstruction& ins) {
|
||||
// bufinfo takes two arguments
|
||||
// (dst0) The destination register
|
||||
@ -2307,6 +2367,29 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
DxbcRegisterValue DxbcCompiler::emitBuildConstVecf32(
|
||||
const float values[4],
|
||||
const DxbcRegMask& writeMask) {
|
||||
std::array<uint32_t, 4> ids = { 0, 0, 0, 0 };
|
||||
uint32_t componentIndex = 0;
|
||||
|
||||
for (uint32_t i = 0; i < 4; i++) {
|
||||
if (writeMask[i])
|
||||
ids[componentIndex++] = m_module.constf32(values[i]);
|
||||
}
|
||||
|
||||
DxbcRegisterValue result;
|
||||
result.type.ctype = DxbcScalarType::Float32;
|
||||
result.type.ccount = componentIndex;
|
||||
result.id = componentIndex > 1
|
||||
? m_module.constComposite(
|
||||
getVectorTypeId(result.type),
|
||||
componentIndex, ids.data())
|
||||
: ids[0];
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
DxbcRegisterValue DxbcCompiler::emitRegisterBitcast(
|
||||
DxbcRegisterValue srcValue,
|
||||
DxbcScalarType dstType) {
|
||||
|
@ -395,6 +395,12 @@ namespace dxvk {
|
||||
void emitBarrier(
|
||||
const DxbcShaderInstruction& ins);
|
||||
|
||||
void emitBitExtract(
|
||||
const DxbcShaderInstruction& ins);
|
||||
|
||||
void emitBitInsert(
|
||||
const DxbcShaderInstruction& ins);
|
||||
|
||||
void emitBufferQuery(
|
||||
const DxbcShaderInstruction& ins);
|
||||
|
||||
@ -445,6 +451,14 @@ namespace dxvk {
|
||||
void emitControlFlow(
|
||||
const DxbcShaderInstruction& ins);
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Constant building methods. These are used to
|
||||
// generate constant vectors that store the same
|
||||
// value in each component.
|
||||
DxbcRegisterValue emitBuildConstVecf32(
|
||||
const float values[4],
|
||||
const DxbcRegMask& writeMask);
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Generic register manipulation methods
|
||||
DxbcRegisterValue emitRegisterBitcast(
|
||||
|
@ -581,7 +581,10 @@ namespace dxvk {
|
||||
/* Gather4PoC */
|
||||
{ },
|
||||
/* Rcp */
|
||||
{ },
|
||||
{ 2, DxbcInstClass::VectorAlu, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||
} },
|
||||
/* F32toF16 */
|
||||
{ },
|
||||
/* F16toF32 */
|
||||
@ -599,11 +602,27 @@ namespace dxvk {
|
||||
/* FirstBitShi */
|
||||
{ },
|
||||
/* UBfe */
|
||||
{ },
|
||||
{ 4, DxbcInstClass::BitExtract, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
} },
|
||||
/* IBfe */
|
||||
{ },
|
||||
{ 4, DxbcInstClass::BitExtract, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Sint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 },
|
||||
} },
|
||||
/* Bfi */
|
||||
{ },
|
||||
{ 5, DxbcInstClass::BitInsert, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
} },
|
||||
/* BfRev */
|
||||
{ },
|
||||
/* Swapc */
|
||||
|
@ -34,6 +34,8 @@ namespace dxvk {
|
||||
GeometryEmit, ///< Special geometry shader instructions
|
||||
Atomic, ///< Atomic operations
|
||||
Barrier, ///< Execution or memory barrier
|
||||
BitExtract, ///< Bit field extract operations
|
||||
BitInsert, ///< Bit field insert operations
|
||||
BufferQuery, ///< Buffer query instruction
|
||||
BufferLoad, ///< Structured or raw buffer load
|
||||
BufferStore, ///< Structured or raw buffer store
|
||||
|
@ -604,6 +604,59 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opBitFieldInsert(
|
||||
uint32_t resultType,
|
||||
uint32_t base,
|
||||
uint32_t insert,
|
||||
uint32_t offset,
|
||||
uint32_t count) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpBitFieldInsert, 7);
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(base);
|
||||
m_code.putWord(insert);
|
||||
m_code.putWord(offset);
|
||||
m_code.putWord(count);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opBitFieldSExtract(
|
||||
uint32_t resultType,
|
||||
uint32_t base,
|
||||
uint32_t offset,
|
||||
uint32_t count) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpBitFieldSExtract, 6);
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(base);
|
||||
m_code.putWord(offset);
|
||||
m_code.putWord(count);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opBitFieldUExtract(
|
||||
uint32_t resultType,
|
||||
uint32_t base,
|
||||
uint32_t offset,
|
||||
uint32_t count) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpBitFieldUExtract, 6);
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(base);
|
||||
m_code.putWord(offset);
|
||||
m_code.putWord(count);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opBitwiseAnd(
|
||||
uint32_t resultType,
|
||||
uint32_t operand1,
|
||||
|
@ -237,6 +237,25 @@ namespace dxvk {
|
||||
uint32_t resultType,
|
||||
uint32_t operand);
|
||||
|
||||
uint32_t opBitFieldInsert(
|
||||
uint32_t resultType,
|
||||
uint32_t base,
|
||||
uint32_t insert,
|
||||
uint32_t offset,
|
||||
uint32_t count);
|
||||
|
||||
uint32_t opBitFieldSExtract(
|
||||
uint32_t resultType,
|
||||
uint32_t base,
|
||||
uint32_t offset,
|
||||
uint32_t count);
|
||||
|
||||
uint32_t opBitFieldUExtract(
|
||||
uint32_t resultType,
|
||||
uint32_t base,
|
||||
uint32_t offset,
|
||||
uint32_t count);
|
||||
|
||||
uint32_t opBitwiseAnd(
|
||||
uint32_t resultType,
|
||||
uint32_t operand1,
|
||||
|
@ -47,7 +47,8 @@ int WINAPI WinMain(HINSTANCE hInstance,
|
||||
"Shader", nullptr, nullptr,
|
||||
str::fromws(entryPoint).c_str(),
|
||||
str::fromws(target).c_str(),
|
||||
0, 0, &binary, &errors);
|
||||
D3DCOMPILE_OPTIMIZATION_LEVEL3,
|
||||
0, &binary, &errors);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
if (errors != nullptr)
|
||||
|
Loading…
x
Reference in New Issue
Block a user