void r600_draw_rectangle(struct blitter_context *blitter, int x1, int y1, int x2, int y2, float depth, enum blitter_attrib_type type, const union pipe_color_union *attrib) { struct r600_common_context *rctx = (struct r600_common_context*)util_blitter_get_pipe(blitter); struct pipe_viewport_state viewport; struct pipe_resource *buf = NULL; unsigned offset = 0; float *vb; if (type == UTIL_BLITTER_ATTRIB_TEXCOORD) { util_blitter_draw_rectangle(blitter, x1, y1, x2, y2, depth, type, attrib); return; } /* Some operations (like color resolve on r6xx) don't work * with the conventional primitive types. * One that works is PT_RECTLIST, which we use here. */ /* setup viewport */ viewport.scale[0] = 1.0f; viewport.scale[1] = 1.0f; viewport.scale[2] = 1.0f; viewport.translate[0] = 0.0f; viewport.translate[1] = 0.0f; viewport.translate[2] = 0.0f; rctx->b.set_viewport_states(&rctx->b, 0, 1, &viewport); /* Upload vertices. The hw rectangle has only 3 vertices, * I guess the 4th one is derived from the first 3. * The vertex specification should match u_blitter's vertex element state. */ u_upload_alloc(rctx->uploader, 0, sizeof(float) * 24, &offset, &buf, (void**)&vb); vb[0] = x1; vb[1] = y1; vb[2] = depth; vb[3] = 1; vb[8] = x1; vb[9] = y2; vb[10] = depth; vb[11] = 1; vb[16] = x2; vb[17] = y1; vb[18] = depth; vb[19] = 1; if (attrib) { memcpy(vb+4, attrib->f, sizeof(float)*4); memcpy(vb+12, attrib->f, sizeof(float)*4); memcpy(vb+20, attrib->f, sizeof(float)*4); } /* draw */ util_draw_vertex_buffer(&rctx->b, NULL, buf, blitter->vb_slot, offset, R600_PRIM_RECTANGLE_LIST, 3, 2); pipe_resource_reference(&buf, NULL); }
/* This functions is used to draw a rectangle for the blitter module. * * If we rendered a quad, the pixels on the main diagonal * would be computed and stored twice, which makes the clear/copy codepaths * somewhat inefficient. Instead we use a rectangular point sprite. */ void r300_blitter_draw_rectangle(struct blitter_context *blitter, int x1, int y1, int x2, int y2, float depth, enum blitter_attrib_type type, const union pipe_color_union *attrib) { struct r300_context *r300 = r300_context(util_blitter_get_pipe(blitter)); unsigned last_sprite_coord_enable = r300->sprite_coord_enable; unsigned width = x2 - x1; unsigned height = y2 - y1; unsigned vertex_size = type == UTIL_BLITTER_ATTRIB_COLOR || !r300->draw ? 8 : 4; unsigned dwords = 13 + vertex_size + (type == UTIL_BLITTER_ATTRIB_TEXCOORD ? 7 : 0); static const union pipe_color_union zeros; CS_LOCALS(r300); /* XXX workaround for a lockup in MSAA resolve on SWTCL chipsets, this * function most probably doesn't handle type=NONE correctly */ if (!r300->screen->caps.has_tcl && type == UTIL_BLITTER_ATTRIB_NONE) { util_blitter_draw_rectangle(blitter, x1, y1, x2, y2, depth, type, attrib); return; } if (r300->skip_rendering) return; if (type == UTIL_BLITTER_ATTRIB_TEXCOORD) r300->sprite_coord_enable = 1; r300_update_derived_state(r300); /* Mark some states we don't care about as non-dirty. */ r300->viewport_state.dirty = FALSE; if (!r300_prepare_for_rendering(r300, PREP_EMIT_STATES, NULL, dwords, 0, 0, -1)) goto done; DBG(r300, DBG_DRAW, "r300: draw_rectangle\n"); BEGIN_CS(dwords); /* Set up GA. */ OUT_CS_REG(R300_GA_POINT_SIZE, (height * 6) | ((width * 6) << 16)); if (type == UTIL_BLITTER_ATTRIB_TEXCOORD) { /* Set up the GA to generate texcoords. */ OUT_CS_REG(R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE | (R300_GB_TEX_STR << R300_GB_TEX0_SOURCE_SHIFT)); OUT_CS_REG_SEQ(R300_GA_POINT_S0, 4); OUT_CS_32F(attrib->f[0]); OUT_CS_32F(attrib->f[3]); OUT_CS_32F(attrib->f[2]); OUT_CS_32F(attrib->f[1]); } /* Set up VAP controls. */ OUT_CS_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE); OUT_CS_REG(R300_VAP_VTE_CNTL, R300_VTX_XY_FMT | R300_VTX_Z_FMT); OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size); OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2); OUT_CS(1); OUT_CS(0); /* Draw. */ OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, vertex_size); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (1 << 16) | R300_VAP_VF_CNTL__PRIM_POINTS); OUT_CS_32F(x1 + width * 0.5f); OUT_CS_32F(y1 + height * 0.5f); OUT_CS_32F(depth); OUT_CS_32F(1); if (vertex_size == 8) { if (!attrib) attrib = &zeros; OUT_CS_TABLE(attrib->f, 4); } END_CS; done: /* Restore the state. */ r300_mark_atom_dirty(r300, &r300->rs_state); r300_mark_atom_dirty(r300, &r300->viewport_state); r300->sprite_coord_enable = last_sprite_coord_enable; }
void r600_draw_rectangle(struct blitter_context *blitter, void *vertex_elements_cso, blitter_get_vs_func get_vs, int x1, int y1, int x2, int y2, float depth, unsigned num_instances, enum blitter_attrib_type type, const union blitter_attrib *attrib) { struct r600_common_context *rctx = (struct r600_common_context*)util_blitter_get_pipe(blitter); struct pipe_viewport_state viewport; struct pipe_resource *buf = NULL; unsigned offset = 0; float *vb; rctx->b.bind_vertex_elements_state(&rctx->b, vertex_elements_cso); rctx->b.bind_vs_state(&rctx->b, get_vs(blitter)); /* Some operations (like color resolve on r6xx) don't work * with the conventional primitive types. * One that works is PT_RECTLIST, which we use here. */ /* setup viewport */ viewport.scale[0] = 1.0f; viewport.scale[1] = 1.0f; viewport.scale[2] = 1.0f; viewport.translate[0] = 0.0f; viewport.translate[1] = 0.0f; viewport.translate[2] = 0.0f; 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, rctx->screen->info.tcc_cache_line_size, &offset, &buf, (void**)&vb); if (!buf) return; vb[0] = x1; vb[1] = y1; vb[2] = depth; vb[3] = 1; vb[8] = x1; vb[9] = y2; vb[10] = depth; vb[11] = 1; vb[16] = x2; vb[17] = y1; vb[18] = depth; vb[19] = 1; switch (type) { case UTIL_BLITTER_ATTRIB_COLOR: memcpy(vb+4, attrib->color, sizeof(float)*4); memcpy(vb+12, attrib->color, sizeof(float)*4); memcpy(vb+20, attrib->color, sizeof(float)*4); break; case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW: case UTIL_BLITTER_ATTRIB_TEXCOORD_XY: vb[6] = vb[14] = vb[22] = attrib->texcoord.z; vb[7] = vb[15] = vb[23] = attrib->texcoord.w; /* fall through */ vb[4] = attrib->texcoord.x1; vb[5] = attrib->texcoord.y1; vb[12] = attrib->texcoord.x1; vb[13] = attrib->texcoord.y2; vb[20] = attrib->texcoord.x2; vb[21] = attrib->texcoord.y1; break; default:; /* Nothing to do. */ } /* draw */ struct pipe_vertex_buffer vbuffer = {}; vbuffer.buffer.resource = buf; vbuffer.stride = 2 * 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); }
/* This functions is used to draw a rectangle for the blitter module. * * If we rendered a quad, the pixels on the main diagonal * would be computed and stored twice, which makes the clear/copy codepaths * somewhat inefficient. Instead we use a rectangular point sprite. */ static void r300_blitter_draw_rectangle(struct blitter_context *blitter, unsigned x1, unsigned y1, unsigned x2, unsigned y2, float depth, enum blitter_attrib_type type, const float attrib[4]) { struct r300_context *r300 = r300_context(util_blitter_get_pipe(blitter)); unsigned last_sprite_coord_enable = r300->sprite_coord_enable; unsigned width = x2 - x1; unsigned height = y2 - y1; unsigned vertex_size = type == UTIL_BLITTER_ATTRIB_COLOR || !r300->draw ? 8 : 4; unsigned dwords = 13 + vertex_size + (type == UTIL_BLITTER_ATTRIB_TEXCOORD ? 7 : 0); const float zeros[4] = {0, 0, 0, 0}; CS_LOCALS(r300); if (type == UTIL_BLITTER_ATTRIB_TEXCOORD) r300->sprite_coord_enable = 1; r300_update_derived_state(r300); /* Mark some states we don't care about as non-dirty. */ r300->clip_state.dirty = FALSE; r300->viewport_state.dirty = FALSE; if (!r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0)) goto done; DBG(r300, DBG_DRAW, "r300: draw_rectangle\n"); BEGIN_CS(dwords); /* Set up GA. */ OUT_CS_REG(R300_GA_POINT_SIZE, (height * 6) | ((width * 6) << 16)); if (type == UTIL_BLITTER_ATTRIB_TEXCOORD) { /* Set up the GA to generate texcoords. */ OUT_CS_REG(R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE | (R300_GB_TEX_STR << R300_GB_TEX0_SOURCE_SHIFT)); OUT_CS_REG_SEQ(R300_GA_POINT_S0, 4); OUT_CS_32F(attrib[0]); OUT_CS_32F(attrib[3]); OUT_CS_32F(attrib[2]); OUT_CS_32F(attrib[1]); } /* Set up VAP controls. */ OUT_CS_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE); OUT_CS_REG(R300_VAP_VTE_CNTL, R300_VTX_XY_FMT | R300_VTX_Z_FMT); OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size); OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2); OUT_CS(1); OUT_CS(0); /* Draw. */ OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, vertex_size); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (1 << 16) | R300_VAP_VF_CNTL__PRIM_POINTS); OUT_CS_32F(x1 + width * 0.5f); OUT_CS_32F(y1 + height * 0.5f); OUT_CS_32F(depth); OUT_CS_32F(1); if (vertex_size == 8) { if (!attrib) attrib = zeros; OUT_CS_TABLE(attrib, 4); } END_CS; done: /* Restore the state. */ r300->clip_state.dirty = TRUE; r300->rs_state.dirty = TRUE; r300->viewport_state.dirty = TRUE; r300->sprite_coord_enable = last_sprite_coord_enable; }