pvr: Load descriptors from memory

Signed-off-by: Simon Perretta <simon.perretta@imgtec.com>
Acked-by Frank Binns <frank.binns@imgtec.com>

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21331>
This commit is contained in:
Simon Perretta 2023-02-07 10:53:13 +00:00 committed by Marge Bot
parent 3355749105
commit 5694755fa0
5 changed files with 208 additions and 84 deletions

View file

@ -38,34 +38,25 @@
*/
static void lower_vulkan_resource_index(nir_builder *b,
nir_intrinsic_instr *intr,
void *pipeline_layout)
nir_intrinsic_instr *intr)
{
/* Pass along the desc_set, binding, desc_type. */
unsigned desc_set = nir_intrinsic_desc_set(intr);
unsigned binding = nir_intrinsic_binding(intr);
unsigned desc_type = nir_intrinsic_desc_type(intr);
nir_ssa_def *def = nir_vec3(b,
nir_imm_int(b, desc_set),
nir_imm_int(b, binding),
nir_imm_int(b, 0));
nir_imm_int(b, desc_type));
nir_ssa_def_rewrite_uses(&intr->dest.ssa, def);
nir_instr_remove(&intr->instr);
}
static void lower_load_vulkan_descriptor(nir_builder *b,
nir_intrinsic_instr *intr)
static void lower_load_global_constant_to_scalar(nir_builder *b,
nir_intrinsic_instr *intr)
{
/* Loading the descriptor happens as part of the load/store instruction so
* this is a no-op.
*/
nir_ssa_def_rewrite_uses(&intr->dest.ssa, intr->src[0].ssa);
nir_instr_remove(&intr->instr);
}
static void lower_load_ubo_to_scalar(nir_builder *b, nir_intrinsic_instr *intr)
{
/* Scalarize the load_ubo. */
/* Scalarize the load_global_constant. */
b->cursor = nir_before_instr(&intr->instr);
assert(intr->dest.is_ssa);
@ -74,7 +65,6 @@ static void lower_load_ubo_to_scalar(nir_builder *b, nir_intrinsic_instr *intr)
nir_ssa_def *loads[NIR_MAX_VEC_COMPONENTS];
for (uint8_t i = 0; i < intr->num_components; i++) {
unsigned scaled_range = nir_intrinsic_range(intr) / intr->num_components;
nir_intrinsic_instr *chan_intr =
nir_intrinsic_instr_create(b->shader, intr->intrinsic);
nir_ssa_dest_init(&chan_intr->instr,
@ -88,16 +78,10 @@ static void lower_load_ubo_to_scalar(nir_builder *b, nir_intrinsic_instr *intr)
nir_intrinsic_set_align_mul(chan_intr, nir_intrinsic_align_mul(intr));
nir_intrinsic_set_align_offset(chan_intr,
nir_intrinsic_align_offset(intr));
nir_intrinsic_set_range_base(chan_intr,
nir_intrinsic_range_base(intr) +
(i * intr->num_components));
nir_intrinsic_set_range(chan_intr, scaled_range);
/* Base (desc_set, binding). */
nir_src_copy(&chan_intr->src[0], &intr->src[0], &chan_intr->instr);
/* Offset (unused). */
chan_intr->src[1] = nir_src_for_ssa(nir_imm_int(b, 0));
/* Address. */
chan_intr->src[0] =
nir_src_for_ssa(nir_iadd_imm(b, intr->src[0].ssa, i * 4));
nir_builder_instr_insert(b, &chan_intr->instr);
@ -109,20 +93,15 @@ static void lower_load_ubo_to_scalar(nir_builder *b, nir_intrinsic_instr *intr)
nir_instr_remove(&intr->instr);
}
static bool
lower_intrinsic(nir_builder *b, nir_intrinsic_instr *instr, void *layout)
static bool lower_intrinsic(nir_builder *b, nir_intrinsic_instr *instr)
{
switch (instr->intrinsic) {
case nir_intrinsic_load_vulkan_descriptor:
lower_load_vulkan_descriptor(b, instr);
return true;
case nir_intrinsic_vulkan_resource_index:
lower_vulkan_resource_index(b, instr, layout);
lower_vulkan_resource_index(b, instr);
return true;
case nir_intrinsic_load_ubo:
lower_load_ubo_to_scalar(b, instr);
case nir_intrinsic_load_global_constant:
lower_load_global_constant_to_scalar(b, instr);
return true;
default:
@ -132,7 +111,7 @@ lower_intrinsic(nir_builder *b, nir_intrinsic_instr *instr, void *layout)
return false;
}
static bool lower_impl(nir_function_impl *impl, void *layout)
static bool lower_impl(nir_function_impl *impl)
{
bool progress = false;
nir_builder b;
@ -144,8 +123,7 @@ static bool lower_impl(nir_function_impl *impl, void *layout)
b.cursor = nir_before_instr(instr);
switch (instr->type) {
case nir_instr_type_intrinsic:
progress |=
lower_intrinsic(&b, nir_instr_as_intrinsic(instr), layout);
progress |= lower_intrinsic(&b, nir_instr_as_intrinsic(instr));
break;
default:
@ -163,13 +141,13 @@ static bool lower_impl(nir_function_impl *impl, void *layout)
}
PUBLIC
bool rogue_nir_lower_io(nir_shader *shader, void *layout)
bool rogue_nir_lower_io(nir_shader *shader)
{
bool progress = false;
nir_foreach_function (function, shader) {
if (function->impl)
progress |= lower_impl(function->impl, layout);
progress |= lower_impl(function->impl);
}
if (progress)

View file

@ -198,22 +198,19 @@ bool rogue_regalloc(rogue_shader *shader)
unreachable("Register allocation failed.");
unsigned regarray_count = list_length(&shader->regarrays);
rogue_regarray **rogue_regarrays =
rzalloc_array_size(shader, sizeof(*rogue_regarrays), regarray_count);
unsigned u = 0;
rogue_regarray **parent_regarrays =
rzalloc_array_size(shader, sizeof(*parent_regarrays), regarray_count);
unsigned num_parent_regarrays = 0;
rogue_foreach_regarray (regarray, shader) {
rogue_regarrays[u++] = regarray;
if (regarray->parent || regarray->regs[0]->class != ROGUE_REG_CLASS_SSA)
continue;
parent_regarrays[num_parent_regarrays++] = regarray;
}
assert(u == regarray_count);
for (u = 0; u < regarray_count; ++u) {
rogue_regarray *regarray = rogue_regarrays[u];
enum rogue_reg_class class = regarray->regs[0]->class;
if (class != ROGUE_REG_CLASS_SSA)
continue;
if (regarray->parent)
continue;
for (unsigned u = 0; u < num_parent_regarrays; ++u) {
rogue_regarray *regarray = parent_regarrays[u];
unsigned start_index = regarray->regs[0]->index;
unsigned new_base_index = ra_get_node_reg(ra_graph, start_index);
@ -238,7 +235,6 @@ bool rogue_regalloc(rogue_shader *shader)
new_class,
new_base_index);
progress |= rogue_regarray_replace(regarray, new_regarray);
rogue_regarray_delete(regarray);
/* Replace subarrays. */
rogue_foreach_subarray_safe (subarray, regarray) {
@ -251,6 +247,8 @@ bool rogue_regalloc(rogue_shader *shader)
progress |= rogue_regarray_replace(subarray, new_regarray);
rogue_regarray_delete(subarray);
}
rogue_regarray_delete(regarray);
}
}
@ -281,7 +279,7 @@ bool rogue_regalloc(rogue_shader *shader)
assert(reg->index < num_temp_regs);
}
ralloc_free(rogue_regarrays);
ralloc_free(parent_regarrays);
ralloc_free(ssa_live_range);
ralloc_free(ra_regs);
return progress;

View file

@ -2762,6 +2762,7 @@ typedef struct rogue_build_ctx {
rogue_common_build_data common_data[MESA_SHADER_FRAGMENT + 1];
rogue_build_data stage_data;
unsigned next_ssa_idx;
} rogue_build_ctx;
rogue_build_ctx *rogue_build_context_create(rogue_compiler *compiler);
@ -2792,7 +2793,7 @@ nir_shader *rogue_spirv_to_nir(rogue_build_ctx *ctx,
/* Custom NIR passes. */
void rogue_nir_pfo(nir_shader *shader);
bool rogue_nir_lower_io(nir_shader *shader, void *layout);
bool rogue_nir_lower_io(nir_shader *shader);
rogue_shader *rogue_nir_to_rogue(rogue_build_ctx *ctx, const nir_shader *nir);

View file

@ -26,6 +26,8 @@
#include "rogue.h"
#include "rogue_builder.h"
#include "util/macros.h"
/* FIXME: Remove once the compiler/driver interface is finalised. */
#include "vulkan/vulkan_core.h"
/**
* \file rogue_compile.c
@ -34,7 +36,7 @@
*/
/* For ALU scalars */
/* TODO: expand and use these helpers. */
static rogue_ref nir_ssa_reg(rogue_shader *shader,
unsigned index,
unsigned num_components,
@ -110,11 +112,33 @@ static void trans_nir_jump(rogue_builder *b, nir_jump_instr *jump)
static void trans_nir_load_const(rogue_builder *b,
nir_load_const_instr *load_const)
{
rogue_reg *dst = rogue_ssa_reg(b->shader, load_const->def.index);
if (load_const->def.bit_size == 32) {
unsigned dst_index = load_const->def.index;
unsigned bit_size = load_const->def.bit_size;
switch (bit_size) {
case 32: {
rogue_reg *dst = rogue_ssa_reg(b->shader, dst_index);
uint32_t imm = nir_const_value_as_uint(load_const->value[0], 32);
rogue_MOV(b, rogue_ref_reg(dst), rogue_ref_imm(imm));
} else {
break;
}
case 64: {
uint64_t imm = nir_const_value_as_uint(load_const->value[0], 64);
uint32_t imm_2x32[2] = { imm & 0xffffffff, (imm >> 32) & 0xffffffff };
rogue_regarray *dst[2] = {
rogue_ssa_vec_regarray(b->shader, 1, dst_index, 0),
rogue_ssa_vec_regarray(b->shader, 1, dst_index, 1),
};
rogue_MOV(b, rogue_ref_regarray(dst[0]), rogue_ref_imm(imm_2x32[0]));
rogue_MOV(b, rogue_ref_regarray(dst[1]), rogue_ref_imm(imm_2x32[1]));
break;
}
default:
unreachable("Unimplemented NIR load_const bit size.");
}
}
@ -247,23 +271,78 @@ static void trans_nir_intrinsic_store_output(rogue_builder *b,
unreachable("Unimplemented NIR store_output variant.");
}
static void trans_nir_intrinsic_load_ubo(rogue_builder *b,
nir_intrinsic_instr *intr)
static void
trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder *b,
nir_intrinsic_instr *intr)
{
struct rogue_ubo_data *ubo_data =
&b->shader->ctx->common_data[b->shader->stage].ubo_data;
rogue_instr *instr;
/* unsigned desc_set = nir_src_comp_as_uint(intr->src[0], 0); */
/* unsigned binding = nir_src_comp_as_uint(intr->src[0], 1); */
ASSERTED VkDescriptorType desc_type = nir_src_comp_as_uint(intr->src[0], 2);
assert(desc_type == nir_intrinsic_desc_type(intr));
unsigned desc_set = nir_src_comp_as_uint(intr->src[0], 0);
unsigned binding = nir_src_comp_as_uint(intr->src[1], 0);
unsigned offset = nir_intrinsic_range_base(intr);
unsigned desc_set_table_addr_idx = b->shader->ctx->next_ssa_idx++;
rogue_regarray *desc_set_table_addr_64 =
rogue_ssa_vec_regarray(b->shader, 2, desc_set_table_addr_idx, 0);
rogue_regarray *desc_set_table_addr_2x32[2] = {
rogue_ssa_vec_regarray(b->shader, 1, desc_set_table_addr_idx, 0),
rogue_ssa_vec_regarray(b->shader, 1, desc_set_table_addr_idx, 1),
};
unsigned sh_index = rogue_ubo_reg(ubo_data, desc_set, binding, offset);
instr = &rogue_MOV(b,
rogue_ref_regarray(desc_set_table_addr_2x32[0]),
rogue_ref_reg(rogue_shared_reg(b->shader, 0)))
->instr;
rogue_add_instr_comment(instr, "desc_set_table_addr_lo");
instr = &rogue_MOV(b,
rogue_ref_regarray(desc_set_table_addr_2x32[1]),
rogue_ref_reg(rogue_shared_reg(b->shader, 1)))
->instr;
rogue_add_instr_comment(instr, "desc_set_table_addr_hi");
/* TODO NEXT: Just using offset 0 for both the descriptor table and the entry
* (UBO), but need to calculate this from desc_set and binding. */
unsigned desc_set_addr_idx = b->shader->ctx->next_ssa_idx++;
rogue_regarray *desc_set_addr_64 =
rogue_ssa_vec_regarray(b->shader, 2, desc_set_addr_idx, 0);
instr = &rogue_LD(b,
rogue_ref_regarray(desc_set_addr_64),
rogue_ref_drc(0),
rogue_ref_val(2),
rogue_ref_regarray(desc_set_table_addr_64))
->instr;
rogue_add_instr_comment(instr, "load descriptor set");
unsigned desc_addr_idx = intr->dest.ssa.index;
rogue_regarray *desc_addr_64 =
rogue_ssa_vec_regarray(b->shader, 2, desc_addr_idx, 0);
instr = &rogue_LD(b,
rogue_ref_regarray(desc_addr_64),
rogue_ref_drc(0),
rogue_ref_val(2),
rogue_ref_regarray(desc_set_addr_64))
->instr;
rogue_add_instr_comment(instr, "load descriptor");
}
static void trans_nir_intrinsic_load_global_constant(rogue_builder *b,
nir_intrinsic_instr *intr)
{
/* 64-bit source address. */
unsigned src_index = intr->src[0].ssa->index;
rogue_regarray *src = rogue_ssa_vec_regarray(b->shader, 2, src_index, 0);
/*** TODO NEXT: this could be either a reg or regarray. ***/
rogue_reg *dst = rogue_ssa_reg(b->shader, intr->dest.ssa.index);
rogue_reg *src = rogue_shared_reg(b->shader, sh_index);
rogue_instr *instr =
&rogue_MOV(b, rogue_ref_reg(dst), rogue_ref_reg(src))->instr;
rogue_add_instr_comment(instr, "load_ubo");
/* TODO NEXT: src[1] should be depending on ssa vec size for burst loads */
rogue_instr *instr = &rogue_LD(b,
rogue_ref_reg(dst),
rogue_ref_drc(0),
rogue_ref_val(1),
rogue_ref_regarray(src))
->instr;
rogue_add_instr_comment(instr, "load_global_constant");
}
static void trans_nir_intrinsic(rogue_builder *b, nir_intrinsic_instr *intr)
@ -275,8 +354,11 @@ static void trans_nir_intrinsic(rogue_builder *b, nir_intrinsic_instr *intr)
case nir_intrinsic_store_output:
return trans_nir_intrinsic_store_output(b, intr);
case nir_intrinsic_load_ubo:
return trans_nir_intrinsic_load_ubo(b, intr);
case nir_intrinsic_load_vulkan_descriptor:
return trans_nir_intrinsic_load_vulkan_descriptor(b, intr);
case nir_intrinsic_load_global_constant:
return trans_nir_intrinsic_load_global_constant(b, intr);
default:
break;
@ -327,6 +409,55 @@ static void trans_nir_alu_vecN(rogue_builder *b, nir_alu_instr *alu, unsigned n)
}
}
static void trans_nir_alu_iadd64(rogue_builder *b, nir_alu_instr *alu)
{
unsigned dst_index = alu->dest.dest.ssa.index;
rogue_regarray *dst[2] = {
rogue_ssa_vec_regarray(b->shader, 1, dst_index, 0),
rogue_ssa_vec_regarray(b->shader, 1, dst_index, 1),
};
unsigned src_index[2] = { alu->src[0].src.ssa->index,
alu->src[1].src.ssa->index };
rogue_regarray *src[2][2] = {
[0] = {
rogue_ssa_vec_regarray(b->shader, 1, src_index[0], 0),
rogue_ssa_vec_regarray(b->shader, 1, src_index[0], 1),
},
[1] = {
rogue_ssa_vec_regarray(b->shader, 1, src_index[1], 0),
rogue_ssa_vec_regarray(b->shader, 1, src_index[1], 1),
},
};
rogue_ADD64(b,
rogue_ref_regarray(dst[0]),
rogue_ref_regarray(dst[1]),
rogue_ref_io(ROGUE_IO_NONE),
rogue_ref_regarray(src[0][0]),
rogue_ref_regarray(src[0][1]),
rogue_ref_regarray(src[1][0]),
rogue_ref_regarray(src[1][1]),
rogue_ref_io(ROGUE_IO_NONE));
}
static void trans_nir_alu_iadd(rogue_builder *b, nir_alu_instr *alu)
{
unsigned bit_size = alu->dest.dest.ssa.bit_size;
switch (bit_size) {
/* TODO: case 32: */
case 64:
return trans_nir_alu_iadd64(b, alu);
default:
break;
}
unreachable("Unsupported bit size.");
}
static void trans_nir_alu(rogue_builder *b, nir_alu_instr *alu)
{
switch (alu->op) {
@ -343,6 +474,9 @@ static void trans_nir_alu(rogue_builder *b, nir_alu_instr *alu)
case nir_op_vec4:
return trans_nir_alu_vecN(b, alu, 4);
case nir_op_iadd:
return trans_nir_alu_iadd(b, alu);
default:
break;
}
@ -362,7 +496,7 @@ static inline void rogue_feedback_used_regs(rogue_build_ctx *ctx,
BITSET_WORDS(rogue_reg_infos[ROGUE_REG_CLASS_INTERNAL].num));
}
static bool index_ssa_def_cb(nir_ssa_def *ssa, void *state)
static bool ssa_def_cb(nir_ssa_def *ssa, void *state)
{
rogue_shader *shader = (rogue_shader *)state;
@ -376,6 +510,9 @@ static bool index_ssa_def_cb(nir_ssa_def *ssa, void *state)
rogue_ssa_vec_regarray(shader, ssa->num_components, ssa->index, 0);
}
/* Keep track of the last SSA index so we can use more. */
shader->ctx->next_ssa_idx = MAX2(shader->ctx->next_ssa_idx, ssa->index);
return true;
}
@ -408,9 +545,15 @@ rogue_shader *rogue_nir_to_rogue(rogue_build_ctx *ctx, const nir_shader *nir)
* declared before the parent arrays. */
nir_foreach_block_unstructured (block, entry) {
nir_foreach_instr (instr, block) {
nir_foreach_ssa_def(instr, index_ssa_def_cb, shader);
if (instr->type == nir_instr_type_load_const) {
nir_load_const_instr *load_const = nir_instr_as_load_const(instr);
if (load_const->def.num_components > 1)
continue;
}
nir_foreach_ssa_def(instr, ssa_def_cb, shader);
}
}
++shader->ctx->next_ssa_idx;
/* Translate shader entrypoint. */
nir_foreach_block (block, entry) {

View file

@ -41,7 +41,7 @@ static const struct spirv_to_nir_options spirv_options = {
.environment = NIR_SPIRV_VULKAN,
/* Buffer address: (descriptor_set, binding), offset. */
.ubo_addr_format = nir_address_format_32bit_index_offset,
.ubo_addr_format = nir_address_format_64bit_global,
};
static const nir_shader_compiler_options nir_options = {
@ -108,6 +108,14 @@ static void rogue_nir_passes(struct rogue_build_ctx *ctx,
/* Lower load_consts to scalars. */
NIR_PASS_V(nir, nir_lower_load_const_to_scalar);
/* Additional I/O lowering. */
NIR_PASS_V(nir,
nir_lower_explicit_io,
nir_var_mem_ubo,
spirv_options.ubo_addr_format);
NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_mem_ubo);
NIR_PASS_V(nir, rogue_nir_lower_io);
/* Algebraic opts. */
do {
progress = false;
@ -120,13 +128,6 @@ static void rogue_nir_passes(struct rogue_build_ctx *ctx,
NIR_PASS_V(nir, nir_opt_gcm, false);
} while (progress);
/* Additional I/O lowering. */
NIR_PASS_V(nir,
nir_lower_explicit_io,
nir_var_mem_ubo,
spirv_options.ubo_addr_format);
NIR_PASS_V(nir, rogue_nir_lower_io, NULL);
/* Late algebraic opts. */
do {
progress = false;
@ -169,6 +170,9 @@ static void rogue_nir_passes(struct rogue_build_ctx *ctx,
&nir->num_outputs,
nir->info.stage);
/* Renumber SSA defs. */
nir_index_ssa_defs(nir_shader_get_entrypoint(nir));
/* Gather info into nir shader struct. */
nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));