cfg.seamless_cube_map = cso->seamless_cube_map;
cfg.border_color_r = cso->border_color.f[0];
- cfg.border_color_g = cso->border_color.f[0];
- cfg.border_color_b = cso->border_color.f[0];
- cfg.border_color_a = cso->border_color.f[0];
+ cfg.border_color_g = cso->border_color.f[1];
+ cfg.border_color_b = cso->border_color.f[2];
+ cfg.border_color_a = cso->border_color.f[3];
}
}
return;
if (device->quirks & IS_BIFROST) {
- struct bifrost_texture_descriptor *descriptors;
+ struct panfrost_transfer T = panfrost_pool_alloc(&batch->pool,
+ MALI_BIFROST_TEXTURE_LENGTH *
+ ctx->sampler_view_count[stage]);
- descriptors = malloc(sizeof(struct bifrost_texture_descriptor) *
- ctx->sampler_view_count[stage]);
+ struct mali_bifrost_texture_packed *out =
+ (struct mali_bifrost_texture_packed *) T.cpu;
for (int i = 0; i < ctx->sampler_view_count[stage]; ++i) {
struct panfrost_sampler_view *view = ctx->sampler_views[stage][i];
struct pipe_sampler_view *pview = &view->base;
struct panfrost_resource *rsrc = pan_resource(pview->texture);
+
panfrost_update_sampler_view(view, &ctx->base);
+ out[i] = view->bifrost_descriptor;
/* Add the BOs to the job so they are retained until the job is done. */
panfrost_batch_add_bo(batch, view->bo,
PAN_BO_ACCESS_SHARED | PAN_BO_ACCESS_READ |
panfrost_bo_access_for_stage(stage));
-
- memcpy(&descriptors[i], view->bifrost_descriptor, sizeof(*view->bifrost_descriptor));
}
- postfix->textures = panfrost_pool_upload(&batch->pool,
- descriptors,
- sizeof(struct bifrost_texture_descriptor) *
- ctx->sampler_view_count[stage]);
-
- free(descriptors);
+ postfix->textures = T.gpu;
} else {
uint64_t trampolines[PIPE_MAX_SHADER_SAMPLER_VIEWS];
postfix->sampler_descriptor = T.gpu;
}
-void
-panfrost_emit_vertex_attr_meta(struct panfrost_batch *batch,
- struct mali_vertex_tiler_postfix *vertex_postfix)
-{
- struct panfrost_context *ctx = batch->ctx;
-
- if (!ctx->vertex)
- return;
-
- struct panfrost_vertex_state *so = ctx->vertex;
-
- panfrost_vertex_state_upd_attr_offs(ctx, vertex_postfix);
- vertex_postfix->attribute_meta = panfrost_pool_upload(&batch->pool, so->hw,
- sizeof(*so->hw) *
- PAN_MAX_ATTRIBUTE);
-}
-
void
panfrost_emit_vertex_data(struct panfrost_batch *batch,
struct mali_vertex_tiler_postfix *vertex_postfix)
struct panfrost_context *ctx = batch->ctx;
struct panfrost_vertex_state *so = ctx->vertex;
+ unsigned instance_shift = vertex_postfix->instance_shift;
+ unsigned instance_odd = vertex_postfix->instance_odd;
+
/* Staged mali_attr, and index into them. i =/= k, depending on the
* vertex buffer mask and instancing. Twice as much room is allocated,
* for a worst case of NPOT_DIVIDEs which take up extra slot */
union mali_attr attrs[PIPE_MAX_ATTRIBS * 2];
+ unsigned attrib_to_buffer[PIPE_MAX_ATTRIBS] = { 0 };
unsigned k = 0;
for (unsigned i = 0; i < so->num_elements; ++i) {
struct pipe_vertex_element *elem = &so->pipe[i];
unsigned vbi = elem->vertex_buffer_index;
-
- /* The exception to 1:1 mapping is that we can have multiple
- * entries (NPOT divisors), so we fixup anyways */
-
- so->hw[i].index = k;
+ attrib_to_buffer[i] = k;
if (!(ctx->vb_mask & (1 << vbi)))
continue;
/* Normal, non-instanced attributes */
attrs[k++].elements |= MALI_ATTR_LINEAR;
} else {
- unsigned instance_shift = vertex_postfix->instance_shift;
- unsigned instance_odd = vertex_postfix->instance_odd;
-
k += panfrost_vertex_instanced(ctx->padded_count,
instance_shift,
instance_odd,
/* Add special gl_VertexID/gl_InstanceID buffers */
+ struct panfrost_transfer T = panfrost_pool_alloc(&batch->pool,
+ MALI_ATTRIBUTE_LENGTH * (PAN_INSTANCE_ID + 1));
+
+ struct mali_attribute_packed *out =
+ (struct mali_attribute_packed *) T.cpu;
+
panfrost_vertex_id(ctx->padded_count, &attrs[k]);
- so->hw[PAN_VERTEX_ID].index = k++;
+
+ pan_pack(out + PAN_VERTEX_ID, ATTRIBUTE, cfg) {
+ cfg.buffer_index = k++;
+ cfg.format = so->formats[PAN_VERTEX_ID];
+ }
+
panfrost_instance_id(ctx->padded_count, &attrs[k]);
- so->hw[PAN_INSTANCE_ID].index = k++;
- /* Upload whatever we emitted and go */
+ pan_pack(out + PAN_INSTANCE_ID, ATTRIBUTE, cfg) {
+ cfg.buffer_index = k++;
+ cfg.format = so->formats[PAN_INSTANCE_ID];
+ }
+
+ /* Attribute addresses require 64-byte alignment, so let:
+ *
+ * base' = base & ~63 = base - (base & 63)
+ * offset' = offset + (base & 63)
+ *
+ * Since base' + offset' = base + offset, these are equivalent
+ * 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];
+
+ /* Adjust by the masked off bits of the offset. Make sure we
+ * read src_offset from so->hw (which is not GPU visible)
+ * rather than target (which is) due to caching effects */
+
+ unsigned src_offset = so->pipe[i].src_offset;
+
+ /* BOs aligned to 4k so guaranteed aligned to 64 */
+ src_offset += (buf->buffer_offset & 63);
+
+ /* 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;
+
+ pan_pack(out + i, ATTRIBUTE, cfg) {
+ cfg.buffer_index = attrib_to_buffer[i];
+ cfg.format = so->formats[i];
+ cfg.offset = src_offset;
+ }
+ }
+
vertex_postfix->attributes = panfrost_pool_upload(&batch->pool, attrs,
k * sizeof(*attrs));
+
+ vertex_postfix->attribute_meta = T.gpu;
}
static mali_ptr
unsigned offset)
{
unsigned nr_channels = MALI_EXTRACT_CHANNELS(format);
+ unsigned swizzle = quirks & HAS_SWIZZLES ?
+ panfrost_get_default_swizzle(nr_channels) :
+ panfrost_bifrost_swizzle(nr_channels);
struct mali_attr_meta meta = {
.index = pan_varying_index(present, buf),
.unknown1 = quirks & IS_BIFROST ? 0x0 : 0x2,
- .swizzle = quirks & HAS_SWIZZLES ?
- panfrost_get_default_swizzle(nr_channels) :
- panfrost_bifrost_swizzle(nr_channels),
- .format = format,
+ .format = (format << 12) | swizzle,
.src_offset = offset
};
enum mali_format format,
struct pipe_stream_output o)
{
+ unsigned swizzle = quirks & HAS_SWIZZLES ?
+ panfrost_get_default_swizzle(o.num_components) :
+ panfrost_bifrost_swizzle(o.num_components);
+
/* Otherwise construct a record for it */
struct mali_attr_meta meta = {
/* XFB buffers come after everything else */
/* As usual unknown bit */
.unknown1 = quirks & IS_BIFROST ? 0x0 : 0x2,
- /* Override swizzle with number of channels */
- .swizzle = quirks & HAS_SWIZZLES ?
- panfrost_get_default_swizzle(o.num_components) :
- panfrost_bifrost_swizzle(o.num_components),
-
/* Override number of channels and precision to highp */
- .format = pan_xfb_format(format, o.num_components),
+ .format = (pan_xfb_format(format, o.num_components) << 12) | swizzle,
/* Apply given offsets together */
.src_offset = (o.dst_offset * 4) /* dwords */