Implementing shader constant register map construction.

This commit is contained in:
Ben Vanik 2016-02-17 23:47:11 -08:00
parent 05107d2d3e
commit 5ab0af9e6d
3 changed files with 47 additions and 2 deletions

View File

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

View File

@ -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]);

View File

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