X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Ffreedreno%2Ffreedreno_context.h;h=f92790c0ecf4353f526c51454fee7935184f29a7;hb=b3efa2a4da206112f6c9b5adb2df37c2efe646e6;hp=f10f7ef4ea50b5ec2673a8aaf71e0911f5b8aa87;hpb=eed9685dd6619ec7598e8c3fd81117d36010510d;p=mesa.git diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index f10f7ef4ea5..f92790c0ecf 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -1,5 +1,3 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - /* * Copyright (C) 2012 Rob Clark * @@ -52,37 +50,33 @@ struct fd_texture_stateobj { struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS]; unsigned num_samplers; unsigned valid_samplers; + /* number of samples per sampler, 2 bits per sampler: */ + uint32_t samples; }; struct fd_program_stateobj { - void *vp, *fp; - - /* rest only used by fd2.. split out: */ - uint8_t num_exports; - /* Indexed by semantic name or TGSI_SEMANTIC_COUNT + semantic index - * for TGSI_SEMANTIC_GENERIC. Special vs exports (position and point- - * size) are not included in this - */ - uint8_t export_linkage[63]; + void *vs, *hs, *ds, *gs, *fs; }; struct fd_constbuf_stateobj { struct pipe_constant_buffer cb[PIPE_MAX_CONSTANT_BUFFERS]; uint32_t enabled_mask; - uint32_t dirty_mask; }; struct fd_shaderbuf_stateobj { struct pipe_shader_buffer sb[PIPE_MAX_SHADER_BUFFERS]; uint32_t enabled_mask; - uint32_t dirty_mask; +}; + +struct fd_shaderimg_stateobj { + struct pipe_image_view si[PIPE_MAX_SHADER_IMAGES]; + uint32_t enabled_mask; }; struct fd_vertexbuf_stateobj { struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS]; unsigned count; uint32_t enabled_mask; - uint32_t dirty_mask; }; struct fd_vertex_stateobj { @@ -92,6 +86,9 @@ struct fd_vertex_stateobj { struct fd_streamout_stateobj { struct pipe_stream_output_target *targets[PIPE_MAX_SO_BUFFERS]; + /* Bitmask of stream that should be reset. */ + unsigned reset; + unsigned num_targets; /* Track offset from vtxcnt for streamout data. This counter * is just incremented by # of vertices on each draw until @@ -104,6 +101,12 @@ struct fd_streamout_stateobj { unsigned offsets[PIPE_MAX_SO_BUFFERS]; }; +#define MAX_GLOBAL_BUFFERS 16 +struct fd_global_bindings_stateobj { + struct pipe_resource *buf[MAX_GLOBAL_BUFFERS]; + uint32_t enabled_mask; +}; + /* 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: @@ -126,6 +129,7 @@ enum fd_dirty_3d_state { FD_DIRTY_VIEWPORT = BIT(8), FD_DIRTY_VTXSTATE = BIT(9), FD_DIRTY_VTXBUF = BIT(10), + FD_DIRTY_MIN_SAMPLES = BIT(11), FD_DIRTY_SCISSOR = BIT(12), FD_DIRTY_STREAMOUT = BIT(13), @@ -149,17 +153,26 @@ enum fd_dirty_shader_state { FD_DIRTY_SHADER_CONST = BIT(1), FD_DIRTY_SHADER_TEX = BIT(2), FD_DIRTY_SHADER_SSBO = BIT(3), + FD_DIRTY_SHADER_IMAGE = BIT(4), }; struct fd_context { struct pipe_context base; + /* We currently need to serialize emitting GMEM batches, because of + * VSC state access in the context. + * + * In practice this lock should not be contended, since pipe_context + * use should be single threaded. But it is needed to protect the + * case, with batch reordering where a ctxB batch triggers flushing + * a ctxA batch + */ + mtx_t gmem_lock; + struct fd_device *dev; struct fd_screen *screen; struct fd_pipe *pipe; - struct util_queue flush_queue; - struct blitter_context *blitter; void *clear_rs_state; struct primconvert_context *primconvert; @@ -208,7 +221,9 @@ struct fd_context { uint64_t prims_emitted; uint64_t prims_generated; uint64_t draw_calls; - uint64_t batch_total, batch_sysmem, batch_gmem, batch_restore; + uint64_t batch_total, batch_sysmem, batch_gmem, batch_nondraw, batch_restore; + uint64_t staging_uploads, shadow_uploads; + uint64_t vs_regs, hs_regs, ds_regs, gs_regs, fs_regs; } stats; /* Current batch.. the rule here is that you can deref ctx->batch @@ -219,8 +234,20 @@ struct fd_context { */ struct fd_batch *batch; + /* NULL if there has been rendering since last flush. Otherwise + * keeps a reference to the last fence so we can re-use it rather + * than having to flush no-op batch. + */ struct pipe_fence_handle *last_fence; + /* track last known reset status globally and per-context to + * determine if more resets occurred since then. If global reset + * count increases, it means some other context crashed. If + * per-context reset count increases, it means we crashed the + * gpu. + */ + uint32_t context_reset_count, global_reset_count; + /* Are we in process of shadowing a resource? Used to detect recursion * in transfer_map, and skip unneeded synchronization. */ @@ -240,15 +267,8 @@ struct fd_context { */ struct pipe_scissor_state disabled_scissor; - /* Current gmem/tiling configuration.. gets updated on render_tiles() - * if out of date with current maximal-scissor/cpp: - * - * (NOTE: this is kind of related to the batch, but moving it there - * means we'd always have to recalc tiles ever batch) - */ - struct fd_gmem_stateobj gmem; - struct fd_vsc_pipe vsc_pipe[16]; - struct fd_tile tile[512]; + /* Per vsc pipe bo's (a2xx-a5xx): */ + struct fd_bo *vsc_pipe_bo[32]; /* which state objects need to be re-emit'd: */ enum fd_dirty_3d_state dirty; @@ -270,11 +290,17 @@ struct fd_context { struct pipe_blend_color blend_color; struct pipe_stencil_ref stencil_ref; unsigned sample_mask; + unsigned min_samples; + /* local context fb state, for when ctx->batch is null: */ + struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple stipple; struct pipe_viewport_state viewport; + struct pipe_scissor_state viewport_scissor; struct fd_constbuf_stateobj constbuf[PIPE_SHADER_TYPES]; struct fd_shaderbuf_stateobj shaderbuf[PIPE_SHADER_TYPES]; + struct fd_shaderimg_stateobj shaderimg[PIPE_SHADER_TYPES]; struct fd_streamout_stateobj streamout; + struct fd_global_bindings_stateobj global_bindings; struct pipe_clip_state ucp; struct pipe_query *cond_query; @@ -285,10 +311,11 @@ struct fd_context { /* GMEM/tile handling fxns: */ void (*emit_tile_init)(struct fd_batch *batch); - void (*emit_tile_prep)(struct fd_batch *batch, struct fd_tile *tile); - void (*emit_tile_mem2gmem)(struct fd_batch *batch, struct fd_tile *tile); - void (*emit_tile_renderprep)(struct fd_batch *batch, struct fd_tile *tile); - void (*emit_tile_gmem2mem)(struct fd_batch *batch, struct fd_tile *tile); + void (*emit_tile_prep)(struct fd_batch *batch, const struct fd_tile *tile); + void (*emit_tile_mem2gmem)(struct fd_batch *batch, const struct fd_tile *tile); + void (*emit_tile_renderprep)(struct fd_batch *batch, const struct fd_tile *tile); + void (*emit_tile)(struct fd_batch *batch, const struct fd_tile *tile); + void (*emit_tile_gmem2mem)(struct fd_batch *batch, const struct fd_tile *tile); void (*emit_tile_fini)(struct fd_batch *batch); /* optional */ /* optional, for GMEM bypass: */ @@ -297,31 +324,26 @@ struct fd_context { /* draw: */ bool (*draw_vbo)(struct fd_context *ctx, const struct pipe_draw_info *info, - unsigned index_offset); + unsigned index_offset); bool (*clear)(struct fd_context *ctx, unsigned buffers, const union pipe_color_union *color, double depth, unsigned stencil); /* compute: */ void (*launch_grid)(struct fd_context *ctx, const struct pipe_grid_info *info); - /* 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); - /* emit bo addresses as constant: */ - void (*emit_const_bo)(struct fd_ringbuffer *ring, enum shader_t type, boolean write, - uint32_t regid, uint32_t num, struct pipe_resource **prscs, uint32_t *offsets); - - /* indirect-branch emit: */ - void (*emit_ib)(struct fd_ringbuffer *ring, struct fd_ringbuffer *target); - /* query: */ - struct fd_query * (*create_query)(struct fd_context *ctx, unsigned query_type); + struct fd_query * (*create_query)(struct fd_context *ctx, unsigned query_type, unsigned index); void (*query_prepare)(struct fd_batch *batch, uint32_t num_tiles); void (*query_prepare_tile)(struct fd_batch *batch, uint32_t n, struct fd_ringbuffer *ring); void (*query_set_stage)(struct fd_batch *batch, enum fd_render_stage stage); + /* blitter: */ + bool (*blit)(struct fd_context *ctx, const struct pipe_blit_info *info); + + /* handling for barriers: */ + void (*framebuffer_barrier)(struct fd_context *ctx); + /* * Common pre-cooked VBO state (used for a3xx and later): */ @@ -342,6 +364,20 @@ struct fd_context { * - solid_vbuf / 12 / R32G32B32_FLOAT */ struct fd_vertex_state blit_vbuf_state; + + /* + * Info about state of previous draw, for state that comes from + * pipe_draw_info (ie. not part of a CSO). This allows us to + * skip some register emit when the state doesn't change from + * draw-to-draw + */ + struct { + bool dirty; /* last draw state unknown */ + bool primitive_restart; + uint32_t index_start; + uint32_t instance_start; + uint32_t restart_index; + } last; }; static inline struct fd_context * @@ -372,6 +408,7 @@ fd_context_unlock(struct fd_context *ctx) static inline void fd_context_all_dirty(struct fd_context *ctx) { + ctx->last.dirty = true; ctx->dirty = ~0; for (unsigned i = 0; i < PIPE_SHADER_TYPES; i++) ctx->dirty_shader[i] = ~0; @@ -407,6 +444,19 @@ fd_supported_prim(struct fd_context *ctx, unsigned prim) return (1 << prim) & ctx->primtype_mask; } +static inline struct fd_batch * +fd_context_batch(struct fd_context *ctx) +{ + if (unlikely(!ctx->batch)) { + struct fd_batch *batch = + fd_batch_from_fb(&ctx->screen->batch_cache, ctx, &ctx->framebuffer); + util_copy_framebuffer_state(&batch->framebuffer, &ctx->framebuffer); + ctx->batch = batch; + fd_context_all_dirty(ctx); + } + return ctx->batch; +} + static inline void fd_batch_set_stage(struct fd_batch *batch, enum fd_render_stage stage) {