Implementing shader constant register map construction.
This commit is contained in:
parent
05107d2d3e
commit
5ab0af9e6d
|
@ -493,6 +493,21 @@ class Shader {
|
||||||
ParsedTextureFetchInstruction fetch_instr;
|
ParsedTextureFetchInstruction fetch_instr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ConstantRegisterMap {
|
||||||
|
// Bitmap of all kConstantFloat registers read by the shader.
|
||||||
|
// Any shader can only read up to 256 of the 512, and the base is dependent
|
||||||
|
// on the shader type. Each bit corresponds to a storage index from the type
|
||||||
|
// base, so bit 0 in a vertex shader is register 0, and bit 0 in a fragment
|
||||||
|
// shader is register 256.
|
||||||
|
uint64_t float_bitmap[256 / 64];
|
||||||
|
// Bitmap of all kConstantInt registers read by the shader.
|
||||||
|
// Each bit corresponds to a storage index [0-31].
|
||||||
|
uint32_t int_bitmap;
|
||||||
|
// Bitmap of all kConstantBool registers read by the shader.
|
||||||
|
// Each bit corresponds to a storage index [0-31].
|
||||||
|
uint32_t bool_bitmap;
|
||||||
|
};
|
||||||
|
|
||||||
Shader(ShaderType shader_type, uint64_t ucode_data_hash,
|
Shader(ShaderType shader_type, uint64_t ucode_data_hash,
|
||||||
const uint32_t* ucode_dwords, size_t ucode_dword_count);
|
const uint32_t* ucode_dwords, size_t ucode_dword_count);
|
||||||
virtual ~Shader();
|
virtual ~Shader();
|
||||||
|
@ -518,6 +533,11 @@ class Shader {
|
||||||
return texture_bindings_;
|
return texture_bindings_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bitmaps of all constant registers accessed by the shader.
|
||||||
|
const ConstantRegisterMap& constant_register_map() const {
|
||||||
|
return constant_register_map_;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns true if the given color target index [0-3].
|
// Returns true if the given color target index [0-3].
|
||||||
bool writes_color_target(int i) const { return writes_color_targets_[i]; }
|
bool writes_color_target(int i) const { return writes_color_targets_[i]; }
|
||||||
|
|
||||||
|
@ -564,6 +584,7 @@ class Shader {
|
||||||
|
|
||||||
std::vector<VertexBinding> vertex_bindings_;
|
std::vector<VertexBinding> vertex_bindings_;
|
||||||
std::vector<TextureBinding> texture_bindings_;
|
std::vector<TextureBinding> texture_bindings_;
|
||||||
|
ConstantRegisterMap constant_register_map_ = {0};
|
||||||
bool writes_color_targets_[4] = {false, false, false, false};
|
bool writes_color_targets_[4] = {false, false, false, false};
|
||||||
|
|
||||||
bool is_valid_ = false;
|
bool is_valid_ = false;
|
||||||
|
|
|
@ -53,13 +53,14 @@ void ShaderTranslator::Reset() {
|
||||||
total_attrib_count_ = 0;
|
total_attrib_count_ = 0;
|
||||||
vertex_bindings_.clear();
|
vertex_bindings_.clear();
|
||||||
texture_bindings_.clear();
|
texture_bindings_.clear();
|
||||||
|
std::memset(&constant_register_map_, 0, sizeof(constant_register_map_));
|
||||||
for (size_t i = 0; i < xe::countof(writes_color_targets_); ++i) {
|
for (size_t i = 0; i < xe::countof(writes_color_targets_); ++i) {
|
||||||
writes_color_targets_[i] = false;
|
writes_color_targets_[i] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShaderTranslator::GatherAllBindingInformation(Shader* shader) {
|
bool ShaderTranslator::GatherAllBindingInformation(Shader* shader) {
|
||||||
// FIXME: This is kind of silly.
|
// DEPRECATED: remove this codepath when GL4 goes away.
|
||||||
Reset();
|
Reset();
|
||||||
|
|
||||||
shader_type_ = shader->type();
|
shader_type_ = shader->type();
|
||||||
|
@ -129,6 +130,7 @@ bool ShaderTranslator::Translate(Shader* shader) {
|
||||||
shader->ucode_disassembly_ = ucode_disasm_buffer_.to_string();
|
shader->ucode_disassembly_ = ucode_disasm_buffer_.to_string();
|
||||||
shader->vertex_bindings_ = std::move(vertex_bindings_);
|
shader->vertex_bindings_ = std::move(vertex_bindings_);
|
||||||
shader->texture_bindings_ = std::move(texture_bindings_);
|
shader->texture_bindings_ = std::move(texture_bindings_);
|
||||||
|
shader->constant_register_map_ = std::move(constant_register_map_);
|
||||||
for (size_t i = 0; i < xe::countof(writes_color_targets_); ++i) {
|
for (size_t i = 0; i < xe::countof(writes_color_targets_); ++i) {
|
||||||
shader->writes_color_targets_[i] = writes_color_targets_[i];
|
shader->writes_color_targets_[i] = writes_color_targets_[i];
|
||||||
}
|
}
|
||||||
|
@ -488,6 +490,7 @@ void ShaderTranslator::TranslateControlFlowCondExec(
|
||||||
i.instruction_count = cf.count();
|
i.instruction_count = cf.count();
|
||||||
i.type = ParsedExecInstruction::Type::kConditional;
|
i.type = ParsedExecInstruction::Type::kConditional;
|
||||||
i.bool_constant_index = cf.bool_address();
|
i.bool_constant_index = cf.bool_address();
|
||||||
|
constant_register_map_.bool_bitmap |= 1 << i.bool_constant_index;
|
||||||
i.condition = cf.condition();
|
i.condition = cf.condition();
|
||||||
switch (cf.opcode()) {
|
switch (cf.opcode()) {
|
||||||
case ControlFlowOpcode::kCondExec:
|
case ControlFlowOpcode::kCondExec:
|
||||||
|
@ -527,6 +530,7 @@ void ShaderTranslator::TranslateControlFlowLoopStart(
|
||||||
ParsedLoopStartInstruction i;
|
ParsedLoopStartInstruction i;
|
||||||
i.dword_index = cf_index_;
|
i.dword_index = cf_index_;
|
||||||
i.loop_constant_index = cf.loop_id();
|
i.loop_constant_index = cf.loop_id();
|
||||||
|
constant_register_map_.int_bitmap |= 1 << i.loop_constant_index;
|
||||||
i.is_repeat = cf.is_repeat();
|
i.is_repeat = cf.is_repeat();
|
||||||
i.loop_skip_address = cf.address();
|
i.loop_skip_address = cf.address();
|
||||||
|
|
||||||
|
@ -542,6 +546,7 @@ void ShaderTranslator::TranslateControlFlowLoopEnd(
|
||||||
i.is_predicated_break = cf.is_predicated_break();
|
i.is_predicated_break = cf.is_predicated_break();
|
||||||
i.predicate_condition = cf.condition();
|
i.predicate_condition = cf.condition();
|
||||||
i.loop_constant_index = cf.loop_id();
|
i.loop_constant_index = cf.loop_id();
|
||||||
|
constant_register_map_.int_bitmap |= 1 << i.loop_constant_index;
|
||||||
i.loop_body_address = cf.address();
|
i.loop_body_address = cf.address();
|
||||||
|
|
||||||
i.Disassemble(&ucode_disasm_buffer_);
|
i.Disassemble(&ucode_disasm_buffer_);
|
||||||
|
@ -562,6 +567,7 @@ void ShaderTranslator::TranslateControlFlowCondCall(
|
||||||
} else {
|
} else {
|
||||||
i.type = ParsedCallInstruction::Type::kConditional;
|
i.type = ParsedCallInstruction::Type::kConditional;
|
||||||
i.bool_constant_index = cf.bool_address();
|
i.bool_constant_index = cf.bool_address();
|
||||||
|
constant_register_map_.bool_bitmap |= 1 << i.bool_constant_index;
|
||||||
i.condition = cf.condition();
|
i.condition = cf.condition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,6 +599,7 @@ void ShaderTranslator::TranslateControlFlowCondJmp(
|
||||||
} else {
|
} else {
|
||||||
i.type = ParsedJumpInstruction::Type::kConditional;
|
i.type = ParsedJumpInstruction::Type::kConditional;
|
||||||
i.bool_constant_index = cf.bool_address();
|
i.bool_constant_index = cf.bool_address();
|
||||||
|
constant_register_map_.bool_bitmap |= 1 << i.bool_constant_index;
|
||||||
i.condition = cf.condition();
|
i.condition = cf.condition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1150,6 +1157,14 @@ void ShaderTranslator::ParseAluVectorInstruction(
|
||||||
for (int j = 0; j < i.operand_count; ++j) {
|
for (int j = 0; j < i.operand_count; ++j) {
|
||||||
ParseAluInstructionOperand(
|
ParseAluInstructionOperand(
|
||||||
op, j + 1, opcode_info.src_swizzle_component_count, &i.operands[j]);
|
op, j + 1, opcode_info.src_swizzle_component_count, &i.operands[j]);
|
||||||
|
|
||||||
|
// Track constant float register loads.
|
||||||
|
if (i.operands[j].storage_source ==
|
||||||
|
InstructionStorageSource::kConstantFloat) {
|
||||||
|
auto register_index = i.operands[j].storage_index;
|
||||||
|
constant_register_map_.float_bitmap[register_index / 64] |=
|
||||||
|
1ull << (register_index % 64);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i.Disassemble(&ucode_disasm_buffer_);
|
i.Disassemble(&ucode_disasm_buffer_);
|
||||||
|
@ -1243,9 +1258,16 @@ void ShaderTranslator::ParseAluScalarInstruction(
|
||||||
uint32_t reg2 = (static_cast<int>(op.scalar_opcode()) & 1) |
|
uint32_t reg2 = (static_cast<int>(op.scalar_opcode()) & 1) |
|
||||||
(src3_swizzle & 0x3C) | (op.src_is_temp(3) << 1);
|
(src3_swizzle & 0x3C) | (op.src_is_temp(3) << 1);
|
||||||
int const_slot = (op.src_is_temp(1) || op.src_is_temp(2)) ? 1 : 0;
|
int const_slot = (op.src_is_temp(1) || op.src_is_temp(2)) ? 1 : 0;
|
||||||
|
|
||||||
ParseAluInstructionOperandSpecial(
|
ParseAluInstructionOperandSpecial(
|
||||||
op, InstructionStorageSource::kConstantFloat, op.src_reg(3),
|
op, InstructionStorageSource::kConstantFloat, op.src_reg(3),
|
||||||
op.src_negate(3), 0, swiz_a, &i.operands[0]);
|
op.src_negate(3), 0, swiz_a, &i.operands[0]);
|
||||||
|
|
||||||
|
// Track constant float register loads.
|
||||||
|
auto register_index = i.operands[0].storage_index;
|
||||||
|
constant_register_map_.float_bitmap[register_index / 64] |=
|
||||||
|
1ull << (register_index % 64);
|
||||||
|
|
||||||
ParseAluInstructionOperandSpecial(op, InstructionStorageSource::kRegister,
|
ParseAluInstructionOperandSpecial(op, InstructionStorageSource::kRegister,
|
||||||
reg2, op.src_negate(3), const_slot,
|
reg2, op.src_negate(3), const_slot,
|
||||||
swiz_b, &i.operands[1]);
|
swiz_b, &i.operands[1]);
|
||||||
|
|
|
@ -27,8 +27,9 @@ class ShaderTranslator {
|
||||||
virtual ~ShaderTranslator();
|
virtual ~ShaderTranslator();
|
||||||
|
|
||||||
// Gathers all vertex/texture bindings. Implicitly called in Translate.
|
// Gathers all vertex/texture bindings. Implicitly called in Translate.
|
||||||
// TODO: Move this functionality to Shader.
|
// DEPRECATED(benvanik): remove this when shader cache is removed.
|
||||||
bool GatherAllBindingInformation(Shader* shader);
|
bool GatherAllBindingInformation(Shader* shader);
|
||||||
|
|
||||||
bool Translate(Shader* shader);
|
bool Translate(Shader* shader);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -191,6 +192,7 @@ class ShaderTranslator {
|
||||||
int total_attrib_count_ = 0;
|
int total_attrib_count_ = 0;
|
||||||
std::vector<Shader::VertexBinding> vertex_bindings_;
|
std::vector<Shader::VertexBinding> vertex_bindings_;
|
||||||
std::vector<Shader::TextureBinding> texture_bindings_;
|
std::vector<Shader::TextureBinding> texture_bindings_;
|
||||||
|
Shader::ConstantRegisterMap constant_register_map_ = {0};
|
||||||
bool writes_color_targets_[4] = {false, false, false, false};
|
bool writes_color_targets_[4] = {false, false, false, false};
|
||||||
|
|
||||||
static const AluOpcodeInfo alu_vector_opcode_infos_[0x20];
|
static const AluOpcodeInfo alu_vector_opcode_infos_[0x20];
|
||||||
|
|
Loading…
Reference in New Issue