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(
/* 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;
/* 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);
+ }
+
+ /* Size check */
+ assert((*shader_offset + shader->size) < 4096);
- memcpy(bo->cpu, shader->buffer, shader->size);
+ 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);
}
.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;
}
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))