return prsc;
}
+static const uint8_t a22x_primtypes[PIPE_PRIM_MAX] = {
+ [PIPE_PRIM_POINTS] = DI_PT_POINTLIST_A2XX,
+ [PIPE_PRIM_LINES] = DI_PT_LINELIST,
+ [PIPE_PRIM_LINE_STRIP] = DI_PT_LINESTRIP,
+ [PIPE_PRIM_LINE_LOOP] = DI_PT_LINELOOP,
+ [PIPE_PRIM_TRIANGLES] = DI_PT_TRILIST,
+ [PIPE_PRIM_TRIANGLE_STRIP] = DI_PT_TRISTRIP,
+ [PIPE_PRIM_TRIANGLE_FAN] = DI_PT_TRIFAN,
+};
+
+static const uint8_t a20x_primtypes[PIPE_PRIM_MAX] = {
+ [PIPE_PRIM_POINTS] = DI_PT_POINTLIST_A2XX,
+ [PIPE_PRIM_LINES] = DI_PT_LINELIST,
+ [PIPE_PRIM_LINE_STRIP] = DI_PT_LINESTRIP,
+ [PIPE_PRIM_TRIANGLES] = DI_PT_TRILIST,
+ [PIPE_PRIM_TRIANGLE_STRIP] = DI_PT_TRISTRIP,
+ [PIPE_PRIM_TRIANGLE_FAN] = DI_PT_TRIFAN,
+};
+
struct pipe_context *
fd2_context_create(struct pipe_screen *pscreen, void *priv)
{
+ struct fd_screen *screen = fd_screen(pscreen);
struct fd2_context *fd2_ctx = CALLOC_STRUCT(fd2_context);
struct pipe_context *pctx;
fd2_texture_init(pctx);
fd2_prog_init(pctx);
- pctx = fd_context_init(&fd2_ctx->base, pscreen, priv);
+ pctx = fd_context_init(&fd2_ctx->base, pscreen,
+ (screen->gpu_id >= 220) ? a22x_primtypes : a20x_primtypes,
+ priv);
if (!pctx)
return NULL;
return prsc;
}
+static const uint8_t primtypes[PIPE_PRIM_MAX] = {
+ [PIPE_PRIM_POINTS] = DI_PT_POINTLIST_A3XX,
+ [PIPE_PRIM_LINES] = DI_PT_LINELIST,
+ [PIPE_PRIM_LINE_STRIP] = DI_PT_LINESTRIP,
+ [PIPE_PRIM_LINE_LOOP] = DI_PT_LINELOOP,
+ [PIPE_PRIM_TRIANGLES] = DI_PT_TRILIST,
+ [PIPE_PRIM_TRIANGLE_STRIP] = DI_PT_TRISTRIP,
+ [PIPE_PRIM_TRIANGLE_FAN] = DI_PT_TRIFAN,
+};
+
struct pipe_context *
fd3_context_create(struct pipe_screen *pscreen, void *priv)
{
fd3_texture_init(pctx);
fd3_prog_init(pctx);
- pctx = fd_context_init(&fd3_ctx->base, pscreen, priv);
+ pctx = fd_context_init(&fd3_ctx->base, pscreen, primtypes, priv);
if (!pctx)
return NULL;
if (ctx->blitter)
util_blitter_destroy(ctx->blitter);
+ if (ctx->primconvert)
+ util_primconvert_destroy(ctx->primconvert);
+
fd_ringmarker_del(ctx->draw_start);
fd_ringmarker_del(ctx->draw_end);
fd_ringbuffer_del(ctx->ring);
}
struct pipe_context *
-fd_context_init(struct fd_context *ctx,
- struct pipe_screen *pscreen, void *priv)
+fd_context_init(struct fd_context *ctx, struct pipe_screen *pscreen,
+ const uint8_t *primtypes, void *priv)
{
struct fd_screen *screen = fd_screen(pscreen);
struct pipe_context *pctx;
ctx->screen = screen;
+ ctx->primtypes = primtypes;
+ ctx->primtype_mask = 0;
+ for (i = 0; i < PIPE_PRIM_MAX; i++)
+ if (primtypes[i])
+ ctx->primtype_mask |= (1 << i);
+
/* need some sane default in case state tracker doesn't
* set some state:
*/
if (!ctx->blitter)
goto fail;
+ ctx->primconvert = util_primconvert_create(pctx, ctx->primtype_mask);
+ if (!ctx->primconvert)
+ goto fail;
return pctx;
#include "draw/draw_context.h"
#include "pipe/p_context.h"
+#include "indices/u_primconvert.h"
#include "util/u_blitter.h"
#include "util/u_slab.h"
#include "util/u_string.h"
struct fd_screen *screen;
struct blitter_context *blitter;
+ struct primconvert_context *primconvert;
struct util_slab_mempool transfer_pool;
+ /* table with PIPE_PRIM_MAX entries mapping PIPE_PRIM_x to
+ * DI_PT_x value to use for draw initiator. There are some
+ * slight differences between generation:
+ */
+ const uint8_t *primtypes;
+ uint32_t primtype_mask;
+
/* shaders used by clear, and gmem->mem blits: */
struct fd_program_stateobj solid_prog; // TODO move to screen?
return &ctx->disabled_scissor;
}
+static INLINE bool
+fd_supported_prim(struct fd_context *ctx, unsigned prim)
+{
+ return (1 << prim) & ctx->primtype_mask;
+}
+
struct pipe_context * fd_context_init(struct fd_context *ctx,
- struct pipe_screen *pscreen, void *priv);
+ struct pipe_screen *pscreen, const uint8_t *primtypes,
+ void *priv);
void fd_context_render(struct pipe_context *pctx);
#include "freedreno_util.h"
-static enum pc_di_primtype
-mode2primtype(unsigned mode)
-{
- switch (mode) {
- case PIPE_PRIM_POINTS: return DI_PT_POINTLIST_A2XX;
- case PIPE_PRIM_LINES: return DI_PT_LINELIST;
- case PIPE_PRIM_LINE_STRIP: return DI_PT_LINESTRIP;
- case PIPE_PRIM_TRIANGLES: return DI_PT_TRILIST;
- case PIPE_PRIM_TRIANGLE_STRIP: return DI_PT_TRISTRIP;
- case PIPE_PRIM_TRIANGLE_FAN: return DI_PT_TRIFAN;
- case PIPE_PRIM_QUADS: return DI_PT_QUADLIST;
- case PIPE_PRIM_QUAD_STRIP: return DI_PT_QUADSTRIP;
- case PIPE_PRIM_POLYGON: return DI_PT_POLYGON;
- }
- DBG("unsupported mode: (%s) %d", u_prim_name(mode), mode);
- assert(0);
- return DI_PT_NONE;
-}
-
static enum pc_di_index_size
size2indextype(unsigned index_size)
{
src_sel = DI_SRC_SEL_AUTO_INDEX;
}
- fd_draw(ctx, mode2primtype(info->mode), src_sel, info->count,
+ fd_draw(ctx, ctx->primtypes[info->mode], src_sel, info->count,
idx_type, idx_size, idx_offset, idx_bo);
}
return;
}
+ /* emulate unsupported primitives: */
+ if (!fd_supported_prim(ctx, info->mode)) {
+ util_primconvert_save_index_buffer(ctx->primconvert, &ctx->indexbuf);
+ util_primconvert_save_rasterizer_state(ctx->primconvert, ctx->rasterizer);
+ util_primconvert_draw_vbo(ctx->primconvert, info);
+ return;
+ }
+
ctx->needs_flush = true;
/*