mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 19:58:09 +02:00
gallium/u_blitter: implement buffer clearing
Although this might be useful for ARB_clear_buffer_object,
I need it for initializating resources in r600g.
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
v2: comment cleanups
NOTE: This is a candidate for the 9.1 branch.
(cherry picked from commit 1ba46bbb4c)
This commit is contained in:
parent
2f4134f7b5
commit
a040faa894
2 changed files with 97 additions and 8 deletions
|
|
@ -100,7 +100,7 @@ struct blitter_context_priv
|
|||
void *velem_state;
|
||||
void *velem_uint_state;
|
||||
void *velem_sint_state;
|
||||
void *velem_state_readbuf;
|
||||
void *velem_state_readbuf[4]; /**< X, XY, XYZ, XYZW */
|
||||
|
||||
/* Sampler state. */
|
||||
void *sampler_state, *sampler_state_linear;
|
||||
|
|
@ -277,9 +277,19 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
|
|||
}
|
||||
|
||||
if (ctx->has_stream_out) {
|
||||
velem[0].src_format = PIPE_FORMAT_R32_UINT;
|
||||
velem[0].vertex_buffer_index = ctx->base.vb_slot;
|
||||
ctx->velem_state_readbuf = pipe->create_vertex_elements_state(pipe, 1, &velem[0]);
|
||||
static enum pipe_format formats[4] = {
|
||||
PIPE_FORMAT_R32_UINT,
|
||||
PIPE_FORMAT_R32G32_UINT,
|
||||
PIPE_FORMAT_R32G32B32_UINT,
|
||||
PIPE_FORMAT_R32G32B32A32_UINT
|
||||
};
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
velem[0].src_format = formats[i];
|
||||
velem[0].vertex_buffer_index = ctx->base.vb_slot;
|
||||
ctx->velem_state_readbuf[i] =
|
||||
pipe->create_vertex_elements_state(pipe, 1, &velem[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/* fragment shaders are created on-demand */
|
||||
|
|
@ -344,8 +354,11 @@ void util_blitter_destroy(struct blitter_context *blitter)
|
|||
pipe->delete_vertex_elements_state(pipe, ctx->velem_sint_state);
|
||||
pipe->delete_vertex_elements_state(pipe, ctx->velem_uint_state);
|
||||
}
|
||||
if (ctx->velem_state_readbuf)
|
||||
pipe->delete_vertex_elements_state(pipe, ctx->velem_state_readbuf);
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (ctx->velem_state_readbuf[i]) {
|
||||
pipe->delete_vertex_elements_state(pipe, ctx->velem_state_readbuf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
|
||||
if (ctx->fs_texfetch_col[i])
|
||||
|
|
@ -1716,7 +1729,7 @@ void util_blitter_copy_buffer(struct blitter_context *blitter,
|
|||
vb.stride = 4;
|
||||
|
||||
pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb);
|
||||
pipe->bind_vertex_elements_state(pipe, ctx->velem_state_readbuf);
|
||||
pipe->bind_vertex_elements_state(pipe, ctx->velem_state_readbuf[0]);
|
||||
pipe->bind_vs_state(pipe, ctx->vs_pos_only);
|
||||
if (ctx->has_geometry_shader)
|
||||
pipe->bind_gs_state(pipe, NULL);
|
||||
|
|
@ -1733,6 +1746,66 @@ void util_blitter_copy_buffer(struct blitter_context *blitter,
|
|||
pipe_so_target_reference(&so_target, NULL);
|
||||
}
|
||||
|
||||
void util_blitter_clear_buffer(struct blitter_context *blitter,
|
||||
struct pipe_resource *dst,
|
||||
unsigned offset, unsigned size,
|
||||
unsigned num_channels,
|
||||
const union pipe_color_union *clear_value)
|
||||
{
|
||||
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
|
||||
struct pipe_context *pipe = ctx->base.pipe;
|
||||
struct pipe_vertex_buffer vb = {0};
|
||||
struct pipe_stream_output_target *so_target;
|
||||
|
||||
assert(num_channels >= 1);
|
||||
assert(num_channels <= 4);
|
||||
|
||||
/* IMPORTANT: DON'T DO ANY BOUNDS CHECKING HERE!
|
||||
*
|
||||
* R600 uses this to initialize texture resources, so width0 might not be
|
||||
* what you think it is.
|
||||
*/
|
||||
|
||||
/* Streamout is required. */
|
||||
if (!ctx->has_stream_out) {
|
||||
assert(!"Streamout unsupported in util_blitter_clear_buffer()");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Some alignment is required. */
|
||||
if (offset % 4 != 0 || size % 4 != 0) {
|
||||
assert(!"Bad alignment in util_blitter_clear_buffer()");
|
||||
return;
|
||||
}
|
||||
|
||||
u_upload_data(ctx->upload, 0, num_channels*4, clear_value,
|
||||
&vb.buffer_offset, &vb.buffer);
|
||||
vb.stride = 0;
|
||||
|
||||
blitter_set_running_flag(ctx);
|
||||
blitter_check_saved_vertex_states(ctx);
|
||||
blitter_disable_render_cond(ctx);
|
||||
|
||||
pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb);
|
||||
pipe->bind_vertex_elements_state(pipe,
|
||||
ctx->velem_state_readbuf[num_channels-1]);
|
||||
pipe->bind_vs_state(pipe, ctx->vs_pos_only);
|
||||
if (ctx->has_geometry_shader)
|
||||
pipe->bind_gs_state(pipe, NULL);
|
||||
pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
|
||||
|
||||
so_target = pipe->create_stream_output_target(pipe, dst, offset, size);
|
||||
pipe->set_stream_output_targets(pipe, 1, &so_target, 0);
|
||||
|
||||
util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4);
|
||||
|
||||
blitter_restore_vertex_states(ctx);
|
||||
blitter_restore_render_cond(ctx);
|
||||
blitter_unset_running_flag(ctx);
|
||||
pipe_so_target_reference(&so_target, NULL);
|
||||
pipe_resource_reference(&vb.buffer, NULL);
|
||||
}
|
||||
|
||||
/* probably radeon specific */
|
||||
void util_blitter_custom_resolve_color(struct blitter_context *blitter,
|
||||
struct pipe_resource *dst,
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ void util_blitter_default_src_texture(struct pipe_sampler_view *src_templ,
|
|||
|
||||
/**
|
||||
* Copy data from one buffer to another using the Stream Output functionality.
|
||||
* Some alignment is required, otherwise software fallback is used.
|
||||
* 4-byte alignment is required, otherwise software fallback is used.
|
||||
*/
|
||||
void util_blitter_copy_buffer(struct blitter_context *blitter,
|
||||
struct pipe_resource *dst,
|
||||
|
|
@ -285,6 +285,22 @@ void util_blitter_copy_buffer(struct blitter_context *blitter,
|
|||
unsigned srcx,
|
||||
unsigned size);
|
||||
|
||||
/**
|
||||
* Clear the contents of a buffer using the Stream Output functionality.
|
||||
* 4-byte alignment is required.
|
||||
*
|
||||
* "num_channels" can be 1, 2, 3, or 4, and specifies if the clear value is
|
||||
* R, RG, RGB, or RGBA.
|
||||
*
|
||||
* For each element, only "num_channels" components of "clear_value" are
|
||||
* copied to the buffer, then the offset is incremented by num_channels*4.
|
||||
*/
|
||||
void util_blitter_clear_buffer(struct blitter_context *blitter,
|
||||
struct pipe_resource *dst,
|
||||
unsigned offset, unsigned size,
|
||||
unsigned num_channels,
|
||||
const union pipe_color_union *clear_value);
|
||||
|
||||
/**
|
||||
* Clear a region of a (color) surface to a constant value.
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue