pvr, pco: rewrite compiler/driver interface for vs & fs I/O

Basic vertex/fragment shader I/O and sysval allocation rewritten to use
the new compiler/driver interface, with allocation moved entirely into
the driver.

RHW coeffs now only emitted when required.

Boilerplate support for converting formats for vs inputs/fs outputs.

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/32258>
This commit is contained in:
Simon Perretta
2024-11-14 00:32:36 +00:00
committed by Marge Bot
parent 99852fbe4d
commit 527b38d1fd
16 changed files with 1405 additions and 648 deletions
@@ -165,4 +165,6 @@
#define ROGUE_USRM_LINE_SIZE_PER_INSTANCE \
(ROGUE_PDS_US_TEMP_ALLOCATION_GRANULARITY * ROGUE_USRM_LINE_SIZE)
#define ROGUE_USC_COEFFICIENT_SET_SIZE 4U
#endif /* ROGUE_HW_DEFS_H */
+3 -3
View File
@@ -288,11 +288,11 @@ void pco_instr_delete(pco_instr *instr)
}
/**
* \brief Returns the number of temps allocated to the entrypoint function.
* \brief Returns the shader data.
*
* \param[in] shader PCO shader.
*/
unsigned pco_shader_temps(pco_shader *shader)
pco_data *pco_shader_data(pco_shader *shader)
{
return pco_entrypoint(shader)->temps;
return &shader->data;
}
+7 -4
View File
@@ -24,6 +24,7 @@ struct pvr_device_info;
/* Compiler-specific forward-declarations. */
typedef struct _pco_shader pco_shader;
typedef struct _pco_ctx pco_ctx;
typedef struct _pco_data pco_data;
pco_ctx *pco_ctx_create(const struct pvr_device_info *dev_info, void *mem_ctx);
const struct spirv_to_nir_options *pco_spirv_options(pco_ctx *ctx);
@@ -31,16 +32,18 @@ const nir_shader_compiler_options *pco_nir_options(pco_ctx *ctx);
void pco_preprocess_nir(pco_ctx *ctx, nir_shader *nir);
void pco_link_nir(pco_ctx *ctx, nir_shader *producer, nir_shader *consumer);
void pco_lower_nir(pco_ctx *ctx, nir_shader *nir);
void pco_postprocess_nir(pco_ctx *ctx, nir_shader *nir);
void pco_rev_link_nir(pco_ctx *ctx, nir_shader *producer, nir_shader *consumer);
void pco_lower_nir(pco_ctx *ctx, nir_shader *nir, pco_data *data);
void pco_postprocess_nir(pco_ctx *ctx, nir_shader *nir, pco_data *data);
pco_shader *pco_trans_nir(pco_ctx *ctx, nir_shader *nir, void *mem_ctx);
pco_shader *
pco_trans_nir(pco_ctx *ctx, nir_shader *nir, pco_data *data, void *mem_ctx);
void pco_process_ir(pco_ctx *ctx, pco_shader *shader);
void pco_encode_ir(pco_ctx *ctx, pco_shader *shader);
void pco_shader_finalize(pco_ctx *ctx, pco_shader *shader);
unsigned pco_shader_temps(pco_shader *shader);
pco_data *pco_shader_data(pco_shader *shader);
unsigned pco_shader_binary_size(pco_shader *shader);
const void *pco_shader_binary_data(pco_shader *shader);
+3
View File
@@ -142,6 +142,9 @@ void pco_shader_finalize(pco_ctx *ctx, pco_shader *shader)
{
puts("finishme: pco_shader_finalize");
pco_func *entry = pco_entrypoint(shader);
shader->data.common.entry_offset = entry->enc_offset;
if (pco_should_print_binary(shader))
pco_print_binary(shader, stdout, "after finalizing");
}
+108
View File
@@ -0,0 +1,108 @@
/*
* Copyright © 2024 Imagination Technologies Ltd.
*
* SPDX-License-Identifier: MIT
*/
#ifndef PCO_DATA_H
#define PCO_DATA_H
/**
* \file pco_data.h
*
* \brief PCO shader-specific data/compiler-driver interface.
*/
#include "compiler/shader_enums.h"
#include "util/format/u_format.h"
#include <stdbool.h>
/** Generic range struct. */
typedef struct _pco_range {
unsigned start;
unsigned count;
} pco_range;
/** PCO vertex shader-specific data. */
typedef struct _pco_vs_data {
/** Attributes/input mappings. */
pco_range attribs[VERT_ATTRIB_MAX];
enum pipe_format attrib_formats[VERT_ATTRIB_MAX];
/** Varyings/output mappings. */
pco_range varyings[VARYING_SLOT_MAX];
unsigned f32_smooth; /** Number of F32 linear varyings. */
unsigned f32_flat; /** Number of F32 flat varyings. */
unsigned f32_npc; /** Number of F32 NPC varyings. */
unsigned f16_smooth; /** Number of F16 linear varyings. */
unsigned f16_flat; /** Number of F16 flat varyings. */
unsigned f16_npc; /** Number of F16 NPC varyings. */
unsigned vtxouts; /** How many vertex outputs are written to. */
} pco_vs_data;
/** PCO fragment shader-specific data. */
typedef struct _pco_fs_data {
/** Varyings/input mappings. */
pco_range varyings[VARYING_SLOT_MAX];
/** Results/output mappings. */
pco_range outputs[FRAG_RESULT_MAX];
/** If outputs are to be placed in pixout regs. */
bool output_reg[FRAG_RESULT_MAX];
/** Fragment output formats. */
enum pipe_format output_formats[FRAG_RESULT_MAX];
struct {
bool w; /** Whether the shader uses pos.w. */
bool z; /** Whether the shader uses pos.z */
bool pntc; /** Whether the shader uses point coord. */
bool phase_change; /** Whether the shader does a phase change. */
} uses;
} pco_fs_data;
/** PCO compute shader-specific data. */
typedef struct _pco_cs_data {
/**/
} pco_cs_data;
/** PCO common data. */
typedef struct _pco_common_data {
/** System value mappings. */
pco_range sys_vals[SYSTEM_VALUE_MAX];
unsigned temps; /** Number of allocated temp registers. */
unsigned vtxins; /** Number of allocated vertex input registers. */
unsigned interns; /** Number of allocated internal registers. */
unsigned coeffs; /** Number of allocated coefficient registers. */
unsigned shareds; /** Number of allocated shared registers. */
unsigned entry_offset; /** Offset of the shader entrypoint. */
struct {
bool atomics; /** Whether the shader uses atomics. */
bool barriers; /** Whether the shader uses barriers. */
bool side_effects; /** Whether the shader has side effects. */
bool empty; /** Whether the shader is empty. */
} uses;
} pco_common_data;
/** PCO shader data. */
typedef struct _pco_data {
union {
pco_vs_data vs;
pco_fs_data fs;
pco_cs_data cs;
};
pco_common_data common;
} pco_data;
#endif /* PCO_DATA_H */
+5 -2
View File
@@ -17,6 +17,7 @@
#include "hwdef/rogue_hw_utils.h"
#include "pco.h"
#include "pco_common.h"
#include "pco_data.h"
#include "pco_ops.h"
#include "spirv/nir_spirv.h"
#include "util/compiler.h"
@@ -340,6 +341,8 @@ typedef struct _pco_shader {
struct list_head funcs; /** List of functions. */
unsigned next_func; /** Next function index. */
pco_data data; /** Shader data. */
struct {
struct util_dynarray buf; /** Shader binary. */
@@ -1116,8 +1119,8 @@ bool pco_dce(pco_shader *shader);
bool pco_end(pco_shader *shader);
bool pco_group_instrs(pco_shader *shader);
bool pco_index(pco_shader *shader, bool skip_ssa);
bool pco_nir_pfo(nir_shader *nir);
bool pco_nir_pvi(nir_shader *nir);
bool pco_nir_pfo(nir_shader *nir, pco_fs_data *fs);
bool pco_nir_pvi(nir_shader *nir, pco_vs_data *vs);
bool pco_opt(pco_shader *shader);
bool pco_ra(pco_shader *shader);
bool pco_schedule(pco_shader *shader);
+181 -10
View File
@@ -10,6 +10,7 @@
* \brief NIR-specific functions.
*/
#include "nir/nir_builder.h"
#include "pco.h"
#include "pco_internal.h"
@@ -140,13 +141,32 @@ static uint8_t vectorize_filter(const nir_instr *instr, UNUSED const void *data)
return 2;
}
/**
* \brief Filters for a varying position load_input in frag shaders.
*
* \param[in] instr Instruction.
* \param[in] data User data.
* \return True if the instruction was found.
*/
static bool frag_pos_filter(const nir_instr *instr, UNUSED const void *data)
{
assert(instr->type == nir_instr_type_intrinsic);
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
if (intr->intrinsic != nir_intrinsic_load_input)
return false;
return nir_intrinsic_io_semantics(intr).location == VARYING_SLOT_POS;
}
/**
* \brief Lowers a NIR shader.
*
* \param[in] ctx PCO compiler context.
* \param[in,out] nir NIR shader.
* \param[in,out] data Shader data.
*/
void pco_lower_nir(pco_ctx *ctx, nir_shader *nir)
void pco_lower_nir(pco_ctx *ctx, nir_shader *nir, pco_data *data)
{
NIR_PASS(_,
nir,
@@ -163,9 +183,9 @@ void pco_lower_nir(pco_ctx *ctx, nir_shader *nir)
nir_var_shader_in | nir_var_shader_out);
if (nir->info.stage == MESA_SHADER_FRAGMENT) {
NIR_PASS(_, nir, pco_nir_pfo);
NIR_PASS(_, nir, pco_nir_pfo, &data->fs);
} else if (nir->info.stage == MESA_SHADER_VERTEX) {
NIR_PASS(_, nir, pco_nir_pvi);
NIR_PASS(_, nir, pco_nir_pvi, &data->vs);
}
/* TODO: this should happen in the linking stage to cull unused I/O. */
@@ -196,10 +216,26 @@ void pco_lower_nir(pco_ctx *ctx, nir_shader *nir)
NIR_PASS(_, nir, nir_opt_cse);
} while (progress);
NIR_PASS(_,
nir,
nir_opt_vectorize_io,
nir_var_shader_in | nir_var_shader_out);
nir_variable_mode vec_modes = nir_var_shader_in;
/* Fragment shader needs scalar writes after pfo. */
if (nir->info.stage != MESA_SHADER_FRAGMENT)
vec_modes |= nir_var_shader_out;
NIR_PASS(_, nir, nir_opt_vectorize_io, vec_modes);
/* Special case for frag coords:
* - x,y come from (non-consecutive) special regs - always scalar.
* - z,w are iterated and driver will make sure they're consecutive.
* - TODO: keep scalar for now, but add pass to vectorize.
*/
if (nir->info.stage == MESA_SHADER_FRAGMENT) {
NIR_PASS(_,
nir,
nir_lower_io_to_scalar,
nir_var_shader_in,
frag_pos_filter,
NULL);
}
NIR_PASS(_, nir, nir_lower_alu_to_scalar, NULL, NULL);
@@ -219,13 +255,88 @@ void pco_lower_nir(pco_ctx *ctx, nir_shader *nir)
}
}
/**
* \brief Gather fragment shader data pass.
*
* \param[in] b NIR builder.
* \param[in] intr NIR intrinsic instruction.
* \param[in,out] cb_data Callback data.
* \return True if the shader was modified (always return false).
*/
static bool gather_fs_data_pass(UNUSED struct nir_builder *b,
nir_intrinsic_instr *intr,
void *cb_data)
{
/* Check whether the shader accesses z/w. */
if (intr->intrinsic != nir_intrinsic_load_input)
return false;
struct nir_io_semantics io_semantics = nir_intrinsic_io_semantics(intr);
if (io_semantics.location != VARYING_SLOT_POS)
return false;
unsigned component = nir_intrinsic_component(intr);
unsigned chans = intr->def.num_components;
pco_data *data = cb_data;
data->fs.uses.z |= (component + chans > 2);
data->fs.uses.w |= (component + chans > 3);
return false;
}
/**
* \brief Gathers fragment shader data.
*
* \param[in] nir NIR shader.
* \param[in,out] data Shader data.
*/
static void gather_fs_data(nir_shader *nir, pco_data *data)
{
nir_shader_intrinsics_pass(nir, gather_fs_data_pass, nir_metadata_all, data);
/* If any inputs use smooth shading, then w is needed. */
if (!data->fs.uses.w) {
nir_foreach_shader_in_variable (var, nir) {
if (var->data.interpolation > INTERP_MODE_SMOOTH)
continue;
data->fs.uses.w = true;
break;
}
}
}
/**
* \brief Gathers shader data.
*
* \param[in] nir NIR shader.
* \param[in,out] data Shader data.
*/
static void gather_data(nir_shader *nir, pco_data *data)
{
switch (nir->info.stage) {
case MESA_SHADER_FRAGMENT:
return gather_fs_data(nir, data);
case MESA_SHADER_VERTEX:
/* TODO */
break;
default:
unreachable();
}
}
/**
* \brief Runs post-processing passes on a NIR shader.
*
* \param[in] ctx PCO compiler context.
* \param[in,out] nir NIR shader.
* \param[in,out] data Shader data.
*/
void pco_postprocess_nir(pco_ctx *ctx, nir_shader *nir)
void pco_postprocess_nir(pco_ctx *ctx, nir_shader *nir, pco_data *data)
{
NIR_PASS(_, nir, nir_move_vec_src_uses_to_dest, false);
@@ -238,6 +349,8 @@ void pco_postprocess_nir(pco_ctx *ctx, nir_shader *nir)
nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
gather_data(nir, data);
if (pco_should_print_nir(nir)) {
puts("after pco_postprocess_nir:");
nir_print_shader(nir, stdout);
@@ -253,6 +366,9 @@ void pco_postprocess_nir(pco_ctx *ctx, nir_shader *nir)
*/
void pco_link_nir(pco_ctx *ctx, nir_shader *producer, nir_shader *consumer)
{
/* TODO */
puts("finishme: pco_link_nir");
if (pco_should_print_nir(producer)) {
puts("producer after pco_link_nir:");
nir_print_shader(producer, stdout);
@@ -262,6 +378,61 @@ void pco_link_nir(pco_ctx *ctx, nir_shader *producer, nir_shader *consumer)
puts("consumer after pco_link_nir:");
nir_print_shader(consumer, stdout);
}
puts("finishme: pco_link_nir");
}
/**
* \brief Checks whether two varying variables are the same.
*
* \param[in] out_var The first varying being compared.
* \param[in] in_var The second varying being compared.
* \return True if the varyings match.
*/
static bool varyings_match(nir_variable *out_var, nir_variable *in_var)
{
return in_var->data.location == out_var->data.location &&
in_var->data.location_frac == out_var->data.location_frac &&
in_var->type == out_var->type;
}
/**
* \brief Performs reverse linking optimizations on consecutive NIR shader
* stages.
*
* \param[in] ctx PCO compiler context.
* \param[in,out] producer NIR producer shader.
* \param[in,out] consumer NIR consumer shader.
*/
PUBLIC
void pco_rev_link_nir(pco_ctx *ctx, nir_shader *producer, nir_shader *consumer)
{
/* TODO */
puts("finishme: pco_rev_link_nir");
/* Propagate back/adjust the interpolation qualifiers. */
nir_foreach_shader_in_variable (in_var, consumer) {
if (in_var->data.location == VARYING_SLOT_POS ||
in_var->data.location == VARYING_SLOT_PNTC) {
in_var->data.interpolation = INTERP_MODE_NOPERSPECTIVE;
} else if (in_var->data.interpolation == INTERP_MODE_NONE) {
in_var->data.interpolation = INTERP_MODE_SMOOTH;
}
nir_foreach_shader_out_variable (out_var, producer) {
if (!varyings_match(out_var, in_var))
continue;
out_var->data.interpolation = in_var->data.interpolation;
break;
}
}
if (pco_should_print_nir(producer)) {
puts("producer after pco_rev_link_nir:");
nir_print_shader(producer, stdout);
}
if (pco_should_print_nir(consumer)) {
puts("consumer after pco_rev_link_nir:");
nir_print_shader(consumer, stdout);
}
}
+74 -22
View File
@@ -10,6 +10,8 @@
* \brief PCO NIR per-vertex/fragment input/output passes.
*/
#include "compiler/glsl_types.h"
#include "compiler/shader_enums.h"
#include "nir.h"
#include "nir_builder.h"
#include "pco.h"
@@ -25,6 +27,7 @@
/** Per-fragment output pass state. */
struct pfo_state {
struct util_dynarray stores; /** List of fragment stores. */
pco_fs_data *fs; /** Fragment-specific data. */
};
/**
@@ -51,6 +54,36 @@ static inline nir_intrinsic_instr *is_intr(nir_instr *instr,
return intr;
}
/**
* \brief Returns the GLSL base type equivalent of a pipe format.
*
* \param[in] format Pipe format.
* \return The GLSL base type, or GLSL_TYPE_ERROR if unsupported/invalid.
*/
static inline enum glsl_base_type base_type_from_fmt(enum pipe_format format)
{
const struct util_format_description *desc = util_format_description(format);
int chan = util_format_get_first_non_void_channel(format);
if (chan < 0)
return GLSL_TYPE_ERROR;
switch (desc->channel[chan].type) {
case UTIL_FORMAT_TYPE_UNSIGNED:
return GLSL_TYPE_UINT;
case UTIL_FORMAT_TYPE_SIGNED:
return GLSL_TYPE_INT;
case UTIL_FORMAT_TYPE_FLOAT:
return GLSL_TYPE_FLOAT;
default:
break;
}
return GLSL_TYPE_ERROR;
}
/**
* \brief Lowers a PFO-related instruction.
*
@@ -89,31 +122,48 @@ static bool lower_pfo(nir_builder *b, nir_instr *instr, void *cb_data)
assert(nir_src_num_components(*value) == 4);
assert(nir_src_bit_size(*value) == 32);
/* Update the type of the stored variable. */
nir_variable *var = nir_find_variable_with_location(
b->shader,
nir_var_shader_out,
nir_intrinsic_io_semantics(intr).location);
struct nir_io_semantics io_semantics = nir_intrinsic_io_semantics(intr);
gl_frag_result location = io_semantics.location;
var->type = glsl_uint_type();
enum pipe_format format = state->fs->output_formats[location];
unsigned format_bits = util_format_get_blocksizebits(format);
assert(!(format_bits % 32));
/* Update the type of the stored variable. */
nir_variable *var = nir_find_variable_with_location(b->shader,
nir_var_shader_out,
location);
assert(var);
var->type = glsl_simple_explicit_type(base_type_from_fmt(format),
format_bits / 32,
1,
0,
false,
0);
b->cursor = nir_after_block(
nir_impl_last_block(nir_shader_get_entrypoint(b->shader)));
/* Emit and track the new store. */
/* TODO NEXT: base is calculated to be the register offset. */
nir_intrinsic_instr *store =
nir_store_output(b,
nir_pack_unorm_4x8(b, value->ssa),
offset->ssa,
.base = nir_intrinsic_base(intr),
.write_mask = 1,
.component = 0,
.src_type = nir_type_uint32,
.io_semantics = nir_intrinsic_io_semantics(intr),
.io_xfb = nir_intrinsic_io_xfb(intr),
.io_xfb2 = nir_intrinsic_io_xfb2(intr));
util_dynarray_append(&state->stores, nir_intrinsic_instr *, store);
/* TODO: support other formats. */
if (format == PIPE_FORMAT_R8G8B8A8_UNORM) {
nir_intrinsic_instr *store =
nir_store_output(b,
nir_pack_unorm_4x8(b, value->ssa),
offset->ssa,
.base = nir_intrinsic_base(intr),
.write_mask = 1,
.component = 0,
.src_type = nir_type_uint32,
.io_semantics = io_semantics,
.io_xfb = nir_intrinsic_io_xfb(intr),
.io_xfb2 = nir_intrinsic_io_xfb2(intr));
util_dynarray_append(&state->stores, nir_intrinsic_instr *, store);
} else {
unreachable();
}
/* Remove the old store. */
b->cursor = nir_instr_remove(instr);
@@ -128,13 +178,14 @@ static bool lower_pfo(nir_builder *b, nir_instr *instr, void *cb_data)
* \brief Per-fragment output pass.
*
* \param[in,out] nir NIR shader.
* \param[in,out] fs Fragment shader-specific data.
* \return True if the pass made progress.
*/
bool pco_nir_pfo(nir_shader *nir)
bool pco_nir_pfo(nir_shader *nir, pco_fs_data *fs)
{
assert(nir->info.stage == MESA_SHADER_FRAGMENT);
struct pfo_state state = {};
struct pfo_state state = { .fs = fs };
util_dynarray_init(&state.stores, NULL);
bool progress =
@@ -149,9 +200,10 @@ bool pco_nir_pfo(nir_shader *nir)
* \brief Per-vertex input pass.
*
* \param[in,out] nir NIR shader.
* \param[in,out] vs Vertex shader-specific data.
* \return True if the pass made progress.
*/
bool pco_nir_pvi(nir_shader *nir)
bool pco_nir_pvi(nir_shader *nir, pco_vs_data *vs)
{
assert(nir->info.stage == MESA_SHADER_VERTEX);
+2
View File
@@ -377,6 +377,8 @@ bool pco_ra(pco_shader *shader)
allocable_temps,
allocable_vtxins,
allocable_interns);
shader->data.common.temps = MAX2(shader->data.common.temps, func->temps);
}
return progress;
+160 -69
View File
@@ -12,6 +12,7 @@
#include "compiler/glsl/list.h"
#include "compiler/shader_enums.h"
#include "hwdef/rogue_hw_defs.h"
#include "pco.h"
#include "pco_builder.h"
#include "pco_internal.h"
@@ -182,21 +183,25 @@ pco_ref_nir_alu_src_t(const nir_alu_instr *alu, unsigned src, trans_ctx *tctx)
static pco_instr *
trans_load_input_vs(trans_ctx *tctx, nir_intrinsic_instr *intr, pco_ref dest)
{
puts("finishme: trans_load_input_vs");
ASSERTED unsigned base = nir_intrinsic_base(intr);
assert(!base);
/* unsigned base = nir_intrinsic_base(intr); */
unsigned base =
nir_intrinsic_io_semantics(intr).location - VERT_ATTRIB_GENERIC0;
ASSERTED nir_alu_type type = nir_intrinsic_dest_type(intr);
assert(type == nir_type_float32);
/* TODO: f16 support. */
ASSERTED const nir_src offset = intr->src[0];
assert(nir_src_as_uint(offset) == 0);
gl_vert_attrib location = nir_intrinsic_io_semantics(intr).location;
unsigned component = nir_intrinsic_component(intr);
unsigned chans = pco_ref_get_chans(dest);
const nir_src offset = intr->src[0];
assert(nir_src_as_uint(offset) == 0);
/* TODO NEXT: Wrong! Do properly! */
unsigned vtxin_offset = (4 * base) + component;
pco_ref src = pco_ref_hwreg_vec(vtxin_offset, PCO_REG_CLASS_VTXIN, chans);
const pco_range *range = &tctx->shader->data.vs.attribs[location];
assert(component + chans <= range->count);
pco_ref src =
pco_ref_hwreg_vec(range->start + component, PCO_REG_CLASS_VTXIN, chans);
return pco_mov(&tctx->b, dest, src, .rpt = chans);
}
@@ -211,34 +216,28 @@ trans_load_input_vs(trans_ctx *tctx, nir_intrinsic_instr *intr, pco_ref dest)
static pco_instr *
trans_store_output_vs(trans_ctx *tctx, nir_intrinsic_instr *intr, pco_ref src)
{
puts("finishme: trans_store_output_vs");
ASSERTED unsigned base = nir_intrinsic_base(intr);
assert(!base);
/* unsigned base = nir_intrinsic_base(intr); */
ASSERTED nir_alu_type type = nir_intrinsic_src_type(intr);
assert(type == nir_type_float32);
/* TODO: f16 support. */
unsigned location = nir_intrinsic_io_semantics(intr).location;
unsigned base;
switch (location) {
case VARYING_SLOT_POS:
base = 0;
break;
case VARYING_SLOT_VAR0 ... VARYING_SLOT_VAR31:
base = location - VARYING_SLOT_VAR0 + 1;
break;
default:
unreachable();
}
ASSERTED const nir_src offset = intr->src[1];
assert(nir_src_as_uint(offset) == 0);
gl_varying_slot location = nir_intrinsic_io_semantics(intr).location;
unsigned component = nir_intrinsic_component(intr);
unsigned chans = pco_ref_get_chans(src);
const nir_src offset = intr->src[1];
assert(nir_src_as_uint(offset) == 0);
/* Only contiguous write masks supported. */
ASSERTED unsigned write_mask = nir_intrinsic_write_mask(intr);
assert(write_mask == BITFIELD_MASK(chans));
/* TODO NEXT: Wrong! Do properly! */
pco_ref vtxout_addr = pco_ref_val8((4 * base) + component);
const pco_range *range = &tctx->shader->data.vs.varyings[location];
assert(component + chans <= range->count);
pco_ref vtxout_addr = pco_ref_val8(range->start + component);
return pco_uvsw_write(&tctx->b, src, vtxout_addr, .rpt = chans);
}
@@ -253,8 +252,7 @@ trans_store_output_vs(trans_ctx *tctx, nir_intrinsic_instr *intr, pco_ref src)
static pco_instr *
trans_load_input_fs(trans_ctx *tctx, nir_intrinsic_instr *intr, pco_ref dest)
{
puts("finishme: trans_load_input_fs");
pco_fs_data *fs_data = &tctx->shader->data.fs;
ASSERTED unsigned base = nir_intrinsic_base(intr);
assert(!base);
@@ -264,34 +262,116 @@ trans_load_input_fs(trans_ctx *tctx, nir_intrinsic_instr *intr, pco_ref dest)
const nir_src offset = intr->src[0];
assert(nir_src_as_uint(offset) == 0);
/* TODO NEXT: Wrong! Do properly! */
unsigned loc_offset =
nir_intrinsic_io_semantics(intr).location - VARYING_SLOT_VAR0;
/* TEMP: +1 to skip over wcoeffs */
unsigned coeffs_index = 4 * (loc_offset + component + 1);
unsigned wcoeffs_index = 0;
struct nir_io_semantics io_semantics = nir_intrinsic_io_semantics(intr);
gl_varying_slot location = io_semantics.location;
pco_ref coeffs =
pco_ref_hwreg_vec(coeffs_index, PCO_REG_CLASS_COEFF, 4 * chans);
pco_ref wcoeffs = pco_ref_hwreg_vec(wcoeffs_index, PCO_REG_CLASS_COEFF, 4);
nir_variable *var = nir_find_variable_with_location(tctx->shader->nir,
nir_var_shader_in,
location);
enum pco_itr_mode itr_mode = PCO_ITR_MODE_PIXEL;
assert(!(var->data.sample && var->data.centroid));
if (var->data.sample)
itr_mode = PCO_ITR_MODE_SAMPLE;
else if (var->data.centroid)
itr_mode = PCO_ITR_MODE_CENTROID;
if (location == VARYING_SLOT_POS) {
/* Only scalar supported for now. */
/* TODO: support vector for zw. */
assert(chans == 1);
/* TODO: support packing/partial vars. */
assert(!var->data.location_frac);
assert(var->data.interpolation == INTERP_MODE_NOPERSPECTIVE);
/* Special case: x and y are loaded from special registers. */
/* TODO: select appropriate regs if sample rate shading. */
switch (component) {
case 0: /* x */
return pco_mov(&tctx->b,
dest,
pco_ref_hwreg(PCO_SR_X_P, PCO_REG_CLASS_SPEC));
case 1: /* y */
return pco_mov(&tctx->b,
dest,
pco_ref_hwreg(PCO_SR_Y_P, PCO_REG_CLASS_SPEC));
case 2:
assert(fs_data->uses.z);
component = 0;
break;
case 3:
assert(fs_data->uses.w);
component = fs_data->uses.z ? 1 : 0;
break;
default:
unreachable();
}
}
const pco_range *range = &fs_data->varyings[location];
assert(component + (ROGUE_USC_COEFFICIENT_SET_SIZE * chans) <= range->count);
unsigned coeffs_index =
range->start + (ROGUE_USC_COEFFICIENT_SET_SIZE * component);
pco_ref coeffs = pco_ref_hwreg_vec(coeffs_index,
PCO_REG_CLASS_COEFF,
ROGUE_USC_COEFFICIENT_SET_SIZE * chans);
pco_ref itr_count = pco_ref_val16(chans);
if (PVR_HAS_FEATURE(tctx->pco_ctx->dev_info, usc_itrsmp_enhanced)) {
return pco_ditrp(&tctx->b,
dest,
pco_ref_drc(PCO_DRC_0),
coeffs,
wcoeffs,
itr_count,
.itr_mode = PCO_ITR_MODE_PIXEL);
} else {
return pco_fitrp(&tctx->b,
dest,
pco_ref_drc(PCO_DRC_0),
coeffs,
wcoeffs,
itr_count,
.itr_mode = PCO_ITR_MODE_PIXEL);
bool usc_itrsmp_enhanced =
PVR_HAS_FEATURE(tctx->pco_ctx->dev_info, usc_itrsmp_enhanced);
switch (var->data.interpolation) {
case INTERP_MODE_SMOOTH: {
assert(fs_data->uses.w);
unsigned wcoeffs_index = fs_data->uses.z ? ROGUE_USC_COEFFICIENT_SET_SIZE
: 0;
pco_ref wcoeffs = pco_ref_hwreg_vec(wcoeffs_index,
PCO_REG_CLASS_COEFF,
ROGUE_USC_COEFFICIENT_SET_SIZE);
return usc_itrsmp_enhanced ? pco_ditrp(&tctx->b,
dest,
pco_ref_drc(PCO_DRC_0),
coeffs,
wcoeffs,
itr_count,
.itr_mode = itr_mode)
: pco_fitrp(&tctx->b,
dest,
pco_ref_drc(PCO_DRC_0),
coeffs,
wcoeffs,
itr_count,
.itr_mode = itr_mode);
}
case INTERP_MODE_NOPERSPECTIVE:
return usc_itrsmp_enhanced ? pco_ditr(&tctx->b,
dest,
pco_ref_drc(PCO_DRC_0),
coeffs,
itr_count,
.itr_mode = itr_mode)
: pco_fitr(&tctx->b,
dest,
pco_ref_drc(PCO_DRC_0),
coeffs,
itr_count,
.itr_mode = itr_mode);
default:
/* Should have been previously lowered. */
unreachable();
}
}
@@ -306,21 +386,26 @@ trans_load_input_fs(trans_ctx *tctx, nir_intrinsic_instr *intr, pco_ref dest)
static pco_instr *
trans_store_output_fs(trans_ctx *tctx, nir_intrinsic_instr *intr, pco_ref src)
{
ASSERTED unsigned base = nir_intrinsic_base(intr);
assert(!base);
assert(pco_ref_is_scalar(src));
puts("finishme: trans_store_output_fs");
unsigned component = nir_intrinsic_component(intr);
bool is_reg_store = nir_src_is_const(intr->src[1]);
unsigned base = nir_intrinsic_base(intr);
ASSERTED const nir_src offset = intr->src[1];
assert(nir_src_as_uint(offset) == 0);
if (is_reg_store) {
/* TODO NEXT: Wrong! Do properly! */
pco_ref dest = pco_ref_hwreg(base, PCO_REG_CLASS_PIXOUT);
/* TODO NEXT: optimize this to be propagated (backwards?) */
/* return pco_mbyp0(&tctx->b, dest, src, .olchk = true); */
return pco_mov(&tctx->b, dest, src, .olchk = true);
}
gl_varying_slot location = nir_intrinsic_io_semantics(intr).location;
unreachable();
const pco_range *range = &tctx->shader->data.fs.outputs[location];
assert(component < range->count);
ASSERTED bool output_reg = tctx->shader->data.fs.output_reg[location];
assert(output_reg);
/* TODO: tile buffer support. */
pco_ref dest = pco_ref_hwreg(range->start + component, PCO_REG_CLASS_PIXOUT);
return pco_mov(&tctx->b, dest, src, .olchk = true);
}
/**
@@ -804,12 +889,18 @@ static pco_block *trans_cf_nodes(trans_ctx *tctx,
*
* \param[in] ctx PCO compiler context.
* \param[in] nir NIR shader.
* \param[in] data Shader-specific data.
* \param[in] mem_ctx Ralloc memory allocation context.
* \return The PCO shader.
*/
pco_shader *pco_trans_nir(pco_ctx *ctx, nir_shader *nir, void *mem_ctx)
pco_shader *
pco_trans_nir(pco_ctx *ctx, nir_shader *nir, pco_data *data, void *mem_ctx)
{
pco_shader *shader = pco_shader_create(ctx, nir, mem_ctx);
if (data)
memcpy(&shader->data, data, sizeof(*data));
trans_ctx tctx = {
.pco_ctx = ctx,
.shader = shader,
+66 -58
View File
@@ -3366,9 +3366,11 @@ pvr_setup_vertex_buffers(struct pvr_cmd_buffer *cmd_buffer,
case PVR_PDS_CONST_MAP_ENTRY_TYPE_DOUTU_ADDRESS: {
const struct pvr_const_map_entry_doutu_address *const doutu_addr =
(struct pvr_const_map_entry_doutu_address *)entries;
const pco_data *const vs_data = &state->gfx_pipeline->vs_data;
const pvr_dev_addr_t exec_addr =
PVR_DEV_ADDR_OFFSET(vertex_state->bo->dev_addr,
vertex_state->entry_offset);
vs_data->common.entry_offset);
uint64_t addr = 0ULL;
pvr_set_usc_execution_address64(&addr, exec_addr.addr);
@@ -4769,19 +4771,10 @@ pvr_update_draw_state(struct pvr_cmd_buffer_state *const state,
static uint32_t pvr_calc_shared_regs_count(
const struct pvr_graphics_pipeline *const gfx_pipeline)
{
const struct pvr_pipeline_stage_state *const vertex_state =
&gfx_pipeline->shader_state.vertex.stage_state;
uint32_t shared_regs = vertex_state->const_shared_reg_count +
vertex_state->const_shared_reg_offset;
uint32_t shared_regs = gfx_pipeline->vs_data.common.shareds;
if (gfx_pipeline->shader_state.fragment.bo) {
const struct pvr_pipeline_stage_state *const fragment_state =
&gfx_pipeline->shader_state.fragment.stage_state;
uint32_t fragment_regs = fragment_state->const_shared_reg_count +
fragment_state->const_shared_reg_offset;
uint32_t fragment_regs = gfx_pipeline->fs_data.common.shareds;
shared_regs = MAX2(shared_regs, fragment_regs);
}
@@ -4797,8 +4790,7 @@ pvr_emit_dirty_pds_state(const struct pvr_cmd_buffer *const cmd_buffer,
const struct pvr_stage_allocation_descriptor_state
*const vertex_descriptor_state =
&state->gfx_pipeline->shader_state.vertex.descriptor_state;
const struct pvr_pipeline_stage_state *const vertex_stage_state =
&state->gfx_pipeline->shader_state.vertex.stage_state;
const pco_data *const vs_data = &state->gfx_pipeline->vs_data;
struct pvr_csb *const csb = &sub_cmd->control_stream;
if (!vertex_descriptor_state->pds_info.code_size_in_dwords)
@@ -4810,7 +4802,7 @@ pvr_emit_dirty_pds_state(const struct pvr_cmd_buffer *const cmd_buffer,
state0.usc_target = ROGUE_VDMCTRL_USC_TARGET_ALL;
state0.usc_common_size =
DIV_ROUND_UP(vertex_stage_state->const_shared_reg_count << 2,
DIV_ROUND_UP(vs_data->common.shareds,
ROGUE_VDMCTRL_PDS_STATE0_USC_COMMON_SIZE_UNIT_SIZE);
state0.pds_data_size = DIV_ROUND_UP(
@@ -4835,21 +4827,33 @@ static void pvr_setup_output_select(struct pvr_cmd_buffer *const cmd_buffer)
{
const struct pvr_graphics_pipeline *const gfx_pipeline =
cmd_buffer->state.gfx_pipeline;
const struct pvr_vertex_shader_state *const vertex_state =
&gfx_pipeline->shader_state.vertex;
struct vk_dynamic_graphics_state *const dynamic_state =
&cmd_buffer->vk.dynamic_graphics_state;
struct ROGUE_TA_STATE_HEADER *const header = &cmd_buffer->state.emit_header;
struct pvr_ppp_state *const ppp_state = &cmd_buffer->state.ppp_state;
const pco_data *const vs_data = &gfx_pipeline->vs_data;
const pco_data *const fs_data = &gfx_pipeline->fs_data;
uint32_t output_selects;
uint32_t varying[2];
/* TODO: Handle vertex and fragment shader state flags. */
const pco_range *varyings = vs_data->vs.varyings;
const bool has_point_size = dynamic_state->ia.primitive_topology ==
VK_PRIMITIVE_TOPOLOGY_POINT_LIST &&
varyings[VARYING_SLOT_PSIZ].count > 0;
const bool has_viewport = varyings[VARYING_SLOT_VIEWPORT].count > 0;
const bool has_layer = varyings[VARYING_SLOT_LAYER].count > 0;
pvr_csb_pack (&output_selects, TA_OUTPUT_SEL, state) {
state.rhw_pres = true;
state.vtxsize = DIV_ROUND_UP(vertex_state->vertex_output_size, 4U);
state.psprite_size_pres = (dynamic_state->ia.primitive_topology ==
VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
state.rhw_pres = fs_data->fs.uses.w;
state.tsp_unclamped_z_pres = fs_data->fs.uses.z;
state.vtxsize = vs_data->vs.vtxouts;
state.psprite_size_pres = has_point_size;
state.vpt_tgt_pres = has_viewport;
state.render_tgt_pres = has_layer;
}
if (ppp_state->output_selects != output_selects) {
@@ -4857,13 +4861,25 @@ static void pvr_setup_output_select(struct pvr_cmd_buffer *const cmd_buffer)
header->pres_outselects = true;
}
if (ppp_state->varying_word[0] != vertex_state->varying[0]) {
ppp_state->varying_word[0] = vertex_state->varying[0];
pvr_csb_pack (&varying[0], TA_STATE_VARYING0, varying0) {
varying0.f32_linear = vs_data->vs.f32_smooth;
varying0.f32_flat = vs_data->vs.f32_flat;
varying0.f32_npc = vs_data->vs.f32_npc;
}
if (ppp_state->varying_word[0] != varying[0]) {
ppp_state->varying_word[0] = varying[0];
header->pres_varying_word0 = true;
}
if (ppp_state->varying_word[1] != vertex_state->varying[1]) {
ppp_state->varying_word[1] = vertex_state->varying[1];
pvr_csb_pack (&varying[1], TA_STATE_VARYING1, varying1) {
varying1.f16_linear = vs_data->vs.f16_smooth;
varying1.f16_flat = vs_data->vs.f16_flat;
varying1.f16_npc = vs_data->vs.f16_npc;
}
if (ppp_state->varying_word[1] != varying[1]) {
ppp_state->varying_word[1] = varying[1];
header->pres_varying_word1 = true;
}
}
@@ -5402,15 +5418,16 @@ pvr_setup_fragment_state_pointers(struct pvr_cmd_buffer *const cmd_buffer,
struct pvr_sub_cmd_gfx *const sub_cmd)
{
struct pvr_cmd_buffer_state *const state = &cmd_buffer->state;
const pco_data *const fs_data = &state->gfx_pipeline->fs_data;
const struct pvr_fragment_shader_state *const fragment =
const struct pvr_fragment_shader_state *const fragment_shader_state =
&state->gfx_pipeline->shader_state.fragment;
const struct pvr_stage_allocation_descriptor_state *descriptor_shader_state =
&fragment->descriptor_state;
&fragment_shader_state->descriptor_state;
const struct pvr_pipeline_stage_state *fragment_state =
&fragment->stage_state;
&fragment_shader_state->stage_state;
const struct pvr_pds_upload *pds_coeff_program =
&fragment->pds_coeff_program;
&fragment_shader_state->pds_coeff_program;
const struct pvr_physical_device *pdevice = cmd_buffer->device->pdevice;
struct ROGUE_TA_STATE_HEADER *const header = &state->emit_header;
@@ -5425,7 +5442,7 @@ pvr_setup_fragment_state_pointers(struct pvr_cmd_buffer *const cmd_buffer,
ROGUE_TA_STATE_PDS_SIZEINFO1_PDS_VARYINGSIZE_UNIT_SIZE);
const uint32_t usc_varying_size =
DIV_ROUND_UP(fragment_state->coefficient_size,
DIV_ROUND_UP(fs_data->common.coeffs,
ROGUE_TA_STATE_PDS_SIZEINFO1_USC_VARYINGSIZE_UNIT_SIZE);
const uint32_t pds_temp_size =
@@ -5433,7 +5450,7 @@ pvr_setup_fragment_state_pointers(struct pvr_cmd_buffer *const cmd_buffer,
ROGUE_TA_STATE_PDS_SIZEINFO1_PDS_TEMPSIZE_UNIT_SIZE);
const uint32_t usc_shared_size =
DIV_ROUND_UP(fragment_state->const_shared_reg_count,
DIV_ROUND_UP(fs_data->common.shareds,
ROGUE_TA_STATE_PDS_SIZEINFO2_USC_SHAREDSIZE_UNIT_SIZE);
const uint32_t max_tiles_in_flight =
@@ -5453,7 +5470,7 @@ pvr_setup_fragment_state_pointers(struct pvr_cmd_buffer *const cmd_buffer,
TA_STATE_PDS_SHADERBASE,
shader_base) {
const struct pvr_pds_upload *const pds_upload =
&fragment->pds_fragment_program;
&fragment_shader_state->pds_fragment_program;
shader_base.addr = PVR_DEV_ADDR(pds_upload->data_offset);
}
@@ -6010,7 +6027,7 @@ pvr_emit_dirty_ppp_state(struct pvr_cmd_buffer *const cmd_buffer,
if (!dynamic_state->rs.rasterizer_discard_enable &&
state->dirty.fragment_descriptors &&
state->gfx_pipeline->shader_state.fragment.bo &&
!state->gfx_pipeline->shader_state.fragment.stage_state.empty_program) {
!state->gfx_pipeline->fs_data.common.uses.empty) {
pvr_setup_fragment_state_pointers(cmd_buffer, sub_cmd);
}
@@ -6127,22 +6144,16 @@ static void pvr_emit_dirty_vdm_state(struct pvr_cmd_buffer *const cmd_buffer,
struct vk_dynamic_graphics_state *const dynamic_state =
&cmd_buffer->vk.dynamic_graphics_state;
const struct pvr_cmd_buffer_state *const state = &cmd_buffer->state;
const struct pvr_vertex_shader_state *const vertex_shader_state =
&state->gfx_pipeline->shader_state.vertex;
const pco_data *const vs_data = &state->gfx_pipeline->vs_data;
struct pvr_csb *const csb = &sub_cmd->control_stream;
uint32_t vs_output_size;
uint32_t max_instances;
uint32_t cam_size;
/* CAM Calculations and HW state take vertex size aligned to DWORDS. */
vs_output_size =
DIV_ROUND_UP(vertex_shader_state->vertex_output_size,
ROGUE_VDMCTRL_VDM_STATE4_VS_OUTPUT_SIZE_UNIT_SIZE);
assert(vs_output_size <= max_user_vertex_output_components);
assert(vs_data->vs.vtxouts <= max_user_vertex_output_components);
pvr_calculate_vertex_cam_size(dev_info,
vs_output_size,
vs_data->vs.vtxouts,
true,
&cam_size,
&max_instances);
@@ -6210,8 +6221,8 @@ static void pvr_emit_dirty_vdm_state(struct pvr_cmd_buffer *const cmd_buffer,
}
if (header.vs_other_present) {
const uint32_t usc_unified_store_size_in_bytes =
vertex_shader_state->vertex_input_size << 2;
const uint32_t usc_unified_store_size_in_bytes = vs_data->common.vtxins
<< 2;
pvr_csb_emit (csb, VDMCTRL_VDM_STATE3, state3) {
state3.vs_pds_code_base_addr =
@@ -6219,7 +6230,7 @@ static void pvr_emit_dirty_vdm_state(struct pvr_cmd_buffer *const cmd_buffer,
}
pvr_csb_emit (csb, VDMCTRL_VDM_STATE4, state4) {
state4.vs_output_size = vs_output_size;
state4.vs_output_size = vs_data->vs.vtxouts;
}
pvr_csb_emit (csb, VDMCTRL_VDM_STATE5, state5) {
@@ -6246,10 +6257,7 @@ static VkResult pvr_validate_draw_state(struct pvr_cmd_buffer *cmd_buffer)
struct vk_dynamic_graphics_state *const dynamic_state =
&cmd_buffer->vk.dynamic_graphics_state;
const struct pvr_graphics_pipeline *const gfx_pipeline = state->gfx_pipeline;
const struct pvr_pipeline_stage_state *const fragment_state =
&gfx_pipeline->shader_state.fragment.stage_state;
const struct pvr_pipeline_stage_state *const vertex_state =
&gfx_pipeline->shader_state.vertex.stage_state;
const pco_data *const fs_data = &gfx_pipeline->fs_data;
struct pvr_sub_cmd_gfx *sub_cmd;
bool fstencil_writemask_zero;
bool bstencil_writemask_zero;
@@ -6282,7 +6290,7 @@ static VkResult pvr_validate_draw_state(struct pvr_cmd_buffer *cmd_buffer)
if (PVR_HAS_FEATURE(&cmd_buffer->device->pdevice->dev_info,
compute_overlap)) {
uint32_t coefficient_size =
DIV_ROUND_UP(fragment_state->coefficient_size,
DIV_ROUND_UP(fs_data->common.coeffs,
ROGUE_TA_STATE_PDS_SIZEINFO1_USC_VARYINGSIZE_UNIT_SIZE);
if (coefficient_size >
@@ -6290,10 +6298,10 @@ static VkResult pvr_validate_draw_state(struct pvr_cmd_buffer *cmd_buffer)
sub_cmd->disable_compute_overlap = true;
}
sub_cmd->frag_uses_atomic_ops |= fragment_state->uses_atomic_ops;
sub_cmd->frag_has_side_effects |= fragment_state->has_side_effects;
sub_cmd->frag_uses_texture_rw |= fragment_state->uses_texture_rw;
sub_cmd->vertex_uses_texture_rw |= vertex_state->uses_texture_rw;
sub_cmd->frag_uses_atomic_ops |= fs_data->common.uses.atomics;
sub_cmd->frag_has_side_effects |= fs_data->common.uses.side_effects;
sub_cmd->frag_uses_texture_rw |= false;
sub_cmd->vertex_uses_texture_rw |= false;
sub_cmd->job.get_vis_results = state->vis_test_enabled;
@@ -6656,8 +6664,8 @@ static void pvr_emit_vdm_index_list(struct pvr_cmd_buffer *cmd_buffer,
uint32_t stride)
{
struct pvr_cmd_buffer_state *state = &cmd_buffer->state;
const bool vertex_shader_has_side_effects =
state->gfx_pipeline->shader_state.vertex.stage_state.has_side_effects;
const pco_data *const vs_data = &state->gfx_pipeline->vs_data;
struct ROGUE_VDMCTRL_INDEX_LIST0 list_hdr = { pvr_cmd_header(
VDMCTRL_INDEX_LIST0) };
pvr_dev_addr_t index_buffer_addr = PVR_DEV_ADDR_INVALID;
@@ -6695,7 +6703,7 @@ static void pvr_emit_vdm_index_list(struct pvr_cmd_buffer *cmd_buffer,
list_hdr.degen_cull_enable =
PVR_HAS_FEATURE(&cmd_buffer->device->pdevice->dev_info,
vdm_degenerate_culling) &&
!vertex_shader_has_side_effects;
!vs_data->common.uses.side_effects;
if (state->draw_state.draw_indirect) {
assert(buffer);
@@ -108,27 +108,6 @@ pvr_zls_format_type_is_int(enum ROGUE_CR_ZLS_FORMAT_TYPE type)
}
}
/******************************************************************************
PDS
******************************************************************************/
/* clang-format off */
static inline enum ROGUE_PDSINST_DOUTU_SAMPLE_RATE
pvr_pdsinst_doutu_sample_rate(enum pvr_msaa_mode msaa_mode)
/* clang-format on */
{
switch (msaa_mode) {
case PVR_MSAA_MODE_PIXEL:
return ROGUE_PDSINST_DOUTU_SAMPLE_RATE_INSTANCE;
case PVR_MSAA_MODE_SELECTIVE:
return ROGUE_PDSINST_DOUTU_SAMPLE_RATE_SELECTIVE;
case PVR_MSAA_MODE_FULL:
return ROGUE_PDSINST_DOUTU_SAMPLE_RATE_FULL;
default:
unreachable("Undefined MSAA mode.");
}
}
/******************************************************************************
PBESTATE
******************************************************************************/
-8
View File
@@ -294,10 +294,6 @@ void pvr_hard_code_graphics_get_build_info(
data->graphics.vert_shader_states[pipeline_n]
->stage_state.pds_temps_count);
assert(data->graphics.build_infos[pipeline_n]->vert_common_data.coeffs ==
data->graphics.vert_shader_states[pipeline_n]
->stage_state.coefficient_size);
build_data->vs = data->graphics.build_infos[pipeline_n]->stage_data.vs;
*common_build_data =
data->graphics.build_infos[pipeline_n]->vert_common_data;
@@ -311,10 +307,6 @@ void pvr_hard_code_graphics_get_build_info(
data->graphics.frag_shader_states[pipeline_n]
->stage_state.pds_temps_count);
assert(data->graphics.build_infos[pipeline_n]->frag_common_data.coeffs ==
data->graphics.frag_shader_states[pipeline_n]
->stage_state.coefficient_size);
build_data->fs = data->graphics.build_infos[pipeline_n]->stage_data.fs;
*common_build_data =
data->graphics.build_infos[pipeline_n]->frag_common_data;
+14 -28
View File
@@ -40,26 +40,6 @@
#include "vk_log.h"
#include "vk_render_pass.h"
/*****************************************************************************
PDS pre-baked program generation parameters and variables.
*****************************************************************************/
/* These would normally be produced by the compiler or other code. We're using
* them for now just to speed up things. All of these should eventually be
* removed.
*/
static const struct {
/* Indicates the amount of temporaries for the shader. */
uint32_t temp_count;
enum pvr_msaa_mode msaa_mode;
/* Indicates the presence of PHAS instruction. */
bool has_phase_rate_change;
} pvr_pds_fragment_program_params = {
.temp_count = 0,
.msaa_mode = PVR_MSAA_MODE_PIXEL,
.has_phase_rate_change = false,
};
static inline bool pvr_subpass_has_msaa_input_attachment(
struct pvr_render_subpass *subpass,
const VkRenderPassCreateInfo2 *pCreateInfo)
@@ -330,14 +310,20 @@ pvr_generate_load_op_shader(struct pvr_device *device,
if (result != VK_SUCCESS)
return result;
result = pvr_pds_fragment_program_create_and_upload(
device,
allocator,
load_op->usc_frag_prog_bo,
pvr_pds_fragment_program_params.temp_count,
pvr_pds_fragment_program_params.msaa_mode,
pvr_pds_fragment_program_params.has_phase_rate_change,
&load_op->pds_frag_prog);
/* TODO: amend this once the hardcoded shaders have been removed. */
struct pvr_fragment_shader_state fragment_state = {
.bo = load_op->usc_frag_prog_bo,
.sample_rate = ROGUE_PDSINST_DOUTU_SAMPLE_RATE_INSTANCE,
.pds_fragment_program = load_op->pds_frag_prog,
};
result = pvr_pds_fragment_program_create_and_upload(device,
allocator,
NULL,
&fragment_state);
load_op->usc_frag_prog_bo = fragment_state.bo;
load_op->pds_frag_prog = fragment_state.pds_fragment_program;
if (result != VK_SUCCESS)
goto err_free_usc_frag_prog_bo;
File diff suppressed because it is too large Load Diff
+7 -32
View File
@@ -39,6 +39,7 @@
#include "compiler/shader_enums.h"
#include "hwdef/rogue_hw_defs.h"
#include "pco/pco.h"
#include "pco/pco_data.h"
#include "pvr_border.h"
#include "pvr_clear.h"
#include "pvr_common.h"
@@ -851,26 +852,7 @@ struct pvr_pds_attrib_program {
};
struct pvr_pipeline_stage_state {
uint32_t const_shared_reg_count;
uint32_t const_shared_reg_offset;
uint32_t pds_temps_count;
uint32_t coefficient_size;
/* True if this shader uses any atomic operations. */
bool uses_atomic_ops;
/* True if this shader uses both texture reads and texture writes. */
bool uses_texture_rw;
/* Only used for compute stage. */
bool uses_barrier;
/* True if this shader has side effects */
bool has_side_effects;
/* True if this shader is simply a nop.end. */
bool empty_program;
};
struct pvr_compute_shader_state {
@@ -891,10 +873,6 @@ struct pvr_compute_shader_state {
struct pvr_vertex_shader_state {
/* Pointer to a buffer object that contains the shader binary. */
struct pvr_suballoc_bo *bo;
uint32_t entry_offset;
/* 2 since we only need STATE_VARYING{0,1} state words. */
uint32_t varying[2];
struct pvr_pds_attrib_program
pds_attrib_programs[PVR_PDS_VERTEX_ATTRIB_PROGRAM_COUNT];
@@ -902,20 +880,17 @@ struct pvr_vertex_shader_state {
struct pvr_pipeline_stage_state stage_state;
/* FIXME: Move this into stage_state? */
struct pvr_stage_allocation_descriptor_state descriptor_state;
uint32_t vertex_input_size;
uint32_t vertex_output_size;
uint32_t user_clip_planes_mask;
};
struct pvr_fragment_shader_state {
/* Pointer to a buffer object that contains the shader binary. */
struct pvr_suballoc_bo *bo;
uint32_t entry_offset;
struct pvr_pipeline_stage_state stage_state;
/* FIXME: Move this into stage_state? */
struct pvr_stage_allocation_descriptor_state descriptor_state;
enum ROGUE_TA_PASSTYPE pass_type;
enum ROGUE_PDSINST_DOUTU_SAMPLE_RATE sample_rate;
struct pvr_pds_upload pds_coeff_program;
struct pvr_pds_upload pds_fragment_program;
@@ -967,6 +942,9 @@ struct pvr_graphics_pipeline {
/* Derived and other state */
size_t stage_indices[MESA_SHADER_STAGES];
pco_data vs_data;
pco_data fs_data;
struct {
struct pvr_vertex_shader_state vertex;
struct pvr_fragment_shader_state fragment;
@@ -1390,11 +1368,8 @@ enum pvr_msaa_mode {
VkResult pvr_pds_fragment_program_create_and_upload(
struct pvr_device *device,
const VkAllocationCallbacks *allocator,
const struct pvr_suballoc_bo *fragment_shader_bo,
uint32_t fragment_temp_count,
enum pvr_msaa_mode msaa_mode,
bool has_phase_rate_change,
struct pvr_pds_upload *const pds_upload_out);
pco_shader *fs,
struct pvr_fragment_shader_state *fragment_state);
VkResult pvr_pds_unitex_state_program_create_and_upload(
struct pvr_device *device,