diff --git a/.gitlab-ci/piglit/freedreno-a630-gl.txt b/.gitlab-ci/piglit/freedreno-a630-gl.txt index ec097eeea1f..81007b182a4 100644 --- a/.gitlab-ci/piglit/freedreno-a630-gl.txt +++ b/.gitlab-ci/piglit/freedreno-a630-gl.txt @@ -3097,8 +3097,6 @@ spec/arb_texture_view/rendering-formats/sample gl_rgba16_snorm as gl_rgba16ui: f 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 @@ -3968,32 +3966,12 @@ spec/ext_texture_srgb/texwrap formats-s3tc bordercolor-swizzled/gl_compressed_sr 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 diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c index e9ea494bd1a..1b773295bae 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c @@ -732,30 +732,38 @@ fd6_emit_streamout(struct fd_ringbuffer *ring, struct fd6_emit *emit, struct ir3 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); diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index 7aed573d10a..214b358f8ab 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -87,6 +87,11 @@ struct fd_vertex_stateobj { 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. */ @@ -485,6 +490,12 @@ fd_context(struct pipe_context *pctx) 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) diff --git a/src/gallium/drivers/freedreno/freedreno_state.c b/src/gallium/drivers/freedreno/freedreno_state.c index 06c86ad97f0..eb5aada190d 100644 --- a/src/gallium/drivers/freedreno/freedreno_state.c +++ b/src/gallium/drivers/freedreno/freedreno_state.c @@ -481,32 +481,39 @@ fd_create_stream_output_target(struct pipe_context *pctx, 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); }