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:
committed by
Marge Bot
parent
20986b77f3
commit
8e48db3028
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
Reference in New Issue
Block a user