mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-25 18:00:52 +01:00
r600/sfn: Implementing instructions blocks
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4609>
This commit is contained in:
parent
b51ced7306
commit
5e036fef1f
12 changed files with 199 additions and 36 deletions
|
|
@ -110,6 +110,8 @@ CXX_SOURCES = \
|
|||
sfn/sfn_instruction_alu.h \
|
||||
sfn/sfn_instruction_base.cpp \
|
||||
sfn/sfn_instruction_base.h \
|
||||
sfn/sfn_instruction_block.cpp \
|
||||
sfn/sfn_instruction_block.h \
|
||||
sfn/sfn_instruction_cf.cpp \
|
||||
sfn/sfn_instruction_cf.h \
|
||||
sfn/sfn_instruction_export.cpp \
|
||||
|
|
|
|||
|
|
@ -127,6 +127,8 @@ files_r600 = files(
|
|||
'sfn/sfn_instruction_alu.h',
|
||||
'sfn/sfn_instruction_base.cpp',
|
||||
'sfn/sfn_instruction_base.h',
|
||||
'sfn/sfn_instruction_block.cpp',
|
||||
'sfn/sfn_instruction_block.h',
|
||||
'sfn/sfn_instruction_cf.cpp',
|
||||
'sfn/sfn_instruction_cf.h',
|
||||
'sfn/sfn_instruction_export.cpp',
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ public:
|
|||
mem_wr_scratch,
|
||||
gds,
|
||||
rat,
|
||||
block,
|
||||
unknown
|
||||
};
|
||||
|
||||
|
|
|
|||
52
src/gallium/drivers/r600/sfn/sfn_instruction_block.cpp
Normal file
52
src/gallium/drivers/r600/sfn/sfn_instruction_block.cpp
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#include "sfn_instruction_block.h"
|
||||
|
||||
namespace r600 {
|
||||
|
||||
|
||||
InstructionBlock::InstructionBlock(unsigned nesting_depth, unsigned block_number):
|
||||
Instruction(block),
|
||||
m_block_number(block_number),
|
||||
m_nesting_depth(nesting_depth)
|
||||
{
|
||||
}
|
||||
|
||||
void InstructionBlock::emit(PInstruction instr)
|
||||
{
|
||||
m_block.push_back(instr);
|
||||
}
|
||||
|
||||
void InstructionBlock::remap_registers(ValueRemapper& map)
|
||||
{
|
||||
for(auto& i: m_block)
|
||||
i->remap_registers(map);
|
||||
}
|
||||
|
||||
void InstructionBlock::do_evalue_liveness(LiverangeEvaluator& eval) const
|
||||
{
|
||||
for(auto& i: m_block)
|
||||
i->evalue_liveness(eval);
|
||||
}
|
||||
|
||||
bool InstructionBlock::is_equal_to(const Instruction& lhs) const
|
||||
{
|
||||
assert(lhs.type() == block);
|
||||
auto& l = static_cast<const InstructionBlock&>(lhs);
|
||||
|
||||
if (m_block.size() != l.m_block.size())
|
||||
return false;
|
||||
|
||||
if (m_block_number != l.m_block_number)
|
||||
return false;
|
||||
|
||||
return std::equal(m_block.begin(), m_block.end(), l.m_block.begin(),
|
||||
[](PInstruction ri, PInstruction li) {return *ri == *li;});
|
||||
}
|
||||
|
||||
void InstructionBlock::do_print(std::ostream& os) const
|
||||
{
|
||||
std::string space(" ", 2 * m_nesting_depth);
|
||||
for(auto& i: m_block)
|
||||
os << space << *i << "\n";
|
||||
}
|
||||
|
||||
}
|
||||
77
src/gallium/drivers/r600/sfn/sfn_instruction_block.h
Normal file
77
src/gallium/drivers/r600/sfn/sfn_instruction_block.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/* -*- mesa-c++ -*-
|
||||
*
|
||||
* Copyright (c) 2018-2019 Collabora LTD
|
||||
*
|
||||
* Author: Gert Wollny <gert.wollny@collabora.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, and/or sell copies of the Software, and to permit persons to whom
|
||||
* the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef sfn_instruction_block_h
|
||||
#define sfn_instruction_block_h
|
||||
|
||||
#include "sfn_instruction_base.h"
|
||||
|
||||
namespace r600 {
|
||||
|
||||
class InstructionBlock : public Instruction
|
||||
{
|
||||
public:
|
||||
InstructionBlock(unsigned nesting_depth, unsigned block_number);
|
||||
|
||||
void emit(PInstruction instr);
|
||||
|
||||
|
||||
std::vector<PInstruction>::const_iterator begin() const {
|
||||
return m_block.begin();
|
||||
}
|
||||
std::vector<PInstruction>::const_iterator end() const {
|
||||
return m_block.end();
|
||||
}
|
||||
|
||||
void remap_registers(ValueRemapper& map);
|
||||
|
||||
size_t size() const {
|
||||
return m_block.size();
|
||||
}
|
||||
|
||||
const PInstruction& operator [] (int i) const {
|
||||
return m_block[i];
|
||||
}
|
||||
|
||||
unsigned number() const {
|
||||
return m_block_number;
|
||||
}
|
||||
|
||||
private:
|
||||
void do_evalue_liveness(LiverangeEvaluator& eval) const override;
|
||||
bool is_equal_to(const Instruction& lhs) const override;
|
||||
void do_print(std::ostream& os) const override;
|
||||
|
||||
std::vector<PInstruction> m_block;
|
||||
|
||||
unsigned m_block_number;
|
||||
unsigned m_nesting_depth;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // INSTRUCTIONBLOCK_H
|
||||
|
|
@ -102,7 +102,7 @@ AssemblyFromShaderLegacy::~AssemblyFromShaderLegacy()
|
|||
delete impl;
|
||||
}
|
||||
|
||||
bool AssemblyFromShaderLegacy::do_lower(const std::vector<Instruction::Pointer>& ir)
|
||||
bool AssemblyFromShaderLegacy::do_lower(const std::vector<InstructionBlock>& ir)
|
||||
{
|
||||
if (impl->m_shader->processor_type == PIPE_SHADER_VERTEX &&
|
||||
impl->m_shader->ninput > 0)
|
||||
|
|
@ -111,11 +111,13 @@ bool AssemblyFromShaderLegacy::do_lower(const std::vector<Instruction::Pointer>&
|
|||
|
||||
std::vector<Instruction::Pointer> exports;
|
||||
|
||||
for (const auto& i : ir) {
|
||||
if (!impl->emit(i))
|
||||
for (const auto& block : ir) {
|
||||
for (const auto& i : block) {
|
||||
if (!impl->emit(i))
|
||||
return false;
|
||||
if (i->type() != Instruction::alu)
|
||||
impl->reset_addr_register();
|
||||
}
|
||||
}
|
||||
/*
|
||||
for (const auto& i : exports) {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public:
|
|||
AssemblyFromShaderLegacy(struct r600_shader *sh, r600_shader_key *key);
|
||||
~AssemblyFromShaderLegacy() override;
|
||||
private:
|
||||
bool do_lower(const std::vector<Instruction::Pointer>& ir) override ;
|
||||
bool do_lower(const std::vector<InstructionBlock> &ir) override ;
|
||||
|
||||
struct AssemblyFromShaderLegacyImpl *impl;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -754,14 +754,16 @@ void LiverangeEvaluator::run(const Shader& shader,
|
|||
|
||||
sfn_log << SfnLog::merge << "have " << temp_acc.size() << " temps\n";
|
||||
|
||||
for (const auto& ir: shader.m_ir) {
|
||||
switch (ir->type()) {
|
||||
case Instruction::cond_if:
|
||||
case Instruction::cond_else:
|
||||
case Instruction::loop_begin:
|
||||
++n_scopes;
|
||||
default:
|
||||
;
|
||||
for (const auto& block: shader.m_ir) {
|
||||
for (const auto& ir: block) {
|
||||
switch (ir->type()) {
|
||||
case Instruction::cond_if:
|
||||
case Instruction::cond_else:
|
||||
case Instruction::loop_begin:
|
||||
++n_scopes;
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -783,12 +785,13 @@ void LiverangeEvaluator::run(const Shader& shader,
|
|||
}
|
||||
}
|
||||
|
||||
for (const auto& ir: shader.m_ir) {
|
||||
ir->evalue_liveness(*this);
|
||||
if (ir->type() != Instruction::alu ||
|
||||
static_cast<const AluInstruction&>(*ir).flag(alu_last_instr))
|
||||
++line;
|
||||
}
|
||||
for (const auto& block: shader.m_ir)
|
||||
for (const auto& ir: block) {
|
||||
ir->evalue_liveness(*this);
|
||||
if (ir->type() != Instruction::alu ||
|
||||
static_cast<const AluInstruction&>(*ir).flag(alu_last_instr))
|
||||
++line;
|
||||
}
|
||||
|
||||
assert(cur_scope->type() == outer_scope);
|
||||
cur_scope->set_end(line);
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@ bool ShaderFromNir::process_declaration()
|
|||
return true;
|
||||
}
|
||||
|
||||
const std::vector<Instruction::Pointer>& ShaderFromNir::shader_ir() const
|
||||
const std::vector<InstructionBlock>& ShaderFromNir::shader_ir() const
|
||||
{
|
||||
assert(impl);
|
||||
return impl->m_output;
|
||||
|
|
@ -301,7 +301,7 @@ AssemblyFromShader::~AssemblyFromShader()
|
|||
{
|
||||
}
|
||||
|
||||
bool AssemblyFromShader::lower(const std::vector<Instruction::Pointer>& ir)
|
||||
bool AssemblyFromShader::lower(const std::vector<InstructionBlock>& ir)
|
||||
{
|
||||
return do_lower(ir);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ bool r600_lower_ubo_to_align16(nir_shader *shader);
|
|||
|
||||
class Shader {
|
||||
public:
|
||||
std::vector<PInstruction>& m_ir;
|
||||
std::vector<InstructionBlock>& m_ir;
|
||||
ValueMap m_temp;
|
||||
};
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ public:
|
|||
|
||||
bool emit_instruction(nir_instr *instr);
|
||||
|
||||
const std::vector<Instruction::Pointer>& shader_ir() const;
|
||||
const std::vector<InstructionBlock> &shader_ir() const;
|
||||
|
||||
Shader shader() const;
|
||||
private:
|
||||
|
|
@ -87,9 +87,9 @@ private:
|
|||
class AssemblyFromShader {
|
||||
public:
|
||||
virtual ~AssemblyFromShader();
|
||||
bool lower(const std::vector<Instruction::Pointer>& ir);
|
||||
bool lower(const std::vector<InstructionBlock> &ir);
|
||||
private:
|
||||
virtual bool do_lower(const std::vector<Instruction::Pointer>& ir) = 0 ;
|
||||
virtual bool do_lower(const std::vector<InstructionBlock>& ir) = 0 ;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,9 @@ ShaderFromNirProcessor::ShaderFromNirProcessor(pipe_shader_type ptype,
|
|||
r600_pipe_shader_selector& sel,
|
||||
r600_shader &sh_info, int scratch_size):
|
||||
m_processor_type(ptype),
|
||||
m_nesting_depth(0),
|
||||
m_block_number(0),
|
||||
m_export_output(0, -1),
|
||||
m_sh_info(sh_info),
|
||||
m_tex_instr(*this),
|
||||
m_alu_instr(*this),
|
||||
|
|
@ -135,10 +138,9 @@ void ShaderFromNirProcessor::remap_registers()
|
|||
if (register_map[i].valid)
|
||||
sfn_log << SfnLog::merge << "Map:" << i << " -> " << register_map[i].new_reg << "\n";
|
||||
|
||||
|
||||
ValueRemapper vmap0(register_map, temp_register_map);
|
||||
for (auto ir: m_output)
|
||||
ir->remap_registers(vmap0);
|
||||
for (auto& block: m_output)
|
||||
block.remap_registers(vmap0);
|
||||
|
||||
remap_shader_info(m_sh_info, register_map, temp_register_map);
|
||||
|
||||
|
|
@ -159,8 +161,8 @@ void ShaderFromNirProcessor::remap_registers()
|
|||
}
|
||||
|
||||
ValueRemapper vmap1(register_map, temp_register_map);
|
||||
for (auto ir: m_output)
|
||||
ir->remap_registers(vmap1);
|
||||
for (auto& ir: m_output)
|
||||
ir.remap_registers(vmap1);
|
||||
|
||||
remap_shader_info(m_sh_info, register_map, temp_register_map);
|
||||
}
|
||||
|
|
@ -280,12 +282,17 @@ bool ShaderFromNirProcessor::emit_tex_instruction(nir_instr* instr)
|
|||
void ShaderFromNirProcessor::emit_instruction(Instruction *ir)
|
||||
{
|
||||
if (m_pending_else) {
|
||||
m_output.push_back(PInstruction(m_pending_else));
|
||||
append_block(-1);
|
||||
m_output.back().emit(PInstruction(m_pending_else));
|
||||
append_block(1);
|
||||
m_pending_else = nullptr;
|
||||
}
|
||||
|
||||
r600::sfn_log << SfnLog::instr << " as '" << *ir << "'\n";
|
||||
m_output.push_back(Instruction::Pointer(ir));
|
||||
if (m_output.empty())
|
||||
append_block(0);
|
||||
|
||||
m_output.back().emit(Instruction::Pointer(ir));
|
||||
}
|
||||
|
||||
void ShaderFromNirProcessor::emit_shader_start()
|
||||
|
|
@ -330,6 +337,7 @@ bool ShaderFromNirProcessor::emit_loop_start(int loop_id)
|
|||
LoopBeginInstruction *loop = new LoopBeginInstruction();
|
||||
emit_instruction(loop);
|
||||
m_loop_begin_block_map[loop_id] = loop;
|
||||
append_block(1);
|
||||
return true;
|
||||
}
|
||||
bool ShaderFromNirProcessor::emit_loop_end(int loop_id)
|
||||
|
|
@ -340,6 +348,9 @@ bool ShaderFromNirProcessor::emit_loop_end(int loop_id)
|
|||
<< loop_id << " not found\n";
|
||||
return false;
|
||||
}
|
||||
m_nesting_depth--;
|
||||
m_block_number++;
|
||||
m_output.push_back(InstructionBlock(m_nesting_depth, m_block_number));
|
||||
LoopEndInstruction *loop = new LoopEndInstruction(start->second);
|
||||
emit_instruction(loop);
|
||||
|
||||
|
|
@ -357,6 +368,8 @@ bool ShaderFromNirProcessor::emit_if_start(int if_id, nir_if *if_stmt)
|
|||
pred->set_flag(alu_update_pred);
|
||||
pred->set_cf_type(cf_alu_push_before);
|
||||
|
||||
append_block(1);
|
||||
|
||||
IfInstruction *ir = new IfInstruction(pred);
|
||||
emit_instruction(ir);
|
||||
assert(m_if_block_start_map.find(if_id) == m_if_block_start_map.end());
|
||||
|
|
@ -401,6 +414,7 @@ bool ShaderFromNirProcessor::emit_ifelse_end(int if_id)
|
|||
|
||||
m_pending_else = nullptr;
|
||||
|
||||
append_block(-1);
|
||||
IfElseEndInstruction *ir = new IfElseEndInstruction();
|
||||
emit_instruction(ir);
|
||||
|
||||
|
|
@ -860,7 +874,7 @@ void ShaderFromNirProcessor::add_param_output_reg(int loc, const GPRVector *gpr)
|
|||
void ShaderFromNirProcessor::emit_export_instruction(WriteoutInstruction *ir)
|
||||
{
|
||||
r600::sfn_log << SfnLog::instr << " as '" << *ir << "'\n";
|
||||
m_export_output.push_back(PInstruction(ir));
|
||||
m_export_output.emit(PInstruction(ir));
|
||||
}
|
||||
|
||||
const GPRVector * ShaderFromNirProcessor::output_register(unsigned location) const
|
||||
|
|
@ -884,6 +898,12 @@ void ShaderFromNirProcessor::set_output(unsigned pos, PValue var)
|
|||
m_outputs[pos] = var;
|
||||
}
|
||||
|
||||
void ShaderFromNirProcessor::append_block(int nesting_change)
|
||||
{
|
||||
m_nesting_depth += nesting_change;
|
||||
m_output.push_back(InstructionBlock(m_nesting_depth, m_block_number++));
|
||||
}
|
||||
|
||||
void ShaderFromNirProcessor::finalize()
|
||||
{
|
||||
do_finalize();
|
||||
|
|
@ -894,8 +914,7 @@ void ShaderFromNirProcessor::finalize()
|
|||
for (auto& i : m_outputs)
|
||||
m_sh_info.output[i.first].gpr = i.second->sel();
|
||||
|
||||
m_output.insert(m_output.end(), m_export_output.begin(), m_export_output.end());
|
||||
m_export_output.clear();
|
||||
m_output.push_back(m_export_output);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "compiler/nir/nir.h"
|
||||
#include "compiler/nir_types.h"
|
||||
|
||||
#include "sfn_instruction_block.h"
|
||||
#include "sfn_instruction_export.h"
|
||||
#include "sfn_alu_defines.h"
|
||||
#include "sfn_valuepool.h"
|
||||
|
|
@ -141,6 +142,8 @@ private:
|
|||
|
||||
void add_array_deref(nir_deref_instr* instr);
|
||||
|
||||
void append_block(int nesting_change);
|
||||
|
||||
virtual void emit_shader_start();
|
||||
virtual bool emit_deref_instruction_override(nir_deref_instr* instr);
|
||||
virtual bool do_process_inputs(nir_variable *input) = 0;
|
||||
|
|
@ -169,8 +172,10 @@ private:
|
|||
|
||||
pipe_shader_type m_processor_type;
|
||||
|
||||
std::vector<PInstruction> m_output;
|
||||
std::vector<PInstruction> m_export_output;
|
||||
std::vector<InstructionBlock> m_output;
|
||||
unsigned m_nesting_depth;
|
||||
unsigned m_block_number;
|
||||
InstructionBlock m_export_output;
|
||||
r600_shader& m_sh_info;
|
||||
|
||||
EmitTexInstruction m_tex_instr;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue