panvk: Split compute/graphics pipeline objects

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Mary Guillemard <mary.guillemard@collabora.com>
Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28927>
This commit is contained in:
Boris Brezillon 2024-02-02 16:23:00 +01:00 committed by Marge Bot
parent 513e0bd46b
commit bd6e32ef9c
4 changed files with 465 additions and 380 deletions

View file

@ -111,7 +111,7 @@ struct panvk_attrib_buf {
struct panvk_cmd_graphics_state {
struct panvk_descriptor_state desc_state;
const struct panvk_pipeline *pipeline;
const struct panvk_graphics_pipeline *pipeline;
uint32_t dirty;
@ -168,7 +168,7 @@ struct panvk_cmd_graphics_state {
struct panvk_cmd_compute_state {
struct panvk_descriptor_state desc_state;
const struct panvk_pipeline *pipeline;
const struct panvk_compute_pipeline *pipeline;
struct panvk_compute_sysvals sysvals;
};
@ -198,10 +198,10 @@ panvk_cmd_get_pipeline(const struct panvk_cmd_buffer *cmdbuf,
{
switch (bindpoint) {
case VK_PIPELINE_BIND_POINT_GRAPHICS:
return cmdbuf->state.gfx.pipeline;
return &cmdbuf->state.gfx.pipeline->base;
case VK_PIPELINE_BIND_POINT_COMPUTE:
return cmdbuf->state.compute.pipeline;
return &cmdbuf->state.compute.pipeline->base;
default:
assert(!"Unsupported bind point");

View file

@ -43,103 +43,140 @@ struct panvk_attribs_info {
unsigned buf_count;
};
enum panvk_pipeline_type {
PANVK_PIPELINE_GRAPHICS,
PANVK_PIPELINE_COMPUTE,
};
struct panvk_pipeline {
struct vk_object_base base;
struct panvk_varyings_info varyings;
struct panvk_attribs_info attribs;
enum panvk_pipeline_type type;
const struct panvk_pipeline_layout *layout;
unsigned active_stages;
uint32_t dynamic_state_mask;
struct panvk_priv_bo *binary_bo;
struct panvk_priv_bo *state_bo;
uint64_t vpd;
unsigned active_stages;
uint64_t rsds[MESA_SHADER_STAGES];
/* shader stage bit is set of the stage accesses storage images */
uint32_t img_access_mask;
unsigned tls_size;
unsigned wls_size;
struct {
uint64_t address;
struct pan_shader_info info;
struct mali_renderer_state_packed rsd_template;
bool required;
bool dynamic_rsd;
uint8_t rt_mask;
} fs;
struct {
struct pan_compute_dim local_size;
} cs;
struct {
unsigned topology;
bool writes_point_size;
bool primitive_restart;
} ia;
struct {
bool clamp_depth;
float line_width;
struct {
bool enable;
float constant_factor;
float clamp;
float slope_factor;
} depth_bias;
bool front_ccw;
bool cull_front_face;
bool cull_back_face;
bool enable;
} rast;
struct {
bool z_test;
bool z_write;
unsigned z_compare_func;
bool s_test;
struct {
unsigned fail_op;
unsigned pass_op;
unsigned z_fail_op;
unsigned compare_func;
uint8_t compare_mask;
uint8_t write_mask;
uint8_t ref;
} s_front, s_back;
} zs;
struct {
uint8_t rast_samples;
uint8_t min_samples;
uint16_t sample_mask;
bool alpha_to_coverage;
bool alpha_to_one;
} ms;
struct {
struct pan_blend_state state;
struct mali_blend_packed bd_template[8];
struct {
uint8_t index;
uint16_t bifrost_factor;
} constant[8];
bool reads_dest;
} blend;
VkViewport viewport;
VkRect2D scissor;
};
VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_pipeline, base, VkPipeline,
VK_OBJECT_TYPE_PIPELINE)
struct panvk_graphics_pipeline {
struct panvk_pipeline base;
struct panvk_varyings_info varyings;
struct {
uint32_t dynamic_mask;
struct {
struct panvk_attribs_info attribs;
} vs;
struct {
uint64_t address;
struct pan_shader_info info;
bool required;
bool dynamic_rsd;
uint8_t rt_mask;
struct mali_renderer_state_packed rsd_template;
} fs;
struct {
unsigned topology;
bool writes_point_size;
bool primitive_restart;
} ia;
struct {
bool clamp_depth;
float line_width;
struct {
bool enable;
float constant_factor;
float clamp;
float slope_factor;
} depth_bias;
bool front_ccw;
bool cull_front_face;
bool cull_back_face;
bool enable;
} rast;
struct {
bool z_test;
bool z_write;
unsigned z_compare_func;
bool s_test;
struct {
unsigned fail_op;
unsigned pass_op;
unsigned z_fail_op;
unsigned compare_func;
uint8_t compare_mask;
uint8_t write_mask;
uint8_t ref;
} s_front, s_back;
} zs;
struct {
uint8_t rast_samples;
uint8_t min_samples;
uint16_t sample_mask;
bool alpha_to_coverage;
bool alpha_to_one;
} ms;
struct {
struct pan_blend_state pstate;
struct {
uint8_t index;
uint16_t bifrost_factor;
} constant[8];
struct mali_blend_packed bd_template[8];
bool reads_dest;
} blend;
struct {
uint64_t vpd;
VkViewport viewport;
VkRect2D scissor;
} vp;
} state;
};
static struct panvk_graphics_pipeline *
panvk_pipeline_to_graphics_pipeline(struct panvk_pipeline *pipeline)
{
if (pipeline->type != PANVK_PIPELINE_GRAPHICS)
return NULL;
return container_of(pipeline, struct panvk_graphics_pipeline, base);
}
struct panvk_compute_pipeline {
struct panvk_pipeline base;
struct pan_compute_dim local_size;
unsigned wls_size;
};
static struct panvk_compute_pipeline *
panvk_pipeline_to_compute_pipeline(struct panvk_pipeline *pipeline)
{
if (pipeline->type != PANVK_PIPELINE_COMPUTE)
return NULL;
return container_of(pipeline, struct panvk_compute_pipeline, base);
}
#endif

View file

@ -522,10 +522,10 @@ static void
panvk_draw_prepare_fs_rsd(struct panvk_cmd_buffer *cmdbuf,
struct panvk_draw_info *draw)
{
const struct panvk_pipeline *pipeline = cmdbuf->state.gfx.pipeline;
const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline;
if (!pipeline->fs.dynamic_rsd) {
draw->fs_rsd = pipeline->rsds[MESA_SHADER_FRAGMENT];
if (!pipeline->state.fs.dynamic_rsd) {
draw->fs_rsd = pipeline->base.rsds[MESA_SHADER_FRAGMENT];
return;
}
@ -533,29 +533,27 @@ panvk_draw_prepare_fs_rsd(struct panvk_cmd_buffer *cmdbuf,
const struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx;
struct panfrost_ptr rsd = pan_pool_alloc_desc_aggregate(
&cmdbuf->desc_pool.base, PAN_DESC(RENDERER_STATE),
PAN_DESC_ARRAY(pipeline->blend.state.rt_count, BLEND));
PAN_DESC_ARRAY(pipeline->state.blend.pstate.rt_count, BLEND));
struct mali_renderer_state_packed rsd_dyn;
struct mali_renderer_state_packed *rsd_templ =
(struct mali_renderer_state_packed *)&pipeline->fs.rsd_template;
STATIC_ASSERT(sizeof(pipeline->fs.rsd_template) >= sizeof(*rsd_templ));
const struct mali_renderer_state_packed *rsd_templ =
&pipeline->state.fs.rsd_template;
pan_pack(&rsd_dyn, RENDERER_STATE, cfg) {
if (pipeline->dynamic_state_mask &
if (pipeline->state.dynamic_mask &
(1 << VK_DYNAMIC_STATE_DEPTH_BIAS)) {
cfg.depth_units = state->rast.depth_bias.constant_factor * 2.0f;
cfg.depth_factor = state->rast.depth_bias.slope_factor;
cfg.depth_bias_clamp = state->rast.depth_bias.clamp;
}
if (pipeline->dynamic_state_mask &
if (pipeline->state.dynamic_mask &
(1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK)) {
cfg.stencil_front.mask = state->zs.s_front.compare_mask;
cfg.stencil_back.mask = state->zs.s_back.compare_mask;
}
if (pipeline->dynamic_state_mask &
if (pipeline->state.dynamic_mask &
(1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) {
cfg.stencil_mask_misc.stencil_mask_front =
state->zs.s_front.write_mask;
@ -563,7 +561,7 @@ panvk_draw_prepare_fs_rsd(struct panvk_cmd_buffer *cmdbuf,
state->zs.s_back.write_mask;
}
if (pipeline->dynamic_state_mask &
if (pipeline->state.dynamic_mask &
(1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE)) {
cfg.stencil_front.reference_value = state->zs.s_front.ref;
cfg.stencil_back.reference_value = state->zs.s_back.ref;
@ -574,15 +572,14 @@ panvk_draw_prepare_fs_rsd(struct panvk_cmd_buffer *cmdbuf,
memcpy(rsd.cpu, &rsd_dyn, sizeof(rsd_dyn));
void *bd = rsd.cpu + pan_size(RENDERER_STATE);
for (unsigned i = 0; i < pipeline->blend.state.rt_count; i++) {
if (pipeline->blend.constant[i].index != (uint8_t)~0) {
for (unsigned i = 0; i < pipeline->state.blend.pstate.rt_count; i++) {
if (pipeline->state.blend.constant[i].index != (uint8_t)~0) {
struct mali_blend_packed bd_dyn;
struct mali_blend_packed *bd_templ =
(struct mali_blend_packed *)&pipeline->blend.bd_template[i];
float constant = cmdbuf->state.gfx.blend
.constants[pipeline->blend.constant[i].index] *
pipeline->blend.constant[i].bifrost_factor;
const struct mali_blend_packed *bd_templ =
&pipeline->state.blend.bd_template[i];
unsigned constant_idx = pipeline->state.blend.constant[i].index;
float constant = cmdbuf->state.gfx.blend.constants[constant_idx] *
pipeline->state.blend.constant[i].bifrost_factor;
pan_pack(&bd_dyn, BLEND, cfg) {
cfg.enable = false;
@ -691,7 +688,7 @@ static void
panvk_draw_prepare_varyings(struct panvk_cmd_buffer *cmdbuf,
struct panvk_draw_info *draw)
{
const struct panvk_pipeline *pipeline = cmdbuf->state.gfx.pipeline;
const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline;
struct panvk_varyings_info *varyings = &cmdbuf->state.gfx.varyings;
panvk_varyings_alloc(varyings, &cmdbuf->varying_pool.base,
@ -726,16 +723,16 @@ panvk_draw_prepare_varyings(struct panvk_cmd_buffer *cmdbuf,
varyings->varying[VARYING_SLOT_POS].offset;
}
if (pipeline->ia.writes_point_size) {
if (pipeline->state.ia.writes_point_size) {
draw->psiz =
varyings->buf[varyings->varying[VARYING_SLOT_PSIZ].buf].address +
varyings->varying[VARYING_SLOT_POS].offset;
} else if (pipeline->ia.topology == MALI_DRAW_MODE_LINES ||
pipeline->ia.topology == MALI_DRAW_MODE_LINE_STRIP ||
pipeline->ia.topology == MALI_DRAW_MODE_LINE_LOOP) {
draw->line_width = pipeline->dynamic_state_mask & PANVK_DYNAMIC_LINE_WIDTH
} else if (pipeline->state.ia.topology == MALI_DRAW_MODE_LINES ||
pipeline->state.ia.topology == MALI_DRAW_MODE_LINE_STRIP ||
pipeline->state.ia.topology == MALI_DRAW_MODE_LINE_LOOP) {
draw->line_width = pipeline->state.dynamic_mask & PANVK_DYNAMIC_LINE_WIDTH
? cmdbuf->state.gfx.rast.line_width
: pipeline->rast.line_width;
: pipeline->state.rast.line_width;
} else {
draw->line_width = 1.0f;
}
@ -907,24 +904,24 @@ panvk_draw_prepare_vs_attribs(struct panvk_cmd_buffer *cmdbuf,
struct panvk_draw_info *draw)
{
struct panvk_descriptor_state *desc_state = &cmdbuf->state.gfx.desc_state;
const struct panvk_pipeline *pipeline = cmdbuf->state.gfx.pipeline;
const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline;
unsigned num_imgs =
pipeline->img_access_mask & BITFIELD_BIT(MESA_SHADER_VERTEX)
? pipeline->layout->num_imgs
pipeline->base.img_access_mask & BITFIELD_BIT(MESA_SHADER_VERTEX)
? pipeline->base.layout->num_imgs
: 0;
unsigned attrib_count = pipeline->attribs.attrib_count + num_imgs;
unsigned attrib_count = pipeline->state.vs.attribs.attrib_count + num_imgs;
if (desc_state->vs_attribs || !attrib_count)
return;
if (!pipeline->attribs.buf_count) {
panvk_prepare_non_vs_attribs(cmdbuf, desc_state, pipeline);
if (!pipeline->state.vs.attribs.buf_count) {
panvk_prepare_non_vs_attribs(cmdbuf, desc_state, &pipeline->base);
desc_state->vs_attrib_bufs = desc_state->non_vs_attrib_bufs;
desc_state->vs_attribs = desc_state->non_vs_attribs;
return;
}
unsigned attrib_buf_count = pipeline->attribs.buf_count * 2;
unsigned attrib_buf_count = pipeline->state.vs.attribs.buf_count * 2;
struct panfrost_ptr bufs = pan_pool_alloc_desc_array(
&cmdbuf->desc_pool.base, attrib_buf_count + 1, ATTRIBUTE_BUFFER);
struct mali_attribute_buffer_packed *attrib_buf_descs = bufs.cpu;
@ -932,29 +929,31 @@ panvk_draw_prepare_vs_attribs(struct panvk_cmd_buffer *cmdbuf,
&cmdbuf->desc_pool.base, attrib_count, ATTRIBUTE);
struct mali_attribute_packed *attrib_descs = attribs.cpu;
for (unsigned i = 0; i < pipeline->attribs.buf_count; i++) {
panvk_draw_emit_attrib_buf(draw, &pipeline->attribs.buf[i],
for (unsigned i = 0; i < pipeline->state.vs.attribs.buf_count; i++) {
panvk_draw_emit_attrib_buf(draw, &pipeline->state.vs.attribs.buf[i],
&cmdbuf->state.gfx.vb.bufs[i],
&attrib_buf_descs[i * 2]);
}
for (unsigned i = 0; i < pipeline->attribs.attrib_count; i++) {
unsigned buf_idx = pipeline->attribs.attrib[i].buf;
for (unsigned i = 0; i < pipeline->state.vs.attribs.attrib_count; i++) {
unsigned buf_idx = pipeline->state.vs.attribs.attrib[i].buf;
panvk_draw_emit_attrib(
draw, &pipeline->attribs.attrib[i], &pipeline->attribs.buf[buf_idx],
&cmdbuf->state.gfx.vb.bufs[buf_idx], &attrib_descs[i]);
panvk_draw_emit_attrib(draw, &pipeline->state.vs.attribs.attrib[i],
&pipeline->state.vs.attribs.buf[buf_idx],
&cmdbuf->state.gfx.vb.bufs[buf_idx],
&attrib_descs[i]);
}
if (attrib_count > pipeline->attribs.attrib_count) {
if (num_imgs) {
unsigned bufs_offset =
pipeline->attribs.buf_count * pan_size(ATTRIBUTE_BUFFER) * 2;
pipeline->state.vs.attribs.buf_count * pan_size(ATTRIBUTE_BUFFER) * 2;
unsigned attribs_offset =
pipeline->attribs.buf_count * pan_size(ATTRIBUTE);
pipeline->state.vs.attribs.buf_count * pan_size(ATTRIBUTE);
panvk_fill_non_vs_attribs(
cmdbuf, desc_state, pipeline, bufs.cpu + bufs_offset,
attribs.cpu + attribs_offset, pipeline->attribs.buf_count * 2);
panvk_fill_non_vs_attribs(cmdbuf, desc_state, &pipeline->base,
bufs.cpu + bufs_offset,
attribs.cpu + attribs_offset,
pipeline->state.vs.attribs.buf_count * 2);
}
/* A NULL entry is needed to stop prefecting on Bifrost */
@ -970,15 +969,15 @@ panvk_draw_prepare_attributes(struct panvk_cmd_buffer *cmdbuf,
struct panvk_draw_info *draw)
{
struct panvk_descriptor_state *desc_state = &cmdbuf->state.gfx.desc_state;
const struct panvk_pipeline *pipeline = cmdbuf->state.gfx.pipeline;
const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline;
for (unsigned i = 0; i < ARRAY_SIZE(draw->stages); i++) {
if (i == MESA_SHADER_VERTEX) {
panvk_draw_prepare_vs_attribs(cmdbuf, draw);
draw->stages[i].attributes = desc_state->vs_attribs;
draw->stages[i].attribute_bufs = desc_state->vs_attrib_bufs;
} else if (pipeline->img_access_mask & BITFIELD_BIT(i)) {
panvk_prepare_non_vs_attribs(cmdbuf, desc_state, pipeline);
} else if (pipeline->base.img_access_mask & BITFIELD_BIT(i)) {
panvk_prepare_non_vs_attribs(cmdbuf, desc_state, &pipeline->base);
draw->stages[i].attributes = desc_state->non_vs_attribs;
draw->stages[i].attribute_bufs = desc_state->non_vs_attrib_bufs;
}
@ -1025,10 +1024,10 @@ static void
panvk_draw_prepare_viewport(struct panvk_cmd_buffer *cmdbuf,
struct panvk_draw_info *draw)
{
const struct panvk_pipeline *pipeline = cmdbuf->state.gfx.pipeline;
const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline;
if (pipeline->vpd) {
draw->viewport = pipeline->vpd;
if (pipeline->state.vp.vpd) {
draw->viewport = pipeline->state.vp.vpd;
} else if (cmdbuf->state.gfx.vpd) {
draw->viewport = cmdbuf->state.gfx.vpd;
} else {
@ -1036,13 +1035,13 @@ panvk_draw_prepare_viewport(struct panvk_cmd_buffer *cmdbuf,
pan_pool_alloc_desc(&cmdbuf->desc_pool.base, VIEWPORT);
const VkViewport *viewport =
pipeline->dynamic_state_mask & PANVK_DYNAMIC_VIEWPORT
pipeline->state.dynamic_mask & PANVK_DYNAMIC_VIEWPORT
? &cmdbuf->state.gfx.viewport
: &pipeline->viewport;
: &pipeline->state.vp.viewport;
const VkRect2D *scissor =
pipeline->dynamic_state_mask & PANVK_DYNAMIC_SCISSOR
pipeline->state.dynamic_mask & PANVK_DYNAMIC_SCISSOR
? &cmdbuf->state.gfx.scissor
: &pipeline->scissor;
: &pipeline->state.vp.scissor;
panvk_per_arch(emit_viewport)(viewport, scissor, vp.cpu);
draw->viewport = cmdbuf->state.gfx.vpd = vp.gpu;
@ -1053,7 +1052,7 @@ static void
panvk_draw_prepare_vertex_job(struct panvk_cmd_buffer *cmdbuf,
struct panvk_draw_info *draw)
{
const struct panvk_pipeline *pipeline = cmdbuf->state.gfx.pipeline;
const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline;
struct panvk_batch *batch = cmdbuf->cur_batch;
struct panfrost_ptr ptr =
pan_pool_alloc_desc(&cmdbuf->desc_pool.base, COMPUTE_JOB);
@ -1069,7 +1068,7 @@ panvk_draw_prepare_vertex_job(struct panvk_cmd_buffer *cmdbuf,
}
pan_section_pack(ptr.cpu, COMPUTE_JOB, DRAW, cfg) {
cfg.state = pipeline->rsds[MESA_SHADER_VERTEX];
cfg.state = pipeline->base.rsds[MESA_SHADER_VERTEX];
cfg.attributes = draw->stages[MESA_SHADER_VERTEX].attributes;
cfg.attribute_buffers = draw->stages[MESA_SHADER_VERTEX].attribute_bufs;
cfg.varyings = draw->stages[MESA_SHADER_VERTEX].varyings;
@ -1086,16 +1085,16 @@ panvk_draw_prepare_vertex_job(struct panvk_cmd_buffer *cmdbuf,
}
static void
panvk_emit_tiler_primitive(const struct panvk_pipeline *pipeline,
panvk_emit_tiler_primitive(const struct panvk_graphics_pipeline *pipeline,
const struct panvk_draw_info *draw, void *prim)
{
pan_pack(prim, PRIMITIVE, cfg) {
cfg.draw_mode = pipeline->ia.topology;
if (pipeline->ia.writes_point_size)
cfg.draw_mode = pipeline->state.ia.topology;
if (pipeline->state.ia.writes_point_size)
cfg.point_size_array_format = MALI_POINT_SIZE_ARRAY_FORMAT_FP16;
cfg.first_provoking_vertex = true;
if (pipeline->ia.primitive_restart)
if (pipeline->state.ia.primitive_restart)
cfg.primitive_restart = MALI_PRIMITIVE_RESTART_IMPLICIT;
cfg.job_task_split = 6;
@ -1125,12 +1124,12 @@ panvk_emit_tiler_primitive(const struct panvk_pipeline *pipeline,
}
static void
panvk_emit_tiler_primitive_size(const struct panvk_pipeline *pipeline,
panvk_emit_tiler_primitive_size(const struct panvk_graphics_pipeline *pipeline,
const struct panvk_draw_info *draw,
void *primsz)
{
pan_pack(primsz, PRIMITIVE_SIZE, cfg) {
if (pipeline->ia.writes_point_size) {
if (pipeline->state.ia.writes_point_size) {
cfg.size_array = draw->psiz;
} else {
cfg.constant = draw->line_width;
@ -1139,13 +1138,13 @@ panvk_emit_tiler_primitive_size(const struct panvk_pipeline *pipeline,
}
static void
panvk_emit_tiler_dcd(const struct panvk_pipeline *pipeline,
panvk_emit_tiler_dcd(const struct panvk_graphics_pipeline *pipeline,
const struct panvk_draw_info *draw, void *dcd)
{
pan_pack(dcd, DRAW, cfg) {
cfg.front_face_ccw = pipeline->rast.front_ccw;
cfg.cull_front_face = pipeline->rast.cull_front_face;
cfg.cull_back_face = pipeline->rast.cull_back_face;
cfg.front_face_ccw = pipeline->state.rast.front_ccw;
cfg.cull_front_face = pipeline->state.rast.cull_front_face;
cfg.cull_back_face = pipeline->state.rast.cull_back_face;
cfg.position = draw->position;
cfg.state = draw->fs_rsd;
cfg.attributes = draw->stages[MESA_SHADER_FRAGMENT].attributes;
@ -1159,9 +1158,9 @@ panvk_emit_tiler_dcd(const struct panvk_pipeline *pipeline,
* be set to 0 and the provoking vertex is selected with the
* PRIMITIVE.first_provoking_vertex field.
*/
if (pipeline->ia.topology == MALI_DRAW_MODE_LINES ||
pipeline->ia.topology == MALI_DRAW_MODE_LINE_STRIP ||
pipeline->ia.topology == MALI_DRAW_MODE_LINE_LOOP) {
if (pipeline->state.ia.topology == MALI_DRAW_MODE_LINES ||
pipeline->state.ia.topology == MALI_DRAW_MODE_LINE_STRIP ||
pipeline->state.ia.topology == MALI_DRAW_MODE_LINE_LOOP) {
cfg.flat_shading_vertex = true;
}
@ -1181,7 +1180,7 @@ static void
panvk_draw_prepare_tiler_job(struct panvk_cmd_buffer *cmdbuf,
struct panvk_draw_info *draw)
{
const struct panvk_pipeline *pipeline = cmdbuf->state.gfx.pipeline;
const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline;
struct panvk_batch *batch = cmdbuf->cur_batch;
struct panfrost_ptr ptr =
pan_pool_alloc_desc(&cmdbuf->desc_pool.base, TILER_JOB);
@ -1255,7 +1254,7 @@ panvk_cmd_draw(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw)
{
struct panvk_batch *batch = cmdbuf->cur_batch;
struct panvk_descriptor_state *desc_state = &cmdbuf->state.gfx.desc_state;
const struct panvk_pipeline *pipeline = cmdbuf->state.gfx.pipeline;
const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline;
/* There are only 16 bits in the descriptor for the job ID, make sure all
* the 3 (2 in Bifrost) jobs in this draw are in the same batch.
@ -1266,19 +1265,19 @@ panvk_cmd_draw(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw)
batch = panvk_per_arch(cmd_open_batch)(cmdbuf);
}
if (pipeline->rast.enable)
if (pipeline->state.rast.enable)
panvk_per_arch(cmd_alloc_fb_desc)(cmdbuf);
panvk_per_arch(cmd_alloc_tls_desc)(cmdbuf, true);
panvk_cmd_prepare_draw_sysvals(cmdbuf, draw);
panvk_cmd_prepare_push_sets(cmdbuf, desc_state, pipeline);
panvk_cmd_prepare_push_sets(cmdbuf, desc_state, &pipeline->base);
panvk_cmd_prepare_push_uniforms(cmdbuf, desc_state,
&cmdbuf->state.gfx.sysvals,
sizeof(cmdbuf->state.gfx.sysvals));
panvk_cmd_prepare_ubos(cmdbuf, desc_state, pipeline);
panvk_cmd_prepare_textures(cmdbuf, desc_state, pipeline);
panvk_cmd_prepare_samplers(cmdbuf, desc_state, pipeline);
panvk_cmd_prepare_ubos(cmdbuf, desc_state, &pipeline->base);
panvk_cmd_prepare_textures(cmdbuf, desc_state, &pipeline->base);
panvk_cmd_prepare_samplers(cmdbuf, desc_state, &pipeline->base);
/* TODO: indexed draws */
draw->tls = batch->tls.gpu;
@ -1299,14 +1298,14 @@ panvk_cmd_draw(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw)
panvk_draw_prepare_tiler_context(cmdbuf, draw);
panvk_draw_prepare_vertex_job(cmdbuf, draw);
panvk_draw_prepare_tiler_job(cmdbuf, draw);
batch->tlsinfo.tls.size = MAX2(pipeline->tls_size, batch->tlsinfo.tls.size);
assert(!pipeline->wls_size);
batch->tlsinfo.tls.size =
MAX2(pipeline->base.tls_size, batch->tlsinfo.tls.size);
unsigned vjob_id =
pan_jc_add_job(&cmdbuf->desc_pool.base, &batch->jc, MALI_JOB_TYPE_VERTEX,
false, false, 0, 0, &draw->jobs.vertex, false);
if (pipeline->rast.enable && draw->position) {
if (pipeline->state.rast.enable && draw->position) {
pan_jc_add_job(&cmdbuf->desc_pool.base, &batch->jc, MALI_JOB_TYPE_TILER,
false, false, vjob_id, 0, &draw->jobs.tiler, false);
}
@ -1402,8 +1401,8 @@ panvk_per_arch(CmdDrawIndexed)(VkCommandBuffer commandBuffer,
if (instanceCount == 0 || indexCount == 0)
return;
const struct panvk_pipeline *pipeline = cmdbuf->state.gfx.pipeline;
bool primitive_restart = pipeline->ia.primitive_restart;
const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline;
bool primitive_restart = pipeline->state.ia.primitive_restart;
panvk_index_minmax_search(cmdbuf, firstIndex, indexCount, primitive_restart,
&min_vertex, &max_vertex);
@ -1689,7 +1688,8 @@ panvk_per_arch(CmdDispatch)(VkCommandBuffer commandBuffer, uint32_t x,
struct panvk_descriptor_state *desc_state =
&cmdbuf->state.compute.desc_state;
const struct panvk_pipeline *pipeline = cmdbuf->state.compute.pipeline;
const struct panvk_compute_pipeline *pipeline =
cmdbuf->state.compute.pipeline;
struct panfrost_ptr job =
pan_pool_alloc_desc(&cmdbuf->desc_pool.base, COMPUTE_JOB);
@ -1697,20 +1697,20 @@ panvk_per_arch(CmdDispatch)(VkCommandBuffer commandBuffer, uint32_t x,
sysvals->num_work_groups.x = x;
sysvals->num_work_groups.y = y;
sysvals->num_work_groups.z = z;
sysvals->local_group_size.x = pipeline->cs.local_size.x;
sysvals->local_group_size.y = pipeline->cs.local_size.y;
sysvals->local_group_size.z = pipeline->cs.local_size.z;
sysvals->local_group_size.x = pipeline->local_size.x;
sysvals->local_group_size.y = pipeline->local_size.y;
sysvals->local_group_size.z = pipeline->local_size.z;
desc_state->push_uniforms = 0;
panvk_per_arch(cmd_alloc_tls_desc)(cmdbuf, false);
dispatch.tsd = batch->tls.gpu;
panvk_cmd_prepare_push_sets(cmdbuf, desc_state, pipeline);
panvk_prepare_non_vs_attribs(cmdbuf, desc_state, pipeline);
panvk_cmd_prepare_push_sets(cmdbuf, desc_state, &pipeline->base);
panvk_prepare_non_vs_attribs(cmdbuf, desc_state, &pipeline->base);
dispatch.attributes = desc_state->non_vs_attribs;
dispatch.attribute_bufs = desc_state->non_vs_attrib_bufs;
panvk_cmd_prepare_ubos(cmdbuf, desc_state, pipeline);
panvk_cmd_prepare_ubos(cmdbuf, desc_state, &pipeline->base);
dispatch.ubos = desc_state->ubos;
panvk_cmd_prepare_push_uniforms(cmdbuf, desc_state,
@ -1718,25 +1718,25 @@ panvk_per_arch(CmdDispatch)(VkCommandBuffer commandBuffer, uint32_t x,
sizeof(cmdbuf->state.compute.sysvals));
dispatch.push_uniforms = desc_state->push_uniforms;
panvk_cmd_prepare_textures(cmdbuf, desc_state, pipeline);
panvk_cmd_prepare_textures(cmdbuf, desc_state, &pipeline->base);
dispatch.textures = desc_state->textures;
panvk_cmd_prepare_samplers(cmdbuf, desc_state, pipeline);
panvk_cmd_prepare_samplers(cmdbuf, desc_state, &pipeline->base);
dispatch.samplers = desc_state->samplers;
panfrost_pack_work_groups_compute(
pan_section_ptr(job.cpu, COMPUTE_JOB, INVOCATION), dispatch.wg_count.x,
dispatch.wg_count.y, dispatch.wg_count.z, pipeline->cs.local_size.x,
pipeline->cs.local_size.y, pipeline->cs.local_size.z, false, false);
dispatch.wg_count.y, dispatch.wg_count.z, pipeline->local_size.x,
pipeline->local_size.y, pipeline->local_size.z, false, false);
pan_section_pack(job.cpu, COMPUTE_JOB, PARAMETERS, cfg) {
cfg.job_task_split = util_logbase2_ceil(pipeline->cs.local_size.x + 1) +
util_logbase2_ceil(pipeline->cs.local_size.y + 1) +
util_logbase2_ceil(pipeline->cs.local_size.z + 1);
cfg.job_task_split = util_logbase2_ceil(pipeline->local_size.x + 1) +
util_logbase2_ceil(pipeline->local_size.y + 1) +
util_logbase2_ceil(pipeline->local_size.z + 1);
}
pan_section_pack(job.cpu, COMPUTE_JOB, DRAW, cfg) {
cfg.state = pipeline->rsds[MESA_SHADER_COMPUTE];
cfg.state = pipeline->base.rsds[MESA_SHADER_COMPUTE];
cfg.attributes = dispatch.attributes;
cfg.attribute_buffers = dispatch.attribute_bufs;
cfg.thread_storage = dispatch.tsd;
@ -1749,7 +1749,7 @@ panvk_per_arch(CmdDispatch)(VkCommandBuffer commandBuffer, uint32_t x,
pan_jc_add_job(&cmdbuf->desc_pool.base, &batch->jc, MALI_JOB_TYPE_COMPUTE,
false, false, 0, 0, &job, false);
batch->tlsinfo.tls.size = pipeline->tls_size;
batch->tlsinfo.tls.size = pipeline->base.tls_size;
batch->tlsinfo.wls.size = pipeline->wls_size;
if (batch->tlsinfo.wls.size) {
unsigned core_id_range;
@ -2118,25 +2118,31 @@ panvk_per_arch(CmdBindPipeline)(VkCommandBuffer commandBuffer,
VK_FROM_HANDLE(panvk_pipeline, pipeline, _pipeline);
switch (pipelineBindPoint) {
case VK_PIPELINE_BIND_POINT_GRAPHICS:
cmdbuf->state.gfx.fs_rsd = 0;
cmdbuf->state.gfx.varyings = pipeline->varyings;
case VK_PIPELINE_BIND_POINT_GRAPHICS: {
struct panvk_graphics_pipeline *gfx_pipeline =
panvk_pipeline_to_graphics_pipeline(pipeline);
if (!(pipeline->dynamic_state_mask &
cmdbuf->state.gfx.fs_rsd = 0;
cmdbuf->state.gfx.varyings = gfx_pipeline->varyings;
if (!(gfx_pipeline->state.dynamic_mask &
BITFIELD_BIT(VK_DYNAMIC_STATE_VIEWPORT))) {
cmdbuf->state.gfx.viewport = pipeline->viewport;
cmdbuf->state.gfx.viewport = gfx_pipeline->state.vp.viewport;
cmdbuf->state.gfx.dirty |= PANVK_DYNAMIC_VIEWPORT;
}
if (!(pipeline->dynamic_state_mask &
if (!(gfx_pipeline->state.dynamic_mask &
BITFIELD_BIT(VK_DYNAMIC_STATE_SCISSOR))) {
cmdbuf->state.gfx.scissor = pipeline->scissor;
cmdbuf->state.gfx.scissor = gfx_pipeline->state.vp.scissor;
cmdbuf->state.gfx.dirty |= PANVK_DYNAMIC_SCISSOR;
}
cmdbuf->state.gfx.pipeline = pipeline;
cmdbuf->state.gfx.pipeline = gfx_pipeline;
break;
}
case VK_PIPELINE_BIND_POINT_COMPUTE:
cmdbuf->state.compute.pipeline = pipeline;
cmdbuf->state.compute.pipeline =
panvk_pipeline_to_compute_pipeline(pipeline);
break;
default:

View file

@ -80,22 +80,6 @@ struct panvk_pipeline_builder {
enum pipe_format color_attachment_formats[MAX_RTS];
};
static VkResult
panvk_pipeline_builder_create_pipeline(struct panvk_pipeline_builder *builder,
struct panvk_pipeline **out_pipeline)
{
struct panvk_device *dev = builder->device;
struct panvk_pipeline *pipeline = vk_object_zalloc(
&dev->vk, builder->alloc, sizeof(*pipeline), VK_OBJECT_TYPE_PIPELINE);
if (!pipeline)
return VK_ERROR_OUT_OF_HOST_MEMORY;
pipeline->layout = builder->layout;
*out_pipeline = pipeline;
return VK_SUCCESS;
}
static void
panvk_pipeline_builder_finish(struct panvk_pipeline_builder *builder)
{
@ -109,15 +93,21 @@ panvk_pipeline_builder_finish(struct panvk_pipeline_builder *builder)
}
static bool
panvk_pipeline_static_state(struct panvk_pipeline *pipeline, uint32_t id)
panvk_graphics_pipeline_static_state(
const struct panvk_graphics_pipeline *pipeline, uint32_t id)
{
return !(pipeline->dynamic_state_mask & (1 << id));
if (!pipeline)
return false;
return !(pipeline->state.dynamic_mask & (1 << id));
}
static VkResult
panvk_pipeline_builder_compile_shaders(struct panvk_pipeline_builder *builder,
struct panvk_pipeline *pipeline)
{
struct panvk_graphics_pipeline *gfx_pipeline =
panvk_pipeline_to_graphics_pipeline(pipeline);
const VkPipelineShaderStageCreateInfo *stage_infos[MESA_SHADER_STAGES] = {
NULL};
const VkPipelineShaderStageCreateInfo *stages =
@ -142,9 +132,9 @@ panvk_pipeline_builder_compile_shaders(struct panvk_pipeline_builder *builder,
shader = panvk_per_arch(shader_create)(
builder->device, stage, stage_info, builder->layout,
&pipeline->blend.state,
panvk_pipeline_static_state(pipeline,
VK_DYNAMIC_STATE_BLEND_CONSTANTS),
gfx_pipeline ? &gfx_pipeline->state.blend.pstate : NULL,
panvk_graphics_pipeline_static_state(gfx_pipeline,
VK_DYNAMIC_STATE_BLEND_CONSTANTS),
builder->alloc);
if (!shader)
return VK_ERROR_OUT_OF_HOST_MEMORY;
@ -192,6 +182,8 @@ static void
panvk_pipeline_builder_alloc_static_state_bo(
struct panvk_pipeline_builder *builder, struct panvk_pipeline *pipeline)
{
struct panvk_graphics_pipeline *gfx_pipeline =
panvk_pipeline_to_graphics_pipeline(pipeline);
unsigned bo_size = 0;
for (uint32_t i = 0; i < MESA_SHADER_STAGES; i++) {
@ -199,19 +191,23 @@ panvk_pipeline_builder_alloc_static_state_bo(
if (!shader && i != MESA_SHADER_FRAGMENT)
continue;
if (pipeline->fs.dynamic_rsd && i == MESA_SHADER_FRAGMENT)
assert(gfx_pipeline);
if (gfx_pipeline->state.fs.dynamic_rsd && i == MESA_SHADER_FRAGMENT)
continue;
bo_size = ALIGN_POT(bo_size, pan_alignment(RENDERER_STATE));
builder->stages[i].rsd_offset = bo_size;
bo_size += pan_size(RENDERER_STATE);
if (i == MESA_SHADER_FRAGMENT)
bo_size += pan_size(BLEND) * MAX2(pipeline->blend.state.rt_count, 1);
bo_size += pan_size(BLEND) *
MAX2(gfx_pipeline->state.blend.pstate.rt_count, 1);
}
if (builder->create_info.gfx &&
panvk_pipeline_static_state(pipeline, VK_DYNAMIC_STATE_VIEWPORT) &&
panvk_pipeline_static_state(pipeline, VK_DYNAMIC_STATE_SCISSOR)) {
panvk_graphics_pipeline_static_state(gfx_pipeline,
VK_DYNAMIC_STATE_VIEWPORT) &&
panvk_graphics_pipeline_static_state(gfx_pipeline,
VK_DYNAMIC_STATE_SCISSOR)) {
bo_size = ALIGN_POT(bo_size, pan_alignment(VIEWPORT));
builder->vpd_offset = bo_size;
bo_size += pan_size(VIEWPORT);
@ -235,29 +231,32 @@ panvk_pipeline_builder_emit_non_fs_rsd(
}
static void
panvk_pipeline_builder_emit_base_fs_rsd(const struct panvk_pipeline *pipeline,
void *rsd)
panvk_pipeline_builder_emit_base_fs_rsd(
const struct panvk_graphics_pipeline *pipeline, void *rsd)
{
const struct pan_shader_info *info = &pipeline->fs.info;
const struct pan_shader_info *info = &pipeline->state.fs.info;
pan_pack(rsd, RENDERER_STATE, cfg) {
if (pipeline->fs.required) {
pan_shader_prepare_rsd(info, pipeline->fs.address, &cfg);
if (pipeline->state.fs.required) {
pan_shader_prepare_rsd(info, pipeline->state.fs.address, &cfg);
uint8_t rt_written =
pipeline->fs.info.outputs_written >> FRAG_RESULT_DATA0;
uint8_t rt_mask = pipeline->fs.rt_mask;
pipeline->state.fs.info.outputs_written >> FRAG_RESULT_DATA0;
uint8_t rt_mask = pipeline->state.fs.rt_mask;
cfg.properties.allow_forward_pixel_to_kill =
pipeline->fs.info.fs.can_fpk && !(rt_mask & ~rt_written) &&
!pipeline->ms.alpha_to_coverage && !pipeline->blend.reads_dest;
pipeline->state.fs.info.fs.can_fpk && !(rt_mask & ~rt_written) &&
!pipeline->state.ms.alpha_to_coverage &&
!pipeline->state.blend.reads_dest;
bool writes_zs = pipeline->zs.z_write || pipeline->zs.s_test;
bool zs_always_passes = !pipeline->zs.z_test && !pipeline->zs.s_test;
bool writes_zs =
pipeline->state.zs.z_write || pipeline->state.zs.s_test;
bool zs_always_passes =
!pipeline->state.zs.z_test && !pipeline->state.zs.s_test;
bool oq = false; /* TODO: Occlusion queries */
struct pan_earlyzs_state earlyzs =
pan_earlyzs_get(pan_earlyzs_analyze(info), writes_zs || oq,
pipeline->ms.alpha_to_coverage, zs_always_passes);
struct pan_earlyzs_state earlyzs = pan_earlyzs_get(
pan_earlyzs_analyze(info), writes_zs || oq,
pipeline->state.ms.alpha_to_coverage, zs_always_passes);
cfg.properties.pixel_kill_operation = earlyzs.kill;
cfg.properties.zs_update_operation = earlyzs.update;
@ -268,66 +267,71 @@ panvk_pipeline_builder_emit_base_fs_rsd(const struct panvk_pipeline *pipeline,
cfg.properties.zs_update_operation = MALI_PIXEL_KILL_STRONG_EARLY;
}
bool msaa = pipeline->ms.rast_samples > 1;
bool msaa = pipeline->state.ms.rast_samples > 1;
cfg.multisample_misc.multisample_enable = msaa;
cfg.multisample_misc.sample_mask =
msaa ? pipeline->ms.sample_mask : UINT16_MAX;
msaa ? pipeline->state.ms.sample_mask : UINT16_MAX;
cfg.multisample_misc.depth_function =
pipeline->zs.z_test ? pipeline->zs.z_compare_func : MALI_FUNC_ALWAYS;
pipeline->state.zs.z_test ? pipeline->state.zs.z_compare_func
: MALI_FUNC_ALWAYS;
cfg.multisample_misc.depth_write_mask = pipeline->zs.z_write;
cfg.multisample_misc.depth_write_mask = pipeline->state.zs.z_write;
cfg.multisample_misc.fixed_function_near_discard =
!pipeline->rast.clamp_depth;
!pipeline->state.rast.clamp_depth;
cfg.multisample_misc.fixed_function_far_discard =
!pipeline->rast.clamp_depth;
!pipeline->state.rast.clamp_depth;
cfg.multisample_misc.shader_depth_range_fixed = true;
cfg.stencil_mask_misc.stencil_enable = pipeline->zs.s_test;
cfg.stencil_mask_misc.alpha_to_coverage = pipeline->ms.alpha_to_coverage;
cfg.stencil_mask_misc.stencil_enable = pipeline->state.zs.s_test;
cfg.stencil_mask_misc.alpha_to_coverage =
pipeline->state.ms.alpha_to_coverage;
cfg.stencil_mask_misc.alpha_test_compare_function = MALI_FUNC_ALWAYS;
cfg.stencil_mask_misc.front_facing_depth_bias =
pipeline->rast.depth_bias.enable;
pipeline->state.rast.depth_bias.enable;
cfg.stencil_mask_misc.back_facing_depth_bias =
pipeline->rast.depth_bias.enable;
pipeline->state.rast.depth_bias.enable;
cfg.stencil_mask_misc.single_sampled_lines =
pipeline->ms.rast_samples <= 1;
pipeline->state.ms.rast_samples <= 1;
if (!(pipeline->dynamic_state_mask &
(1 << VK_DYNAMIC_STATE_DEPTH_BIAS))) {
cfg.depth_units = pipeline->rast.depth_bias.constant_factor * 2.0f;
cfg.depth_factor = pipeline->rast.depth_bias.slope_factor;
cfg.depth_bias_clamp = pipeline->rast.depth_bias.clamp;
if (panvk_graphics_pipeline_static_state(pipeline,
VK_DYNAMIC_STATE_DEPTH_BIAS)) {
cfg.depth_units =
pipeline->state.rast.depth_bias.constant_factor * 2.0f;
cfg.depth_factor = pipeline->state.rast.depth_bias.slope_factor;
cfg.depth_bias_clamp = pipeline->state.rast.depth_bias.clamp;
}
if (!(pipeline->dynamic_state_mask &
(1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK))) {
cfg.stencil_front.mask = pipeline->zs.s_front.compare_mask;
cfg.stencil_back.mask = pipeline->zs.s_back.compare_mask;
if (panvk_graphics_pipeline_static_state(
pipeline, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK)) {
cfg.stencil_front.mask = pipeline->state.zs.s_front.compare_mask;
cfg.stencil_back.mask = pipeline->state.zs.s_back.compare_mask;
}
if (!(pipeline->dynamic_state_mask &
(1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK))) {
if (panvk_graphics_pipeline_static_state(
pipeline, VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) {
cfg.stencil_mask_misc.stencil_mask_front =
pipeline->zs.s_front.write_mask;
pipeline->state.zs.s_front.write_mask;
cfg.stencil_mask_misc.stencil_mask_back =
pipeline->zs.s_back.write_mask;
pipeline->state.zs.s_back.write_mask;
}
if (!(pipeline->dynamic_state_mask &
(1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE))) {
cfg.stencil_front.reference_value = pipeline->zs.s_front.ref;
cfg.stencil_back.reference_value = pipeline->zs.s_back.ref;
if (panvk_graphics_pipeline_static_state(
pipeline, VK_DYNAMIC_STATE_STENCIL_REFERENCE)) {
cfg.stencil_front.reference_value = pipeline->state.zs.s_front.ref;
cfg.stencil_back.reference_value = pipeline->state.zs.s_back.ref;
}
cfg.stencil_front.compare_function = pipeline->zs.s_front.compare_func;
cfg.stencil_front.stencil_fail = pipeline->zs.s_front.fail_op;
cfg.stencil_front.depth_fail = pipeline->zs.s_front.z_fail_op;
cfg.stencil_front.depth_pass = pipeline->zs.s_front.pass_op;
cfg.stencil_back.compare_function = pipeline->zs.s_back.compare_func;
cfg.stencil_back.stencil_fail = pipeline->zs.s_back.fail_op;
cfg.stencil_back.depth_fail = pipeline->zs.s_back.z_fail_op;
cfg.stencil_back.depth_pass = pipeline->zs.s_back.pass_op;
cfg.stencil_front.compare_function =
pipeline->state.zs.s_front.compare_func;
cfg.stencil_front.stencil_fail = pipeline->state.zs.s_front.fail_op;
cfg.stencil_front.depth_fail = pipeline->state.zs.s_front.z_fail_op;
cfg.stencil_front.depth_pass = pipeline->state.zs.s_front.pass_op;
cfg.stencil_back.compare_function =
pipeline->state.zs.s_back.compare_func;
cfg.stencil_back.stencil_fail = pipeline->state.zs.s_back.fail_op;
cfg.stencil_back.depth_fail = pipeline->state.zs.s_back.z_fail_op;
cfg.stencil_back.depth_pass = pipeline->state.zs.s_back.pass_op;
}
}
@ -355,10 +359,10 @@ blend_type_from_nir(nir_alu_type nir_type)
}
static void
panvk_pipeline_builder_emit_blend(const struct panvk_pipeline *pipeline,
unsigned rt, void *bd)
panvk_pipeline_builder_emit_blend(
const struct panvk_graphics_pipeline *pipeline, unsigned rt, void *bd)
{
const struct pan_blend_state *blend = &pipeline->blend.state;
const struct pan_blend_state *blend = &pipeline->state.blend.pstate;
const struct pan_blend_rt_state *rts = &blend->rts[rt];
bool dithered = false;
@ -407,7 +411,7 @@ panvk_pipeline_builder_emit_blend(const struct panvk_pipeline *pipeline,
cfg.internal.fixed_function.conversion.memory_format =
GENX(panfrost_dithered_format_from_pipe_format)(rts->format, dithered);
cfg.internal.fixed_function.conversion.register_format =
blend_type_from_nir(pipeline->fs.info.bifrost.blend[rt].type);
blend_type_from_nir(pipeline->state.fs.info.bifrost.blend[rt].type);
cfg.internal.fixed_function.rt = rt;
}
}
@ -416,13 +420,17 @@ static void
panvk_pipeline_builder_init_shaders(struct panvk_pipeline_builder *builder,
struct panvk_pipeline *pipeline)
{
struct panvk_graphics_pipeline *gfx_pipeline =
panvk_pipeline_to_graphics_pipeline(pipeline);
struct panvk_compute_pipeline *compute_pipeline =
panvk_pipeline_to_compute_pipeline(pipeline);
for (uint32_t i = 0; i < MESA_SHADER_STAGES; i++) {
const struct panvk_shader *shader = builder->shaders[i];
if (!shader)
continue;
pipeline->tls_size = MAX2(pipeline->tls_size, shader->info.tls_size);
pipeline->wls_size = MAX2(pipeline->wls_size, shader->info.wls_size);
if (shader->has_img_access)
pipeline->img_access_mask |= BITFIELD_BIT(i);
@ -436,7 +444,7 @@ panvk_pipeline_builder_init_shaders(struct panvk_pipeline_builder *builder,
* pipeline to write point size when we're actually drawing points.
* Otherwise the point size write would conflict with wide lines.
*/
pipeline->ia.writes_point_size = points;
gfx_pipeline->state.ia.writes_point_size = points;
}
mali_ptr shader_ptr = 0;
@ -457,38 +465,42 @@ panvk_pipeline_builder_init_shaders(struct panvk_pipeline_builder *builder,
pipeline->rsds[i] = gpu_rsd;
}
if (i == MESA_SHADER_COMPUTE)
pipeline->cs.local_size = shader->local_size;
if (i == MESA_SHADER_COMPUTE) {
compute_pipeline->local_size = shader->local_size;
compute_pipeline->wls_size = shader->info.wls_size;
}
}
if (builder->create_info.gfx && !pipeline->fs.dynamic_rsd) {
if (builder->create_info.gfx && !gfx_pipeline->state.fs.dynamic_rsd) {
void *rsd = pipeline->state_bo->addr.host +
builder->stages[MESA_SHADER_FRAGMENT].rsd_offset;
mali_ptr gpu_rsd = pipeline->state_bo->addr.dev +
builder->stages[MESA_SHADER_FRAGMENT].rsd_offset;
void *bd = rsd + pan_size(RENDERER_STATE);
panvk_pipeline_builder_emit_base_fs_rsd(pipeline, rsd);
for (unsigned rt = 0; rt < pipeline->blend.state.rt_count; rt++) {
panvk_pipeline_builder_emit_blend(pipeline, rt, bd);
panvk_pipeline_builder_emit_base_fs_rsd(gfx_pipeline, rsd);
for (unsigned rt = 0; rt < gfx_pipeline->state.blend.pstate.rt_count;
rt++) {
panvk_pipeline_builder_emit_blend(gfx_pipeline, rt, bd);
bd += pan_size(BLEND);
}
pipeline->rsds[MESA_SHADER_FRAGMENT] = gpu_rsd;
} else if (builder->create_info.gfx) {
panvk_pipeline_builder_emit_base_fs_rsd(pipeline,
&pipeline->fs.rsd_template);
for (unsigned rt = 0; rt < MAX2(pipeline->blend.state.rt_count, 1);
rt++) {
panvk_pipeline_builder_emit_blend(pipeline, rt,
&pipeline->blend.bd_template[rt]);
panvk_pipeline_builder_emit_base_fs_rsd(
gfx_pipeline, gfx_pipeline->state.fs.rsd_template.opaque);
for (unsigned rt = 0;
rt < MAX2(gfx_pipeline->state.blend.pstate.rt_count, 1); rt++) {
panvk_pipeline_builder_emit_blend(
gfx_pipeline, rt,
&gfx_pipeline->state.blend.bd_template[rt].opaque);
}
}
}
static void
panvk_pipeline_builder_parse_viewport(struct panvk_pipeline_builder *builder,
struct panvk_pipeline *pipeline)
struct panvk_graphics_pipeline *pipeline)
{
/* The spec says:
*
@ -497,28 +509,34 @@ panvk_pipeline_builder_parse_viewport(struct panvk_pipeline_builder *builder,
* pipeline has rasterization disabled.
*/
if (!builder->rasterizer_discard &&
panvk_pipeline_static_state(pipeline, VK_DYNAMIC_STATE_VIEWPORT) &&
panvk_pipeline_static_state(pipeline, VK_DYNAMIC_STATE_SCISSOR)) {
void *vpd = pipeline->state_bo->addr.host + builder->vpd_offset;
panvk_graphics_pipeline_static_state(pipeline,
VK_DYNAMIC_STATE_VIEWPORT) &&
panvk_graphics_pipeline_static_state(pipeline,
VK_DYNAMIC_STATE_SCISSOR)) {
void *vpd = pipeline->base.state_bo->addr.host + builder->vpd_offset;
panvk_per_arch(emit_viewport)(
builder->create_info.gfx->pViewportState->pViewports,
builder->create_info.gfx->pViewportState->pScissors, vpd);
pipeline->vpd = pipeline->state_bo->addr.dev + builder->vpd_offset;
pipeline->state.vp.vpd =
pipeline->base.state_bo->addr.dev + builder->vpd_offset;
}
if (panvk_pipeline_static_state(pipeline, VK_DYNAMIC_STATE_VIEWPORT) &&
if (panvk_graphics_pipeline_static_state(pipeline,
VK_DYNAMIC_STATE_VIEWPORT) &&
builder->create_info.gfx->pViewportState)
pipeline->viewport =
pipeline->state.vp.viewport =
builder->create_info.gfx->pViewportState->pViewports[0];
if (panvk_pipeline_static_state(pipeline, VK_DYNAMIC_STATE_SCISSOR) &&
if (panvk_graphics_pipeline_static_state(pipeline,
VK_DYNAMIC_STATE_SCISSOR) &&
builder->create_info.gfx->pViewportState)
pipeline->scissor =
pipeline->state.vp.scissor =
builder->create_info.gfx->pViewportState->pScissors[0];
}
static void
panvk_pipeline_builder_parse_dynamic(struct panvk_pipeline_builder *builder,
struct panvk_pipeline *pipeline)
struct panvk_graphics_pipeline *pipeline)
{
const VkPipelineDynamicStateCreateInfo *dynamic_info =
builder->create_info.gfx->pDynamicState;
@ -530,7 +548,7 @@ panvk_pipeline_builder_parse_dynamic(struct panvk_pipeline_builder *builder,
VkDynamicState state = dynamic_info->pDynamicStates[i];
switch (state) {
case VK_DYNAMIC_STATE_VIEWPORT ... VK_DYNAMIC_STATE_STENCIL_REFERENCE:
pipeline->dynamic_state_mask |= 1 << state;
pipeline->state.dynamic_mask |= 1 << state;
break;
default:
unreachable("unsupported dynamic state");
@ -566,35 +584,37 @@ translate_prim_topology(VkPrimitiveTopology in)
static void
panvk_pipeline_builder_parse_input_assembly(
struct panvk_pipeline_builder *builder, struct panvk_pipeline *pipeline)
struct panvk_pipeline_builder *builder,
struct panvk_graphics_pipeline *pipeline)
{
pipeline->ia.primitive_restart =
pipeline->state.ia.primitive_restart =
builder->create_info.gfx->pInputAssemblyState->primitiveRestartEnable;
pipeline->ia.topology = translate_prim_topology(
pipeline->state.ia.topology = translate_prim_topology(
builder->create_info.gfx->pInputAssemblyState->topology);
}
static void
panvk_pipeline_builder_parse_color_blend(struct panvk_pipeline_builder *builder,
struct panvk_pipeline *pipeline)
panvk_pipeline_builder_parse_color_blend(
struct panvk_pipeline_builder *builder,
struct panvk_graphics_pipeline *pipeline)
{
if (!builder->create_info.gfx->pColorBlendState)
return;
pipeline->blend.state.logicop_enable =
pipeline->state.blend.pstate.logicop_enable =
builder->create_info.gfx->pColorBlendState->logicOpEnable;
pipeline->blend.state.logicop_func =
pipeline->state.blend.pstate.logicop_func =
vk_logic_op_to_pipe(builder->create_info.gfx->pColorBlendState->logicOp);
pipeline->blend.state.rt_count =
pipeline->state.blend.pstate.rt_count =
util_last_bit(builder->active_color_attachments);
memcpy(pipeline->blend.state.constants,
memcpy(pipeline->state.blend.pstate.constants,
builder->create_info.gfx->pColorBlendState->blendConstants,
sizeof(pipeline->blend.state.constants));
sizeof(pipeline->state.blend.pstate.constants));
for (unsigned i = 0; i < pipeline->blend.state.rt_count; i++) {
for (unsigned i = 0; i < pipeline->state.blend.pstate.rt_count; i++) {
const VkPipelineColorBlendAttachmentState *in =
&builder->create_info.gfx->pColorBlendState->pAttachments[i];
struct pan_blend_rt_state *out = &pipeline->blend.state.rts[i];
struct pan_blend_rt_state *out = &pipeline->state.blend.pstate.rts[i];
out->format = builder->color_attachment_formats[i];
@ -627,13 +647,14 @@ panvk_pipeline_builder_parse_color_blend(struct panvk_pipeline_builder *builder,
util_blend_dst_alpha_to_one(out->equation.alpha_dst_factor);
}
pipeline->blend.reads_dest |= pan_blend_reads_dest(out->equation);
pipeline->state.blend.reads_dest |= pan_blend_reads_dest(out->equation);
unsigned constant_mask = panvk_per_arch(blend_needs_lowering)(
builder->device, &pipeline->blend.state, i)
? 0
: pan_blend_constant_mask(out->equation);
pipeline->blend.constant[i].index = ffs(constant_mask) - 1;
unsigned constant_mask =
panvk_per_arch(blend_needs_lowering)(builder->device,
&pipeline->state.blend.pstate, i)
? 0
: pan_blend_constant_mask(out->equation);
pipeline->state.blend.constant[i].index = ffs(constant_mask) - 1;
if (constant_mask) {
/* On Bifrost, the blend constant is expressed with a UNORM of the
* size of the target format. The value is then shifted such that
@ -647,26 +668,27 @@ panvk_pipeline_builder_parse_color_blend(struct panvk_pipeline_builder *builder,
unsigned chan_size = 0;
for (unsigned c = 0; c < format_desc->nr_channels; c++)
chan_size = MAX2(format_desc->channel[c].size, chan_size);
pipeline->blend.constant[i].bifrost_factor = ((1 << chan_size) - 1)
<< (16 - chan_size);
pipeline->state.blend.constant[i].bifrost_factor =
((1 << chan_size) - 1) << (16 - chan_size);
}
}
}
static void
panvk_pipeline_builder_parse_multisample(struct panvk_pipeline_builder *builder,
struct panvk_pipeline *pipeline)
panvk_pipeline_builder_parse_multisample(
struct panvk_pipeline_builder *builder,
struct panvk_graphics_pipeline *pipeline)
{
unsigned nr_samples = MAX2(
builder->create_info.gfx->pMultisampleState->rasterizationSamples, 1);
pipeline->ms.rast_samples =
pipeline->state.ms.rast_samples =
builder->create_info.gfx->pMultisampleState->rasterizationSamples;
pipeline->ms.sample_mask =
pipeline->state.ms.sample_mask =
builder->create_info.gfx->pMultisampleState->pSampleMask
? builder->create_info.gfx->pMultisampleState->pSampleMask[0]
: UINT16_MAX;
pipeline->ms.min_samples =
pipeline->state.ms.min_samples =
MAX2(builder->create_info.gfx->pMultisampleState->minSampleShading *
nr_samples,
1);
@ -715,12 +737,12 @@ translate_compare_func(VkCompareOp comp)
static void
panvk_pipeline_builder_parse_zs(struct panvk_pipeline_builder *builder,
struct panvk_pipeline *pipeline)
struct panvk_graphics_pipeline *pipeline)
{
if (!builder->use_depth_stencil_attachment)
return;
pipeline->zs.z_test =
pipeline->state.zs.z_test =
builder->create_info.gfx->pDepthStencilState->depthTestEnable;
/* The Vulkan spec says:
@ -732,84 +754,84 @@ panvk_pipeline_builder_parse_zs(struct panvk_pipeline_builder *builder,
* The hardware does not make this distinction, though, so we AND in the
* condition ourselves.
*/
pipeline->zs.z_write =
pipeline->zs.z_test &&
pipeline->state.zs.z_write =
pipeline->state.zs.z_test &&
builder->create_info.gfx->pDepthStencilState->depthWriteEnable;
pipeline->zs.z_compare_func = translate_compare_func(
pipeline->state.zs.z_compare_func = translate_compare_func(
builder->create_info.gfx->pDepthStencilState->depthCompareOp);
pipeline->zs.s_test =
pipeline->state.zs.s_test =
builder->create_info.gfx->pDepthStencilState->stencilTestEnable;
pipeline->zs.s_front.fail_op = translate_stencil_op(
pipeline->state.zs.s_front.fail_op = translate_stencil_op(
builder->create_info.gfx->pDepthStencilState->front.failOp);
pipeline->zs.s_front.pass_op = translate_stencil_op(
pipeline->state.zs.s_front.pass_op = translate_stencil_op(
builder->create_info.gfx->pDepthStencilState->front.passOp);
pipeline->zs.s_front.z_fail_op = translate_stencil_op(
pipeline->state.zs.s_front.z_fail_op = translate_stencil_op(
builder->create_info.gfx->pDepthStencilState->front.depthFailOp);
pipeline->zs.s_front.compare_func = translate_compare_func(
pipeline->state.zs.s_front.compare_func = translate_compare_func(
builder->create_info.gfx->pDepthStencilState->front.compareOp);
pipeline->zs.s_front.compare_mask =
pipeline->state.zs.s_front.compare_mask =
builder->create_info.gfx->pDepthStencilState->front.compareMask;
pipeline->zs.s_front.write_mask =
pipeline->state.zs.s_front.write_mask =
builder->create_info.gfx->pDepthStencilState->front.writeMask;
pipeline->zs.s_front.ref =
pipeline->state.zs.s_front.ref =
builder->create_info.gfx->pDepthStencilState->front.reference;
pipeline->zs.s_back.fail_op = translate_stencil_op(
pipeline->state.zs.s_back.fail_op = translate_stencil_op(
builder->create_info.gfx->pDepthStencilState->back.failOp);
pipeline->zs.s_back.pass_op = translate_stencil_op(
pipeline->state.zs.s_back.pass_op = translate_stencil_op(
builder->create_info.gfx->pDepthStencilState->back.passOp);
pipeline->zs.s_back.z_fail_op = translate_stencil_op(
pipeline->state.zs.s_back.z_fail_op = translate_stencil_op(
builder->create_info.gfx->pDepthStencilState->back.depthFailOp);
pipeline->zs.s_back.compare_func = translate_compare_func(
pipeline->state.zs.s_back.compare_func = translate_compare_func(
builder->create_info.gfx->pDepthStencilState->back.compareOp);
pipeline->zs.s_back.compare_mask =
pipeline->state.zs.s_back.compare_mask =
builder->create_info.gfx->pDepthStencilState->back.compareMask;
pipeline->zs.s_back.write_mask =
pipeline->state.zs.s_back.write_mask =
builder->create_info.gfx->pDepthStencilState->back.writeMask;
pipeline->zs.s_back.ref =
pipeline->state.zs.s_back.ref =
builder->create_info.gfx->pDepthStencilState->back.reference;
}
static void
panvk_pipeline_builder_parse_rast(struct panvk_pipeline_builder *builder,
struct panvk_pipeline *pipeline)
struct panvk_graphics_pipeline *pipeline)
{
pipeline->rast.clamp_depth =
pipeline->state.rast.clamp_depth =
builder->create_info.gfx->pRasterizationState->depthClampEnable;
pipeline->rast.depth_bias.enable =
pipeline->state.rast.depth_bias.enable =
builder->create_info.gfx->pRasterizationState->depthBiasEnable;
pipeline->rast.depth_bias.constant_factor =
pipeline->state.rast.depth_bias.constant_factor =
builder->create_info.gfx->pRasterizationState->depthBiasConstantFactor;
pipeline->rast.depth_bias.clamp =
pipeline->state.rast.depth_bias.clamp =
builder->create_info.gfx->pRasterizationState->depthBiasClamp;
pipeline->rast.depth_bias.slope_factor =
pipeline->state.rast.depth_bias.slope_factor =
builder->create_info.gfx->pRasterizationState->depthBiasSlopeFactor;
pipeline->rast.front_ccw =
pipeline->state.rast.front_ccw =
builder->create_info.gfx->pRasterizationState->frontFace ==
VK_FRONT_FACE_COUNTER_CLOCKWISE;
pipeline->rast.cull_front_face =
pipeline->state.rast.cull_front_face =
builder->create_info.gfx->pRasterizationState->cullMode &
VK_CULL_MODE_FRONT_BIT;
pipeline->rast.cull_back_face =
pipeline->state.rast.cull_back_face =
builder->create_info.gfx->pRasterizationState->cullMode &
VK_CULL_MODE_BACK_BIT;
pipeline->rast.line_width =
pipeline->state.rast.line_width =
builder->create_info.gfx->pRasterizationState->lineWidth;
pipeline->rast.enable =
pipeline->state.rast.enable =
!builder->create_info.gfx->pRasterizationState->rasterizerDiscardEnable;
}
static bool
panvk_fs_required(struct panvk_pipeline *pipeline)
panvk_fs_required(struct panvk_graphics_pipeline *pipeline)
{
const struct pan_shader_info *info = &pipeline->fs.info;
const struct pan_shader_info *info = &pipeline->state.fs.info;
/* If we generally have side effects */
if (info->fs.sidefx)
return true;
/* If colour is written we need to execute */
const struct pan_blend_state *blend = &pipeline->blend.state;
const struct pan_blend_state *blend = &pipeline->state.blend.pstate;
for (unsigned i = 0; i < blend->rt_count; ++i) {
if (blend->rts[i].equation.color_mask)
return true;
@ -829,18 +851,19 @@ panvk_fs_required(struct panvk_pipeline *pipeline)
static void
panvk_pipeline_builder_init_fs_state(struct panvk_pipeline_builder *builder,
struct panvk_pipeline *pipeline)
struct panvk_graphics_pipeline *pipeline)
{
if (!builder->shaders[MESA_SHADER_FRAGMENT])
return;
pipeline->fs.dynamic_rsd =
pipeline->dynamic_state_mask & PANVK_DYNAMIC_FS_RSD_MASK;
pipeline->fs.address = pipeline->binary_bo->addr.dev +
builder->stages[MESA_SHADER_FRAGMENT].shader_offset;
pipeline->fs.info = builder->shaders[MESA_SHADER_FRAGMENT]->info;
pipeline->fs.rt_mask = builder->active_color_attachments;
pipeline->fs.required = panvk_fs_required(pipeline);
pipeline->state.fs.dynamic_rsd =
pipeline->state.dynamic_mask & PANVK_DYNAMIC_FS_RSD_MASK;
pipeline->state.fs.address =
pipeline->base.binary_bo->addr.dev +
builder->stages[MESA_SHADER_FRAGMENT].shader_offset;
pipeline->state.fs.info = builder->shaders[MESA_SHADER_FRAGMENT]->info;
pipeline->state.fs.rt_mask = builder->active_color_attachments;
pipeline->state.fs.required = panvk_fs_required(pipeline);
}
static void
@ -887,7 +910,7 @@ panvk_pipeline_update_varying_slot(struct panvk_varyings_info *varyings,
static void
panvk_pipeline_builder_collect_varyings(struct panvk_pipeline_builder *builder,
struct panvk_pipeline *pipeline)
struct panvk_graphics_pipeline *pipeline)
{
for (uint32_t s = 0; s < MESA_SHADER_STAGES; s++) {
if (!builder->shaders[s])
@ -925,9 +948,10 @@ panvk_pipeline_builder_collect_varyings(struct panvk_pipeline_builder *builder,
static void
panvk_pipeline_builder_parse_vertex_input(
struct panvk_pipeline_builder *builder, struct panvk_pipeline *pipeline)
struct panvk_pipeline_builder *builder,
struct panvk_graphics_pipeline *pipeline)
{
struct panvk_attribs_info *attribs = &pipeline->attribs;
struct panvk_attribs_info *attribs = &pipeline->state.vs.attribs;
const VkPipelineVertexInputStateCreateInfo *info =
builder->create_info.gfx->pVertexInputState;
@ -976,27 +1000,45 @@ static VkResult
panvk_pipeline_builder_build(struct panvk_pipeline_builder *builder,
struct panvk_pipeline **pipeline)
{
VkResult result = panvk_pipeline_builder_create_pipeline(builder, pipeline);
if (result != VK_SUCCESS)
return result;
struct panvk_device *dev = builder->device;
/* TODO: make those functions return a result and handle errors */
if (builder->create_info.gfx) {
panvk_pipeline_builder_parse_dynamic(builder, *pipeline);
panvk_pipeline_builder_parse_color_blend(builder, *pipeline);
struct panvk_graphics_pipeline *gfx_pipeline =
vk_object_zalloc(&dev->vk, builder->alloc, sizeof(*gfx_pipeline),
VK_OBJECT_TYPE_PIPELINE);
if (!gfx_pipeline)
return VK_ERROR_OUT_OF_HOST_MEMORY;
*pipeline = &gfx_pipeline->base;
gfx_pipeline->base.layout = builder->layout;
gfx_pipeline->base.type = PANVK_PIPELINE_GRAPHICS;
panvk_pipeline_builder_parse_dynamic(builder, gfx_pipeline);
panvk_pipeline_builder_parse_color_blend(builder, gfx_pipeline);
panvk_pipeline_builder_compile_shaders(builder, *pipeline);
panvk_pipeline_builder_collect_varyings(builder, *pipeline);
panvk_pipeline_builder_parse_input_assembly(builder, *pipeline);
panvk_pipeline_builder_parse_multisample(builder, *pipeline);
panvk_pipeline_builder_parse_zs(builder, *pipeline);
panvk_pipeline_builder_parse_rast(builder, *pipeline);
panvk_pipeline_builder_parse_vertex_input(builder, *pipeline);
panvk_pipeline_builder_collect_varyings(builder, gfx_pipeline);
panvk_pipeline_builder_parse_input_assembly(builder, gfx_pipeline);
panvk_pipeline_builder_parse_multisample(builder, gfx_pipeline);
panvk_pipeline_builder_parse_zs(builder, gfx_pipeline);
panvk_pipeline_builder_parse_rast(builder, gfx_pipeline);
panvk_pipeline_builder_parse_vertex_input(builder, gfx_pipeline);
panvk_pipeline_builder_upload_shaders(builder, *pipeline);
panvk_pipeline_builder_init_fs_state(builder, *pipeline);
panvk_pipeline_builder_init_fs_state(builder, gfx_pipeline);
panvk_pipeline_builder_alloc_static_state_bo(builder, *pipeline);
panvk_pipeline_builder_init_shaders(builder, *pipeline);
panvk_pipeline_builder_parse_viewport(builder, *pipeline);
panvk_pipeline_builder_parse_viewport(builder, gfx_pipeline);
} else {
struct panvk_compute_pipeline *compute_pipeline =
vk_object_zalloc(&dev->vk, builder->alloc, sizeof(*compute_pipeline),
VK_OBJECT_TYPE_PIPELINE);
if (!compute_pipeline)
return VK_ERROR_OUT_OF_HOST_MEMORY;
*pipeline = &compute_pipeline->base;
compute_pipeline->base.layout = builder->layout;
compute_pipeline->base.type = PANVK_PIPELINE_COMPUTE;
panvk_pipeline_builder_compile_shaders(builder, *pipeline);
panvk_pipeline_builder_upload_shaders(builder, *pipeline);
panvk_pipeline_builder_alloc_static_state_bo(builder, *pipeline);