freedreno/ir3: 'keeps' need neighbors found too
[mesa.git] / src / gallium / drivers / freedreno / freedreno_context.h
index b7e016bb4691a90026f3e6007a6c235f18e806ae..509a90fdf2395cba7d5362613f5466c5302aa6e6 100644 (file)
@@ -32,7 +32,7 @@
 #include "pipe/p_context.h"
 #include "indices/u_primconvert.h"
 #include "util/u_blitter.h"
-#include "util/u_double_list.h"
+#include "util/list.h"
 #include "util/u_slab.h"
 #include "util/u_string.h"
 
@@ -82,6 +82,29 @@ struct fd_vertex_stateobj {
        unsigned num_elements;
 };
 
+struct fd_streamout_stateobj {
+       struct pipe_stream_output_target *targets[PIPE_MAX_SO_BUFFERS];
+       unsigned num_targets;
+       /* Track offset from vtxcnt for streamout data.  This counter
+        * is just incremented by # of vertices on each draw until
+        * reset or new streamout buffer bound.
+        *
+        * When we eventually have GS, the CPU won't actually know the
+        * number of vertices per draw, so I think we'll have to do
+        * something more clever.
+        */
+       unsigned offsets[PIPE_MAX_SO_BUFFERS];
+};
+
+/* 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
@@ -156,6 +179,9 @@ struct fd_context {
        struct fd_bo *query_bo;
        uint32_t query_tile_stride;
 
+       /* list of resources used by currently-unsubmitted renders */
+       struct list_head used_resources;
+
        /* 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:
@@ -167,20 +193,25 @@ struct fd_context {
        struct fd_program_stateobj solid_prog; // TODO move to screen?
 
        /* shaders used by mem->gmem blits: */
-       struct fd_program_stateobj blit_prog; // TODO move to screen?
+       struct fd_program_stateobj blit_prog[MAX_RENDER_TARGETS]; // TODO move to screen?
+       struct fd_program_stateobj blit_z, blit_zs;
 
        /* do we need to mem2gmem before rendering.  We don't, if for example,
         * there was a glClear() that invalidated the entire previous buffer
         * contents.  Keep track of which buffer(s) are cleared, or needs
         * restore.  Masks of PIPE_CLEAR_*
+        *
+        * The 'cleared' bits will be set for buffers which are *entirely*
+        * cleared, and 'partial_cleared' bits will be set if you must
+        * check cleared_scissor.
         */
        enum {
                /* align bitmask values w/ PIPE_CLEAR_*.. since that is convenient.. */
-               FD_BUFFER_COLOR   = PIPE_CLEAR_COLOR0,
+               FD_BUFFER_COLOR   = PIPE_CLEAR_COLOR,
                FD_BUFFER_DEPTH   = PIPE_CLEAR_DEPTH,
                FD_BUFFER_STENCIL = PIPE_CLEAR_STENCIL,
                FD_BUFFER_ALL     = FD_BUFFER_COLOR | FD_BUFFER_DEPTH | FD_BUFFER_STENCIL,
-       } cleared, restore, resolve;
+       } cleared, partial_cleared, restore, resolve;
 
        bool needs_flush;
 
@@ -267,12 +298,20 @@ struct fd_context {
         */
        struct pipe_scissor_state max_scissor;
 
+       /* Track the cleared scissor for color/depth/stencil, so we know
+        * which, if any, tiles need to be restored (mem2gmem).  Only valid
+        * if the corresponding bit in ctx->cleared is set.
+        */
+       struct {
+               struct pipe_scissor_state color, depth, stencil;
+       } cleared_scissor;
+
        /* Current gmem/tiling configuration.. gets updated on render_tiles()
         * if out of date with current maximal-scissor/cpp:
         */
        struct fd_gmem_stateobj gmem;
        struct fd_vsc_pipe      pipe[8];
-       struct fd_tile          tile[64];
+       struct fd_tile          tile[256];
 
        /* which state objects need to be re-emit'd: */
        enum {
@@ -294,6 +333,7 @@ struct fd_context {
                FD_DIRTY_VTXBUF      = (1 << 15),
                FD_DIRTY_INDEXBUF    = (1 << 16),
                FD_DIRTY_SCISSOR     = (1 << 17),
+               FD_DIRTY_STREAMOUT   = (1 << 18),
        } dirty;
 
        struct pipe_blend_state *blend;
@@ -304,7 +344,7 @@ struct fd_context {
 
        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;
@@ -313,8 +353,8 @@ struct fd_context {
        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;
+       struct fd_streamout_stateobj streamout;
 
        /* GMEM/tile handling fxns: */
        void (*emit_tile_init)(struct fd_context *ctx);
@@ -327,18 +367,25 @@ struct fd_context {
        void (*emit_sysmem_prep)(struct fd_context *ctx);
 
        /* draw: */
-       void (*draw)(struct fd_context *pctx, const struct pipe_draw_info *info);
+       void (*draw_vbo)(struct fd_context *ctx, const struct pipe_draw_info *info);
        void (*clear)(struct fd_context *ctx, unsigned buffers,
                        const union pipe_color_union *color, double depth, unsigned stencil);
+
+       /* constant emit:  (note currently not used/needed for a2xx) */
+       void (*emit_const)(struct fd_ringbuffer *ring, enum shader_t type,
+                       uint32_t regid, uint32_t offset, uint32_t sizedwords,
+                       const uint32_t *dwords, struct pipe_resource *prsc);
+       void (*emit_const_bo)(struct fd_ringbuffer *ring, enum shader_t type, boolean write,
+                       uint32_t regid, uint32_t num, struct fd_bo **bos, uint32_t *offsets);
 };
 
-static INLINE struct fd_context *
+static inline struct fd_context *
 fd_context(struct pipe_context *pctx)
 {
        return (struct fd_context *)pctx;
 }
 
-static INLINE struct pipe_scissor_state *
+static inline struct pipe_scissor_state *
 fd_context_get_scissor(struct fd_context *ctx)
 {
        if (ctx->rasterizer && ctx->rasterizer->scissor)
@@ -346,13 +393,13 @@ fd_context_get_scissor(struct fd_context *ctx)
        return &ctx->disabled_scissor;
 }
 
-static INLINE bool
+static inline bool
 fd_supported_prim(struct fd_context *ctx, unsigned prim)
 {
        return (1 << prim) & ctx->primtype_mask;
 }
 
-static INLINE void
+static inline void
 fd_reset_wfi(struct fd_context *ctx)
 {
        ctx->needs_wfi = true;