diff --git a/src/gallium/drivers/panfrost/pan_blend.h b/src/gallium/drivers/panfrost/pan_blend.h index df1227bfd01..0a0e5bc3f6f 100644 --- a/src/gallium/drivers/panfrost/pan_blend.h +++ b/src/gallium/drivers/panfrost/pan_blend.h @@ -121,7 +121,7 @@ void panfrost_blend_context_init(struct pipe_context *pipe); struct panfrost_blend_final -panfrost_get_blend_for_context(struct panfrost_context *ctx, unsigned rt); +panfrost_get_blend_for_context(struct panfrost_context *ctx, unsigned rt, struct panfrost_bo **bo, unsigned *shader_offset); struct panfrost_blend_shader * panfrost_get_blend_shader( diff --git a/src/gallium/drivers/panfrost/pan_blend_cso.c b/src/gallium/drivers/panfrost/pan_blend_cso.c index 46b0832fe06..43edddb9dd5 100644 --- a/src/gallium/drivers/panfrost/pan_blend_cso.c +++ b/src/gallium/drivers/panfrost/pan_blend_cso.c @@ -212,7 +212,7 @@ panfrost_blend_constant(float *out, float *in, unsigned mask) /* Create a final blend given the context */ struct panfrost_blend_final -panfrost_get_blend_for_context(struct panfrost_context *ctx, unsigned rti) +panfrost_get_blend_for_context(struct panfrost_context *ctx, unsigned rti, struct panfrost_bo **bo, unsigned *shader_offset) { struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx); struct pipe_framebuffer_state *fb = &ctx->pipe_framebuffer; @@ -247,19 +247,25 @@ panfrost_get_blend_for_context(struct panfrost_context *ctx, unsigned rti) /* Otherwise, we need to grab a shader */ struct panfrost_blend_shader *shader = panfrost_get_blend_shader(ctx, blend, fmt, rti); - struct panfrost_bo *bo = panfrost_batch_create_bo(batch, shader->size, + /* Upload the shader, sharing a BO */ + if (!(*bo)) { + *bo = panfrost_batch_create_bo(batch, 4096, PAN_BO_EXECUTE, PAN_BO_ACCESS_PRIVATE | PAN_BO_ACCESS_READ | PAN_BO_ACCESS_FRAGMENT); + } - memcpy(bo->cpu, shader->buffer, shader->size); + /* Size check */ + assert((*shader_offset + shader->size) < 4096); + + memcpy((*bo)->cpu + *shader_offset, shader->buffer, shader->size); if (shader->patch_index) { /* We have to specialize the blend shader to use constants, so * patch in the current constants */ - float *patch = (float *) (bo->cpu + shader->patch_index); + float *patch = (float *) ((*bo)->cpu + *shader_offset + shader->patch_index); memcpy(patch, ctx->blend_color.color, sizeof(float) * 4); } @@ -268,11 +274,13 @@ panfrost_get_blend_for_context(struct panfrost_context *ctx, unsigned rti) .shader = { .work_count = shader->work_count, .first_tag = shader->first_tag, - .gpu = bo->gpu, + .gpu = (*bo)->gpu + *shader_offset, }, .load_dest = rt->load_dest, }; + *shader_offset += shader->size; + return final; } diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index 2e5ddc3e0b5..5a872ae1b43 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -579,10 +579,12 @@ panfrost_emit_frag_shader_meta(struct panfrost_batch *batch) xfer = panfrost_pool_alloc_aligned(&batch->pool, desc_size, MALI_STATE_LENGTH); struct panfrost_blend_final blend[PIPE_MAX_COLOR_BUFS]; + unsigned shader_offset = 0; + struct panfrost_bo *shader_bo = NULL; for (unsigned c = 0; c < ctx->pipe_framebuffer.nr_cbufs; ++c) - blend[c] = panfrost_get_blend_for_context(ctx, c); - + blend[c] = panfrost_get_blend_for_context(ctx, c, &shader_bo, + &shader_offset); panfrost_emit_frag_shader(ctx, (struct mali_state_packed *) xfer.cpu, blend); if (!(dev->quirks & MIDGARD_SFBD))