spec/arb_texture_view/rendering-layers-image/layers rendering of image1darray: fail
spec/arb_texture_view/rendering-layers-image/layers rendering of imagecubearray: fail
spec/arb_timer_query/timestamp-get: fail
-spec/arb_transform_feedback2/change objects while paused: fail
-spec/arb_transform_feedback2/change objects while paused (gles3): fail
spec/arb_transform_feedback3/arb_transform_feedback3-draw_using_invalid_stream_index: skip
spec/arb_transform_feedback3/arb_transform_feedback3-ext_interleaved_two_bufs_gs: skip
spec/arb_transform_feedback3/arb_transform_feedback3-ext_interleaved_two_bufs_gs_max: skip
spec/ext_texture_srgb/texwrap formats-s3tc bordercolor-swizzled/gl_compressed_srgb_alpha_s3tc_dxt5_ext, swizzled, border color only: fail
spec/ext_texture_srgb/texwrap formats-s3tc bordercolor-swizzled/gl_compressed_srgb_s3tc_dxt1_ext, swizzled, border color only: fail
spec/ext_transform_feedback2/draw-auto: crash
-spec/ext_transform_feedback/alignment 12: fail
-spec/ext_transform_feedback/alignment 4: fail
-spec/ext_transform_feedback/alignment 8: fail
-spec/ext_transform_feedback/change-size offset-grow: fail
-spec/ext_transform_feedback/change-size offset-shrink: fail
-spec/ext_transform_feedback/change-size range-grow: fail
-spec/ext_transform_feedback/change-size range-shrink: fail
spec/ext_transform_feedback/geometry-shaders-basic: fail
spec/ext_transform_feedback/immediate-reuse-index-buffer: fail
-spec/ext_transform_feedback/immediate-reuse-uniform-buffer: fail
spec/ext_transform_feedback/intervening-read prims_generated: fail
spec/ext_transform_feedback/intervening-read prims_generated use_gs: fail
spec/ext_transform_feedback/overflow-edge-cases: fail
spec/ext_transform_feedback/overflow-edge-cases use_gs: fail
-spec/ext_transform_feedback/position-readback-bufferoffset: fail
-spec/ext_transform_feedback/position-readback-bufferoffset-discard: fail
-spec/ext_transform_feedback/position-readback-bufferrange: fail
-spec/ext_transform_feedback/position-readback-bufferrange-discard: fail
-spec/ext_transform_feedback/position-render-bufferoffset: fail
-spec/ext_transform_feedback/position-render-bufferoffset-discard: fail
-spec/ext_transform_feedback/position-render-bufferrange: fail
-spec/ext_transform_feedback/position-render-bufferrange-discard: fail
-spec/ext_transform_feedback/query-primitives_written-bufferoffset: fail
-spec/ext_transform_feedback/query-primitives_written-bufferoffset-discard: fail
-spec/ext_transform_feedback/query-primitives_written-bufferrange: fail
-spec/ext_transform_feedback/query-primitives_written-bufferrange-discard: fail
spec/ext_transform_feedback/structs struct-array-elem run: fail
spec/ext_transform_feedback/structs struct-array-elem run interface: fail
spec/ext_transform_feedback/tessellation triangle_fan flat_first: fail
emit->streamout_mask = 0;
for (unsigned i = 0; i < so->num_targets; i++) {
- struct pipe_stream_output_target *target = so->targets[i];
+ struct fd_stream_output_target *target = fd_stream_output_target(so->targets[i]);
if (!target)
continue;
OUT_PKT4(ring, REG_A6XX_VPC_SO_BUFFER_BASE_LO(i), 3);
/* VPC_SO[i].BUFFER_BASE_LO: */
- OUT_RELOC(ring, fd_resource(target->buffer)->bo, target->buffer_offset, 0, 0);
- OUT_RING(ring, target->buffer_size - target->buffer_offset);
+ OUT_RELOC(ring, fd_resource(target->base.buffer)->bo, 0, 0, 0);
+ OUT_RING(ring, target->base.buffer_size + target->base.buffer_offset);
+
+ struct fd_bo *offset_bo = fd_resource(target->offset_buf)->bo;
if (so->reset & (1 << i)) {
- unsigned offset = (so->offsets[i] * info->stride[i] * 4);
+ assert(so->offsets[i] == 0);
+
+ OUT_PKT7(ring, CP_MEM_WRITE, 3);
+ OUT_RELOC(ring, offset_bo, 0, 0, 0);
+ OUT_RING(ring, target->base.buffer_offset);
+
OUT_PKT4(ring, REG_A6XX_VPC_SO_BUFFER_OFFSET(i), 1);
- OUT_RING(ring, offset);
+ OUT_RING(ring, target->base.buffer_offset);
} else {
OUT_PKT7(ring, CP_MEM_TO_REG, 3);
OUT_RING(ring, CP_MEM_TO_REG_0_REG(REG_A6XX_VPC_SO_BUFFER_OFFSET(i)) |
CP_MEM_TO_REG_0_SHIFT_BY_2 | CP_MEM_TO_REG_0_UNK31 |
CP_MEM_TO_REG_0_CNT(0));
- OUT_RELOC(ring, control_ptr(fd6_context(ctx), flush_base[i].offset));
+ OUT_RELOC(ring, offset_bo, 0, 0, 0);
}
+ // After a draw HW would write the new offset to offset_bo
OUT_PKT4(ring, REG_A6XX_VPC_SO_FLUSH_BASE_LO(i), 2);
- OUT_RELOC(ring, control_ptr(fd6_context(ctx), flush_base[i]));
+ OUT_RELOC(ring, offset_bo, 0, 0, 0);
so->reset &= ~(1 << i);
unsigned num_elements;
};
+struct fd_stream_output_target {
+ struct pipe_stream_output_target base;
+ struct pipe_resource *offset_buf;
+};
+
struct fd_streamout_stateobj {
struct pipe_stream_output_target *targets[PIPE_MAX_SO_BUFFERS];
/* Bitmask of stream that should be reset. */
return (struct fd_context *)pctx;
}
+static inline struct fd_stream_output_target *
+fd_stream_output_target(struct pipe_stream_output_target *target)
+{
+ return (struct fd_stream_output_target *)target;
+}
+
/* mark all state dirty: */
static inline void
fd_context_all_dirty(struct fd_context *ctx)
struct pipe_resource *prsc, unsigned buffer_offset,
unsigned buffer_size)
{
- struct pipe_stream_output_target *target;
+ struct fd_stream_output_target *target;
struct fd_resource *rsc = fd_resource(prsc);
- target = CALLOC_STRUCT(pipe_stream_output_target);
+ target = CALLOC_STRUCT(fd_stream_output_target);
if (!target)
return NULL;
- pipe_reference_init(&target->reference, 1);
- pipe_resource_reference(&target->buffer, prsc);
+ pipe_reference_init(&target->base.reference, 1);
+ pipe_resource_reference(&target->base.buffer, prsc);
- target->context = pctx;
- target->buffer_offset = buffer_offset;
- target->buffer_size = buffer_size;
+ target->base.context = pctx;
+ target->base.buffer_offset = buffer_offset;
+ target->base.buffer_size = buffer_size;
+
+ target->offset_buf = pipe_buffer_create(pctx->screen,
+ PIPE_BIND_CUSTOM, PIPE_USAGE_IMMUTABLE, sizeof(uint32_t));
assert(rsc->base.target == PIPE_BUFFER);
util_range_add(&rsc->base, &rsc->valid_buffer_range,
buffer_offset, buffer_offset + buffer_size);
- return target;
+ return &target->base;
}
static void
fd_stream_output_target_destroy(struct pipe_context *pctx,
struct pipe_stream_output_target *target)
{
- pipe_resource_reference(&target->buffer, NULL);
+ struct fd_stream_output_target *cso = fd_stream_output_target(target);
+
+ pipe_resource_reference(&cso->base.buffer, NULL);
+ pipe_resource_reference(&cso->offset_buf, NULL);
+
FREE(target);
}