diff options
author | Eric Anholt <[email protected]> | 2017-12-10 17:11:25 -0800 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2019-01-14 15:40:55 -0800 |
commit | 5932c2f0b9b56e6eeee87baa7b0b493227850f69 (patch) | |
tree | c93d65bea9cebf3f236fc72ad6960ef7dca1b416 /src/gallium/drivers | |
parent | 6c8edcb89c1264c43f5e98444551edb8df2f91f9 (diff) |
v3d: Add SSBO/atomic counters support.
So far I assume that all the buffers get written. If they weren't, you'd
probably be using UBOs instead.
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r-- | src/gallium/drivers/v3d/v3d_context.c | 11 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3d_context.h | 7 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3d_screen.c | 5 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3d_uniforms.c | 20 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3dx_draw.c | 11 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3dx_state.c | 49 |
6 files changed, 102 insertions, 1 deletions
diff --git a/src/gallium/drivers/v3d/v3d_context.c b/src/gallium/drivers/v3d/v3d_context.c index b9eaf7e67ec..104096d5248 100644 --- a/src/gallium/drivers/v3d/v3d_context.c +++ b/src/gallium/drivers/v3d/v3d_context.c @@ -66,6 +66,16 @@ v3d_pipe_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence, } static void +v3d_memory_barrier(struct pipe_context *pctx, unsigned int flags) +{ + struct v3d_context *v3d = v3d_context(pctx); + + /* We only need to flush jobs writing to SSBOs/images. */ + perf_debug("Flushing all jobs for glMemoryBarrier(), could do better"); + v3d_flush(pctx); +} + +static void v3d_set_debug_callback(struct pipe_context *pctx, const struct pipe_debug_callback *cb) { @@ -172,6 +182,7 @@ v3d_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) pctx->priv = priv; pctx->destroy = v3d_context_destroy; pctx->flush = v3d_pipe_flush; + pctx->memory_barrier = v3d_memory_barrier; pctx->set_debug_callback = v3d_set_debug_callback; pctx->invalidate_resource = v3d_invalidate_resource; pctx->get_sample_position = v3d_get_sample_position; diff --git a/src/gallium/drivers/v3d/v3d_context.h b/src/gallium/drivers/v3d/v3d_context.h index 25be07c2437..686ecfa8024 100644 --- a/src/gallium/drivers/v3d/v3d_context.h +++ b/src/gallium/drivers/v3d/v3d_context.h @@ -82,6 +82,7 @@ void v3d_job_add_bo(struct v3d_job *job, struct v3d_bo *bo); #define VC5_DIRTY_OQ (1 << 28) #define VC5_DIRTY_CENTROID_FLAGS (1 << 29) #define VC5_DIRTY_NOPERSPECTIVE_FLAGS (1 << 30) +#define VC5_DIRTY_SSBO (1 << 31) #define VC5_MAX_FS_INPUTS 64 @@ -203,6 +204,11 @@ struct v3d_streamout_stateobj { unsigned num_targets; }; +struct v3d_ssbo_stateobj { + struct pipe_shader_buffer sb[PIPE_MAX_SHADER_BUFFERS]; + uint32_t enabled_mask; +}; + /* Hash table key for v3d->jobs */ struct v3d_job_key { struct pipe_surface *cbufs[4]; @@ -433,6 +439,7 @@ struct v3d_context { struct pipe_poly_stipple stipple; struct pipe_clip_state clip; struct pipe_viewport_state viewport; + struct v3d_ssbo_stateobj ssbo[PIPE_SHADER_TYPES]; struct v3d_constbuf_stateobj constbuf[PIPE_SHADER_TYPES]; struct v3d_texture_stateobj tex[PIPE_SHADER_TYPES]; struct v3d_vertexbuf_stateobj vertexbuf; diff --git a/src/gallium/drivers/v3d/v3d_screen.c b/src/gallium/drivers/v3d/v3d_screen.c index 5d949514d09..dd5eda87e8f 100644 --- a/src/gallium/drivers/v3d/v3d_screen.c +++ b/src/gallium/drivers/v3d/v3d_screen.c @@ -299,8 +299,11 @@ v3d_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: case PIPE_SHADER_CAP_MAX_SHADER_IMAGES: - case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS: return VC5_MAX_TEXTURE_SAMPLERS; + + case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS: + return PIPE_MAX_SHADER_BUFFERS; + case PIPE_SHADER_CAP_PREFERRED_IR: return PIPE_SHADER_IR_NIR; case PIPE_SHADER_CAP_SUPPORTED_IRS: diff --git a/src/gallium/drivers/v3d/v3d_uniforms.c b/src/gallium/drivers/v3d/v3d_uniforms.c index bc680af0956..5d907726349 100644 --- a/src/gallium/drivers/v3d/v3d_uniforms.c +++ b/src/gallium/drivers/v3d/v3d_uniforms.c @@ -276,6 +276,21 @@ v3d_write_uniforms(struct v3d_context *v3d, struct v3d_compiled_shader *shader, } break; + case QUNIFORM_SSBO_OFFSET: { + struct pipe_shader_buffer *sb = + &v3d->ssbo[stage].sb[data]; + + cl_aligned_reloc(&job->indirect, &uniforms, + v3d_resource(sb->buffer)->bo, + sb->buffer_offset); + break; + } + + case QUNIFORM_GET_BUFFER_SIZE: + cl_aligned_u32(&uniforms, + v3d->ssbo[stage].sb[data].buffer_size); + break; + case QUNIFORM_TEXTURE_FIRST_LEVEL: cl_aligned_f(&uniforms, texstate->textures[data]->u.tex.first_level); @@ -362,6 +377,11 @@ v3d_set_shader_uniform_dirty_flags(struct v3d_compiled_shader *shader) dirty |= VC5_DIRTY_FRAGTEX | VC5_DIRTY_VERTTEX; break; + case QUNIFORM_SSBO_OFFSET: + case QUNIFORM_GET_BUFFER_SIZE: + dirty |= VC5_DIRTY_SSBO; + break; + case QUNIFORM_ALPHA_REF: dirty |= VC5_DIRTY_ZSA; break; diff --git a/src/gallium/drivers/v3d/v3dx_draw.c b/src/gallium/drivers/v3d/v3dx_draw.c index 46e629d0c64..7f111bbe75f 100644 --- a/src/gallium/drivers/v3d/v3dx_draw.c +++ b/src/gallium/drivers/v3d/v3dx_draw.c @@ -478,6 +478,17 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) job->submit.in_sync_bcl = v3d->out_sync; } + /* Mark SSBOs as being written. We don't actually know which ones are + * read vs written, so just assume the worst + */ + for (int s = 0; s < PIPE_SHADER_TYPES; s++) { + foreach_bit(i, v3d->ssbo[s].enabled_mask) { + v3d_job_add_write_resource(job, + v3d->ssbo[s].sb[i].buffer); + job->tmu_dirty_rcl = true; + } + } + /* Get space to emit our draw call into the BCL, using a branch to * jump to a new BO if necessary. */ diff --git a/src/gallium/drivers/v3d/v3dx_state.c b/src/gallium/drivers/v3d/v3dx_state.c index 95a2dc30c8b..7ea5dabbe1f 100644 --- a/src/gallium/drivers/v3d/v3dx_state.c +++ b/src/gallium/drivers/v3d/v3dx_state.c @@ -986,6 +986,53 @@ v3d_set_stream_output_targets(struct pipe_context *pctx, ctx->dirty |= VC5_DIRTY_STREAMOUT; } +static void +v3d_set_shader_buffers(struct pipe_context *pctx, + enum pipe_shader_type shader, + unsigned start, unsigned count, + const struct pipe_shader_buffer *buffers) +{ + struct v3d_context *v3d = v3d_context(pctx); + struct v3d_ssbo_stateobj *so = &v3d->ssbo[shader]; + unsigned mask = 0; + + if (buffers) { + for (unsigned i = 0; i < count; i++) { + unsigned n = i + start; + struct pipe_shader_buffer *buf = &so->sb[n]; + + if ((buf->buffer == buffers[i].buffer) && + (buf->buffer_offset == buffers[i].buffer_offset) && + (buf->buffer_size == buffers[i].buffer_size)) + continue; + + mask |= 1 << n; + + buf->buffer_offset = buffers[i].buffer_offset; + buf->buffer_size = buffers[i].buffer_size; + pipe_resource_reference(&buf->buffer, buffers[i].buffer); + + if (buf->buffer) + so->enabled_mask |= 1 << n; + else + so->enabled_mask &= ~(1 << n); + } + } else { + mask = ((1 << count) - 1) << start; + + for (unsigned i = 0; i < count; i++) { + unsigned n = i + start; + struct pipe_shader_buffer *buf = &so->sb[n]; + + pipe_resource_reference(&buf->buffer, NULL); + } + + so->enabled_mask &= ~mask; + } + + v3d->dirty |= VC5_DIRTY_SSBO; +} + void v3dX(state_init)(struct pipe_context *pctx) { @@ -1025,6 +1072,8 @@ v3dX(state_init)(struct pipe_context *pctx) pctx->sampler_view_destroy = v3d_sampler_view_destroy; pctx->set_sampler_views = v3d_set_sampler_views; + pctx->set_shader_buffers = v3d_set_shader_buffers; + pctx->create_stream_output_target = v3d_create_stream_output_target; pctx->stream_output_target_destroy = v3d_stream_output_target_destroy; pctx->set_stream_output_targets = v3d_set_stream_output_targets; |