[GPU] Detect dynamic temp indexing before translating shaders
This commit is contained in:
parent
8c314072c8
commit
dad10c30e9
|
@ -58,6 +58,7 @@ void ShaderTranslator::Reset() {
|
||||||
texture_bindings_.clear();
|
texture_bindings_.clear();
|
||||||
unique_texture_bindings_ = 0;
|
unique_texture_bindings_ = 0;
|
||||||
std::memset(&constant_register_map_, 0, sizeof(constant_register_map_));
|
std::memset(&constant_register_map_, 0, sizeof(constant_register_map_));
|
||||||
|
uses_register_relative_addressing_ = false;
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -85,8 +86,8 @@ bool ShaderTranslator::GatherAllBindingInformation(Shader* shader) {
|
||||||
std::min(max_cf_dword_index, cf_b.exec.address() * 3);
|
std::min(max_cf_dword_index, cf_b.exec.address() * 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
GatherBindingInformation(cf_a);
|
GatherInstructionInformation(cf_a);
|
||||||
GatherBindingInformation(cf_b);
|
GatherInstructionInformation(cf_b);
|
||||||
}
|
}
|
||||||
|
|
||||||
shader->vertex_bindings_ = std::move(vertex_bindings_);
|
shader->vertex_bindings_ = std::move(vertex_bindings_);
|
||||||
|
@ -117,7 +118,8 @@ bool ShaderTranslator::TranslateInternal(Shader* shader) {
|
||||||
ucode_dwords_ = shader->ucode_dwords();
|
ucode_dwords_ = shader->ucode_dwords();
|
||||||
ucode_dword_count_ = shader->ucode_dword_count();
|
ucode_dword_count_ = shader->ucode_dword_count();
|
||||||
|
|
||||||
// Run through and gather all binding information.
|
// Run through and gather all binding information and to check whether
|
||||||
|
// registers are dynamically addressed.
|
||||||
// Translators may need this before they start codegen.
|
// Translators may need this before they start codegen.
|
||||||
uint32_t max_cf_dword_index = static_cast<uint32_t>(ucode_dword_count_);
|
uint32_t max_cf_dword_index = static_cast<uint32_t>(ucode_dword_count_);
|
||||||
for (uint32_t i = 0; i < max_cf_dword_index; i += 3) {
|
for (uint32_t i = 0; i < max_cf_dword_index; i += 3) {
|
||||||
|
@ -133,8 +135,8 @@ bool ShaderTranslator::TranslateInternal(Shader* shader) {
|
||||||
std::min(max_cf_dword_index, cf_b.exec.address() * 3);
|
std::min(max_cf_dword_index, cf_b.exec.address() * 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
GatherBindingInformation(cf_a);
|
GatherInstructionInformation(cf_a);
|
||||||
GatherBindingInformation(cf_b);
|
GatherInstructionInformation(cf_b);
|
||||||
}
|
}
|
||||||
|
|
||||||
StartTranslation();
|
StartTranslation();
|
||||||
|
@ -225,7 +227,7 @@ void ShaderTranslator::EmitUnimplementedTranslationError() {
|
||||||
errors_.push_back(std::move(error));
|
errors_.push_back(std::move(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderTranslator::GatherBindingInformation(
|
void ShaderTranslator::GatherInstructionInformation(
|
||||||
const ControlFlowInstruction& cf) {
|
const ControlFlowInstruction& cf) {
|
||||||
switch (cf.opcode()) {
|
switch (cf.opcode()) {
|
||||||
case ControlFlowOpcode::kExec:
|
case ControlFlowOpcode::kExec:
|
||||||
|
@ -247,24 +249,52 @@ void ShaderTranslator::GatherBindingInformation(
|
||||||
static_cast<FetchOpcode>(ucode_dwords_[instr_offset * 3] & 0x1F);
|
static_cast<FetchOpcode>(ucode_dwords_[instr_offset * 3] & 0x1F);
|
||||||
if (fetch_opcode == FetchOpcode::kVertexFetch) {
|
if (fetch_opcode == FetchOpcode::kVertexFetch) {
|
||||||
assert_true(is_vertex_shader());
|
assert_true(is_vertex_shader());
|
||||||
GatherVertexBindingInformation(
|
GatherVertexFetchInformation(
|
||||||
*reinterpret_cast<const VertexFetchInstruction*>(
|
*reinterpret_cast<const VertexFetchInstruction*>(
|
||||||
ucode_dwords_ + instr_offset * 3));
|
ucode_dwords_ + instr_offset * 3));
|
||||||
} else {
|
} else {
|
||||||
GatherTextureBindingInformation(
|
GatherTextureFetchInformation(
|
||||||
*reinterpret_cast<const TextureFetchInstruction*>(
|
*reinterpret_cast<const TextureFetchInstruction*>(
|
||||||
ucode_dwords_ + instr_offset * 3));
|
ucode_dwords_ + instr_offset * 3));
|
||||||
}
|
}
|
||||||
} else if (is_pixel_shader()) {
|
} else {
|
||||||
// Gather up color targets written to.
|
// Gather up color targets written to, and check if using dynamic
|
||||||
|
// register indices.
|
||||||
auto& op = *reinterpret_cast<const AluInstruction*>(ucode_dwords_ +
|
auto& op = *reinterpret_cast<const AluInstruction*>(ucode_dwords_ +
|
||||||
instr_offset * 3);
|
instr_offset * 3);
|
||||||
if (op.is_export()) {
|
if (op.has_vector_op()) {
|
||||||
if (op.has_vector_op() && op.vector_dest() <= 3) {
|
const auto& opcode_info =
|
||||||
writes_color_targets_[op.vector_dest()] = true;
|
alu_vector_opcode_infos_[static_cast<int>(op.vector_opcode())];
|
||||||
|
for (size_t i = 0; i < opcode_info.argument_count; ++i) {
|
||||||
|
if (op.src_is_temp(i) && (op.src_reg(i) & 0x40)) {
|
||||||
|
uses_register_relative_addressing_ = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (op.has_scalar_op() && op.scalar_dest() <= 3) {
|
if (op.is_export()) {
|
||||||
writes_color_targets_[op.scalar_dest()] = true;
|
if (is_pixel_shader() && op.vector_dest() <= 3) {
|
||||||
|
writes_color_targets_[op.vector_dest()] = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (op.is_vector_dest_relative()) {
|
||||||
|
uses_register_relative_addressing_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (op.has_scalar_op()) {
|
||||||
|
const auto& opcode_info =
|
||||||
|
alu_scalar_opcode_infos_[static_cast<int>(op.scalar_opcode())];
|
||||||
|
if (opcode_info.argument_count == 1 && op.src_is_temp(0) &&
|
||||||
|
(op.src_reg(0) & 0x40)) {
|
||||||
|
uses_register_relative_addressing_ = true;
|
||||||
|
}
|
||||||
|
if (op.is_export()) {
|
||||||
|
if (is_pixel_shader() && op.scalar_dest() <= 3) {
|
||||||
|
writes_color_targets_[op.scalar_dest()] = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (op.is_scalar_dest_relative()) {
|
||||||
|
uses_register_relative_addressing_ = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -275,7 +305,7 @@ void ShaderTranslator::GatherBindingInformation(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderTranslator::GatherVertexBindingInformation(
|
void ShaderTranslator::GatherVertexFetchInformation(
|
||||||
const VertexFetchInstruction& op) {
|
const VertexFetchInstruction& op) {
|
||||||
ParsedVertexFetchInstruction fetch_instr;
|
ParsedVertexFetchInstruction fetch_instr;
|
||||||
ParseVertexFetchInstruction(op, &fetch_instr);
|
ParseVertexFetchInstruction(op, &fetch_instr);
|
||||||
|
@ -285,6 +315,11 @@ void ShaderTranslator::GatherVertexBindingInformation(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if using dynamic register indices.
|
||||||
|
if (op.is_dest_relative() || op.is_src_relative()) {
|
||||||
|
uses_register_relative_addressing_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Try to allocate an attribute on an existing binding.
|
// Try to allocate an attribute on an existing binding.
|
||||||
// If no binding for this fetch slot is found create it.
|
// If no binding for this fetch slot is found create it.
|
||||||
using VertexBinding = Shader::VertexBinding;
|
using VertexBinding = Shader::VertexBinding;
|
||||||
|
@ -317,8 +352,13 @@ void ShaderTranslator::GatherVertexBindingInformation(
|
||||||
GetVertexFormatSizeInWords(attrib->fetch_instr.attributes.data_format);
|
GetVertexFormatSizeInWords(attrib->fetch_instr.attributes.data_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderTranslator::GatherTextureBindingInformation(
|
void ShaderTranslator::GatherTextureFetchInformation(
|
||||||
const TextureFetchInstruction& op) {
|
const TextureFetchInstruction& op) {
|
||||||
|
// Check if using dynamic register indices.
|
||||||
|
if (op.is_dest_relative() || op.is_src_relative()) {
|
||||||
|
uses_register_relative_addressing_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
switch (op.opcode()) {
|
switch (op.opcode()) {
|
||||||
case FetchOpcode::kSetTextureLod:
|
case FetchOpcode::kSetTextureLod:
|
||||||
case FetchOpcode::kSetTextureGradientsHorz:
|
case FetchOpcode::kSetTextureGradientsHorz:
|
||||||
|
|
|
@ -143,10 +143,9 @@ class ShaderTranslator {
|
||||||
void AppendUcodeDisasmFormat(const char* format, ...);
|
void AppendUcodeDisasmFormat(const char* format, ...);
|
||||||
|
|
||||||
bool TranslateBlocks();
|
bool TranslateBlocks();
|
||||||
void GatherBindingInformation(const ucode::ControlFlowInstruction& cf);
|
void GatherInstructionInformation(const ucode::ControlFlowInstruction& cf);
|
||||||
void GatherVertexBindingInformation(const ucode::VertexFetchInstruction& op);
|
void GatherVertexFetchInformation(const ucode::VertexFetchInstruction& op);
|
||||||
void GatherTextureBindingInformation(
|
void GatherTextureFetchInformation(const ucode::TextureFetchInstruction& op);
|
||||||
const ucode::TextureFetchInstruction& op);
|
|
||||||
void TranslateControlFlowInstruction(const ucode::ControlFlowInstruction& cf);
|
void TranslateControlFlowInstruction(const ucode::ControlFlowInstruction& cf);
|
||||||
void TranslateControlFlowNop(const ucode::ControlFlowInstruction& cf);
|
void TranslateControlFlowNop(const ucode::ControlFlowInstruction& cf);
|
||||||
void TranslateControlFlowExec(const ucode::ControlFlowExecInstruction& cf);
|
void TranslateControlFlowExec(const ucode::ControlFlowExecInstruction& cf);
|
||||||
|
@ -216,6 +215,7 @@ class ShaderTranslator {
|
||||||
uint32_t unique_texture_bindings_ = 0;
|
uint32_t unique_texture_bindings_ = 0;
|
||||||
|
|
||||||
Shader::ConstantRegisterMap constant_register_map_ = {0};
|
Shader::ConstantRegisterMap constant_register_map_ = {0};
|
||||||
|
bool uses_register_relative_addressing_ = false;
|
||||||
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