1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009 VMware, Inc.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Binner data structures and bin-related functions.
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note: the "setup" code is concerned with building scenes while
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The "rast" code is concerned with consuming/executing scenes.
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef LP_SCENE_H
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define LP_SCENE_H
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "os/os_thread.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_tile_soa.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_rast.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_debug.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct lp_scene_queue;
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct lp_rast_state;
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* We're limited to 2K by 2K for 32bit fixed point rasterization.
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Will need a 64-bit version for larger framebuffers.
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define TILES_X (LP_MAX_WIDTH / TILE_SIZE)
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define TILES_Y (LP_MAX_HEIGHT / TILE_SIZE)
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define CMD_BLOCK_MAX 128
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DATA_BLOCK_SIZE (64 * 1024)
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Scene temporary storage is clamped to this size:
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define LP_SCENE_MAX_SIZE (4*1024*1024)
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* The maximum amount of texture storage referenced by a scene is
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * clamped ot this size:
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define LP_SCENE_MAX_RESOURCE_SIZE (64*1024*1024)
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* switch to a non-pointer value for this:
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypedef void (*lp_rast_cmd_func)( struct lp_rasterizer_task *,
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  const union lp_rast_cmd_arg );
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct cmd_block {
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint8_t cmd[CMD_BLOCK_MAX];
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   union lp_rast_cmd_arg arg[CMD_BLOCK_MAX];
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned count;
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cmd_block *next;
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct cmd_block_list {
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cmd_block *head;
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cmd_block *tail;
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct data_block {
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ubyte data[DATA_BLOCK_SIZE];
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned used;
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct data_block *next;
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * For each screen tile we have one of these bins.
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct cmd_bin {
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ushort x;
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ushort y;
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct lp_rast_state *last_state;       /* most recent state set in bin */
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cmd_block *head;
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cmd_block *tail;
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This stores bulk data which is used for all memory allocations
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * within a scene.
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Examples include triangle data and state data.  The commands in
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the per-tile bins will point to chunks of data in this structure.
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Include the first block of data statically to ensure we can always
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * initiate a scene without relying on malloc succeeding.
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct data_block_list {
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct data_block first;
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct data_block *head;
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct resource_ref;
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All bins and bin data are contained here.
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Per-bin data goes into the 'tile' bins.
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Shared data goes into the 'data' buffer.
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * When there are multiple threads, will want to double-buffer between
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * scenes:
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct lp_scene {
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_context *pipe;
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_fence *fence;
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Framebuffer mappings - valid only between begin_rasterization()
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * and end_rasterization().
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct {
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      uint8_t *map;
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned stride;
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned blocksize;
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } zsbuf, cbufs[PIPE_MAX_COLOR_BUFS];
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /** the framebuffer to render the scene into */
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_framebuffer_state fb;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /** list of resources referenced by the scene commands */
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct resource_ref *resources;
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /** Total memory used by the scene (in bytes).  This sums all the
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * data blocks and counts all bins, state, resource references and
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * other random allocations within the scene.
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned scene_size;
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /** Sum of sizes of all resources referenced by the scene.  Sums
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * all the textures read by the scene:
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned resource_reference_size;
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean alloc_failed;
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean has_depthstencil_clear;
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /**
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Number of active tiles in each dimension.
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * This basically the framebuffer size divided by tile size
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned tiles_x, tiles_y;
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int curr_x, curr_y;  /**< for iterating over bins */
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_mutex mutex;
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cmd_bin tile[TILES_X][TILES_Y];
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct data_block_list data;
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct lp_scene *lp_scene_create(struct pipe_context *pipe);
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid lp_scene_destroy(struct lp_scene *scene);
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgboolean lp_scene_is_empty(struct lp_scene *scene );
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgboolean lp_scene_is_oom(struct lp_scene *scene );
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct data_block *lp_scene_new_data_block( struct lp_scene *scene );
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct cmd_block *lp_scene_new_cmd_block( struct lp_scene *scene,
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          struct cmd_bin *bin );
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgboolean lp_scene_add_resource_reference(struct lp_scene *scene,
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        struct pipe_resource *resource,
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        boolean initializing_scene);
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgboolean lp_scene_is_resource_referenced(const struct lp_scene *scene,
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        const struct pipe_resource *resource );
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Allocate space for a command/data in the bin's data buffer.
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Grow the block list if needed.
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void *
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_scene_alloc( struct lp_scene *scene, unsigned size)
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct data_block_list *list = &scene->data;
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct data_block *block = list->head;
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(size <= DATA_BLOCK_SIZE);
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(block != NULL);
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (LP_DEBUG & DEBUG_MEM)
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("alloc %u block %u/%u tot %u/%u\n",
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   size, block->used, DATA_BLOCK_SIZE,
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   scene->scene_size, LP_SCENE_MAX_SIZE);
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (block->used + size > DATA_BLOCK_SIZE) {
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      block = lp_scene_new_data_block( scene );
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!block) {
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* out of memory */
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return NULL;
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ubyte *data = block->data + block->used;
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      block->used += size;
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return data;
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * As above, but with specific alignment.
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void *
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_scene_alloc_aligned( struct lp_scene *scene, unsigned size,
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned alignment )
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct data_block_list *list = &scene->data;
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct data_block *block = list->head;
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(block != NULL);
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (LP_DEBUG & DEBUG_MEM)
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("alloc %u block %u/%u tot %u/%u\n",
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   size + alignment - 1,
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   block->used, DATA_BLOCK_SIZE,
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   scene->scene_size, LP_SCENE_MAX_SIZE);
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (block->used + size + alignment - 1 > DATA_BLOCK_SIZE) {
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      block = lp_scene_new_data_block( scene );
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!block)
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return NULL;
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ubyte *data = block->data + block->used;
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned offset = (((uintptr_t)data + alignment - 1) & ~(alignment - 1)) - (uintptr_t)data;
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      block->used += offset + size;
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return data + offset;
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Put back data if we decide not to use it, eg. culled triangles.
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_scene_putback_data( struct lp_scene *scene, unsigned size)
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct data_block_list *list = &scene->data;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(list->head && list->head->used >= size);
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   list->head->used -= size;
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Return pointer to a particular tile's bin. */
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE struct cmd_bin *
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_scene_get_bin(struct lp_scene *scene, unsigned x, unsigned y)
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &scene->tile[x][y];
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Remove all commands from a bin */
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_scene_bin_reset(struct lp_scene *scene, unsigned x, unsigned y);
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Add a command to bin[x][y].
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_scene_bin_command( struct lp_scene *scene,
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      unsigned x, unsigned y,
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      unsigned cmd,
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      union lp_rast_cmd_arg arg )
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cmd_block *tail = bin->tail;
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(x < scene->tiles_x);
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(y < scene->tiles_y);
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(cmd < LP_RAST_OP_MAX);
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (tail == NULL || tail->count == CMD_BLOCK_MAX) {
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tail = lp_scene_new_cmd_block( scene, bin );
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!tail) {
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(tail->count == 0);
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned i = tail->count;
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tail->cmd[i] = cmd & LP_RAST_OP_MASK;
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tail->arg[i] = arg;
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tail->count++;
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_scene_bin_cmd_with_state( struct lp_scene *scene,
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             unsigned x, unsigned y,
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             const struct lp_rast_state *state,
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             unsigned cmd,
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             union lp_rast_cmd_arg arg )
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (state != bin->last_state) {
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bin->last_state = state;
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!lp_scene_bin_command(scene, x, y,
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                LP_RAST_OP_SET_STATE,
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                lp_rast_arg_state(state)))
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!lp_scene_bin_command( scene, x, y, cmd, arg ))
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Add a command to all active bins.
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_scene_bin_everywhere( struct lp_scene *scene,
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 unsigned cmd,
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 const union lp_rast_cmd_arg arg )
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i, j;
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < scene->tiles_x; i++) {
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (j = 0; j < scene->tiles_y; j++) {
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!lp_scene_bin_command( scene, i, j, cmd, arg ))
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE unsigned
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_scene_get_num_bins( const struct lp_scene *scene )
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return scene->tiles_x * scene->tiles_y;
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_scene_bin_iter_begin( struct lp_scene *scene );
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct cmd_bin *
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_scene_bin_iter_next( struct lp_scene *scene );
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Begin/end binning of a scene
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_scene_begin_binning( struct lp_scene *scene,
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        struct pipe_framebuffer_state *fb );
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_scene_end_binning( struct lp_scene *scene );
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Begin/end rasterization of a scene
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_scene_begin_rasterization(struct lp_scene *scene);
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_scene_end_rasterization(struct lp_scene *scene );
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* LP_BIN_H */
404