mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-18 02:52:10 +01:00
[dxbc] Unify constants
Identical constants will now be reused. Considerably reduces code size.
This commit is contained in:
parent
097eb89cfb
commit
4b44d3ce39
@ -1,3 +1,5 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "spirv_module.h"
|
||||
|
||||
namespace dxvk {
|
||||
@ -136,91 +138,89 @@ namespace dxvk {
|
||||
|
||||
uint32_t SpirvModule::constBool(
|
||||
bool v) {
|
||||
uint32_t typeId = this->defBoolType();
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_typeConstDefs.putIns (v ? spv::OpConstantTrue : spv::OpConstantFalse, 3);
|
||||
m_typeConstDefs.putWord (typeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
return resultId;
|
||||
return this->defConst(v
|
||||
? spv::OpConstantTrue
|
||||
: spv::OpConstantFalse,
|
||||
this->defBoolType(),
|
||||
0, nullptr);
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::consti32(
|
||||
int32_t v) {
|
||||
uint32_t typeId = this->defIntType(32, 1);
|
||||
uint32_t resultId = this->allocateId();
|
||||
std::array<uint32_t, 1> data;
|
||||
std::memcpy(data.data(), &v, sizeof(v));
|
||||
|
||||
m_typeConstDefs.putIns (spv::OpConstant, 4);
|
||||
m_typeConstDefs.putWord (typeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
m_typeConstDefs.putInt32(v);
|
||||
return resultId;
|
||||
return this->defConst(
|
||||
spv::OpConstant,
|
||||
this->defIntType(32, 1),
|
||||
data.size(),
|
||||
data.data());
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::consti64(
|
||||
int64_t v) {
|
||||
uint32_t typeId = this->defIntType(64, 1);
|
||||
uint32_t resultId = this->allocateId();
|
||||
std::array<uint32_t, 2> data;
|
||||
std::memcpy(data.data(), &v, sizeof(v));
|
||||
|
||||
m_typeConstDefs.putIns (spv::OpConstant, 5);
|
||||
m_typeConstDefs.putWord (typeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
m_typeConstDefs.putInt64(v);
|
||||
return resultId;
|
||||
return this->defConst(
|
||||
spv::OpConstant,
|
||||
this->defIntType(64, 1),
|
||||
data.size(),
|
||||
data.data());
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::constu32(
|
||||
uint32_t v) {
|
||||
uint32_t typeId = this->defIntType(32, 0);
|
||||
uint32_t resultId = this->allocateId();
|
||||
std::array<uint32_t, 1> data;
|
||||
std::memcpy(data.data(), &v, sizeof(v));
|
||||
|
||||
m_typeConstDefs.putIns (spv::OpConstant, 4);
|
||||
m_typeConstDefs.putWord (typeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
m_typeConstDefs.putInt32(v);
|
||||
return resultId;
|
||||
return this->defConst(
|
||||
spv::OpConstant,
|
||||
this->defIntType(32, 0),
|
||||
data.size(),
|
||||
data.data());
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::constu64(
|
||||
uint64_t v) {
|
||||
uint32_t typeId = this->defIntType(64, 0);
|
||||
uint32_t resultId = this->allocateId();
|
||||
std::array<uint32_t, 2> data;
|
||||
std::memcpy(data.data(), &v, sizeof(v));
|
||||
|
||||
m_typeConstDefs.putIns (spv::OpConstant, 5);
|
||||
m_typeConstDefs.putWord (typeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
m_typeConstDefs.putInt64(v);
|
||||
return resultId;
|
||||
return this->defConst(
|
||||
spv::OpConstant,
|
||||
this->defIntType(64, 0),
|
||||
data.size(),
|
||||
data.data());
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::constf32(
|
||||
float v) {
|
||||
uint32_t typeId = this->defFloatType(32);
|
||||
uint32_t resultId = this->allocateId();
|
||||
std::array<uint32_t, 1> data;
|
||||
std::memcpy(data.data(), &v, sizeof(v));
|
||||
|
||||
m_typeConstDefs.putIns (spv::OpConstant, 4);
|
||||
m_typeConstDefs.putWord (typeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
m_typeConstDefs.putFloat32(v);
|
||||
return resultId;
|
||||
return this->defConst(
|
||||
spv::OpConstant,
|
||||
this->defFloatType(32),
|
||||
data.size(),
|
||||
data.data());
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::constf64(
|
||||
double v) {
|
||||
uint32_t typeId = this->defFloatType(64);
|
||||
uint32_t resultId = this->allocateId();
|
||||
std::array<uint32_t, 2> data;
|
||||
std::memcpy(data.data(), &v, sizeof(v));
|
||||
|
||||
m_typeConstDefs.putIns (spv::OpConstant, 5);
|
||||
m_typeConstDefs.putWord (typeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
m_typeConstDefs.putFloat64(v);
|
||||
return resultId;
|
||||
return this->defConst(
|
||||
spv::OpConstant,
|
||||
this->defFloatType(64),
|
||||
data.size(),
|
||||
data.data());
|
||||
}
|
||||
|
||||
|
||||
@ -229,24 +229,15 @@ namespace dxvk {
|
||||
int32_t y,
|
||||
int32_t z,
|
||||
int32_t w) {
|
||||
std::array<uint32_t, 4> args = {{
|
||||
this->consti32(x), this->consti32(y),
|
||||
this->consti32(z), this->consti32(w),
|
||||
}};
|
||||
|
||||
uint32_t scalarTypeId = this->defIntType(32, 1);
|
||||
uint32_t vectorTypeId = this->defVectorType(scalarTypeId, 4);
|
||||
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
uint32_t xConst = this->consti32(x);
|
||||
uint32_t yConst = this->consti32(y);
|
||||
uint32_t zConst = this->consti32(z);
|
||||
uint32_t wConst = this->consti32(w);
|
||||
|
||||
m_typeConstDefs.putIns (spv::OpConstantComposite, 7);
|
||||
m_typeConstDefs.putWord (vectorTypeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
m_typeConstDefs.putWord (xConst);
|
||||
m_typeConstDefs.putWord (yConst);
|
||||
m_typeConstDefs.putWord (zConst);
|
||||
m_typeConstDefs.putWord (wConst);
|
||||
return resultId;
|
||||
return this->constComposite(vectorTypeId, args.size(), args.data());
|
||||
}
|
||||
|
||||
|
||||
@ -255,24 +246,15 @@ namespace dxvk {
|
||||
uint32_t y,
|
||||
uint32_t z,
|
||||
uint32_t w) {
|
||||
std::array<uint32_t, 4> args = {{
|
||||
this->constu32(x), this->constu32(y),
|
||||
this->constu32(z), this->constu32(w),
|
||||
}};
|
||||
|
||||
uint32_t scalarTypeId = this->defIntType(32, 0);
|
||||
uint32_t vectorTypeId = this->defVectorType(scalarTypeId, 4);
|
||||
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
uint32_t xConst = this->constu32(x);
|
||||
uint32_t yConst = this->constu32(y);
|
||||
uint32_t zConst = this->constu32(z);
|
||||
uint32_t wConst = this->constu32(w);
|
||||
|
||||
m_typeConstDefs.putIns (spv::OpConstantComposite, 7);
|
||||
m_typeConstDefs.putWord (vectorTypeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
m_typeConstDefs.putWord (xConst);
|
||||
m_typeConstDefs.putWord (yConst);
|
||||
m_typeConstDefs.putWord (zConst);
|
||||
m_typeConstDefs.putWord (wConst);
|
||||
return resultId;
|
||||
return this->constComposite(vectorTypeId, args.size(), args.data());
|
||||
}
|
||||
|
||||
|
||||
@ -281,24 +263,15 @@ namespace dxvk {
|
||||
float y,
|
||||
float z,
|
||||
float w) {
|
||||
std::array<uint32_t, 4> args = {{
|
||||
this->constf32(x), this->constf32(y),
|
||||
this->constf32(z), this->constf32(w),
|
||||
}};
|
||||
|
||||
uint32_t scalarTypeId = this->defFloatType(32);
|
||||
uint32_t vectorTypeId = this->defVectorType(scalarTypeId, 4);
|
||||
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
uint32_t xConst = this->constf32(x);
|
||||
uint32_t yConst = this->constf32(y);
|
||||
uint32_t zConst = this->constf32(z);
|
||||
uint32_t wConst = this->constf32(w);
|
||||
|
||||
m_typeConstDefs.putIns (spv::OpConstantComposite, 7);
|
||||
m_typeConstDefs.putWord (vectorTypeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
m_typeConstDefs.putWord (xConst);
|
||||
m_typeConstDefs.putWord (yConst);
|
||||
m_typeConstDefs.putWord (zConst);
|
||||
m_typeConstDefs.putWord (wConst);
|
||||
return resultId;
|
||||
return this->constComposite(vectorTypeId, args.size(), args.data());
|
||||
}
|
||||
|
||||
|
||||
@ -306,15 +279,9 @@ namespace dxvk {
|
||||
uint32_t typeId,
|
||||
uint32_t constCount,
|
||||
const uint32_t* constIds) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_typeConstDefs.putIns (spv::OpConstantComposite, 3 + constCount);
|
||||
m_typeConstDefs.putWord (typeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
|
||||
for (uint32_t i = 0; i < constCount; i++)
|
||||
m_typeConstDefs.putWord(constIds[i]);
|
||||
return resultId;
|
||||
return this->defConst(
|
||||
spv::OpConstantComposite,
|
||||
typeId, constCount, constIds);
|
||||
}
|
||||
|
||||
|
||||
@ -2929,6 +2896,36 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::defConst(
|
||||
spv::Op op,
|
||||
uint32_t typeId,
|
||||
uint32_t argCount,
|
||||
const uint32_t* argIds) {
|
||||
// Avoid declaring constants multiple times
|
||||
for (auto ins : m_typeConstDefs) {
|
||||
bool match = ins.opCode() == op
|
||||
&& ins.length() == 3 + argCount
|
||||
&& ins.arg(1) == typeId;
|
||||
|
||||
for (uint32_t i = 0; i < argCount && match; i++)
|
||||
match &= ins.arg(3 + i) == argIds[i];
|
||||
|
||||
if (match)
|
||||
return ins.arg(2);
|
||||
}
|
||||
|
||||
// Constant not yet declared, make a new one
|
||||
uint32_t resultId = this->allocateId();
|
||||
m_typeConstDefs.putIns (op, 3 + argCount);
|
||||
m_typeConstDefs.putWord(typeId);
|
||||
m_typeConstDefs.putWord(resultId);
|
||||
|
||||
for (uint32_t i = 0; i < argCount; i++)
|
||||
m_typeConstDefs.putWord(argIds[i]);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
void SpirvModule::instImportGlsl450() {
|
||||
m_instExtGlsl450 = this->allocateId();
|
||||
const char* name = "GLSL.std.450";
|
||||
|
@ -1022,6 +1022,12 @@ namespace dxvk {
|
||||
uint32_t argCount,
|
||||
const uint32_t* argIds);
|
||||
|
||||
uint32_t defConst(
|
||||
spv::Op op,
|
||||
uint32_t typeId,
|
||||
uint32_t argCount,
|
||||
const uint32_t* argIds);
|
||||
|
||||
void instImportGlsl450();
|
||||
|
||||
uint32_t getImageOperandWordCount(
|
||||
|
Loading…
x
Reference in New Issue
Block a user