PAN_BO_ACCESS_VERTEX_TILER;
}
-static void
-panfrost_vt_emit_shared_memory(struct panfrost_context *ctx,
- struct mali_vertex_tiler_postfix *postfix)
+mali_ptr
+panfrost_vt_emit_shared_memory(struct panfrost_batch *batch)
{
- struct panfrost_device *dev = pan_device(ctx->base.screen);
- struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
+ struct panfrost_device *dev = pan_device(batch->ctx->base.screen);
struct mali_shared_memory shared = {
.shared_workgroup_count = ~0,
shared.scratchpad = stack->gpu;
}
- postfix->shared_memory = panfrost_pool_upload_aligned(&batch->pool, &shared, sizeof(shared), 64);
-}
-
-static void
-panfrost_vt_attach_framebuffer(struct panfrost_context *ctx,
- struct mali_vertex_tiler_postfix *postfix)
-{
- struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
- postfix->shared_memory = panfrost_batch_reserve_framebuffer(batch);
-}
-
-static void
-panfrost_vt_update_rasterizer(struct panfrost_rasterizer *rasterizer,
- struct mali_vertex_tiler_prefix *prefix,
- struct mali_vertex_tiler_postfix *postfix)
-{
- postfix->gl_enables |= 0x7;
- SET_BIT(postfix->gl_enables, MALI_FRONT_CCW_TOP,
- rasterizer->base.front_ccw);
- SET_BIT(postfix->gl_enables, MALI_CULL_FACE_FRONT,
- (rasterizer->base.cull_face & PIPE_FACE_FRONT));
- SET_BIT(postfix->gl_enables, MALI_CULL_FACE_BACK,
- (rasterizer->base.cull_face & PIPE_FACE_BACK));
- SET_BIT(prefix->unknown_draw, MALI_DRAW_FLATSHADE_FIRST,
- rasterizer->base.flatshade_first);
+ return panfrost_pool_upload_aligned(&batch->pool, &shared, sizeof(shared), 64);
}
void
}
}
-static void
-panfrost_vt_update_occlusion_query(struct panfrost_context *ctx,
- struct mali_vertex_tiler_postfix *postfix)
-{
- SET_BIT(postfix->gl_enables, MALI_OCCLUSION_QUERY, ctx->occlusion_query);
- if (ctx->occlusion_query) {
- postfix->occlusion_counter = ctx->occlusion_query->bo->gpu;
- panfrost_batch_add_bo(ctx->batch, ctx->occlusion_query->bo,
- PAN_BO_ACCESS_SHARED |
- PAN_BO_ACCESS_RW |
- PAN_BO_ACCESS_FRAGMENT);
- } else {
- postfix->occlusion_counter = 0;
- }
-}
-
-void
-panfrost_vt_init(struct panfrost_context *ctx,
- enum pipe_shader_type stage,
- struct mali_vertex_tiler_prefix *prefix,
- struct mali_vertex_tiler_postfix *postfix)
-{
- struct panfrost_device *device = pan_device(ctx->base.screen);
-
- if (!ctx->shader[stage])
- return;
-
- memset(prefix, 0, sizeof(*prefix));
- memset(postfix, 0, sizeof(*postfix));
-
- if (device->quirks & IS_BIFROST) {
- postfix->gl_enables = 0x2;
- panfrost_vt_emit_shared_memory(ctx, postfix);
- } else {
- postfix->gl_enables = 0x6;
- panfrost_vt_attach_framebuffer(ctx, postfix);
- }
-
- if (stage == PIPE_SHADER_FRAGMENT) {
- panfrost_vt_update_occlusion_query(ctx, postfix);
- panfrost_vt_update_rasterizer(ctx->rasterizer, prefix, postfix);
- }
-}
-
-static unsigned
+unsigned
panfrost_translate_index_size(unsigned size)
{
switch (size) {
* these operations together because there are natural optimizations which
* require them to be together. */
-static mali_ptr
+mali_ptr
panfrost_get_index_buffer_bounded(struct panfrost_context *ctx,
const struct pipe_draw_info *info,
unsigned *min_index, unsigned *max_index)
return out;
}
-void
-panfrost_vt_set_draw_info(struct panfrost_context *ctx,
- const struct pipe_draw_info *info,
- enum mali_draw_mode draw_mode,
- struct mali_vertex_tiler_postfix *vertex_postfix,
- struct mali_vertex_tiler_prefix *tiler_prefix,
- struct mali_vertex_tiler_postfix *tiler_postfix,
- unsigned *vertex_count,
- unsigned *padded_count)
-{
- tiler_prefix->draw_mode = draw_mode;
-
- unsigned draw_flags = 0;
-
- if (panfrost_writes_point_size(ctx))
- draw_flags |= MALI_DRAW_VARYING_SIZE;
-
- if (info->primitive_restart)
- draw_flags |= MALI_DRAW_PRIMITIVE_RESTART_FIXED_INDEX;
-
- /* These doesn't make much sense */
-
- draw_flags |= 0x3000;
-
- if (info->index_size) {
- unsigned min_index = 0, max_index = 0;
-
- tiler_prefix->indices = panfrost_get_index_buffer_bounded(ctx,
- info,
- &min_index,
- &max_index);
-
- /* Use the corresponding values */
- *vertex_count = max_index - min_index + 1;
- tiler_postfix->offset_start = vertex_postfix->offset_start = min_index + info->index_bias;
- tiler_prefix->offset_bias_correction = -min_index;
- tiler_prefix->index_count = MALI_POSITIVE(info->count);
- draw_flags |= panfrost_translate_index_size(info->index_size);
- } else {
- tiler_prefix->indices = 0;
- *vertex_count = ctx->vertex_count;
- tiler_postfix->offset_start = vertex_postfix->offset_start = info->start;
- tiler_prefix->offset_bias_correction = 0;
- tiler_prefix->index_count = MALI_POSITIVE(ctx->vertex_count);
- }
-
- tiler_prefix->unknown_draw = draw_flags;
-
- /* Encode the padded vertex count */
-
- if (info->instance_count > 1) {
- *padded_count = panfrost_padded_vertex_count(*vertex_count);
-
- unsigned shift = __builtin_ctz(ctx->padded_count);
- unsigned k = ctx->padded_count >> (shift + 1);
-
- tiler_postfix->instance_shift = vertex_postfix->instance_shift = shift;
- tiler_postfix->instance_odd = vertex_postfix->instance_odd = k;
- } else {
- *padded_count = *vertex_count;
-
- /* Reset instancing state */
- tiler_postfix->instance_shift = vertex_postfix->instance_shift = 0;
- tiler_postfix->instance_odd = vertex_postfix->instance_odd = 0;
- }
-}
-
static unsigned
translate_tex_wrap(enum pipe_tex_wrap w)
{
struct panfrost_device *dev = pan_device(ctx->base.screen);
unsigned rt_count = MAX2(ctx->pipe_framebuffer.nr_cbufs, 1);
- void *rts = NULL;
struct panfrost_transfer xfer;
unsigned rt_size;
rt_size = sizeof(struct midgard_blend_rt);
unsigned desc_size = MALI_STATE_LENGTH + rt_size * rt_count;
-
- if (rt_size)
- rts = rzalloc_size(ctx, rt_size * rt_count);
+ xfer = panfrost_pool_alloc_aligned(&batch->pool, desc_size, MALI_STATE_LENGTH);
struct panfrost_blend_final blend[PIPE_MAX_COLOR_BUFS];
for (unsigned c = 0; c < ctx->pipe_framebuffer.nr_cbufs; ++c)
blend[c] = panfrost_get_blend_for_context(ctx, c);
+ panfrost_emit_frag_shader(ctx, (struct mali_state_packed *) xfer.cpu, blend);
+
if (!(dev->quirks & MIDGARD_SFBD))
- panfrost_emit_blend(batch, rts, blend);
+ panfrost_emit_blend(batch, xfer.cpu + MALI_STATE_LENGTH, blend);
else
batch->draws |= PIPE_CLEAR_COLOR0;
- xfer = panfrost_pool_alloc_aligned(&batch->pool, desc_size, MALI_STATE_LENGTH);
-
- panfrost_emit_frag_shader(ctx, (struct mali_state_packed *) xfer.cpu, blend);
-
- memcpy(xfer.cpu + MALI_STATE_LENGTH, rts, rt_size * rt_count);
-
- if (rt_size)
- ralloc_free(rts);
-
return xfer.gpu;
}
-void
-panfrost_emit_viewport(struct panfrost_batch *batch,
- struct mali_vertex_tiler_postfix *tiler_postfix)
+mali_ptr
+panfrost_emit_viewport(struct panfrost_batch *batch)
{
struct panfrost_context *ctx = batch->ctx;
const struct pipe_viewport_state *vp = &ctx->pipe_viewport;
cfg.maximum_z = rast->depth_clip_far ? maxz : INFINITY;
}
- tiler_postfix->viewport = T.gpu;
panfrost_batch_union_scissor(batch, minx, miny, maxx, maxy);
+ return T.gpu;
}
static mali_ptr
unreachable("No constant buffer");
}
-void
+mali_ptr
panfrost_emit_const_buf(struct panfrost_batch *batch,
enum pipe_shader_type stage,
- struct mali_vertex_tiler_postfix *postfix)
+ mali_ptr *push_constants)
{
struct panfrost_context *ctx = batch->ctx;
struct panfrost_shader_variants *all = ctx->shader[stage];
if (!all)
- return;
+ return 0;
struct panfrost_constant_buffer *buf = &ctx->constant_buffer[stage];
}
}
- postfix->uniforms = transfer.gpu;
- postfix->uniform_buffers = ubos.gpu;
+ *push_constants = transfer.gpu;
buf->dirty_mask = 0;
+ return ubos.gpu;
}
-void
+mali_ptr
panfrost_emit_shared_memory(struct panfrost_batch *batch,
- const struct pipe_grid_info *info,
- struct midgard_payload_vertex_tiler *vtp)
+ const struct pipe_grid_info *info)
{
struct panfrost_context *ctx = batch->ctx;
struct panfrost_device *dev = pan_device(ctx->base.screen);
.shared_shift = util_logbase2(single_size) + 1
};
- vtp->postfix.shared_memory = panfrost_pool_upload_aligned(&batch->pool, &shared,
- sizeof(shared), 64);
+ return panfrost_pool_upload_aligned(&batch->pool, &shared,
+ sizeof(shared), 64);
}
static mali_ptr
}
}
-void
+mali_ptr
panfrost_emit_texture_descriptors(struct panfrost_batch *batch,
- enum pipe_shader_type stage,
- struct mali_vertex_tiler_postfix *postfix)
+ enum pipe_shader_type stage)
{
struct panfrost_context *ctx = batch->ctx;
struct panfrost_device *device = pan_device(ctx->base.screen);
if (!ctx->sampler_view_count[stage])
- return;
+ return 0;
if (device->quirks & IS_BIFROST) {
struct panfrost_transfer T = panfrost_pool_alloc_aligned(&batch->pool,
panfrost_bo_access_for_stage(stage));
}
- postfix->textures = T.gpu;
+ return T.gpu;
} else {
uint64_t trampolines[PIPE_MAX_SHADER_SAMPLER_VIEWS];
trampolines[i] = panfrost_get_tex_desc(batch, stage, view);
}
- postfix->textures = panfrost_pool_upload_aligned(&batch->pool,
- trampolines,
- sizeof(uint64_t) *
- ctx->sampler_view_count[stage],
- sizeof(uint64_t));
+ return panfrost_pool_upload_aligned(&batch->pool, trampolines,
+ sizeof(uint64_t) *
+ ctx->sampler_view_count[stage],
+ sizeof(uint64_t));
}
}
-void
+mali_ptr
panfrost_emit_sampler_descriptors(struct panfrost_batch *batch,
- enum pipe_shader_type stage,
- struct mali_vertex_tiler_postfix *postfix)
+ enum pipe_shader_type stage)
{
struct panfrost_context *ctx = batch->ctx;
if (!ctx->sampler_count[stage])
- return;
+ return 0;
size_t desc_size = MALI_BIFROST_SAMPLER_LENGTH;
assert(MALI_BIFROST_SAMPLER_LENGTH == MALI_MIDGARD_SAMPLER_LENGTH);
for (unsigned i = 0; i < ctx->sampler_count[stage]; ++i)
out[i] = ctx->samplers[stage][i]->hw;
- postfix->sampler_descriptor = T.gpu;
+ return T.gpu;
}
-void
+mali_ptr
panfrost_emit_vertex_data(struct panfrost_batch *batch,
- struct mali_vertex_tiler_postfix *vertex_postfix)
+ mali_ptr *buffers)
{
struct panfrost_context *ctx = batch->ctx;
struct panfrost_vertex_state *so = ctx->vertex;
struct panfrost_shader_state *vs = panfrost_get_shader_state(ctx, PIPE_SHADER_VERTEX);
- unsigned instance_shift = vertex_postfix->instance_shift;
- unsigned instance_odd = vertex_postfix->instance_odd;
-
/* Worst case: everything is NPOT, which is only possible if instancing
* is enabled. Otherwise single record is gauranteed */
- bool could_npot = instance_shift || instance_odd;
-
struct panfrost_transfer S = panfrost_pool_alloc_aligned(&batch->pool,
MALI_ATTRIBUTE_BUFFER_LENGTH * vs->attribute_count *
- (could_npot ? 2 : 1),
+ (ctx->instance_count > 1 ? 2 : 1),
MALI_ATTRIBUTE_BUFFER_LENGTH * 2);
struct panfrost_transfer T = panfrost_pool_alloc_aligned(&batch->pool,
if (!divisor || ctx->instance_count <= 1) {
pan_pack(bufs + k, ATTRIBUTE_BUFFER, cfg) {
- if (ctx->instance_count > 1)
+ if (ctx->instance_count > 1) {
cfg.type = MALI_ATTRIBUTE_TYPE_1D_MODULUS;
+ cfg.divisor = ctx->padded_count;
+ }
cfg.pointer = addr;
cfg.stride = stride;
cfg.size = size;
- cfg.divisor_r = instance_shift;
- cfg.divisor_p = instance_odd;
}
} else if (util_is_power_of_two_or_zero(hw_divisor)) {
pan_pack(bufs + k, ATTRIBUTE_BUFFER, cfg) {
* addressing modes and now base is 64 aligned.
*/
- unsigned start = vertex_postfix->offset_start;
-
for (unsigned i = 0; i < so->num_elements; ++i) {
unsigned vbi = so->pipe[i].vertex_buffer_index;
struct pipe_vertex_buffer *buf = &ctx->vertex_buffers[vbi];
/* Also, somewhat obscurely per-instance data needs to be
* offset in response to a delayed start in an indexed draw */
- if (so->pipe[i].instance_divisor && ctx->instance_count > 1 && start)
- src_offset -= buf->stride * start;
+ if (so->pipe[i].instance_divisor && ctx->instance_count > 1)
+ src_offset -= buf->stride * ctx->offset_start;
pan_pack(out + i, ATTRIBUTE, cfg) {
cfg.buffer_index = attrib_to_buffer[i];
}
}
- vertex_postfix->attributes = S.gpu;
- vertex_postfix->attribute_meta = T.gpu;
+ *buffers = S.gpu;
+ return T.gpu;
}
static mali_ptr
void
panfrost_emit_varying_descriptor(struct panfrost_batch *batch,
unsigned vertex_count,
- struct mali_vertex_tiler_postfix *vertex_postfix,
- struct mali_vertex_tiler_postfix *tiler_postfix,
- union midgard_primitive_size *primitive_size)
+ mali_ptr *vs_attribs,
+ mali_ptr *fs_attribs,
+ mali_ptr *buffers,
+ mali_ptr *position,
+ mali_ptr *psiz)
{
/* Load the shaders */
struct panfrost_context *ctx = batch->ctx;
gen_stride, vertex_count);
/* fp32 vec4 gl_Position */
- tiler_postfix->position_varying = panfrost_emit_varyings(batch,
+ *position = panfrost_emit_varyings(batch,
&varyings[pan_varying_index(present, PAN_VARY_POSITION)],
sizeof(float) * 4, vertex_count);
if (present & (1 << PAN_VARY_PSIZ)) {
- primitive_size->pointer = panfrost_emit_varyings(batch,
+ *psiz = panfrost_emit_varyings(batch,
&varyings[pan_varying_index(present, PAN_VARY_PSIZ)],
2, vertex_count);
}
pan_emit_special_input(varyings, present, PAN_VARY_FACE, MALI_ATTRIBUTE_SPECIAL_FRONT_FACING);
pan_emit_special_input(varyings, present, PAN_VARY_FRAGCOORD, MALI_ATTRIBUTE_SPECIAL_FRAG_COORD);
- vertex_postfix->varyings = T.gpu;
- tiler_postfix->varyings = T.gpu;
-
- vertex_postfix->varying_meta = trans.gpu;
- tiler_postfix->varying_meta = trans.gpu + vs_size;
+ *buffers = T.gpu;
+ *vs_attribs = trans.gpu;
+ *fs_attribs = trans.gpu + vs_size;
}
void
panfrost_emit_vertex_tiler_jobs(struct panfrost_batch *batch,
struct mali_vertex_tiler_prefix *vertex_prefix,
- struct mali_vertex_tiler_postfix *vertex_postfix,
+ struct mali_draw_packed *vertex_draw,
struct mali_vertex_tiler_prefix *tiler_prefix,
- struct mali_vertex_tiler_postfix *tiler_postfix,
+ struct mali_draw_packed *tiler_draw,
union midgard_primitive_size *primitive_size)
{
struct panfrost_context *ctx = batch->ctx;
if (device->quirks & IS_BIFROST) {
bifrost_vertex.prefix = *vertex_prefix;
- bifrost_vertex.postfix = *vertex_postfix;
+ memcpy(&bifrost_vertex.postfix, vertex_draw, MALI_DRAW_LENGTH);
vp = &bifrost_vertex;
vp_size = sizeof(bifrost_vertex);
bifrost_tiler.prefix = *tiler_prefix;
bifrost_tiler.tiler.primitive_size = *primitive_size;
bifrost_tiler.tiler.tiler_meta = panfrost_batch_get_tiler_meta(batch, ~0);
- bifrost_tiler.postfix = *tiler_postfix;
+ memcpy(&bifrost_tiler.postfix, tiler_draw, MALI_DRAW_LENGTH);
tp = &bifrost_tiler;
tp_size = sizeof(bifrost_tiler);
} else {
midgard_vertex.prefix = *vertex_prefix;
- midgard_vertex.postfix = *vertex_postfix;
+ memcpy(&midgard_vertex.postfix, vertex_draw, MALI_DRAW_LENGTH);
vp = &midgard_vertex;
vp_size = sizeof(midgard_vertex);
midgard_tiler.prefix = *tiler_prefix;
- midgard_tiler.postfix = *tiler_postfix;
+ memcpy(&midgard_tiler.postfix, tiler_draw, MALI_DRAW_LENGTH);
midgard_tiler.primitive_size = *primitive_size;
tp = &midgard_tiler;
tp_size = sizeof(midgard_tiler);