1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-06 13:54:14 +01:00

[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" #include "spirv_module.h"
namespace dxvk { namespace dxvk {
@ -136,91 +138,89 @@ namespace dxvk {
uint32_t SpirvModule::constBool( uint32_t SpirvModule::constBool(
bool v) { bool v) {
uint32_t typeId = this->defBoolType(); return this->defConst(v
uint32_t resultId = this->allocateId(); ? spv::OpConstantTrue
: spv::OpConstantFalse,
m_typeConstDefs.putIns (v ? spv::OpConstantTrue : spv::OpConstantFalse, 3); this->defBoolType(),
m_typeConstDefs.putWord (typeId); 0, nullptr);
m_typeConstDefs.putWord (resultId);
return resultId;
} }
uint32_t SpirvModule::consti32( uint32_t SpirvModule::consti32(
int32_t v) { int32_t v) {
uint32_t typeId = this->defIntType(32, 1); std::array<uint32_t, 1> data;
uint32_t resultId = this->allocateId(); std::memcpy(data.data(), &v, sizeof(v));
m_typeConstDefs.putIns (spv::OpConstant, 4); return this->defConst(
m_typeConstDefs.putWord (typeId); spv::OpConstant,
m_typeConstDefs.putWord (resultId); this->defIntType(32, 1),
m_typeConstDefs.putInt32(v); data.size(),
return resultId; data.data());
} }
uint32_t SpirvModule::consti64( uint32_t SpirvModule::consti64(
int64_t v) { int64_t v) {
uint32_t typeId = this->defIntType(64, 1); std::array<uint32_t, 2> data;
uint32_t resultId = this->allocateId(); std::memcpy(data.data(), &v, sizeof(v));
m_typeConstDefs.putIns (spv::OpConstant, 5); return this->defConst(
m_typeConstDefs.putWord (typeId); spv::OpConstant,
m_typeConstDefs.putWord (resultId); this->defIntType(64, 1),
m_typeConstDefs.putInt64(v); data.size(),
return resultId; data.data());
} }
uint32_t SpirvModule::constu32( uint32_t SpirvModule::constu32(
uint32_t v) { uint32_t v) {
uint32_t typeId = this->defIntType(32, 0); std::array<uint32_t, 1> data;
uint32_t resultId = this->allocateId(); std::memcpy(data.data(), &v, sizeof(v));
m_typeConstDefs.putIns (spv::OpConstant, 4); return this->defConst(
m_typeConstDefs.putWord (typeId); spv::OpConstant,
m_typeConstDefs.putWord (resultId); this->defIntType(32, 0),
m_typeConstDefs.putInt32(v); data.size(),
return resultId; data.data());
} }
uint32_t SpirvModule::constu64( uint32_t SpirvModule::constu64(
uint64_t v) { uint64_t v) {
uint32_t typeId = this->defIntType(64, 0); std::array<uint32_t, 2> data;
uint32_t resultId = this->allocateId(); std::memcpy(data.data(), &v, sizeof(v));
m_typeConstDefs.putIns (spv::OpConstant, 5); return this->defConst(
m_typeConstDefs.putWord (typeId); spv::OpConstant,
m_typeConstDefs.putWord (resultId); this->defIntType(64, 0),
m_typeConstDefs.putInt64(v); data.size(),
return resultId; data.data());
} }
uint32_t SpirvModule::constf32( uint32_t SpirvModule::constf32(
float v) { float v) {
uint32_t typeId = this->defFloatType(32); std::array<uint32_t, 1> data;
uint32_t resultId = this->allocateId(); std::memcpy(data.data(), &v, sizeof(v));
m_typeConstDefs.putIns (spv::OpConstant, 4); return this->defConst(
m_typeConstDefs.putWord (typeId); spv::OpConstant,
m_typeConstDefs.putWord (resultId); this->defFloatType(32),
m_typeConstDefs.putFloat32(v); data.size(),
return resultId; data.data());
} }
uint32_t SpirvModule::constf64( uint32_t SpirvModule::constf64(
double v) { double v) {
uint32_t typeId = this->defFloatType(64); std::array<uint32_t, 2> data;
uint32_t resultId = this->allocateId(); std::memcpy(data.data(), &v, sizeof(v));
m_typeConstDefs.putIns (spv::OpConstant, 5); return this->defConst(
m_typeConstDefs.putWord (typeId); spv::OpConstant,
m_typeConstDefs.putWord (resultId); this->defFloatType(64),
m_typeConstDefs.putFloat64(v); data.size(),
return resultId; data.data());
} }
@ -229,24 +229,15 @@ namespace dxvk {
int32_t y, int32_t y,
int32_t z, int32_t z,
int32_t w) { 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 scalarTypeId = this->defIntType(32, 1);
uint32_t vectorTypeId = this->defVectorType(scalarTypeId, 4); uint32_t vectorTypeId = this->defVectorType(scalarTypeId, 4);
uint32_t resultId = this->allocateId(); return this->constComposite(vectorTypeId, args.size(), args.data());
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;
} }
@ -255,24 +246,15 @@ namespace dxvk {
uint32_t y, uint32_t y,
uint32_t z, uint32_t z,
uint32_t w) { 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 scalarTypeId = this->defIntType(32, 0);
uint32_t vectorTypeId = this->defVectorType(scalarTypeId, 4); uint32_t vectorTypeId = this->defVectorType(scalarTypeId, 4);
uint32_t resultId = this->allocateId(); return this->constComposite(vectorTypeId, args.size(), args.data());
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;
} }
@ -281,24 +263,15 @@ namespace dxvk {
float y, float y,
float z, float z,
float w) { 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 scalarTypeId = this->defFloatType(32);
uint32_t vectorTypeId = this->defVectorType(scalarTypeId, 4); uint32_t vectorTypeId = this->defVectorType(scalarTypeId, 4);
uint32_t resultId = this->allocateId(); return this->constComposite(vectorTypeId, args.size(), args.data());
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;
} }
@ -306,15 +279,9 @@ namespace dxvk {
uint32_t typeId, uint32_t typeId,
uint32_t constCount, uint32_t constCount,
const uint32_t* constIds) { const uint32_t* constIds) {
uint32_t resultId = this->allocateId(); return this->defConst(
spv::OpConstantComposite,
m_typeConstDefs.putIns (spv::OpConstantComposite, 3 + constCount); typeId, constCount, constIds);
m_typeConstDefs.putWord (typeId);
m_typeConstDefs.putWord (resultId);
for (uint32_t i = 0; i < constCount; i++)
m_typeConstDefs.putWord(constIds[i]);
return resultId;
} }
@ -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() { void SpirvModule::instImportGlsl450() {
m_instExtGlsl450 = this->allocateId(); m_instExtGlsl450 = this->allocateId();
const char* name = "GLSL.std.450"; const char* name = "GLSL.std.450";

View File

@ -1022,6 +1022,12 @@ namespace dxvk {
uint32_t argCount, uint32_t argCount,
const uint32_t* argIds); const uint32_t* argIds);
uint32_t defConst(
spv::Op op,
uint32_t typeId,
uint32_t argCount,
const uint32_t* argIds);
void instImportGlsl450(); void instImportGlsl450();
uint32_t getImageOperandWordCount( uint32_t getImageOperandWordCount(