127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/**************************************************************************
227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang *
327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * Copyright 2009 VMware, Inc.
427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * All Rights Reserved.
527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang *
627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * Permission is hereby granted, free of charge, to any person obtaining a
727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * copy of this software and associated documentation files (the
827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * "Software"), to deal in the Software without restriction, including
927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * without limitation the rights to use, copy, modify, merge, publish,
1027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * distribute, sub license, and/or sell copies of the Software, and to
1127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * permit persons to whom the Software is furnished to do so, subject to
1227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * the following conditions:
1327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang *
1427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * The above copyright notice and this permission notice (including the
1527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * next paragraph) shall be included in all copies or substantial portions
1627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * of the Software.
1727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang *
1827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
2127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
2227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang *
2627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang **************************************************************************/
2727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
2827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
2927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/**
3027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * Binner data structures and bin-related functions.
3127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * Note: the "setup" code is concerned with building scenes while
3227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * The "rast" code is concerned with consuming/executing scenes.
3327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang */
3427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
3527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang#ifndef LP_SCENE_H
3627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang#define LP_SCENE_H
3727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
3827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang#include "os/os_thread.h"
3927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang#include "lp_tile_soa.h"
4027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang#include "lp_rast.h"
4127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang#include "lp_debug.h"
4227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
4327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangstruct lp_scene_queue;
4427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangstruct lp_rast_state;
4527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
4627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/* We're limited to 2K by 2K for 32bit fixed point rasterization.
4727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * Will need a 64-bit version for larger framebuffers.
4827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang */
4927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang#define TILES_X (LP_MAX_WIDTH / TILE_SIZE)
5027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang#define TILES_Y (LP_MAX_HEIGHT / TILE_SIZE)
5127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
5227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
5327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang#define CMD_BLOCK_MAX 128
5427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang#define DATA_BLOCK_SIZE (64 * 1024)
5527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
5627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/* Scene temporary storage is clamped to this size:
5727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang */
5827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang#define LP_SCENE_MAX_SIZE (4*1024*1024)
5927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
6027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/* The maximum amount of texture storage referenced by a scene is
6127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * clamped ot this size:
6227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang */
6327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang#define LP_SCENE_MAX_RESOURCE_SIZE (64*1024*1024)
6427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
6527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
6627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/* switch to a non-pointer value for this:
6727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang */
6827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangtypedef void (*lp_rast_cmd_func)( struct lp_rasterizer_task *,
6927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang                                  const union lp_rast_cmd_arg );
7027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
7127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
7227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangstruct cmd_block {
7327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   uint8_t cmd[CMD_BLOCK_MAX];
7427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   union lp_rast_cmd_arg arg[CMD_BLOCK_MAX];
7527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   unsigned count;
7627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct cmd_block *next;
7727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang};
7827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
7927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangstruct cmd_block_list {
8027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct cmd_block *head;
8127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct cmd_block *tail;
8227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang};
8327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
8427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangstruct data_block {
8527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   ubyte data[DATA_BLOCK_SIZE];
8627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   unsigned used;
8727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct data_block *next;
8827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang};
8927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
9027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
9127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
9227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/**
9327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * For each screen tile we have one of these bins.
9427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang */
9527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangstruct cmd_bin {
9627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   ushort x;
9727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   ushort y;
9827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   const struct lp_rast_state *last_state;       /* most recent state set in bin */
9927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct cmd_block *head;
10027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct cmd_block *tail;
10127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang};
10227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
10327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
10427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/**
10527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * This stores bulk data which is used for all memory allocations
10627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * within a scene.
10727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang *
10827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * Examples include triangle data and state data.  The commands in
10927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * the per-tile bins will point to chunks of data in this structure.
11027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang *
11127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * Include the first block of data statically to ensure we can always
11227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * initiate a scene without relying on malloc succeeding.
11327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang */
11427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangstruct data_block_list {
11527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct data_block first;
11627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct data_block *head;
11727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang};
11827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
11927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangstruct resource_ref;
12027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
12127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/**
12227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * All bins and bin data are contained here.
12327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * Per-bin data goes into the 'tile' bins.
12427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * Shared data goes into the 'data' buffer.
12527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang *
12627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * When there are multiple threads, will want to double-buffer between
12727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * scenes:
12827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang */
12927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangstruct lp_scene {
13027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct pipe_context *pipe;
13127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct lp_fence *fence;
13227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
13327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   /* Framebuffer mappings - valid only between begin_rasterization()
13427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang    * and end_rasterization().
13527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang    */
13627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct {
13727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      uint8_t *map;
13827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      unsigned stride;
13918999c2cfd477050de0ca88c3a73458235d82656Wei Wang      unsigned blocksize;
14018999c2cfd477050de0ca88c3a73458235d82656Wei Wang   } zsbuf, cbufs[PIPE_MAX_COLOR_BUFS];
14118999c2cfd477050de0ca88c3a73458235d82656Wei Wang
14218999c2cfd477050de0ca88c3a73458235d82656Wei Wang   /** the framebuffer to render the scene into */
14327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct pipe_framebuffer_state fb;
14427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
14527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   /** list of resources referenced by the scene commands */
14627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct resource_ref *resources;
14727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
14818999c2cfd477050de0ca88c3a73458235d82656Wei Wang   /** Total memory used by the scene (in bytes).  This sums all the
14918999c2cfd477050de0ca88c3a73458235d82656Wei Wang    * data blocks and counts all bins, state, resource references and
15018999c2cfd477050de0ca88c3a73458235d82656Wei Wang    * other random allocations within the scene.
15118999c2cfd477050de0ca88c3a73458235d82656Wei Wang    */
15218999c2cfd477050de0ca88c3a73458235d82656Wei Wang   unsigned scene_size;
15318999c2cfd477050de0ca88c3a73458235d82656Wei Wang
15418999c2cfd477050de0ca88c3a73458235d82656Wei Wang   /** Sum of sizes of all resources referenced by the scene.  Sums
15518999c2cfd477050de0ca88c3a73458235d82656Wei Wang    * all the textures read by the scene:
15618999c2cfd477050de0ca88c3a73458235d82656Wei Wang    */
15727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   unsigned resource_reference_size;
15827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
15927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   boolean alloc_failed;
16027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   boolean has_depthstencil_clear;
16127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
16227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   /**
16327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang    * Number of active tiles in each dimension.
16427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang    * This basically the framebuffer size divided by tile size
16527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang    */
16627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   unsigned tiles_x, tiles_y;
16727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
16827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   int curr_x, curr_y;  /**< for iterating over bins */
16927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   pipe_mutex mutex;
17027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
17127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct cmd_bin tile[TILES_X][TILES_Y];
17227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct data_block_list data;
17327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang};
17427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
17527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
17627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
17727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangstruct lp_scene *lp_scene_create(struct pipe_context *pipe);
17827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
17927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangvoid lp_scene_destroy(struct lp_scene *scene);
18027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
18127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangboolean lp_scene_is_empty(struct lp_scene *scene );
18227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangboolean lp_scene_is_oom(struct lp_scene *scene );
18327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
18427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
18527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangstruct data_block *lp_scene_new_data_block( struct lp_scene *scene );
18627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
18727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangstruct cmd_block *lp_scene_new_cmd_block( struct lp_scene *scene,
18827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang                                          struct cmd_bin *bin );
18927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
19027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangboolean lp_scene_add_resource_reference(struct lp_scene *scene,
19127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang                                        struct pipe_resource *resource,
19227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang                                        boolean initializing_scene);
19327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
19427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangboolean lp_scene_is_resource_referenced(const struct lp_scene *scene,
19527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang                                        const struct pipe_resource *resource );
19627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
19727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
19827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/**
19927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * Allocate space for a command/data in the bin's data buffer.
20027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * Grow the block list if needed.
20127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang */
20227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangstatic INLINE void *
20327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wanglp_scene_alloc( struct lp_scene *scene, unsigned size)
20427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang{
20527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct data_block_list *list = &scene->data;
20627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct data_block *block = list->head;
20727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
20827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   assert(size <= DATA_BLOCK_SIZE);
209039bf1606bddb3794fd6aa9adee704733f89544fWei Wang   assert(block != NULL);
210039bf1606bddb3794fd6aa9adee704733f89544fWei Wang
211039bf1606bddb3794fd6aa9adee704733f89544fWei Wang   if (LP_DEBUG & DEBUG_MEM)
212039bf1606bddb3794fd6aa9adee704733f89544fWei Wang      debug_printf("alloc %u block %u/%u tot %u/%u\n",
213039bf1606bddb3794fd6aa9adee704733f89544fWei Wang		   size, block->used, DATA_BLOCK_SIZE,
214039bf1606bddb3794fd6aa9adee704733f89544fWei Wang		   scene->scene_size, LP_SCENE_MAX_SIZE);
21527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
21661b76fd94c45ee1909cde1d08a643fc031ef287fYicheng Fan   if (block->used + size > DATA_BLOCK_SIZE) {
21727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      block = lp_scene_new_data_block( scene );
21827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      if (!block) {
21927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang         /* out of memory */
22027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang         return NULL;
22127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      }
22227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   }
22327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
22427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   {
22527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      ubyte *data = block->data + block->used;
22627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      block->used += size;
22727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      return data;
22827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   }
22927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang}
23027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
23127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
23227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/**
23327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * As above, but with specific alignment.
23427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang */
23527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangstatic INLINE void *
23627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wanglp_scene_alloc_aligned( struct lp_scene *scene, unsigned size,
23727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang			unsigned alignment )
23827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang{
23927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct data_block_list *list = &scene->data;
24027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct data_block *block = list->head;
24127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
24227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   assert(block != NULL);
24327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
24427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   if (LP_DEBUG & DEBUG_MEM)
24527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      debug_printf("alloc %u block %u/%u tot %u/%u\n",
24627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang		   size + alignment - 1,
24727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang		   block->used, DATA_BLOCK_SIZE,
24827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang		   scene->scene_size, LP_SCENE_MAX_SIZE);
24927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
25027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   if (block->used + size + alignment - 1 > DATA_BLOCK_SIZE) {
25127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      block = lp_scene_new_data_block( scene );
25227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      if (!block)
25327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang         return NULL;
25427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   }
25527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
25627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   {
25727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      ubyte *data = block->data + block->used;
25827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      unsigned offset = (((uintptr_t)data + alignment - 1) & ~(alignment - 1)) - (uintptr_t)data;
25927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      block->used += offset + size;
26027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      return data + offset;
26127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   }
26227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang}
26327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
26427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
26527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/* Put back data if we decide not to use it, eg. culled triangles.
26627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang */
26727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangstatic INLINE void
26827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wanglp_scene_putback_data( struct lp_scene *scene, unsigned size)
26927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang{
27027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct data_block_list *list = &scene->data;
27127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   assert(list->head && list->head->used >= size);
27227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   list->head->used -= size;
27327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang}
27427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
27527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
27627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/** Return pointer to a particular tile's bin. */
27727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangstatic INLINE struct cmd_bin *
27827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wanglp_scene_get_bin(struct lp_scene *scene, unsigned x, unsigned y)
27927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang{
28027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   return &scene->tile[x][y];
28127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang}
28227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
28327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
28427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/** Remove all commands from a bin */
28527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangvoid
28627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wanglp_scene_bin_reset(struct lp_scene *scene, unsigned x, unsigned y);
28727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
28827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
28927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/* Add a command to bin[x][y].
29027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang */
29127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangstatic INLINE boolean
29227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wanglp_scene_bin_command( struct lp_scene *scene,
29327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang                      unsigned x, unsigned y,
29427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang                      unsigned cmd,
29527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang                      union lp_rast_cmd_arg arg )
29627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang{
29727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
29827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct cmd_block *tail = bin->tail;
29927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
30027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   assert(x < scene->tiles_x);
30127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   assert(y < scene->tiles_y);
30227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   assert(cmd < LP_RAST_OP_MAX);
30327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
30427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   if (tail == NULL || tail->count == CMD_BLOCK_MAX) {
30527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      tail = lp_scene_new_cmd_block( scene, bin );
306db0920ed7d9ef5385e36dfa922f351e4e6556a3eWei Wang      if (!tail) {
307db0920ed7d9ef5385e36dfa922f351e4e6556a3eWei Wang         return FALSE;
30827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      }
30927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      assert(tail->count == 0);
31027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   }
31127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
31227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   {
313c1512abbe9bb60c94c5f46e90918983d1514c8e3Andre Eisenbach      unsigned i = tail->count;
314db0920ed7d9ef5385e36dfa922f351e4e6556a3eWei Wang      tail->cmd[i] = cmd & LP_RAST_OP_MASK;
31527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      tail->arg[i] = arg;
31627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      tail->count++;
31727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   }
31827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
31927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   return TRUE;
32027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang}
32186c292ab0f0fed25345a2eaef0fd92ff9c72a9e5Wei Wang
32227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
32327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangstatic INLINE boolean
324bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wanglp_scene_bin_cmd_with_state( struct lp_scene *scene,
32527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang                             unsigned x, unsigned y,
326bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang                             const struct lp_rast_state *state,
32727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang                             unsigned cmd,
32827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang                             union lp_rast_cmd_arg arg )
32927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang{
33027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
33127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
33227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   if (state != bin->last_state) {
33327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      bin->last_state = state;
33427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      if (!lp_scene_bin_command(scene, x, y,
33527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang                                LP_RAST_OP_SET_STATE,
336bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang                                lp_rast_arg_state(state)))
33727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang         return FALSE;
33827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   }
33927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
34027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   if (!lp_scene_bin_command( scene, x, y, cmd, arg ))
34127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang      return FALSE;
34227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
34327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang   return TRUE;
34427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang}
34527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
34627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
34727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/* Add a command to all active bins.
348bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang */
349bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wangstatic INLINE boolean
350e34b91565499994a4b04a1014432c8f90678972aWei Wanglp_scene_bin_everywhere( struct lp_scene *scene,
351bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang			 unsigned cmd,
352bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang			 const union lp_rast_cmd_arg arg )
353e34b91565499994a4b04a1014432c8f90678972aWei Wang{
354e34b91565499994a4b04a1014432c8f90678972aWei Wang   unsigned i, j;
355e34b91565499994a4b04a1014432c8f90678972aWei Wang   for (i = 0; i < scene->tiles_x; i++) {
356bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang      for (j = 0; j < scene->tiles_y; j++) {
357bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang         if (!lp_scene_bin_command( scene, i, j, cmd, arg ))
358bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang            return FALSE;
359bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang      }
360bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang   }
361bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang
362bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang   return TRUE;
363bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang}
364bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang
365bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang
366bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wangstatic INLINE unsigned
367bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wanglp_scene_get_num_bins( const struct lp_scene *scene )
368bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang{
369e34b91565499994a4b04a1014432c8f90678972aWei Wang   return scene->tiles_x * scene->tiles_y;
370bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang}
371bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang
372e34b91565499994a4b04a1014432c8f90678972aWei Wang
373e34b91565499994a4b04a1014432c8f90678972aWei Wangvoid
374bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wanglp_scene_bin_iter_begin( struct lp_scene *scene );
375bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang
376bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wangstruct cmd_bin *
377bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wanglp_scene_bin_iter_next( struct lp_scene *scene );
378e34b91565499994a4b04a1014432c8f90678972aWei Wang
379bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang
380bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang
381bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang/* Begin/end binning of a scene
382bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang */
383bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wangvoid
384bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wanglp_scene_begin_binning( struct lp_scene *scene,
385bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang                        struct pipe_framebuffer_state *fb );
386bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wang
387bebb0fe84fe06a47bd88cdfb9cba8ffe4d2c463aWei Wangvoid
38827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wanglp_scene_end_binning( struct lp_scene *scene );
38927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
39027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
39127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/* Begin/end rasterization of a scene
39227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang */
39327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangvoid
39427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wanglp_scene_begin_rasterization(struct lp_scene *scene);
39527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
39627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangvoid
39727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wanglp_scene_end_rasterization(struct lp_scene *scene );
39827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
39927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
40027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
40127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
40227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang
40327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang#endif /* LP_BIN_H */
40427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang