llvmpipe: move bin-related structures and functions into new lp_bin.[ch]

And put lp_ prefixes on some functions.
This commit is contained in:
Brian Paul 2009-12-04 12:54:37 -07:00
parent 5c7d1b592a
commit d9dc3d5976
8 changed files with 243 additions and 149 deletions

View File

@ -6,6 +6,7 @@ LIBNAME = llvmpipe
CFLAGS += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS
C_SOURCES = \
lp_bin.c \
lp_bld_alpha.c \
lp_bld_arit.c \
lp_bld_blend_aos.c \

View File

@ -19,6 +19,7 @@ env.CodeGenerate(
llvmpipe = env.ConvenienceLibrary(
target = 'llvmpipe',
source = [
'lp_bin.c',
'lp_bld_alpha.c',
'lp_bld_arit.c',
'lp_bld_blend_aos.c',
@ -46,7 +47,7 @@ llvmpipe = env.ConvenienceLibrary(
'lp_flush.c',
'lp_jit.c',
'lp_prim_vbuf.c',
'lp_query.c',
'lp_query.c',
'lp_setup.c',
'lp_setup_tri.c',
'lp_setup_line.c',
@ -62,8 +63,8 @@ llvmpipe = env.ConvenienceLibrary(
'lp_state_vertex.c',
'lp_state_vs.c',
'lp_surface.c',
'lp_rast.c',
'lp_rast_tri.c',
'lp_rast.c',
'lp_rast_tri.c',
'lp_tex_sample_llvm.c',
'lp_texture.c',
'lp_tile_soa.c',

View File

@ -0,0 +1,51 @@
/**************************************************************************
*
* Copyright 2009 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "util/u_memory.h"
#include "lp_bin.h"
void
lp_bin_new_cmd_block( struct cmd_block_list *list )
{
struct cmd_block *block = MALLOC_STRUCT(cmd_block);
list->tail->next = block;
list->tail = block;
block->next = NULL;
block->count = 0;
}
void
lp_bin_new_data_block( struct data_block_list *list )
{
struct data_block *block = MALLOC_STRUCT(data_block);
list->tail->next = block;
list->tail = block;
block->next = NULL;
block->used = 0;
}

View File

@ -0,0 +1,167 @@
/**************************************************************************
*
* Copyright 2009 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
/**
* Binner data structures and bin-related functions.
* Note: the "setup" code is concerned with building bins while
* The "rast" code is concerned with consuming/executing bins.
*/
#ifndef LP_BIN_H
#define LP_BIN_H
#include "lp_rast.h"
#define CMD_BLOCK_MAX 128
#define DATA_BLOCK_SIZE (16 * 1024 - sizeof(unsigned) - sizeof(void *))
/* switch to a non-pointer value for this:
*/
typedef void (*lp_rast_cmd)( struct lp_rasterizer *, const union lp_rast_cmd_arg );
struct cmd_block {
lp_rast_cmd cmd[CMD_BLOCK_MAX];
union lp_rast_cmd_arg arg[CMD_BLOCK_MAX];
unsigned count;
struct cmd_block *next;
};
struct data_block {
ubyte data[DATA_BLOCK_SIZE];
unsigned used;
struct data_block *next;
};
struct cmd_block_list {
struct cmd_block *head;
struct cmd_block *tail;
};
/**
* For each screen tile we have one of these bins.
*/
struct cmd_bin {
struct cmd_block_list commands;
};
/**
* This stores bulk data which is shared by all bins.
* Examples include triangle data and state data. The commands in
* the per-tile bins will point to chunks of data in this structure.
*/
struct data_block_list {
struct data_block *head;
struct data_block *tail;
};
extern void lp_bin_new_data_block( struct data_block_list *list );
extern void lp_bin_new_cmd_block( struct cmd_block_list *list );
/**
* Allocate space for a command/data in the given block list.
* Grow the block list if needed.
*/
static INLINE void *
lp_bin_alloc( struct data_block_list *list, unsigned size)
{
if (list->tail->used + size > DATA_BLOCK_SIZE) {
lp_bin_new_data_block( list );
}
{
struct data_block *tail = list->tail;
ubyte *data = tail->data + tail->used;
tail->used += size;
return data;
}
}
/**
* As above, but with specific alignment.
*/
static INLINE void *
lp_bin_alloc_aligned( struct data_block_list *list, unsigned size,
unsigned alignment )
{
if (list->tail->used + size + alignment - 1 > DATA_BLOCK_SIZE) {
lp_bin_new_data_block( list );
}
{
struct data_block *tail = list->tail;
ubyte *data = tail->data + tail->used;
unsigned offset = (((uintptr_t)data + alignment - 1) & ~(alignment - 1)) - (uintptr_t)data;
tail->used += offset + size;
return data + offset;
}
}
/* Put back data if we decide not to use it, eg. culled triangles.
*/
static INLINE void
lp_bin_putback_data( struct data_block_list *list, unsigned size)
{
assert(list->tail->used >= size);
list->tail->used -= size;
}
/* Add a command to a given bin.
*/
static INLINE void
lp_bin_command( struct cmd_bin *bin,
lp_rast_cmd cmd,
union lp_rast_cmd_arg arg )
{
struct cmd_block_list *list = &bin->commands;
if (list->tail->count == CMD_BLOCK_MAX) {
lp_bin_new_cmd_block( list );
}
{
struct cmd_block *tail = list->tail;
unsigned i = tail->count;
tail->cmd[i] = cmd;
tail->arg[i] = arg;
tail->count++;
}
}
#endif /* LP_BIN_H */

View File

@ -43,6 +43,11 @@ struct pipe_screen;
#define FIXED_ONE (1<<FIXED_ORDER)
/**
* Rasterization state.
* Objects of this type are put into the shared data bin and pointed
* to by commands in the per-tile bins.
*/
struct lp_rast_state {
/* State for the shader:
*/

View File

@ -46,23 +46,6 @@
static void set_state( struct setup_context *, unsigned );
void lp_setup_new_cmd_block( struct cmd_block_list *list )
{
struct cmd_block *block = MALLOC_STRUCT(cmd_block);
list->tail->next = block;
list->tail = block;
block->next = NULL;
block->count = 0;
}
void lp_setup_new_data_block( struct data_block_list *list )
{
struct data_block *block = MALLOC_STRUCT(data_block);
list->tail->next = block;
list->tail = block;
block->next = NULL;
block->used = 0;
}
static void
@ -194,7 +177,7 @@ static void bin_everywhere( struct setup_context *setup,
unsigned i, j;
for (i = 0; i < setup->tiles_x; i++)
for (j = 0; j < setup->tiles_y; j++)
bin_command( &setup->tile[i][j], cmd, arg );
lp_bin_command( &setup->tile[i][j], cmd, arg );
}
@ -217,7 +200,7 @@ bin_state_command( struct setup_context *setup,
lp_replace_last_command_arg(bin, arg);
}
else {
bin_command( bin, cmd, arg );
lp_bin_command( bin, cmd, arg );
}
}
}
@ -594,7 +577,7 @@ lp_setup_update_shader_state( struct setup_context *setup )
uint8_t *stored;
unsigned i, j;
stored = get_data_aligned(&setup->data, 4 * 16, 16);
stored = lp_bin_alloc_aligned(&setup->data, 4 * 16, 16);
/* smear each blend color component across 16 ubyte elements */
for (i = 0; i < 4; ++i) {
@ -626,7 +609,7 @@ lp_setup_update_shader_state( struct setup_context *setup )
current_size) != 0) {
void *stored;
stored = get_data(&setup->data, current_size);
stored = lp_bin_alloc(&setup->data, current_size);
if(stored) {
memcpy(stored,
current_data,
@ -656,7 +639,7 @@ lp_setup_update_shader_state( struct setup_context *setup )
* and append it to the bin's setup data buffer.
*/
struct lp_rast_state *stored =
(struct lp_rast_state *) get_data(&setup->data, sizeof *stored);
(struct lp_rast_state *) lp_bin_alloc(&setup->data, sizeof *stored);
if(stored) {
memcpy(stored,
&setup->fs.current,

View File

@ -31,6 +31,7 @@
#include "lp_setup.h"
#include "lp_rast.h"
#include "lp_tile_soa.h" /* for TILE_SIZE */
#include "lp_bin.h"
/* We're limited to 2K by 2K for 32bit fixed point rasterization.
* Will need a 64-bit version for larger framebuffers.
@ -40,56 +41,12 @@
#define TILES_X (MAXWIDTH / TILE_SIZE)
#define TILES_Y (MAXHEIGHT / TILE_SIZE)
#define CMD_BLOCK_MAX 128
#define DATA_BLOCK_SIZE (16 * 1024 - sizeof(unsigned) - sizeof(void *))
#define LP_SETUP_NEW_FS 0x01
#define LP_SETUP_NEW_CONSTANTS 0x02
#define LP_SETUP_NEW_BLEND_COLOR 0x04
/* switch to a non-pointer value for this:
*/
typedef void (*lp_rast_cmd)( struct lp_rasterizer *, const union lp_rast_cmd_arg );
struct cmd_block {
lp_rast_cmd cmd[CMD_BLOCK_MAX];
union lp_rast_cmd_arg arg[CMD_BLOCK_MAX];
unsigned count;
struct cmd_block *next;
};
struct data_block {
ubyte data[DATA_BLOCK_SIZE];
unsigned used;
struct data_block *next;
};
struct cmd_block_list {
struct cmd_block *head;
struct cmd_block *tail;
};
/**
* For each screen tile we have one of these bins.
*/
struct cmd_bin {
struct cmd_block_list commands;
};
/**
* This stores bulk data which is shared by all bins.
* Examples include triangle data and state data. The commands in
* the per-tile bins will point to chunks of data in this structure.
*/
struct data_block_list {
struct data_block *head;
struct data_block *tail;
};
/**
* Point/line/triangle setup context.
* Note: "stored" below indicates data which is stored in the bins,
@ -174,75 +131,4 @@ void lp_setup_choose_line( struct setup_context *setup );
void lp_setup_choose_point( struct setup_context *setup );
void lp_setup_new_data_block( struct data_block_list *list );
void lp_setup_new_cmd_block( struct cmd_block_list *list );
/**
* Allocate space for a command/data in the given block list.
* Grow the block list if needed.
*/
static INLINE void *get_data( struct data_block_list *list,
unsigned size)
{
if (list->tail->used + size > DATA_BLOCK_SIZE) {
lp_setup_new_data_block( list );
}
{
struct data_block *tail = list->tail;
ubyte *data = tail->data + tail->used;
tail->used += size;
return data;
}
}
/* Put back data if we decide not to use it, eg. culled triangles.
*/
static INLINE void putback_data( struct data_block_list *list,
unsigned size)
{
list->tail->used -= size;
}
static INLINE void *get_data_aligned( struct data_block_list *list,
unsigned size,
unsigned alignment )
{
if (list->tail->used + size + alignment - 1 > DATA_BLOCK_SIZE) {
lp_setup_new_data_block( list );
}
{
struct data_block *tail = list->tail;
ubyte *data = tail->data + tail->used;
unsigned offset = (((uintptr_t)data + alignment - 1) & ~(alignment - 1)) - (uintptr_t)data;
tail->used += offset + size;
return data + offset;
}
}
/* Add a command to a given bin.
*/
static INLINE void bin_command( struct cmd_bin *bin,
lp_rast_cmd cmd,
union lp_rast_cmd_arg arg )
{
struct cmd_block_list *list = &bin->commands;
if (list->tail->count == CMD_BLOCK_MAX) {
lp_setup_new_cmd_block( list );
}
{
struct cmd_block *tail = list->tail;
unsigned i = tail->count;
tail->cmd[i] = cmd;
tail->arg[i] = arg;
tail->count++;
}
}
#endif

View File

@ -185,9 +185,9 @@ static void setup_tri_coefficients( struct setup_context *setup,
{
unsigned bytes;
bytes = (setup->fs.nr_inputs + 1) * 4 * sizeof(float);
tri->inputs.a0 = get_data_aligned( &setup->data, bytes, 16 );
tri->inputs.dadx = get_data_aligned( &setup->data, bytes, 16 );
tri->inputs.dady = get_data_aligned( &setup->data, bytes, 16 );
tri->inputs.a0 = lp_bin_alloc_aligned( &setup->data, bytes, 16 );
tri->inputs.dadx = lp_bin_alloc_aligned( &setup->data, bytes, 16 );
tri->inputs.dady = lp_bin_alloc_aligned( &setup->data, bytes, 16 );
}
/* The internal position input is in slot zero:
@ -263,7 +263,7 @@ do_triangle_ccw(struct setup_context *setup,
const int y2 = subpixel_snap(v2[0][1]);
const int y3 = subpixel_snap(v3[0][1]);
struct lp_rast_triangle *tri = get_data( &setup->data, sizeof *tri );
struct lp_rast_triangle *tri = lp_bin_alloc( &setup->data, sizeof *tri );
float area, oneoverarea;
int minx, maxx, miny, maxy;
@ -283,7 +283,7 @@ do_triangle_ccw(struct setup_context *setup,
* XXX: subject to overflow??
*/
if (area <= 0) {
putback_data( &setup->data, sizeof *tri );
lp_bin_putback_data( &setup->data, sizeof *tri );
return;
}
@ -295,7 +295,7 @@ do_triangle_ccw(struct setup_context *setup,
if (tri->miny == tri->maxy ||
tri->minx == tri->maxx) {
putback_data( &setup->data, sizeof *tri );
lp_bin_putback_data( &setup->data, sizeof *tri );
return;
}
@ -405,7 +405,7 @@ do_triangle_ccw(struct setup_context *setup,
{
/* Triangle is contained in a single tile:
*/
bin_command( &setup->tile[minx][miny], lp_rast_triangle,
lp_bin_command( &setup->tile[minx][miny], lp_rast_triangle,
lp_rast_arg_triangle(tri) );
}
else
@ -464,7 +464,7 @@ do_triangle_ccw(struct setup_context *setup,
{
in = 1;
/* triangle covers the whole tile- shade whole tile */
bin_command( &setup->tile[x][y],
lp_bin_command( &setup->tile[x][y],
lp_rast_shade_tile,
lp_rast_arg_inputs(&tri->inputs) );
}
@ -472,7 +472,7 @@ do_triangle_ccw(struct setup_context *setup,
{
in = 1;
/* shade partial tile */
bin_command( &setup->tile[x][y],
lp_bin_command( &setup->tile[x][y],
lp_rast_triangle,
lp_rast_arg_triangle(tri) );
}