From: Marek Olšák <marek.ol...@amd.com> --- src/gallium/auxiliary/util/u_blitter.c | 118 +++++++++++++++++++------- src/gallium/drivers/radeon/r600_pipe_common.c | 37 +++----- 2 files changed, 96 insertions(+), 59 deletions(-)
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 54d3009..6827da8 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -55,20 +55,21 @@ ((clear_buffers) / PIPE_CLEAR_COLOR0) #define NUM_RESOLVE_FRAG_SHADERS 5 /* MSAA 2x, 4x, 8x, 16x, 32x */ #define GET_MSAA_RESOLVE_FS_IDX(nr_samples) (util_logbase2(nr_samples)-1) struct blitter_context_priv { struct blitter_context base; float vertices[4][2][4]; /**< {pos, color} or {pos, texcoord} */ + float vertices_nopos[4][4]; /**< {color} or {texcoord} only */ /* Templates for various state objects. */ /* Constant state objects. */ /* Vertex shaders. */ void *vs; /**< Vertex shader which passes {pos, generic} to the output.*/ void *vs_pos_only[4]; /**< Vertex shader which passes pos to the output.*/ void *vs_layered; /**< Vertex shader which sets LAYER = INSTANCEID. */ /* Fragment shaders. */ @@ -124,20 +125,21 @@ struct blitter_context_priv void *rs_state, *rs_state_scissor, *rs_discard_state; boolean has_geometry_shader; boolean has_tessellation; boolean has_layered; boolean has_stream_out; boolean has_stencil_export; boolean has_texture_multisample; boolean has_tex_lz; boolean has_txf; + boolean has_vertex_id; boolean cube_as_2darray; boolean cached_all_shaders; /* The Draw module overrides these functions. * Always create the blitter before Draw. */ void (*bind_fs_state)(struct pipe_context *, void *); void (*delete_fs_state)(struct pipe_context *, void *); }; struct blitter_context *util_blitter_create(struct pipe_context *pipe) @@ -189,20 +191,21 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT); ctx->has_texture_multisample = pipe->screen->get_param(pipe->screen, PIPE_CAP_TEXTURE_MULTISAMPLE); ctx->has_tex_lz = pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_TEX_TXF_LZ); ctx->has_txf = pipe->screen->get_param(pipe->screen, PIPE_CAP_GLSL_FEATURE_LEVEL) > 130; + ctx->has_vertex_id = ctx->has_txf; ctx->cube_as_2darray = pipe->screen->get_param(pipe->screen, PIPE_CAP_SAMPLER_VIEW_TARGET); /* blend state objects */ memset(&blend, 0, sizeof(blend)); for (i = 0; i <= PIPE_MASK_RGBA; i++) { for (j = 0; j < 2; j++) { memset(&blend.rt[0], 0, sizeof(blend.rt[0])); blend.rt[0].colormask = i; @@ -277,27 +280,30 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) if (ctx->has_stream_out) { rs_state.scissor = 0; rs_state.rasterizer_discard = 1; ctx->rs_discard_state = pipe->create_rasterizer_state(pipe, &rs_state); } ctx->base.cb_slot = 0; /* 0 for now */ ctx->base.vb_slot = 0; /* 0 for now */ /* vertex elements states */ - memset(&velem[0], 0, sizeof(velem[0]) * 2); - for (i = 0; i < 2; i++) { + unsigned num_attribs = ctx->has_vertex_id ? 1 : 2; + + memset(&velem[0], 0, sizeof(velem[0]) * num_attribs); + for (i = 0; i < num_attribs; i++) { velem[i].src_offset = i * 4 * sizeof(float); velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; velem[i].vertex_buffer_index = ctx->base.vb_slot; } - ctx->velem_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]); + ctx->velem_state = pipe->create_vertex_elements_state(pipe, num_attribs, + &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++) { @@ -345,35 +351,38 @@ static void bind_vs_pos_only(struct blitter_context_priv *ctx, } static void bind_vs_passthrough(struct blitter_context_priv *ctx) { struct pipe_context *pipe = ctx->base.pipe; if (!ctx->vs) { const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_GENERIC }; const uint semantic_indices[] = { 0, 0 }; + unsigned offset = ctx->has_vertex_id ? 1 : 0; + ctx->vs = - util_make_vertex_passthrough_shader(pipe, 2, semantic_names, - semantic_indices, FALSE); + util_make_vertex_passthrough_shader(pipe, 2 - offset, + semantic_names + offset, + semantic_indices + offset, FALSE); } pipe->bind_vs_state(pipe, ctx->vs); } static void bind_vs_layered(struct blitter_context_priv *ctx) { struct pipe_context *pipe = ctx->base.pipe; if (!ctx->vs_layered) { ctx->vs_layered = - util_make_layered_clear_vertex_shader(pipe, true); + util_make_layered_clear_vertex_shader(pipe, !ctx->has_vertex_id); } pipe->bind_vs_state(pipe, ctx->vs_layered); } static void bind_fs_empty(struct blitter_context_priv *ctx) { struct pipe_context *pipe = ctx->base.pipe; if (!ctx->fs_empty) { @@ -702,54 +711,66 @@ void util_blitter_restore_constant_buffer_state(struct blitter_context *blitter) } static void blitter_set_rectangle(struct blitter_context_priv *ctx, int x1, int y1, int x2, int y2, float depth) { int width = x2 - x1; int height = y2 - y1; /* set vertex positions */ - ctx->vertices[0][0][0] = -1; /*v0.x*/ - ctx->vertices[0][0][1] = -1; /*v0.y*/ + if (!ctx->has_vertex_id) { + ctx->vertices[0][0][0] = -1; /*v0.x*/ + ctx->vertices[0][0][1] = -1; /*v0.y*/ - ctx->vertices[1][0][0] = 1; /*v1.x*/ - ctx->vertices[1][0][1] = -1; /*v1.y*/ + ctx->vertices[1][0][0] = 1; /*v1.x*/ + ctx->vertices[1][0][1] = -1; /*v1.y*/ - ctx->vertices[2][0][0] = 1; /*v2.x*/ - ctx->vertices[2][0][1] = 1; /*v2.y*/ + ctx->vertices[2][0][0] = 1; /*v2.x*/ + ctx->vertices[2][0][1] = 1; /*v2.y*/ - ctx->vertices[3][0][0] = -1; /*v3.x*/ - ctx->vertices[3][0][1] = 1; /*v3.y*/ + ctx->vertices[3][0][0] = -1; /*v3.x*/ + ctx->vertices[3][0][1] = 1; /*v3.y*/ + } /* viewport */ struct pipe_viewport_state viewport; viewport.scale[0] = width / 2.0; viewport.scale[1] = height / 2.0; viewport.scale[2] = 0; viewport.translate[0] = width / 2.0 + x1; viewport.translate[1] = height / 2.0 + y1; viewport.translate[2] = depth; ctx->base.pipe->set_viewport_states(ctx->base.pipe, 0, 1, &viewport); } static void blitter_set_clear_color(struct blitter_context_priv *ctx, const uint32_t color[4]) { int i; - if (color) { - for (i = 0; i < 4; i++) - memcpy(&ctx->vertices[i][1][0], color, sizeof(uint32_t) * 4); + if (ctx->has_vertex_id) { + if (color) { + for (i = 0; i < 4; i++) + memcpy(&ctx->vertices_nopos[i][0], color, sizeof(uint32_t) * 4); + } else { + for (i = 0; i < 4; i++) + memset(&ctx->vertices_nopos[i][0], 0, sizeof(uint32_t) * 4); + } } else { - for (i = 0; i < 4; i++) - memset(&ctx->vertices[i][1][0], 0, sizeof(uint32_t) * 4); + if (color) { + for (i = 0; i < 4; i++) + memcpy(&ctx->vertices[i][1][0], color, sizeof(uint32_t) * 4); + } else { + for (i = 0; i < 4; i++) + memset(&ctx->vertices[i][1][0], 0, sizeof(uint32_t) * 4); + } } } static void get_texcoords(struct pipe_sampler_view *src, unsigned src_width0, unsigned src_height0, int x1, int y1, int x2, int y2, float layer, unsigned sample, bool uses_txf, union blitter_attrib *out) { unsigned level = src->u.tex.first_level; @@ -1202,24 +1223,34 @@ static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx, static void blitter_draw(struct blitter_context_priv *ctx, int x1, int y1, int x2, int y2, float depth, unsigned num_instances) { struct pipe_context *pipe = ctx->base.pipe; struct pipe_vertex_buffer vb = {0}; blitter_set_rectangle(ctx, x1, y1, x2, y2, depth); - vb.stride = 8 * sizeof(float); + if (ctx->has_vertex_id) { + vb.stride = 4 * sizeof(float); - u_upload_data(pipe->stream_uploader, 0, sizeof(ctx->vertices), 4, ctx->vertices, - &vb.buffer_offset, &vb.buffer.resource); + /* Align vertices to a cache line. */ + u_upload_data(pipe->stream_uploader, 0, sizeof(ctx->vertices_nopos), 64, + ctx->vertices_nopos, &vb.buffer_offset, + &vb.buffer.resource); + } else { + vb.stride = 8 * sizeof(float); + + /* Align vertices to a cache line. */ + u_upload_data(pipe->stream_uploader, 0, sizeof(ctx->vertices), 64, + ctx->vertices, &vb.buffer_offset, &vb.buffer.resource); + } if (!vb.buffer.resource) return; u_upload_unmap(pipe->stream_uploader); pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb); util_draw_arrays_instanced(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, 4, 0, num_instances); pipe_resource_reference(&vb.buffer.resource, NULL); } @@ -1231,27 +1262,37 @@ void util_blitter_draw_rectangle(struct blitter_context *blitter, { struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; unsigned i; switch (type) { case UTIL_BLITTER_ATTRIB_COLOR: blitter_set_clear_color(ctx, (uint32_t*)attrib->color); break; case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW: - for (i = 0; i < 4; i++) { - ctx->vertices[i][1][2] = attrib->texcoord.z; - ctx->vertices[i][1][3] = attrib->texcoord.w; + if (ctx->has_vertex_id) { + for (i = 0; i < 4; i++) { + ctx->vertices_nopos[i][2] = attrib->texcoord.z; + ctx->vertices_nopos[i][3] = attrib->texcoord.w; + } + } else { + for (i = 0; i < 4; i++) { + ctx->vertices[i][1][2] = attrib->texcoord.z; + ctx->vertices[i][1][3] = attrib->texcoord.w; + } } /* fall through */ case UTIL_BLITTER_ATTRIB_TEXCOORD_XY: - set_texcoords_in_vertices(attrib, &ctx->vertices[0][1][0], 8); + if (ctx->has_vertex_id) + set_texcoords_in_vertices(attrib, &ctx->vertices_nopos[0][0], 4); + else + set_texcoords_in_vertices(attrib, &ctx->vertices[0][1][0], 8); break; default:; } blitter_draw(ctx, x1, y1, x2, y2, depth, num_instances); } static void *get_clear_blend_state(struct blitter_context_priv *ctx, unsigned clear_buffers) @@ -1571,27 +1612,38 @@ blitter_draw_tex(struct blitter_context_priv *ctx, get_texcoords(src, src_width0, src_height0, src_x1, src_y1, src_x2, src_y2, layer, sample, uses_txf, &coord); if (src->target == PIPE_TEXTURE_CUBE || src->target == PIPE_TEXTURE_CUBE_ARRAY) { float face_coord[4][2]; set_texcoords_in_vertices(&coord, &face_coord[0][0], 2); - util_map_texcoords2d_onto_cubemap((unsigned)layer % 6, - /* pointer, stride in floats */ - &face_coord[0][0], 2, - &ctx->vertices[0][1][0], 8, - FALSE); - for (unsigned i = 0; i < 4; i++) - ctx->vertices[i][1][3] = coord.texcoord.w; + + if (ctx->has_vertex_id) { + util_map_texcoords2d_onto_cubemap((unsigned)layer % 6, + /* pointer, stride in floats */ + &face_coord[0][0], 2, + &ctx->vertices_nopos[0][0], 4, + FALSE); + for (unsigned i = 0; i < 4; i++) + ctx->vertices_nopos[i][3] = coord.texcoord.w; + } else { + util_map_texcoords2d_onto_cubemap((unsigned)layer % 6, + /* pointer, stride in floats */ + &face_coord[0][0], 2, + &ctx->vertices[0][1][0], 8, + FALSE); + for (unsigned i = 0; i < 4; i++) + ctx->vertices[i][1][3] = coord.texcoord.w; + } /* Cubemaps don't use draw_rectangle. */ blitter_draw(ctx, dst_x1, dst_y1, dst_x2, dst_y2, 0, 1); } else { ctx->base.draw_rectangle(&ctx->base, dst_x1, dst_y1, dst_x2, dst_y2, 0, 1, type, &coord); } } static void do_blits(struct blitter_context_priv *ctx, diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c index 5b54906..3539803 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.c +++ b/src/gallium/drivers/radeon/r600_pipe_common.c @@ -229,66 +229,51 @@ void r600_draw_rectangle(struct blitter_context *blitter, viewport.scale[1] = height / 2.0; viewport.scale[2] = 0; viewport.translate[0] = width / 2.0 + x1; viewport.translate[1] = height / 2.0 + y1; viewport.translate[2] = depth; rctx->b.set_viewport_states(&rctx->b, 0, 1, &viewport); /* Upload vertices. The hw rectangle has only 3 vertices, * The 4th one is derived from the first 3. * The vertex specification should match u_blitter's vertex element state. */ - u_upload_alloc(rctx->b.stream_uploader, 0, sizeof(float) * 24, + u_upload_alloc(rctx->b.stream_uploader, 0, sizeof(float) * 12, rctx->screen->info.tcc_cache_line_size, &offset, &buf, (void**)&vb); if (!buf) return; - vb[0] = -1; - vb[1] = -1; - vb[2] = 0; - vb[3] = 1; - - vb[8] = -1; - vb[9] = 1; - vb[10] = 0; - vb[11] = 1; - - vb[16] = 1; - vb[17] = 1; - vb[18] = 0; - vb[19] = 1; - switch (type) { case UTIL_BLITTER_ATTRIB_COLOR: + memcpy(vb, attrib->color, sizeof(float)*4); memcpy(vb+4, attrib->color, sizeof(float)*4); - memcpy(vb+12, attrib->color, sizeof(float)*4); - memcpy(vb+20, attrib->color, sizeof(float)*4); + memcpy(vb+8, attrib->color, sizeof(float)*4); break; case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW: - vb[6] = vb[14] = vb[22] = attrib->texcoord.z; - vb[7] = vb[15] = vb[23] = attrib->texcoord.w; + vb[2] = vb[6] = vb[10] = attrib->texcoord.z; + vb[3] = vb[7] = vb[11] = attrib->texcoord.w; /* fall through */ case UTIL_BLITTER_ATTRIB_TEXCOORD_XY: - vb[4] = attrib->texcoord.x1; + vb[0] = attrib->texcoord.x1; + vb[1] = attrib->texcoord.y1; + vb[4] = attrib->texcoord.x2; vb[5] = attrib->texcoord.y1; - vb[12] = attrib->texcoord.x1; - vb[13] = attrib->texcoord.y2; - vb[20] = attrib->texcoord.x2; - vb[21] = attrib->texcoord.y2; + vb[8] = attrib->texcoord.x2; + vb[9] = attrib->texcoord.y2; break; default:; /* Nothing to do. */ } /* draw */ struct pipe_vertex_buffer vbuffer = {}; vbuffer.buffer.resource = buf; - vbuffer.stride = 2 * 4 * sizeof(float); /* vertex size */ + vbuffer.stride = 4 * sizeof(float); /* vertex size */ vbuffer.buffer_offset = offset; rctx->b.set_vertex_buffers(&rctx->b, blitter->vb_slot, 1, &vbuffer); util_draw_arrays_instanced(&rctx->b, R600_PRIM_RECTANGLE_LIST, 0, 3, 0, num_instances); pipe_resource_reference(&buf, NULL); } static void r600_dma_emit_wait_idle(struct r600_common_context *rctx) { -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev