Path: blob/21.2-virgl/src/gallium/drivers/llvmpipe/lp_scene.h
4570 views
/**************************************************************************1*2* Copyright 2009 VMware, Inc.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/262728/**29* Binner data structures and bin-related functions.30* Note: the "setup" code is concerned with building scenes while31* The "rast" code is concerned with consuming/executing scenes.32*/3334#ifndef LP_SCENE_H35#define LP_SCENE_H3637#include "os/os_thread.h"38#include "lp_rast.h"39#include "lp_debug.h"4041struct lp_scene_queue;42struct lp_rast_state;4344/* We're limited to 2K by 2K for 32bit fixed point rasterization.45* Will need a 64-bit version for larger framebuffers.46*/47#define TILES_X (LP_MAX_WIDTH / TILE_SIZE)48#define TILES_Y (LP_MAX_HEIGHT / TILE_SIZE)495051/* Commands per command block (ideally so sizeof(cmd_block) is a power of52* two in size.)53*/54#define CMD_BLOCK_MAX 295556/* Bytes per data block.57*/58#define DATA_BLOCK_SIZE (64 * 1024)5960/* Scene temporary storage is clamped to this size:61*/62#define LP_SCENE_MAX_SIZE (36*1024*1024)6364/* The maximum amount of texture storage referenced by a scene is65* clamped to this size:66*/67#define LP_SCENE_MAX_RESOURCE_SIZE (64*1024*1024)686970/* switch to a non-pointer value for this:71*/72typedef void (*lp_rast_cmd_func)( struct lp_rasterizer_task *,73const union lp_rast_cmd_arg );747576struct cmd_block {77uint8_t cmd[CMD_BLOCK_MAX];78union lp_rast_cmd_arg arg[CMD_BLOCK_MAX];79unsigned count;80struct cmd_block *next;81};828384struct data_block {85ubyte data[DATA_BLOCK_SIZE];86unsigned used;87struct data_block *next;88};89909192/**93* For each screen tile we have one of these bins.94*/95struct cmd_bin {96const struct lp_rast_state *last_state; /* most recent state set in bin */97struct cmd_block *head;98struct cmd_block *tail;99};100101102/**103* This stores bulk data which is used for all memory allocations104* within a scene.105*106* Examples include triangle data and state data. The commands in107* the per-tile bins will point to chunks of data in this structure.108*109* Include the first block of data statically to ensure we can always110* initiate a scene without relying on malloc succeeding.111*/112struct data_block_list {113struct data_block first;114struct data_block *head;115};116117struct resource_ref;118119struct shader_ref;120121struct lp_scene_surface {122uint8_t *map;123unsigned stride;124unsigned layer_stride;125unsigned format_bytes;126unsigned sample_stride;127unsigned nr_samples;128};129130/**131* All bins and bin data are contained here.132* Per-bin data goes into the 'tile' bins.133* Shared data goes into the 'data' buffer.134*135* When there are multiple threads, will want to double-buffer between136* scenes:137*/138struct lp_scene {139struct pipe_context *pipe;140struct lp_fence *fence;141142/* The queries still active at end of scene */143struct llvmpipe_query *active_queries[LP_MAX_ACTIVE_BINNED_QUERIES];144unsigned num_active_queries;145/* If queries were either active or there were begin/end query commands */146boolean had_queries;147148/* Framebuffer mappings - valid only between begin_rasterization()149* and end_rasterization().150*/151struct lp_scene_surface zsbuf, cbufs[PIPE_MAX_COLOR_BUFS];152153/* The amount of layers in the fb (minimum of all attachments) */154unsigned fb_max_layer;155156/* fixed point sample positions. */157int32_t fixed_sample_pos[LP_MAX_SAMPLES][2];158159/* max samples for bound framebuffer */160unsigned fb_max_samples;161162/** the framebuffer to render the scene into */163struct pipe_framebuffer_state fb;164165/** list of resources referenced by the scene commands */166struct resource_ref *resources;167168/** list of frag shaders referenced by the scene commands */169struct shader_ref *frag_shaders;170171/** Total memory used by the scene (in bytes). This sums all the172* data blocks and counts all bins, state, resource references and173* other random allocations within the scene.174*/175unsigned scene_size;176177/** Sum of sizes of all resources referenced by the scene. Sums178* all the textures read by the scene:179*/180unsigned resource_reference_size;181182boolean alloc_failed;183/**184* Number of active tiles in each dimension.185* This basically the framebuffer size divided by tile size186*/187unsigned tiles_x, tiles_y;188189int curr_x, curr_y; /**< for iterating over bins */190mtx_t mutex;191192struct cmd_bin tile[TILES_X][TILES_Y];193struct data_block_list data;194};195196197198struct lp_scene *lp_scene_create(struct pipe_context *pipe);199200void lp_scene_destroy(struct lp_scene *scene);201202boolean lp_scene_is_empty(struct lp_scene *scene );203boolean lp_scene_is_oom(struct lp_scene *scene );204205206struct data_block *lp_scene_new_data_block( struct lp_scene *scene );207208struct cmd_block *lp_scene_new_cmd_block( struct lp_scene *scene,209struct cmd_bin *bin );210211boolean lp_scene_add_resource_reference(struct lp_scene *scene,212struct pipe_resource *resource,213boolean initializing_scene);214215boolean lp_scene_is_resource_referenced(const struct lp_scene *scene,216const struct pipe_resource *resource );217218boolean lp_scene_add_frag_shader_reference(struct lp_scene *scene,219struct lp_fragment_shader_variant *variant);220221222223/**224* Allocate space for a command/data in the bin's data buffer.225* Grow the block list if needed.226*/227static inline void *228lp_scene_alloc( struct lp_scene *scene, unsigned size)229{230struct data_block_list *list = &scene->data;231struct data_block *block = list->head;232233assert(size <= DATA_BLOCK_SIZE);234assert(block != NULL);235236if (LP_DEBUG & DEBUG_MEM)237debug_printf("alloc %u block %u/%u tot %u/%u\n",238size, block->used, DATA_BLOCK_SIZE,239scene->scene_size, LP_SCENE_MAX_SIZE);240241if (block->used + size > DATA_BLOCK_SIZE) {242block = lp_scene_new_data_block( scene );243if (!block) {244/* out of memory */245return NULL;246}247}248249{250ubyte *data = block->data + block->used;251block->used += size;252return data;253}254}255256257/**258* As above, but with specific alignment.259*/260static inline void *261lp_scene_alloc_aligned( struct lp_scene *scene, unsigned size,262unsigned alignment )263{264struct data_block_list *list = &scene->data;265struct data_block *block = list->head;266267assert(block != NULL);268269if (LP_DEBUG & DEBUG_MEM)270debug_printf("alloc %u block %u/%u tot %u/%u\n",271size + alignment - 1,272block->used, DATA_BLOCK_SIZE,273scene->scene_size, LP_SCENE_MAX_SIZE);274275if (block->used + size + alignment - 1 > DATA_BLOCK_SIZE) {276block = lp_scene_new_data_block( scene );277if (!block)278return NULL;279}280281{282ubyte *data = block->data + block->used;283unsigned offset = (((uintptr_t)data + alignment - 1) & ~(alignment - 1)) - (uintptr_t)data;284block->used += offset + size;285return data + offset;286}287}288289290/* Put back data if we decide not to use it, eg. culled triangles.291*/292static inline void293lp_scene_putback_data( struct lp_scene *scene, unsigned size)294{295struct data_block_list *list = &scene->data;296assert(list->head && list->head->used >= size);297list->head->used -= size;298}299300301/** Return pointer to a particular tile's bin. */302static inline struct cmd_bin *303lp_scene_get_bin(struct lp_scene *scene, unsigned x, unsigned y)304{305return &scene->tile[x][y];306}307308309/** Remove all commands from a bin */310void311lp_scene_bin_reset(struct lp_scene *scene, unsigned x, unsigned y);312313314/* Add a command to bin[x][y].315*/316static inline boolean317lp_scene_bin_command( struct lp_scene *scene,318unsigned x, unsigned y,319unsigned cmd,320union lp_rast_cmd_arg arg )321{322struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);323struct cmd_block *tail = bin->tail;324325assert(x < scene->tiles_x);326assert(y < scene->tiles_y);327assert(cmd < LP_RAST_OP_MAX);328329if (tail == NULL || tail->count == CMD_BLOCK_MAX) {330tail = lp_scene_new_cmd_block( scene, bin );331if (!tail) {332return FALSE;333}334assert(tail->count == 0);335}336337{338unsigned i = tail->count;339tail->cmd[i] = cmd & LP_RAST_OP_MASK;340tail->arg[i] = arg;341tail->count++;342}343344return TRUE;345}346347348static inline boolean349lp_scene_bin_cmd_with_state( struct lp_scene *scene,350unsigned x, unsigned y,351const struct lp_rast_state *state,352unsigned cmd,353union lp_rast_cmd_arg arg )354{355struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);356357if (state != bin->last_state) {358bin->last_state = state;359if (!lp_scene_bin_command(scene, x, y,360LP_RAST_OP_SET_STATE,361lp_rast_arg_state(state)))362return FALSE;363}364365if (!lp_scene_bin_command( scene, x, y, cmd, arg ))366return FALSE;367368return TRUE;369}370371372/* Add a command to all active bins.373*/374static inline boolean375lp_scene_bin_everywhere( struct lp_scene *scene,376unsigned cmd,377const union lp_rast_cmd_arg arg )378{379unsigned i, j;380for (i = 0; i < scene->tiles_x; i++) {381for (j = 0; j < scene->tiles_y; j++) {382if (!lp_scene_bin_command( scene, i, j, cmd, arg ))383return FALSE;384}385}386387return TRUE;388}389390391static inline unsigned392lp_scene_get_num_bins( const struct lp_scene *scene )393{394return scene->tiles_x * scene->tiles_y;395}396397398void399lp_scene_bin_iter_begin( struct lp_scene *scene );400401struct cmd_bin *402lp_scene_bin_iter_next( struct lp_scene *scene, int *x, int *y );403404405406/* Begin/end binning of a scene407*/408void409lp_scene_begin_binning(struct lp_scene *scene,410struct pipe_framebuffer_state *fb);411412void413lp_scene_end_binning(struct lp_scene *scene);414415416/* Begin/end rasterization of a scene417*/418void419lp_scene_begin_rasterization(struct lp_scene *scene);420421void422lp_scene_end_rasterization(struct lp_scene *scene);423424425426427428#endif /* LP_BIN_H */429430431