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;
}
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 */
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])
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);
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,
/**
* 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,
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.
*