mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-15 07:29:17 +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:
|
case DxbcInstClass::Barrier:
|
||||||
return this->emitBarrier(ins);
|
return this->emitBarrier(ins);
|
||||||
|
|
||||||
|
case DxbcInstClass::BitExtract:
|
||||||
|
return this->emitBitExtract(ins);
|
||||||
|
|
||||||
|
case DxbcInstClass::BitInsert:
|
||||||
|
return this->emitBitInsert(ins);
|
||||||
|
|
||||||
case DxbcInstClass::BufferQuery:
|
case DxbcInstClass::BufferQuery:
|
||||||
return this->emitBufferQuery(ins);
|
return this->emitBufferQuery(ins);
|
||||||
|
|
||||||
@ -996,6 +1002,13 @@ namespace dxvk {
|
|||||||
src.at(0).id, src.at(1).id);
|
src.at(0).id, src.at(1).id);
|
||||||
break;
|
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:
|
case DxbcOpcode::RoundNe:
|
||||||
dst.id = m_module.opRoundEven(
|
dst.id = m_module.opRoundEven(
|
||||||
typeId, src.at(0).id);
|
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) {
|
void DxbcCompiler::emitBufferQuery(const DxbcShaderInstruction& ins) {
|
||||||
// bufinfo takes two arguments
|
// bufinfo takes two arguments
|
||||||
// (dst0) The destination register
|
// (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 DxbcCompiler::emitRegisterBitcast(
|
||||||
DxbcRegisterValue srcValue,
|
DxbcRegisterValue srcValue,
|
||||||
DxbcScalarType dstType) {
|
DxbcScalarType dstType) {
|
||||||
|
@ -395,6 +395,12 @@ namespace dxvk {
|
|||||||
void emitBarrier(
|
void emitBarrier(
|
||||||
const DxbcShaderInstruction& ins);
|
const DxbcShaderInstruction& ins);
|
||||||
|
|
||||||
|
void emitBitExtract(
|
||||||
|
const DxbcShaderInstruction& ins);
|
||||||
|
|
||||||
|
void emitBitInsert(
|
||||||
|
const DxbcShaderInstruction& ins);
|
||||||
|
|
||||||
void emitBufferQuery(
|
void emitBufferQuery(
|
||||||
const DxbcShaderInstruction& ins);
|
const DxbcShaderInstruction& ins);
|
||||||
|
|
||||||
@ -445,6 +451,14 @@ namespace dxvk {
|
|||||||
void emitControlFlow(
|
void emitControlFlow(
|
||||||
const DxbcShaderInstruction& ins);
|
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
|
// Generic register manipulation methods
|
||||||
DxbcRegisterValue emitRegisterBitcast(
|
DxbcRegisterValue emitRegisterBitcast(
|
||||||
|
@ -581,7 +581,10 @@ namespace dxvk {
|
|||||||
/* Gather4PoC */
|
/* Gather4PoC */
|
||||||
{ },
|
{ },
|
||||||
/* Rcp */
|
/* Rcp */
|
||||||
{ },
|
{ 2, DxbcInstClass::VectorAlu, {
|
||||||
|
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
|
||||||
|
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||||
|
} },
|
||||||
/* F32toF16 */
|
/* F32toF16 */
|
||||||
{ },
|
{ },
|
||||||
/* F16toF32 */
|
/* F16toF32 */
|
||||||
@ -599,11 +602,27 @@ namespace dxvk {
|
|||||||
/* FirstBitShi */
|
/* FirstBitShi */
|
||||||
{ },
|
{ },
|
||||||
/* UBfe */
|
/* UBfe */
|
||||||
{ },
|
{ 4, DxbcInstClass::BitExtract, {
|
||||||
|
{ DxbcOperandKind::DstReg, DxbcScalarType::Uint32 },
|
||||||
|
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||||
|
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||||
|
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||||
|
} },
|
||||||
/* IBfe */
|
/* IBfe */
|
||||||
{ },
|
{ 4, DxbcInstClass::BitExtract, {
|
||||||
|
{ DxbcOperandKind::DstReg, DxbcScalarType::Sint32 },
|
||||||
|
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||||
|
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||||
|
{ DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 },
|
||||||
|
} },
|
||||||
/* Bfi */
|
/* 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 */
|
/* BfRev */
|
||||||
{ },
|
{ },
|
||||||
/* Swapc */
|
/* Swapc */
|
||||||
|
@ -34,6 +34,8 @@ namespace dxvk {
|
|||||||
GeometryEmit, ///< Special geometry shader instructions
|
GeometryEmit, ///< Special geometry shader instructions
|
||||||
Atomic, ///< Atomic operations
|
Atomic, ///< Atomic operations
|
||||||
Barrier, ///< Execution or memory barrier
|
Barrier, ///< Execution or memory barrier
|
||||||
|
BitExtract, ///< Bit field extract operations
|
||||||
|
BitInsert, ///< Bit field insert operations
|
||||||
BufferQuery, ///< Buffer query instruction
|
BufferQuery, ///< Buffer query instruction
|
||||||
BufferLoad, ///< Structured or raw buffer load
|
BufferLoad, ///< Structured or raw buffer load
|
||||||
BufferStore, ///< Structured or raw buffer store
|
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 SpirvModule::opBitwiseAnd(
|
||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t operand1,
|
uint32_t operand1,
|
||||||
|
@ -237,6 +237,25 @@ namespace dxvk {
|
|||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t operand);
|
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 opBitwiseAnd(
|
||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t operand1,
|
uint32_t operand1,
|
||||||
|
@ -47,7 +47,8 @@ int WINAPI WinMain(HINSTANCE hInstance,
|
|||||||
"Shader", nullptr, nullptr,
|
"Shader", nullptr, nullptr,
|
||||||
str::fromws(entryPoint).c_str(),
|
str::fromws(entryPoint).c_str(),
|
||||||
str::fromws(target).c_str(),
|
str::fromws(target).c_str(),
|
||||||
0, 0, &binary, &errors);
|
D3DCOMPILE_OPTIMIZATION_LEVEL3,
|
||||||
|
0, &binary, &errors);
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
if (errors != nullptr)
|
if (errors != nullptr)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user