[dxbc] Unify constants

Identical constants will now be reused. Considerably reduces code size.
This commit is contained in:
Philip Rebohle 2018-04-02 19:41:22 +02:00
parent 097eb89cfb
commit 4b44d3ce39
2 changed files with 106 additions and 103 deletions

View File

@ -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";

View File

@ -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(