r600: ingest u_blitter_clear_buffer

r600 is the only driver using this functionality, so let's move it there.

There's a few functions we used that aren't available outside of
u_blitter.c, but it turns out these aren't really needed. The first one
is blitter_check_saved_vertex_states(), that one just verifies that
certain states are saved as they should be. It's a bit sad to lose these
checks, but they are currently always passing, so nothing should break
by dropping them right now.

The second one is blitter_disable_render_cond(), and this one is also OK
to drop, because r600 never calls util_blitter_save_render_condition()
in the first place.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34954>
This commit is contained in:
Erik Faye-Lund
2024-01-26 17:22:17 +01:00
committed by Marge Bot
parent 20986b77f3
commit 8e48db3028
4 changed files with 126 additions and 122 deletions
+2 -121
View File
@@ -69,8 +69,6 @@ struct blitter_context_priv
/* Vertex shaders. */
void *vs; /**< Vertex shader which passes {pos, generic} to the output.*/
void *vs_nogeneric;
void *vs_pos_only[4]; /**< Vertex shader which passes pos to the output
for clear_buffer.*/
void *vs_layered; /**< Vertex shader which sets LAYER = INSTANCEID. */
/* Fragment shaders. */
@@ -122,7 +120,6 @@ struct blitter_context_priv
/* Vertex elements states. */
void *velem_state;
void *velem_state_readbuf[4]; /**< X, XY, XYZ, XYZW */
/* Sampler state. */
void *sampler_state;
@@ -315,23 +312,6 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
}
ctx->velem_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
if (ctx->has_stream_out) {
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 = 0;
velem[0].src_stride = 0;
ctx->velem_state_readbuf[i] =
pipe->create_vertex_elements_state(pipe, 1, &velem[0]);
}
}
ctx->has_layered =
pipe->screen->caps.vs_instanceid &&
pipe->screen->caps.vs_layer_viewport;
@@ -366,32 +346,6 @@ void *util_blitter_get_discard_rasterizer_state(struct blitter_context *blitter)
return ctx->rs_discard_state;
}
static void bind_vs_pos_only(struct blitter_context_priv *ctx,
unsigned num_so_channels)
{
struct pipe_context *pipe = ctx->base.pipe;
int index = num_so_channels ? num_so_channels - 1 : 0;
if (!ctx->vs_pos_only[index]) {
struct pipe_stream_output_info so;
static const enum tgsi_semantic semantic_names[] =
{ TGSI_SEMANTIC_POSITION };
const unsigned semantic_indices[] = { 0 };
memset(&so, 0, sizeof(so));
so.num_outputs = 1;
so.output[0].num_components = num_so_channels;
so.stride[0] = num_so_channels;
ctx->vs_pos_only[index] =
util_make_vertex_passthrough_shader_with_so(pipe, 1, semantic_names,
semantic_indices, false,
false, &so);
}
pipe->bind_vs_state(pipe, ctx->vs_pos_only[index]);
}
static void *get_vs_passthrough_pos_generic(struct blitter_context *blitter)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
@@ -501,17 +455,11 @@ void util_blitter_destroy(struct blitter_context *blitter)
pipe->delete_vs_state(pipe, ctx->vs);
if (ctx->vs_nogeneric)
pipe->delete_vs_state(pipe, ctx->vs_nogeneric);
for (i = 0; i < 4; i++)
if (ctx->vs_pos_only[i])
pipe->delete_vs_state(pipe, ctx->vs_pos_only[i]);
if (ctx->vs_layered)
pipe->delete_vs_state(pipe, ctx->vs_layered);
pipe->delete_vertex_elements_state(pipe, ctx->velem_state);
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++) {
for (unsigned type = 0; type < ARRAY_SIZE(ctx->fs_texfetch_col); ++type) {
@@ -2607,73 +2555,6 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
util_blitter_unset_running_flag(blitter);
}
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 = NULL;
unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
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(pipe->stream_uploader, 0, num_channels*4, 4, clear_value,
&vb.buffer_offset, &vb.buffer.resource);
if (!vb.buffer.resource)
goto out;
util_blitter_set_running_flag(blitter);
blitter_check_saved_vertex_states(ctx);
blitter_disable_render_cond(ctx);
pipe->bind_vertex_elements_state(pipe,
ctx->velem_state_readbuf[num_channels-1]);
pipe->set_vertex_buffers(pipe, 1, &vb);
bind_vs_pos_only(ctx, num_channels);
if (ctx->has_geometry_shader)
pipe->bind_gs_state(pipe, NULL);
if (ctx->has_tessellation) {
pipe->bind_tcs_state(pipe, NULL);
pipe->bind_tes_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, offsets, MESA_PRIM_POINTS);
util_draw_arrays(pipe, MESA_PRIM_POINTS, 0, size / 4);
out:
util_blitter_restore_vertex_states(blitter);
util_blitter_restore_render_cond(blitter);
util_blitter_unset_running_flag(blitter);
pipe_so_target_reference(&so_target, NULL);
}
/* probably radeon specific */
void util_blitter_custom_resolve_color(struct blitter_context *blitter,
struct pipe_resource *dst,
+92 -1
View File
@@ -6,7 +6,10 @@
#include "r600_pipe.h"
#include "compute_memory_pool.h"
#include "evergreen_compute.h"
#include "util/u_draw.h"
#include "util/u_simple_shaders.h"
#include "util/u_surface.h"
#include "util/u_upload_mgr.h"
#include "util/format/u_format.h"
#include "evergreend.h"
@@ -628,6 +631,94 @@ static void r600_copy_global_buffer(struct pipe_context *ctx,
r600_copy_buffer(ctx, dst, dstx, src, &new_src_box);
}
static void bind_vs_pos_only(struct r600_context *ctx,
unsigned num_so_channels)
{
struct pipe_context *pipe = &ctx->b.b;
int index = num_so_channels ? num_so_channels - 1 : 0;
if (!ctx->vs_pos_only[index]) {
struct pipe_stream_output_info so;
static const enum tgsi_semantic semantic_names[] =
{ TGSI_SEMANTIC_POSITION };
const unsigned semantic_indices[] = { 0 };
memset(&so, 0, sizeof(so));
so.num_outputs = 1;
so.output[0].num_components = num_so_channels;
so.stride[0] = num_so_channels;
ctx->vs_pos_only[index] =
util_make_vertex_passthrough_shader_with_so(pipe, 1, semantic_names,
semantic_indices, false,
false, &so);
}
pipe->bind_vs_state(pipe, ctx->vs_pos_only[index]);
}
static void r600_blitter_clear_buffer(struct r600_context *rctx,
struct pipe_resource *dst,
unsigned offset, unsigned size,
unsigned num_channels,
const union pipe_color_union *clear_value)
{
struct pipe_context *pipe = &rctx->b.b;
struct r600_screen *rscreen = (struct r600_screen *)pipe->screen;
struct pipe_vertex_buffer vb = {0};
struct pipe_stream_output_target *so_target = NULL;
unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
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.
*/
/* Some alignment is required. */
if (offset % 4 != 0 || size % 4 != 0) {
assert(!"Bad alignment in r600_blitter_clear_buffer()");
return;
}
u_upload_data(pipe->stream_uploader, 0, num_channels*4, 4, clear_value,
&vb.buffer_offset, &vb.buffer.resource);
if (!vb.buffer.resource)
goto out;
util_blitter_set_running_flag(rctx->blitter);
#if 0
blitter_check_saved_vertex_states(rctx->blitter); // never asserts on r600
blitter_disable_render_cond(rctx->blitter); // r600 never saves render cond
#endif
pipe->set_vertex_buffers(pipe, 1, &vb);
pipe->bind_vertex_elements_state(pipe, rctx->velem_state_readbuf[num_channels-1]);
bind_vs_pos_only(rctx, num_channels);
pipe->bind_gs_state(pipe, NULL);
if (rscreen->b.family >= CHIP_CEDAR) {
pipe->bind_tcs_state(pipe, NULL);
pipe->bind_tes_state(pipe, NULL);
}
pipe->bind_rasterizer_state(pipe, util_blitter_get_discard_rasterizer_state(rctx->blitter));
so_target = pipe->create_stream_output_target(pipe, dst, offset, size);
pipe->set_stream_output_targets(pipe, 1, &so_target, offsets, MESA_PRIM_POINTS);
util_draw_arrays(pipe, MESA_PRIM_POINTS, 0, size / 4);
out:
util_blitter_restore_vertex_states(rctx->blitter);
util_blitter_restore_render_cond(rctx->blitter);
util_blitter_unset_running_flag(rctx->blitter);
pipe_so_target_reference(&so_target, NULL);
pipe_resource_reference(&vb.buffer.resource, NULL);
}
static void r600_clear_buffer(struct pipe_context *ctx, struct pipe_resource *dst,
uint64_t offset, uint64_t size, unsigned value,
enum r600_coherency coher)
@@ -643,7 +734,7 @@ static void r600_clear_buffer(struct pipe_context *ctx, struct pipe_resource *ds
clear_value.ui[0] = value;
r600_blitter_begin(ctx, R600_DISABLE_RENDER_COND);
util_blitter_clear_buffer(rctx->blitter, dst, offset, size,
r600_blitter_clear_buffer(rctx, dst, offset, size,
1, &clear_value);
r600_blitter_end(ctx);
} else {
+28
View File
@@ -88,6 +88,16 @@ static void r600_destroy_context(struct pipe_context *context)
if (rctx->blitter) {
util_blitter_destroy(rctx->blitter);
for (i = 0; i < 4; i++)
if (rctx->vs_pos_only[i])
rctx->b.b.delete_vs_state(&rctx->b.b, rctx->vs_pos_only[i]);
for (i = 0; i < 4; i++) {
if (rctx->velem_state_readbuf[i]) {
rctx->b.b.delete_vertex_elements_state(&rctx->b.b, rctx->velem_state_readbuf[i]);
}
}
}
u_suballocator_destroy(&rctx->allocator_fetch_shader);
@@ -207,6 +217,24 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen,
rctx->blitter = util_blitter_create(&rctx->b.b);
if (rctx->blitter == NULL)
goto fail;
static enum pipe_format formats[4] = {
PIPE_FORMAT_R32_UINT,
PIPE_FORMAT_R32G32_UINT,
PIPE_FORMAT_R32G32B32_UINT,
PIPE_FORMAT_R32G32B32A32_UINT
};
struct pipe_vertex_element velem;
memset(&velem, 0, sizeof(velem));
for (int i = 0; i < 4; i++) {
velem.src_format = formats[i];
velem.vertex_buffer_index = 0;
velem.src_stride = 0;
rctx->velem_state_readbuf[i] =
rctx->b.b.create_vertex_elements_state(&rctx->b.b, 1, &velem);
}
util_blitter_set_texture_multisample(rctx->blitter, rscreen->has_msaa);
rctx->blitter->draw_rectangle = r600_draw_rectangle;
+4
View File
@@ -485,6 +485,10 @@ struct r600_context {
struct blitter_context *blitter;
struct u_suballocator allocator_fetch_shader;
/* blitter state */
void *vs_pos_only[4];
void *velem_state_readbuf[4]; /**< X, XY, XYZ, XYZW */
/* Hardware info. */
bool has_vertex_cache;
unsigned default_gprs[EG_NUM_HW_STAGES];