[Mesa-dev] [PATCH 14/18] gallium/u_blitter: generate VS POSITION output from VERTEXID if possible
Marek Olšák
maraeo at gmail.com
Thu Aug 17 18:31:35 UTC 2017
From: Marek Olšák <marek.olsak at 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
More information about the mesa-dev
mailing list