void fd4_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd4_emit *emit) { int32_t i, j, last = -1; uint32_t total_in = 0; const struct fd_vertex_state *vtx = emit->vtx; struct ir3_shader_variant *vp = fd4_emit_get_vp(emit); unsigned vertex_regid = regid(63, 0), instance_regid = regid(63, 0); for (i = 0; i < vp->inputs_count; i++) { uint8_t semantic = sem2name(vp->inputs[i].semantic); if (semantic == TGSI_SEMANTIC_VERTEXID_NOBASE) vertex_regid = vp->inputs[i].regid; else if (semantic == TGSI_SEMANTIC_INSTANCEID) instance_regid = vp->inputs[i].regid; else if ((i < vtx->vtx->num_elements) && vp->inputs[i].compmask) last = i; } /* hw doesn't like to be configured for zero vbo's, it seems: */ if ((vtx->vtx->num_elements == 0) && (vertex_regid == regid(63, 0)) && (instance_regid == regid(63, 0))) return; for (i = 0, j = 0; i <= last; i++) { assert(sem2name(vp->inputs[i].semantic) == 0); if (vp->inputs[i].compmask) { struct pipe_vertex_element *elem = &vtx->vtx->pipe[i]; const 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 a4xx_vtx_fmt fmt = fd4_pipe2vtx(pfmt); bool switchnext = (i != last) || (vertex_regid != regid(63, 0)) || (instance_regid != regid(63, 0)); bool isint = util_format_is_pure_integer(pfmt); uint32_t fs = util_format_get_blocksize(pfmt); uint32_t off = vb->buffer_offset + elem->src_offset; uint32_t size = fd_bo_size(rsc->bo) - off; debug_assert(fmt != ~0); OUT_PKT0(ring, REG_A4XX_VFD_FETCH(j), 4); OUT_RING(ring, A4XX_VFD_FETCH_INSTR_0_FETCHSIZE(fs - 1) | A4XX_VFD_FETCH_INSTR_0_BUFSTRIDE(vb->stride) | COND(elem->instance_divisor, A4XX_VFD_FETCH_INSTR_0_INSTANCED) | COND(switchnext, A4XX_VFD_FETCH_INSTR_0_SWITCHNEXT)); OUT_RELOC(ring, rsc->bo, off, 0, 0); OUT_RING(ring, A4XX_VFD_FETCH_INSTR_2_SIZE(size)); OUT_RING(ring, A4XX_VFD_FETCH_INSTR_3_STEPRATE(MAX2(1, elem->instance_divisor))); OUT_PKT0(ring, REG_A4XX_VFD_DECODE_INSTR(j), 1); OUT_RING(ring, A4XX_VFD_DECODE_INSTR_CONSTFILL | A4XX_VFD_DECODE_INSTR_WRITEMASK(vp->inputs[i].compmask) | A4XX_VFD_DECODE_INSTR_FORMAT(fmt) | A4XX_VFD_DECODE_INSTR_SWAP(fd4_pipe2swap(pfmt)) | A4XX_VFD_DECODE_INSTR_REGID(vp->inputs[i].regid) | A4XX_VFD_DECODE_INSTR_SHIFTCNT(fs) | A4XX_VFD_DECODE_INSTR_LASTCOMPVALID | COND(isint, A4XX_VFD_DECODE_INSTR_INT) | COND(switchnext, A4XX_VFD_DECODE_INSTR_SWITCHNEXT)); total_in += vp->inputs[i].ncomp; j++; } } OUT_PKT0(ring, REG_A4XX_VFD_CONTROL_0, 5); OUT_RING(ring, A4XX_VFD_CONTROL_0_TOTALATTRTOVS(total_in) | 0xa0000 | /* XXX */ A4XX_VFD_CONTROL_0_STRMDECINSTRCNT(j) | A4XX_VFD_CONTROL_0_STRMFETCHINSTRCNT(j)); OUT_RING(ring, A4XX_VFD_CONTROL_1_MAXSTORAGE(129) | // XXX A4XX_VFD_CONTROL_1_REGID4VTX(vertex_regid) | A4XX_VFD_CONTROL_1_REGID4INST(instance_regid)); OUT_RING(ring, 0x00000000); /* XXX VFD_CONTROL_2 */ OUT_RING(ring, A4XX_VFD_CONTROL_3_REGID_VTXCNT(regid(63, 0))); OUT_RING(ring, 0x00000000); /* XXX VFD_CONTROL_4 */ /* cache invalidate, otherwise vertex fetch could see * stale vbo contents: */ OUT_PKT0(ring, REG_A4XX_UCHE_INVALIDATE0, 2); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000012); }
static boolean fd4_screen_is_format_supported(struct pipe_screen *pscreen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, unsigned storage_sample_count, unsigned usage) { unsigned retval = 0; if ((target >= PIPE_MAX_TEXTURE_TYPES) || (sample_count > 1)) { /* TODO add MSAA */ DBG("not supported: format=%s, target=%d, sample_count=%d, usage=%x", util_format_name(format), target, sample_count, usage); return FALSE; } if (MAX2(1, sample_count) != MAX2(1, storage_sample_count)) return false; if ((usage & PIPE_BIND_VERTEX_BUFFER) && (fd4_pipe2vtx(format) != (enum a4xx_vtx_fmt)~0)) { retval |= PIPE_BIND_VERTEX_BUFFER; } if ((usage & PIPE_BIND_SAMPLER_VIEW) && (target == PIPE_BUFFER || util_format_get_blocksize(format) != 12) && (fd4_pipe2tex(format) != (enum a4xx_tex_fmt)~0)) { retval |= PIPE_BIND_SAMPLER_VIEW; } if ((usage & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED)) && (fd4_pipe2color(format) != (enum a4xx_color_fmt)~0) && (fd4_pipe2tex(format) != (enum a4xx_tex_fmt)~0)) { retval |= usage & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED); } /* For ARB_framebuffer_no_attachments: */ if ((usage & PIPE_BIND_RENDER_TARGET) && (format == PIPE_FORMAT_NONE)) { retval |= usage & PIPE_BIND_RENDER_TARGET; } if ((usage & PIPE_BIND_DEPTH_STENCIL) && (fd4_pipe2depth(format) != (enum a4xx_depth_format)~0) && (fd4_pipe2tex(format) != (enum a4xx_tex_fmt)~0)) { retval |= PIPE_BIND_DEPTH_STENCIL; } if ((usage & PIPE_BIND_INDEX_BUFFER) && (fd_pipe2index(format) != (enum pc_di_index_size)~0)) { retval |= PIPE_BIND_INDEX_BUFFER; } if (retval != usage) { DBG("not supported: format=%s, target=%d, sample_count=%d, " "usage=%x, retval=%x", util_format_name(format), target, sample_count, usage, retval); } return retval == usage; }