Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
  2.  
  3. /*
  4.  * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice (including the next
  14.  * paragraph) shall be included in all copies or substantial portions of the
  15.  * Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23.  * SOFTWARE.
  24.  *
  25.  * Authors:
  26.  *    Rob Clark <robclark@freedesktop.org>
  27.  */
  28.  
  29. #ifndef FREEDRENO_CONTEXT_H_
  30. #define FREEDRENO_CONTEXT_H_
  31.  
  32. #include "pipe/p_context.h"
  33. #include "indices/u_primconvert.h"
  34. #include "util/u_blitter.h"
  35. #include "util/list.h"
  36. #include "util/u_slab.h"
  37. #include "util/u_string.h"
  38.  
  39. #include "freedreno_screen.h"
  40. #include "freedreno_gmem.h"
  41. #include "freedreno_util.h"
  42.  
  43. struct fd_vertex_stateobj;
  44.  
  45. struct fd_texture_stateobj {
  46.         struct pipe_sampler_view *textures[PIPE_MAX_SAMPLERS];
  47.         unsigned num_textures;
  48.         struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
  49.         unsigned num_samplers;
  50.         unsigned dirty_samplers;
  51. };
  52.  
  53. struct fd_program_stateobj {
  54.         void *vp, *fp;
  55.         enum {
  56.                 FD_SHADER_DIRTY_VP = (1 << 0),
  57.                 FD_SHADER_DIRTY_FP = (1 << 1),
  58.         } dirty;
  59.         uint8_t num_exports;
  60.         /* Indexed by semantic name or TGSI_SEMANTIC_COUNT + semantic index
  61.          * for TGSI_SEMANTIC_GENERIC.  Special vs exports (position and point-
  62.          * size) are not included in this
  63.          */
  64.         uint8_t export_linkage[63];
  65. };
  66.  
  67. struct fd_constbuf_stateobj {
  68.         struct pipe_constant_buffer cb[PIPE_MAX_CONSTANT_BUFFERS];
  69.         uint32_t enabled_mask;
  70.         uint32_t dirty_mask;
  71. };
  72.  
  73. struct fd_vertexbuf_stateobj {
  74.         struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
  75.         unsigned count;
  76.         uint32_t enabled_mask;
  77.         uint32_t dirty_mask;
  78. };
  79.  
  80. struct fd_vertex_stateobj {
  81.         struct pipe_vertex_element pipe[PIPE_MAX_ATTRIBS];
  82.         unsigned num_elements;
  83. };
  84.  
  85. /* group together the vertex and vertexbuf state.. for ease of passing
  86.  * around, and because various internal operations (gmem<->mem, etc)
  87.  * need their own vertex state:
  88.  */
  89. struct fd_vertex_state {
  90.         struct fd_vertex_stateobj *vtx;
  91.         struct fd_vertexbuf_stateobj vertexbuf;
  92. };
  93.  
  94. /* Bitmask of stages in rendering that a particular query query is
  95.  * active.  Queries will be automatically started/stopped (generating
  96.  * additional fd_hw_sample_period's) on entrance/exit from stages that
  97.  * are applicable to the query.
  98.  *
  99.  * NOTE: set the stage to NULL at end of IB to ensure no query is still
  100.  * active.  Things aren't going to work out the way you want if a query
  101.  * is active across IB's (or between tile IB and draw IB)
  102.  */
  103. enum fd_render_stage {
  104.         FD_STAGE_NULL     = 0x00,
  105.         FD_STAGE_DRAW     = 0x01,
  106.         FD_STAGE_CLEAR    = 0x02,
  107.         /* TODO before queries which include MEM2GMEM or GMEM2MEM will
  108.          * work we will need to call fd_hw_query_prepare() from somewhere
  109.          * appropriate so that queries in the tiling IB get backed with
  110.          * memory to write results to.
  111.          */
  112.         FD_STAGE_MEM2GMEM = 0x04,
  113.         FD_STAGE_GMEM2MEM = 0x08,
  114.         /* used for driver internal draws (ie. util_blitter_blit()): */
  115.         FD_STAGE_BLIT     = 0x10,
  116. };
  117.  
  118. #define MAX_HW_SAMPLE_PROVIDERS 4
  119. struct fd_hw_sample_provider;
  120. struct fd_hw_sample;
  121.  
  122. struct fd_context {
  123.         struct pipe_context base;
  124.  
  125.         struct fd_device *dev;
  126.         struct fd_screen *screen;
  127.  
  128.         struct blitter_context *blitter;
  129.         struct primconvert_context *primconvert;
  130.  
  131.         /* slab for pipe_transfer allocations: */
  132.         struct util_slab_mempool transfer_pool;
  133.  
  134.         /* slabs for fd_hw_sample and fd_hw_sample_period allocations: */
  135.         struct util_slab_mempool sample_pool;
  136.         struct util_slab_mempool sample_period_pool;
  137.  
  138.         /* next sample offset.. incremented for each sample in the batch/
  139.          * submit, reset to zero on next submit.
  140.          */
  141.         uint32_t next_sample_offset;
  142.  
  143.         /* sample-providers for hw queries: */
  144.         const struct fd_hw_sample_provider *sample_providers[MAX_HW_SAMPLE_PROVIDERS];
  145.  
  146.         /* cached samples (in case multiple queries need to reference
  147.          * the same sample snapshot)
  148.          */
  149.         struct fd_hw_sample *sample_cache[MAX_HW_SAMPLE_PROVIDERS];
  150.  
  151.         /* tracking for current stage, to know when to start/stop
  152.          * any active queries:
  153.          */
  154.         enum fd_render_stage stage;
  155.  
  156.         /* list of active queries: */
  157.         struct list_head active_queries;
  158.  
  159.         /* list of queries that are not active, but were active in the
  160.          * current submit:
  161.          */
  162.         struct list_head current_queries;
  163.  
  164.         /* current query result bo and tile stride: */
  165.         struct fd_bo *query_bo;
  166.         uint32_t query_tile_stride;
  167.  
  168.         /* list of resources used by currently-unsubmitted renders */
  169.         struct list_head used_resources;
  170.  
  171.         /* table with PIPE_PRIM_MAX entries mapping PIPE_PRIM_x to
  172.          * DI_PT_x value to use for draw initiator.  There are some
  173.          * slight differences between generation:
  174.          */
  175.         const uint8_t *primtypes;
  176.         uint32_t primtype_mask;
  177.  
  178.         /* shaders used by clear, and gmem->mem blits: */
  179.         struct fd_program_stateobj solid_prog; // TODO move to screen?
  180.  
  181.         /* shaders used by mem->gmem blits: */
  182.         struct fd_program_stateobj blit_prog[8]; // TODO move to screen?
  183.         struct fd_program_stateobj blit_z, blit_zs;
  184.  
  185.         /* do we need to mem2gmem before rendering.  We don't, if for example,
  186.          * there was a glClear() that invalidated the entire previous buffer
  187.          * contents.  Keep track of which buffer(s) are cleared, or needs
  188.          * restore.  Masks of PIPE_CLEAR_*
  189.          *
  190.          * The 'cleared' bits will be set for buffers which are *entirely*
  191.          * cleared, and 'partial_cleared' bits will be set if you must
  192.          * check cleared_scissor.
  193.          */
  194.         enum {
  195.                 /* align bitmask values w/ PIPE_CLEAR_*.. since that is convenient.. */
  196.                 FD_BUFFER_COLOR   = PIPE_CLEAR_COLOR,
  197.                 FD_BUFFER_DEPTH   = PIPE_CLEAR_DEPTH,
  198.                 FD_BUFFER_STENCIL = PIPE_CLEAR_STENCIL,
  199.                 FD_BUFFER_ALL     = FD_BUFFER_COLOR | FD_BUFFER_DEPTH | FD_BUFFER_STENCIL,
  200.         } cleared, partial_cleared, restore, resolve;
  201.  
  202.         bool needs_flush;
  203.  
  204.         /* To decide whether to render to system memory, keep track of the
  205.          * number of draws, and whether any of them require multisample,
  206.          * depth_test (or depth write), stencil_test, blending, and
  207.          * color_logic_Op (since those functions are disabled when by-
  208.          * passing GMEM.
  209.          */
  210.         enum {
  211.                 FD_GMEM_CLEARS_DEPTH_STENCIL = 0x01,
  212.                 FD_GMEM_DEPTH_ENABLED        = 0x02,
  213.                 FD_GMEM_STENCIL_ENABLED      = 0x04,
  214.  
  215.                 FD_GMEM_MSAA_ENABLED         = 0x08,
  216.                 FD_GMEM_BLEND_ENABLED        = 0x10,
  217.                 FD_GMEM_LOGICOP_ENABLED      = 0x20,
  218.         } gmem_reason;
  219.         unsigned num_draws;   /* number of draws in current batch */
  220.  
  221.         /* Stats/counters:
  222.          */
  223.         struct {
  224.                 uint64_t prims_emitted;
  225.                 uint64_t draw_calls;
  226.                 uint64_t batch_total, batch_sysmem, batch_gmem, batch_restore;
  227.         } stats;
  228.  
  229.         /* we can't really sanely deal with wraparound point in ringbuffer
  230.          * and because of the way tiling works we can't really flush at
  231.          * arbitrary points (without a big performance hit).  When we get
  232.          * too close to the end of the current ringbuffer, cycle to the next
  233.          * one (and wait for pending rendering from next rb to complete).
  234.          * We want the # of ringbuffers to be high enough that we don't
  235.          * normally have to wait before resetting to the start of the next
  236.          * rb.
  237.          */
  238.         struct fd_ringbuffer *rings[8];
  239.         unsigned rings_idx;
  240.  
  241.         /* NOTE: currently using a single ringbuffer for both draw and
  242.          * tiling commands, we need to make sure we need to leave enough
  243.          * room at the end to append the tiling commands when we flush.
  244.          * 0x7000 dwords should be a couple times more than we ever need
  245.          * so should be a nice conservative threshold.
  246.          */
  247. #define FD_TILING_COMMANDS_DWORDS 0x7000
  248.  
  249.         /* normal draw/clear cmds: */
  250.         struct fd_ringbuffer *ring;
  251.         struct fd_ringmarker *draw_start, *draw_end;
  252.  
  253.         /* binning pass draw/clear cmds: */
  254.         struct fd_ringbuffer *binning_ring;
  255.         struct fd_ringmarker *binning_start, *binning_end;
  256.  
  257.         /* Keep track if WAIT_FOR_IDLE is needed for registers we need
  258.          * to update via RMW:
  259.          */
  260.         bool needs_wfi;
  261.  
  262.         /* Do we need to re-emit RB_FRAME_BUFFER_DIMENSION?  At least on a3xx
  263.          * it is not a banked context register, so it needs a WFI to update.
  264.          * Keep track if it has actually changed, to avoid unneeded WFI.
  265.          * */
  266.         bool needs_rb_fbd;
  267.  
  268.         /* Keep track of DRAW initiators that need to be patched up depending
  269.          * on whether we using binning or not:
  270.          */
  271.         struct util_dynarray draw_patches;
  272.  
  273.         struct pipe_scissor_state scissor;
  274.  
  275.         /* we don't have a disable/enable bit for scissor, so instead we keep
  276.          * a disabled-scissor state which matches the entire bound framebuffer
  277.          * and use that when scissor is not enabled.
  278.          */
  279.         struct pipe_scissor_state disabled_scissor;
  280.  
  281.         /* Track the maximal bounds of the scissor of all the draws within a
  282.          * batch.  Used at the tile rendering step (fd_gmem_render_tiles(),
  283.          * mem2gmem/gmem2mem) to avoid needlessly moving data in/out of gmem.
  284.          */
  285.         struct pipe_scissor_state max_scissor;
  286.  
  287.         /* Track the cleared scissor for color/depth/stencil, so we know
  288.          * which, if any, tiles need to be restored (mem2gmem).  Only valid
  289.          * if the corresponding bit in ctx->cleared is set.
  290.          */
  291.         struct {
  292.                 struct pipe_scissor_state color, depth, stencil;
  293.         } cleared_scissor;
  294.  
  295.         /* Current gmem/tiling configuration.. gets updated on render_tiles()
  296.          * if out of date with current maximal-scissor/cpp:
  297.          */
  298.         struct fd_gmem_stateobj gmem;
  299.         struct fd_vsc_pipe      pipe[8];
  300.         struct fd_tile          tile[256];
  301.  
  302.         /* which state objects need to be re-emit'd: */
  303.         enum {
  304.                 FD_DIRTY_BLEND       = (1 <<  0),
  305.                 FD_DIRTY_RASTERIZER  = (1 <<  1),
  306.                 FD_DIRTY_ZSA         = (1 <<  2),
  307.                 FD_DIRTY_FRAGTEX     = (1 <<  3),
  308.                 FD_DIRTY_VERTTEX     = (1 <<  4),
  309.                 FD_DIRTY_TEXSTATE    = (1 <<  5),
  310.                 FD_DIRTY_PROG        = (1 <<  6),
  311.                 FD_DIRTY_BLEND_COLOR = (1 <<  7),
  312.                 FD_DIRTY_STENCIL_REF = (1 <<  8),
  313.                 FD_DIRTY_SAMPLE_MASK = (1 <<  9),
  314.                 FD_DIRTY_FRAMEBUFFER = (1 << 10),
  315.                 FD_DIRTY_STIPPLE     = (1 << 11),
  316.                 FD_DIRTY_VIEWPORT    = (1 << 12),
  317.                 FD_DIRTY_CONSTBUF    = (1 << 13),
  318.                 FD_DIRTY_VTXSTATE    = (1 << 14),
  319.                 FD_DIRTY_VTXBUF      = (1 << 15),
  320.                 FD_DIRTY_INDEXBUF    = (1 << 16),
  321.                 FD_DIRTY_SCISSOR     = (1 << 17),
  322.         } dirty;
  323.  
  324.         struct pipe_blend_state *blend;
  325.         struct pipe_rasterizer_state *rasterizer;
  326.         struct pipe_depth_stencil_alpha_state *zsa;
  327.  
  328.         struct fd_texture_stateobj verttex, fragtex;
  329.  
  330.         struct fd_program_stateobj prog;
  331.  
  332.         struct fd_vertex_state vtx;
  333.  
  334.         struct pipe_blend_color blend_color;
  335.         struct pipe_stencil_ref stencil_ref;
  336.         unsigned sample_mask;
  337.         struct pipe_framebuffer_state framebuffer;
  338.         struct pipe_poly_stipple stipple;
  339.         struct pipe_viewport_state viewport;
  340.         struct fd_constbuf_stateobj constbuf[PIPE_SHADER_TYPES];
  341.         struct pipe_index_buffer indexbuf;
  342.  
  343.         /* GMEM/tile handling fxns: */
  344.         void (*emit_tile_init)(struct fd_context *ctx);
  345.         void (*emit_tile_prep)(struct fd_context *ctx, struct fd_tile *tile);
  346.         void (*emit_tile_mem2gmem)(struct fd_context *ctx, struct fd_tile *tile);
  347.         void (*emit_tile_renderprep)(struct fd_context *ctx, struct fd_tile *tile);
  348.         void (*emit_tile_gmem2mem)(struct fd_context *ctx, struct fd_tile *tile);
  349.  
  350.         /* optional, for GMEM bypass: */
  351.         void (*emit_sysmem_prep)(struct fd_context *ctx);
  352.  
  353.         /* draw: */
  354.         void (*draw_vbo)(struct fd_context *pctx, const struct pipe_draw_info *info);
  355.         void (*clear)(struct fd_context *ctx, unsigned buffers,
  356.                         const union pipe_color_union *color, double depth, unsigned stencil);
  357. };
  358.  
  359. static INLINE struct fd_context *
  360. fd_context(struct pipe_context *pctx)
  361. {
  362.         return (struct fd_context *)pctx;
  363. }
  364.  
  365. static INLINE struct pipe_scissor_state *
  366. fd_context_get_scissor(struct fd_context *ctx)
  367. {
  368.         if (ctx->rasterizer && ctx->rasterizer->scissor)
  369.                 return &ctx->scissor;
  370.         return &ctx->disabled_scissor;
  371. }
  372.  
  373. static INLINE bool
  374. fd_supported_prim(struct fd_context *ctx, unsigned prim)
  375. {
  376.         return (1 << prim) & ctx->primtype_mask;
  377. }
  378.  
  379. static INLINE void
  380. fd_reset_wfi(struct fd_context *ctx)
  381. {
  382.         ctx->needs_wfi = true;
  383. }
  384.  
  385. /* emit a WAIT_FOR_IDLE only if needed, ie. if there has not already
  386.  * been one since last draw:
  387.  */
  388. static inline void
  389. fd_wfi(struct fd_context *ctx, struct fd_ringbuffer *ring)
  390. {
  391.         if (ctx->needs_wfi) {
  392.                 OUT_WFI(ring);
  393.                 ctx->needs_wfi = false;
  394.         }
  395. }
  396.  
  397. /* emit a CP_EVENT_WRITE:
  398.  */
  399. static inline void
  400. fd_event_write(struct fd_context *ctx, struct fd_ringbuffer *ring,
  401.                 enum vgt_event_type evt)
  402. {
  403.         OUT_PKT3(ring, CP_EVENT_WRITE, 1);
  404.         OUT_RING(ring, evt);
  405.         fd_reset_wfi(ctx);
  406. }
  407.  
  408. struct pipe_context * fd_context_init(struct fd_context *ctx,
  409.                 struct pipe_screen *pscreen, const uint8_t *primtypes,
  410.                 void *priv);
  411.  
  412. void fd_context_render(struct pipe_context *pctx);
  413.  
  414. void fd_context_destroy(struct pipe_context *pctx);
  415.  
  416. #endif /* FREEDRENO_CONTEXT_H_ */
  417.