[spirv] Add 'late' constants

Late constants can be used to reserve a placeholder ID for a constant
before the constant's value is known. The value can be changed later.
Only scalar 32-bit integer and floating point types are supported
as of right now.
This commit is contained in:
Philip Rebohle 2019-10-02 15:08:25 +02:00
parent 59d4556641
commit df61a479a2
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 50 additions and 2 deletions

View File

@ -361,6 +361,38 @@ namespace dxvk {
}
uint32_t SpirvModule::lateConst32(
uint32_t typeId) {
uint32_t resultId = this->allocateId();
m_lateConsts.insert(resultId);
m_typeConstDefs.putIns (spv::OpConstant, 4);
m_typeConstDefs.putWord(typeId);
m_typeConstDefs.putWord(resultId);
m_typeConstDefs.putWord(0);
return resultId;
}
void SpirvModule::setLateConst(
uint32_t constId,
const uint32_t* argIds) {
for (auto ins : m_typeConstDefs) {
if (ins.opCode() != spv::OpConstant
&& ins.opCode() != spv::OpConstantComposite)
continue;
if (ins.arg(2) != constId)
continue;
for (uint32_t i = 3; i < ins.length(); i++)
ins.setArg(i, argIds[i - 3]);
return;
}
}
uint32_t SpirvModule::specConstBool(
bool v) {
uint32_t typeId = this->defBoolType();
@ -3371,8 +3403,13 @@ namespace dxvk {
for (uint32_t i = 0; i < argCount && match; i++)
match &= ins.arg(3 + i) == argIds[i];
if (match)
return ins.arg(2);
if (!match)
continue;
uint32_t id = ins.arg(2);
if (m_lateConsts.find(id) == m_lateConsts.end())
return id;
}
// Constant not yet declared, make a new one

View File

@ -1,5 +1,7 @@
#pragma once
#include <unordered_set>
#include "spirv_code_buffer.h"
namespace dxvk {
@ -167,6 +169,13 @@ namespace dxvk {
uint32_t constUndef(
uint32_t typeId);
uint32_t lateConst32(
uint32_t typeId);
void setLateConst(
uint32_t constId,
const uint32_t* argIds);
uint32_t specConstBool(
bool v);
@ -1166,6 +1175,8 @@ namespace dxvk {
SpirvCodeBuffer m_typeConstDefs;
SpirvCodeBuffer m_variables;
SpirvCodeBuffer m_code;
std::unordered_set<uint32_t> m_lateConsts;
uint32_t defType(
spv::Op op,