|
|
@@ -73,6 +73,76 @@ static void si_compute_internal_end(struct si_context *sctx) |
|
|
|
sctx->render_cond_force_off = false; |
|
|
|
} |
|
|
|
|
|
|
|
static void si_compute_clear_12bytes_buffer(struct si_context *sctx, |
|
|
|
struct pipe_resource *dst, |
|
|
|
unsigned dst_offset, |
|
|
|
unsigned size, |
|
|
|
const uint32_t *clear_value, |
|
|
|
enum si_coherency coher) |
|
|
|
{ |
|
|
|
struct pipe_context *ctx = &sctx->b; |
|
|
|
|
|
|
|
assert(dst_offset % 4 == 0); |
|
|
|
assert(size % 4 == 0); |
|
|
|
unsigned size_12 = DIV_ROUND_UP(size, 12); |
|
|
|
|
|
|
|
unsigned data[4] = {0}; |
|
|
|
memcpy(data, clear_value, 12); |
|
|
|
|
|
|
|
si_compute_internal_begin(sctx); |
|
|
|
|
|
|
|
sctx->flags |= SI_CONTEXT_PS_PARTIAL_FLUSH | |
|
|
|
SI_CONTEXT_CS_PARTIAL_FLUSH | |
|
|
|
si_get_flush_flags(sctx, coher, SI_COMPUTE_DST_CACHE_POLICY); |
|
|
|
|
|
|
|
struct pipe_shader_buffer saved_sb = {0}; |
|
|
|
si_get_shader_buffers(sctx, PIPE_SHADER_COMPUTE, 0, 1, &saved_sb); |
|
|
|
|
|
|
|
unsigned saved_writable_mask = 0; |
|
|
|
if (sctx->const_and_shader_buffers[PIPE_SHADER_COMPUTE].writable_mask & |
|
|
|
(1u << si_get_shaderbuf_slot(0))) |
|
|
|
saved_writable_mask = 1; |
|
|
|
|
|
|
|
struct pipe_constant_buffer saved_cb = {}; |
|
|
|
si_get_pipe_constant_buffer(sctx, PIPE_SHADER_COMPUTE, 0, &saved_cb); |
|
|
|
|
|
|
|
void *saved_cs = sctx->cs_shader_state.program; |
|
|
|
|
|
|
|
struct pipe_constant_buffer cb = {}; |
|
|
|
cb.buffer_size = sizeof(data); |
|
|
|
cb.user_buffer = data; |
|
|
|
ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, &cb); |
|
|
|
|
|
|
|
struct pipe_shader_buffer sb = {0}; |
|
|
|
sb.buffer = dst; |
|
|
|
sb.buffer_offset = dst_offset; |
|
|
|
sb.buffer_size = size; |
|
|
|
|
|
|
|
ctx->set_shader_buffers(ctx, PIPE_SHADER_COMPUTE, 0, 1, &sb, 0x1); |
|
|
|
|
|
|
|
struct pipe_grid_info info = {0}; |
|
|
|
|
|
|
|
if (!sctx->cs_clear_12bytes_buffer) |
|
|
|
sctx->cs_clear_12bytes_buffer = |
|
|
|
si_clear_12bytes_buffer_shader(ctx); |
|
|
|
ctx->bind_compute_state(ctx, sctx->cs_clear_12bytes_buffer); |
|
|
|
info.block[0] = 64; |
|
|
|
info.last_block[0] = size_12 % 64; |
|
|
|
info.block[1] = 1; |
|
|
|
info.block[2] = 1; |
|
|
|
info.grid[0] = DIV_ROUND_UP(size_12, 64); |
|
|
|
info.grid[1] = 1; |
|
|
|
info.grid[2] = 1; |
|
|
|
|
|
|
|
ctx->launch_grid(ctx, &info); |
|
|
|
|
|
|
|
ctx->bind_compute_state(ctx, saved_cs); |
|
|
|
ctx->set_shader_buffers(ctx, PIPE_SHADER_COMPUTE, 0, 1, &saved_sb, saved_writable_mask); |
|
|
|
ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, &saved_cb); |
|
|
|
|
|
|
|
si_compute_internal_end(sctx); |
|
|
|
} |
|
|
|
|
|
|
|
static void si_compute_do_clear_or_copy(struct si_context *sctx, |
|
|
|
struct pipe_resource *dst, |
|
|
|
unsigned dst_offset, |
|
|
@@ -231,17 +301,8 @@ void si_clear_buffer(struct si_context *sctx, struct pipe_resource *dst, |
|
|
|
clear_value_size = 4; |
|
|
|
} |
|
|
|
|
|
|
|
/* Use transform feedback for 12-byte clears. */ |
|
|
|
/* TODO: Use compute. */ |
|
|
|
if (clear_value_size == 12) { |
|
|
|
union pipe_color_union streamout_clear_value; |
|
|
|
|
|
|
|
memcpy(&streamout_clear_value, clear_value, clear_value_size); |
|
|
|
si_blitter_begin(sctx, SI_DISABLE_RENDER_COND); |
|
|
|
util_blitter_clear_buffer(sctx->blitter, dst, offset, |
|
|
|
size, clear_value_size / 4, |
|
|
|
&streamout_clear_value); |
|
|
|
si_blitter_end(sctx); |
|
|
|
si_compute_clear_12bytes_buffer(sctx, dst, offset, size, clear_value, coher); |
|
|
|
return; |
|
|
|
} |
|
|
|
|