diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 540381e8ead..ceb5eb5b4ca 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -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, diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 3d3da99512c..31aaa769c22 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -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 { diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 0f3078d1fcc..d97cb28ba49 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -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; diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 08fd97f771f..104d5bafb7f 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -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];