static void
emit_vertexbufs(struct fd_context *ctx)
{
- struct fd_vertex_stateobj *vtx = ctx->vtx;
- struct fd_vertexbuf_stateobj *vertexbuf = &ctx->vertexbuf;
+ struct fd_vertex_stateobj *vtx = ctx->vtx.vtx;
+ struct fd_vertexbuf_stateobj *vertexbuf = &ctx->vtx.vertexbuf;
struct fd2_vertex_buf bufs[PIPE_MAX_ATTRIBS];
unsigned i;
struct ir2_instruction *instr = so->vfetch_instrs[i];
struct pipe_vertex_element *elem = &vtx->pipe[i];
struct pipe_vertex_buffer *vb =
- &ctx->vertexbuf.vb[elem->vertex_buffer_index];
+ &ctx->vtx.vertexbuf.vb[elem->vertex_buffer_index];
enum pipe_format format = elem->src_format;
const struct util_format_description *desc =
util_format_description(format);
/* if necessary, fix up vertex fetch instructions: */
if (ctx->dirty & (FD_DIRTY_VTXSTATE | FD_DIRTY_PROG))
- patch_vtx_fetches(ctx, prog->vp, ctx->vtx);
+ patch_vtx_fetches(ctx, prog->vp, ctx->vtx.vtx);
/* if necessary, fix up texture fetch instructions: */
if (ctx->dirty & (FD_DIRTY_TEXSTATE | FD_DIRTY_PROG)) {
fd_bo_del(fd3_ctx->fs_pvt_mem);
fd_bo_del(fd3_ctx->vsc_size_mem);
+ pctx->delete_vertex_elements_state(pctx, fd3_ctx->solid_vbuf_state.vtx);
+ pctx->delete_vertex_elements_state(pctx, fd3_ctx->blit_vbuf_state.vtx);
+
pipe_resource_reference(&fd3_ctx->solid_vbuf, NULL);
pipe_resource_reference(&fd3_ctx->blit_texcoord_vbuf, NULL);
fd3_ctx->solid_vbuf = create_solid_vertexbuf(pctx);
fd3_ctx->blit_texcoord_vbuf = create_blit_texcoord_vertexbuf(pctx);
+ /* setup solid_vbuf_state: */
+ fd3_ctx->solid_vbuf_state.vtx = pctx->create_vertex_elements_state(
+ pctx, 1, (struct pipe_vertex_element[]){{
+ .vertex_buffer_index = 0,
+ .src_offset = 0,
+ .src_format = PIPE_FORMAT_R32G32B32_FLOAT,
+ }});
+ fd3_ctx->solid_vbuf_state.vertexbuf.count = 1;
+ fd3_ctx->solid_vbuf_state.vertexbuf.vb[0].stride = 12;
+ fd3_ctx->solid_vbuf_state.vertexbuf.vb[0].buffer = fd3_ctx->solid_vbuf;
+
+ /* setup blit_vbuf_state: */
+ fd3_ctx->blit_vbuf_state.vtx = pctx->create_vertex_elements_state(
+ pctx, 2, (struct pipe_vertex_element[]){{
+ .vertex_buffer_index = 0,
+ .src_offset = 0,
+ .src_format = PIPE_FORMAT_R32G32_FLOAT,
+ }, {
+ .vertex_buffer_index = 1,
+ .src_offset = 0,
+ .src_format = PIPE_FORMAT_R32G32B32_FLOAT,
+ }});
+ fd3_ctx->blit_vbuf_state.vertexbuf.count = 2;
+ fd3_ctx->blit_vbuf_state.vertexbuf.vb[0].stride = 8;
+ fd3_ctx->blit_vbuf_state.vertexbuf.vb[0].buffer = fd3_ctx->blit_texcoord_vbuf;
+ fd3_ctx->blit_vbuf_state.vertexbuf.vb[1].stride = 12;
+ fd3_ctx->blit_vbuf_state.vertexbuf.vb[1].buffer = fd3_ctx->solid_vbuf;
+
fd3_query_context_init(pctx);
fd3_ctx->border_color_uploader = u_upload_create(pctx, 4096,
*/
struct pipe_resource *blit_texcoord_vbuf;
+ /* vertex state for solid_vbuf:
+ * - solid_vbuf / 12 / R32G32B32_FLOAT
+ */
+ struct fd_vertex_state solid_vbuf_state;
+
+ /* vertex state for blit_prog:
+ * - blit_texcoord_vbuf / 8 / R32G32_FLOAT
+ * - solid_vbuf / 12 / R32G32B32_FLOAT
+ */
+ struct fd_vertex_state blit_vbuf_state;
+
+
/*
* Border color layout *appears* to be as arrays of 0x40 byte
* elements, with frag shader elements starting at (16 x 0x40).
emit_vertexbufs(struct fd_context *ctx, struct fd_ringbuffer *ring,
struct ir3_shader_key key)
{
- struct fd_vertex_stateobj *vtx = ctx->vtx;
- struct fd_vertexbuf_stateobj *vertexbuf = &ctx->vertexbuf;
- struct fd3_vertex_buf bufs[PIPE_MAX_ATTRIBS];
- unsigned i;
-
- if (!vtx->num_elements)
- return;
-
- for (i = 0; i < vtx->num_elements; i++) {
- struct pipe_vertex_element *elem = &vtx->pipe[i];
- struct pipe_vertex_buffer *vb =
- &vertexbuf->vb[elem->vertex_buffer_index];
- bufs[i].offset = vb->buffer_offset + elem->src_offset;
- bufs[i].stride = vb->stride;
- bufs[i].prsc = vb->buffer;
- bufs[i].format = elem->src_format;
- }
-
- fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->prog.vp, key),
- bufs, vtx->num_elements);
+ fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->prog.vp, key), &ctx->vtx);
}
static void
{
fd3_emit_state(ctx, ring, info, &ctx->prog, key, dirty);
- if (dirty & FD_DIRTY_VTXBUF)
+ if (dirty & (FD_DIRTY_VTXBUF | FD_DIRTY_VTXSTATE))
emit_vertexbufs(ctx, ring, key);
OUT_PKT0(ring, REG_A3XX_PC_VERTEX_REUSE_BLOCK_CNTL, 1);
fd3_emit_state(ctx, ring, NULL, &ctx->solid_prog, key, dirty);
fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->solid_prog.vp, key),
- (struct fd3_vertex_buf[]) {{
- .prsc = fd3_ctx->solid_vbuf,
- .stride = 12,
- .format = PIPE_FORMAT_R32G32B32_FLOAT,
- }}, 1);
+ &fd3_ctx->solid_vbuf_state);
OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1);
OUT_RING(ring, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(0) |
OUT_RING(ring, A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0));
fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->solid_prog.vp, key),
- (struct fd3_vertex_buf[]) {{
- .prsc = fd3_ctx->solid_vbuf,
- .stride = 12,
- .format = PIPE_FORMAT_R32G32B32_FLOAT,
- }}, 1);
+ &fd3_ctx->solid_vbuf_state);
fd3_emit_constant(ring, SB_FRAG_SHADER, 0, 0, 4, color->ui, NULL);
void
fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
- struct ir3_shader_variant *vp,
- struct fd3_vertex_buf *vbufs, uint32_t n)
+ struct ir3_shader_variant *vp, struct fd_vertex_state *vtx)
{
uint32_t i, j, last = 0;
uint32_t total_in = 0;
+ unsigned n = MIN2(vtx->vtx->num_elements, vp->inputs_count);
- n = MIN2(n, vp->inputs_count);
+ /* hw doesn't like to be configured for zero vbo's, it seems: */
+ if (vtx->vtx->num_elements == 0)
+ return;
for (i = 0; i < n; i++)
if (vp->inputs[i].compmask)
for (i = 0, j = 0; i <= last; i++) {
if (vp->inputs[i].compmask) {
- struct pipe_resource *prsc = vbufs[i].prsc;
- struct fd_resource *rsc = fd_resource(prsc);
- enum pipe_format pfmt = vbufs[i].format;
+ struct pipe_vertex_element *elem = &vtx->vtx->pipe[i];
+ struct pipe_vertex_buffer *vb =
+ &vtx->vertexbuf.vb[elem->vertex_buffer_index];
+ struct fd_resource *rsc = fd_resource(vb->buffer);
+ enum pipe_format pfmt = elem->src_format;
enum a3xx_vtx_fmt fmt = fd3_pipe2vtx(pfmt);
bool switchnext = (i != last);
bool isint = util_format_is_pure_integer(pfmt);
OUT_PKT0(ring, REG_A3XX_VFD_FETCH(j), 2);
OUT_RING(ring, A3XX_VFD_FETCH_INSTR_0_FETCHSIZE(fs - 1) |
- A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE(vbufs[i].stride) |
+ A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE(vb->stride) |
COND(switchnext, A3XX_VFD_FETCH_INSTR_0_SWITCHNEXT) |
A3XX_VFD_FETCH_INSTR_0_INDEXCODE(j) |
A3XX_VFD_FETCH_INSTR_0_STEPRATE(1));
- OUT_RELOC(ring, rsc->bo, vbufs[i].offset, 0, 0);
+ OUT_RELOC(ring, rsc->bo, vb->buffer_offset + elem->src_offset, 0, 0);
OUT_PKT0(ring, REG_A3XX_VFD_DECODE_INSTR(j), 1);
OUT_RING(ring, A3XX_VFD_DECODE_INSTR_CONSTFILL |
void fd3_emit_gmem_restore_tex(struct fd_ringbuffer *ring,
struct pipe_surface *psurf);
-/* NOTE: this just exists because we don't have proper vertex/vertexbuf
- * state objs for clear, and mem2gmem/gmem2mem operations..
- */
-struct fd3_vertex_buf {
- unsigned offset, stride;
- struct pipe_resource *prsc;
- enum pipe_format format;
-};
-
void fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
- struct ir3_shader_variant *vp,
- struct fd3_vertex_buf *vbufs, uint32_t n);
+ struct ir3_shader_variant *vp, struct fd_vertex_state *vtx);
+
void fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
const struct pipe_draw_info *info, struct fd_program_stateobj *prog,
struct ir3_shader_key key, uint32_t dirty);
+
void fd3_emit_restore(struct fd_context *ctx);
#endif /* FD3_EMIT_H */
fd3_program_emit(ring, &ctx->solid_prog, key, false);
fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->solid_prog.vp, key),
- (struct fd3_vertex_buf[]) {{
- .prsc = fd3_ctx->solid_vbuf,
- .stride = 12,
- .format = PIPE_FORMAT_R32G32B32_FLOAT,
- }}, 1);
+ &fd3_ctx->solid_vbuf_state);
OUT_PKT0(ring, REG_A3XX_HLSQ_CONTROL_0_REG, 4);
OUT_RING(ring, A3XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE(FOUR_QUADS) |
fd3_program_emit(ring, &ctx->solid_prog, key, false);
fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->solid_prog.vp, key),
- (struct fd3_vertex_buf[]) {{
- .prsc = fd3_ctx->solid_vbuf,
- .stride = 12,
- .format = PIPE_FORMAT_R32G32B32_FLOAT,
- }}, 1);
+ &fd3_ctx->solid_vbuf_state);
if (ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) {
uint32_t base = depth_base(ctx);
fd3_program_emit(ring, &ctx->blit_prog, key, false);
fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->blit_prog.vp, key),
- (struct fd3_vertex_buf[]) {{
- .prsc = fd3_ctx->blit_texcoord_vbuf,
- .stride = 8,
- .format = PIPE_FORMAT_R32G32_FLOAT,
- }, {
- .prsc = fd3_ctx->solid_vbuf,
- .stride = 12,
- .format = PIPE_FORMAT_R32G32B32_FLOAT,
- }}, 2);
+ &fd3_ctx->blit_vbuf_state);
/* for gmem pitch/base calculations, we need to use the non-
* truncated tile sizes:
unsigned num_elements;
};
+/* group together the vertex and vertexbuf state.. for ease of passing
+ * around, and because various internal operations (gmem<->mem, etc)
+ * need their own vertex state:
+ */
+struct fd_vertex_state {
+ struct fd_vertex_stateobj *vtx;
+ struct fd_vertexbuf_stateobj vertexbuf;
+};
+
/* Bitmask of stages in rendering that a particular query query is
* active. Queries will be automatically started/stopped (generating
* additional fd_hw_sample_period's) on entrance/exit from stages that
struct fd_program_stateobj prog;
- struct fd_vertex_stateobj *vtx;
+ struct fd_vertex_state vtx;
struct pipe_blend_color blend_color;
struct pipe_stencil_ref stencil_ref;
struct pipe_poly_stipple stipple;
struct pipe_viewport_state viewport;
struct fd_constbuf_stateobj constbuf[PIPE_SHADER_TYPES];
- struct fd_vertexbuf_stateobj vertexbuf;
struct pipe_index_buffer indexbuf;
/* GMEM/tile handling fxns: */
static void
fd_blitter_pipe_begin(struct fd_context *ctx)
{
- util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vertexbuf.vb);
- util_blitter_save_vertex_elements(ctx->blitter, ctx->vtx);
+ util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vtx.vertexbuf.vb);
+ util_blitter_save_vertex_elements(ctx->blitter, ctx->vtx.vtx);
util_blitter_save_vertex_shader(ctx->blitter, ctx->prog.vp);
util_blitter_save_rasterizer(ctx->blitter, ctx->rasterizer);
util_blitter_save_viewport(ctx->blitter, &ctx->viewport);
const struct pipe_vertex_buffer *vb)
{
struct fd_context *ctx = fd_context(pctx);
- struct fd_vertexbuf_stateobj *so = &ctx->vertexbuf;
+ struct fd_vertexbuf_stateobj *so = &ctx->vtx.vertexbuf;
int i;
/* on a2xx, pitch is encoded in the vtx fetch instruction, so
fd_vertex_state_bind(struct pipe_context *pctx, void *hwcso)
{
struct fd_context *ctx = fd_context(pctx);
- ctx->vtx = hwcso;
+ ctx->vtx.vtx = hwcso;
ctx->dirty |= FD_DIRTY_VTXSTATE;
}