diff options
Diffstat (limited to 'src/mesa/pipe/softpipe')
21 files changed, 431 insertions, 647 deletions
diff --git a/src/mesa/pipe/softpipe/sp_clear.c b/src/mesa/pipe/softpipe/sp_clear.c index 5b3857145d..571f64b38d 100644 --- a/src/mesa/pipe/softpipe/sp_clear.c +++ b/src/mesa/pipe/softpipe/sp_clear.c @@ -53,24 +53,19 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, softpipe_update_derived(softpipe); /* not needed?? */ #endif -#if TILE_CLEAR_OPTIMIZATION - if (ps == sp_tile_cache_get_surface(softpipe->zbuf_cache)) { - sp_tile_cache_clear(softpipe->zbuf_cache, clearValue); + if (ps == sp_tile_cache_get_surface(softpipe->zsbuf_cache)) { + sp_tile_cache_clear(softpipe->zsbuf_cache, clearValue); return; } for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) { if (ps == sp_tile_cache_get_surface(softpipe->cbuf_cache[i])) { sp_tile_cache_clear(softpipe->cbuf_cache[i], clearValue); - return; } } -#endif +#if !TILE_CLEAR_OPTIMIZATION /* non-cached surface */ pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); - -#if 0 - sp_clear_tile_cache(ps, clearValue); #endif } diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c index 68c18e2d05..cea6b90104 100644 --- a/src/mesa/pipe/softpipe/sp_context.c +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -37,6 +37,7 @@ #include "sp_context.h" #include "sp_flush.h" #include "sp_prim_setup.h" +#include "sp_prim_vbuf.h" #include "sp_state.h" #include "sp_surface.h" #include "sp_tile_cache.h" @@ -81,9 +82,7 @@ softpipe_map_surfaces(struct softpipe_context *sp) sp_tile_cache_map_surfaces(sp->cbuf_cache[i]); } - sp_tile_cache_map_surfaces(sp->zbuf_cache); - - sp_tile_cache_map_surfaces(sp->sbuf_cache); + sp_tile_cache_map_surfaces(sp->zsbuf_cache); } @@ -97,16 +96,12 @@ softpipe_unmap_surfaces(struct softpipe_context *sp) for (i = 0; i < sp->framebuffer.num_cbufs; i++) sp_flush_tile_cache(sp, sp->cbuf_cache[i]); - sp_flush_tile_cache(sp, sp->zbuf_cache); - sp_flush_tile_cache(sp, sp->sbuf_cache); + sp_flush_tile_cache(sp, sp->zsbuf_cache); for (i = 0; i < sp->framebuffer.num_cbufs; i++) { sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]); } - - sp_tile_cache_unmap_surfaces(sp->zbuf_cache); - - sp_tile_cache_unmap_surfaces(sp->sbuf_cache); + sp_tile_cache_unmap_surfaces(sp->zsbuf_cache); } @@ -133,15 +128,14 @@ static void softpipe_destroy( struct pipe_context *pipe ) for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) sp_destroy_tile_cache(softpipe->cbuf_cache[i]); - sp_destroy_tile_cache(softpipe->zbuf_cache); - sp_destroy_tile_cache(softpipe->sbuf_cache_sep); + sp_destroy_tile_cache(softpipe->zsbuf_cache); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) sp_destroy_tile_cache(softpipe->tex_cache[i]); for (i = 0; i < Elements(softpipe->constants); i++) { if (softpipe->constants[i].buffer) { - ws->buffer_reference(ws, &softpipe->constants[i].buffer, NULL); + pipe_buffer_reference(ws, &softpipe->constants[i].buffer, NULL); } } @@ -297,9 +291,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, */ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) softpipe->cbuf_cache[i] = sp_create_tile_cache(); - softpipe->zbuf_cache = sp_create_tile_cache(); - softpipe->sbuf_cache_sep = sp_create_tile_cache(); - softpipe->sbuf_cache = softpipe->sbuf_cache_sep; /* initial value */ + softpipe->zsbuf_cache = sp_create_tile_cache(); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) softpipe->tex_cache[i] = sp_create_tile_cache(); @@ -329,11 +321,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, softpipe->setup = sp_draw_render_stage(softpipe); if (GETENV( "SP_VBUF" ) != NULL) { - softpipe->vbuf = sp_draw_vbuf_stage(softpipe->draw, - &softpipe->pipe, - sp_vbuf_render); - - draw_set_rasterize_stage(softpipe->draw, softpipe->vbuf); + sp_init_vbuf(softpipe); } else { draw_set_rasterize_stage(softpipe->draw, softpipe->setup); diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h index 3537f86a61..aff8c2cc5d 100644 --- a/src/mesa/pipe/softpipe/sp_context.h +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -40,6 +40,7 @@ struct softpipe_winsys; +struct softpipe_vbuf_render; struct draw_context; struct draw_stage; struct softpipe_tile_cache; @@ -88,8 +89,8 @@ struct softpipe_context { /** Vertex format */ struct vertex_info vertex_info; - unsigned attr_mask; - unsigned nr_frag_attrs; /**< number of active fragment attribs */ + struct vertex_info vertex_info_vbuf; + int psize_slot; #if 0 @@ -125,15 +126,12 @@ struct softpipe_context { struct draw_context *draw; struct draw_stage *setup; struct draw_stage *vbuf; + struct softpipe_vbuf_render *vbuf_render; uint current_cbuf; /**< current color buffer being written to */ struct softpipe_tile_cache *cbuf_cache[PIPE_MAX_COLOR_BUFS]; - struct softpipe_tile_cache *zbuf_cache; - /** Stencil buffer cache, for stencil separate from Z */ - struct softpipe_tile_cache *sbuf_cache_sep; - /** This either points to zbuf_cache or sbuf_cache_sep */ - struct softpipe_tile_cache *sbuf_cache; + struct softpipe_tile_cache *zsbuf_cache; struct softpipe_tile_cache *tex_cache[PIPE_MAX_SAMPLERS]; diff --git a/src/mesa/pipe/softpipe/sp_draw_arrays.c b/src/mesa/pipe/softpipe/sp_draw_arrays.c index b7626f8a5f..71a303a8b5 100644 --- a/src/mesa/pipe/softpipe/sp_draw_arrays.c +++ b/src/mesa/pipe/softpipe/sp_draw_arrays.c @@ -50,7 +50,7 @@ softpipe_map_constant_buffers(struct softpipe_context *sp) for (i = 0; i < 2; i++) { if (sp->constants[i].size) sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i].buffer, - PIPE_BUFFER_FLAG_READ); + PIPE_BUFFER_USAGE_CPU_READ); } draw_set_mapped_constant_buffer(sp->draw, @@ -88,7 +88,7 @@ softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, */ boolean softpipe_draw_elements(struct pipe_context *pipe, - struct pipe_buffer_handle *indexBuffer, + struct pipe_buffer *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count) { @@ -122,7 +122,7 @@ softpipe_draw_elements(struct pipe_context *pipe, void *buf = pipe->winsys->buffer_map(pipe->winsys, sp->vertex_buffer[i].buffer, - PIPE_BUFFER_FLAG_READ); + PIPE_BUFFER_USAGE_CPU_READ); draw_set_mapped_vertex_buffer(draw, i, buf); } } @@ -130,7 +130,7 @@ softpipe_draw_elements(struct pipe_context *pipe, if (indexBuffer) { void *mapped_indexes = pipe->winsys->buffer_map(pipe->winsys, indexBuffer, - PIPE_BUFFER_FLAG_READ); + PIPE_BUFFER_USAGE_CPU_READ); draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes); } else { @@ -142,21 +142,18 @@ softpipe_draw_elements(struct pipe_context *pipe, /* draw! */ draw_arrays(draw, mode, start, count); - /* always flush for now */ - draw_flush(draw); - /* - * unmap vertex/index buffers + * unmap vertex/index buffers - will cause draw module to flush */ for (i = 0; i < PIPE_ATTRIB_MAX; i++) { if (sp->vertex_buffer[i].buffer) { - pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer); draw_set_mapped_vertex_buffer(draw, i, NULL); + pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer); } } if (indexBuffer) { - pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer); draw_set_mapped_element_buffer(draw, 0, NULL); + pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer); } diff --git a/src/mesa/pipe/softpipe/sp_flush.c b/src/mesa/pipe/softpipe/sp_flush.c index 47b11803ce..ec6bb4a0dc 100644 --- a/src/mesa/pipe/softpipe/sp_flush.c +++ b/src/mesa/pipe/softpipe/sp_flush.c @@ -59,11 +59,8 @@ softpipe_flush( struct pipe_context *pipe, if (softpipe->cbuf_cache[i]) sp_flush_tile_cache(softpipe, softpipe->cbuf_cache[i]); - if (softpipe->zbuf_cache) - sp_flush_tile_cache(softpipe, softpipe->zbuf_cache); - - if (softpipe->sbuf_cache) - sp_flush_tile_cache(softpipe, softpipe->sbuf_cache); + if (softpipe->zsbuf_cache) + sp_flush_tile_cache(softpipe, softpipe->zsbuf_cache); /* Need this call for hardware buffers before swapbuffers. * diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.c b/src/mesa/pipe/softpipe/sp_prim_setup.c index cdc385e4db..b17801d13d 100644 --- a/src/mesa/pipe/softpipe/sp_prim_setup.c +++ b/src/mesa/pipe/softpipe/sp_prim_setup.c @@ -85,8 +85,6 @@ struct setup_stage { struct tgsi_interp_coef posCoef; /* For Z, W */ struct quad_header quad; - uint firstFpInput; /** Semantic type of first frag input */ - struct { int left[2]; /**< [0] = row0, [1] = row1 */ int right[2]; @@ -515,11 +513,8 @@ setup_fragcoord_coeff(struct setup_stage *setup) */ static void setup_tri_coefficients( struct setup_stage *setup ) { - const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode; -#define USE_INPUT_MAP 01 -#if USE_INPUT_MAP - const struct pipe_shader_state *fs = &setup->softpipe->fs->shader; -#endif + const struct softpipe_context *softpipe = setup->softpipe; + const struct pipe_shader_state *fs = &softpipe->fs->shader; uint fragSlot; /* z and w are done by linear interpolation: @@ -529,64 +524,37 @@ static void setup_tri_coefficients( struct setup_stage *setup ) /* setup interpolation for all the remaining attributes: */ - for (fragSlot = 0; fragSlot < setup->quad.nr_attrs; fragSlot++) { - /* which vertex output maps to this fragment input: */ -#if !USE_INPUT_MAP - uint vertSlot; - if (setup->firstFpInput == TGSI_SEMANTIC_POSITION) { - if (fragSlot == 0) { - setup_fragcoord_coeff(setup); - continue; - } - vertSlot = fragSlot; - } - else { - vertSlot = fragSlot + 1; - } - -#else - uint vertSlot = fs->input_map[fragSlot]; - - if (vertSlot == 0) { - /* special case: shader is reading gl_FragCoord */ - /* XXX with a new INTERP_POSITION token, we could just add a - * new case to the switch below. - */ + for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) { + const uint vertSlot = softpipe->vertex_info.src_index[fragSlot]; + uint j; + + switch (softpipe->vertex_info.interp_mode[fragSlot]) { + case INTERP_CONSTANT: + for (j = 0; j < NUM_CHANNELS; j++) + const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_LINEAR: + for (j = 0; j < NUM_CHANNELS; j++) + tri_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_PERSPECTIVE: + for (j = 0; j < NUM_CHANNELS; j++) + tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_POS: + assert(fragSlot == 0); setup_fragcoord_coeff(setup); + break; + default: + assert(0); } - else { -#endif - uint j; - switch (interp[vertSlot]) { - case INTERP_CONSTANT: - for (j = 0; j < NUM_CHANNELS; j++) - const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); - break; - case INTERP_LINEAR: - for (j = 0; j < NUM_CHANNELS; j++) - tri_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); - break; - case INTERP_PERSPECTIVE: - for (j = 0; j < NUM_CHANNELS; j++) - tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); - break; - default: - /* invalid interp mode */ - /* assert(0); re-enable this and run demos/fogcoord.c ... */ - ; - } - if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { - /* FOG.y = front/back facing XXX fix this */ - setup->coef[fragSlot].a0[1] = 1 - setup->quad.facing; - setup->coef[fragSlot].dadx[1] = 0.0; - setup->coef[fragSlot].dady[1] = 0.0; - } - - -#if USE_INPUT_MAP + if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { + /* FOG.y = front/back facing XXX fix this */ + setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing; + setup->coef[fragSlot].dadx[1] = 0.0; + setup->coef[fragSlot].dady[1] = 0.0; } -#endif } } @@ -788,9 +756,9 @@ line_persp_coeff(struct setup_stage *setup, static INLINE void setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim) { - const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode; + const struct softpipe_context *softpipe = setup->softpipe; const struct pipe_shader_state *fs = &setup->softpipe->fs->shader; - unsigned fragSlot; + uint fragSlot; /* use setup->vmin, vmax to point to vertices */ setup->vprovoke = prim->v[1]; @@ -810,34 +778,37 @@ setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim) /* setup interpolation for all the remaining attributes: */ - for (fragSlot = 0; fragSlot < setup->quad.nr_attrs; fragSlot++) { - /* which vertex output maps to this fragment input: */ - uint vertSlot = fs->input_map[fragSlot]; - - if (vertSlot == 0) { - /* special case: shader is reading gl_FragCoord */ + for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) { + const uint vertSlot = softpipe->vertex_info.src_index[fragSlot]; + uint j; + + switch (softpipe->vertex_info.interp_mode[fragSlot]) { + case INTERP_CONSTANT: + for (j = 0; j < NUM_CHANNELS; j++) + const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_LINEAR: + for (j = 0; j < NUM_CHANNELS; j++) + line_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_PERSPECTIVE: + for (j = 0; j < NUM_CHANNELS; j++) + line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_POS: + assert(fragSlot == 0); + assert(0); /* XXX fix this: */ setup_fragcoord_coeff(setup); + break; + default: + assert(0); } - else { - uint j; - switch (interp[vertSlot]) { - case INTERP_CONSTANT: - for (j = 0; j < NUM_CHANNELS; j++) - const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); - break; - case INTERP_LINEAR: - for (j = 0; j < NUM_CHANNELS; j++) - line_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); - break; - case INTERP_PERSPECTIVE: - for (j = 0; j < NUM_CHANNELS; j++) - line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); - break; - - default: - /* invalid interp mode */ - assert(0); - } + + if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { + /* FOG.y = front/back facing XXX fix this */ + setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing; + setup->coef[fragSlot].dadx[1] = 0.0; + setup->coef[fragSlot].dady[1] = 0.0; } } } @@ -996,8 +967,8 @@ static void setup_point(struct draw_stage *stage, struct prim_header *prim) { struct setup_stage *setup = setup_stage( stage ); - const struct pipe_shader_state *fs = &setup->softpipe->fs->shader; - const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode; + struct softpipe_context *softpipe = setup->softpipe; + const struct pipe_shader_state *fs = &softpipe->fs->shader; const struct vertex_header *v0 = prim->v[0]; const int sizeAttr = setup->softpipe->psize_slot; const float size @@ -1031,31 +1002,36 @@ setup_point(struct draw_stage *stage, struct prim_header *prim) const_coeff(setup, &setup->posCoef, 0, 2); const_coeff(setup, &setup->posCoef, 0, 3); - for (fragSlot = 0; fragSlot < setup->quad.nr_attrs; fragSlot++) { - /* which vertex output maps to this fragment input: */ - uint vertSlot = fs->input_map[fragSlot]; - - if (vertSlot == 0) { - /* special case: shader is reading gl_FragCoord */ + for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) { + const uint vertSlot = softpipe->vertex_info.src_index[fragSlot]; + uint j; + + switch (softpipe->vertex_info.interp_mode[fragSlot]) { + case INTERP_CONSTANT: + /* fall-through */ + case INTERP_LINEAR: + for (j = 0; j < NUM_CHANNELS; j++) + const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_PERSPECTIVE: + for (j = 0; j < NUM_CHANNELS; j++) + point_persp_coeff(setup, setup->vprovoke, + &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_POS: + assert(fragSlot == 0); + assert(0); /* XXX fix this: */ setup_fragcoord_coeff(setup); + break; + default: + assert(0); } - else { - uint j; - switch (interp[vertSlot]) { - case INTERP_CONSTANT: - /* fall-through */ - case INTERP_LINEAR: - for (j = 0; j < NUM_CHANNELS; j++) - const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); - break; - case INTERP_PERSPECTIVE: - for (j = 0; j < NUM_CHANNELS; j++) - point_persp_coeff(setup, setup->vprovoke, - &setup->coef[fragSlot], vertSlot, j); - break; - default: - assert(0); - } + + if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { + /* FOG.y = front/back facing XXX fix this */ + setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing; + setup->coef[fragSlot].dadx[1] = 0.0; + setup->coef[fragSlot].dady[1] = 0.0; } } @@ -1191,16 +1167,46 @@ static void setup_begin( struct draw_stage *stage ) struct softpipe_context *sp = setup->softpipe; const struct pipe_shader_state *fs = &setup->softpipe->fs->shader; - setup->quad.nr_attrs = setup->softpipe->nr_frag_attrs; - - setup->firstFpInput = fs->input_semantic_name[0]; + setup->quad.nr_attrs = fs->num_inputs; sp->quad.first->begin(sp->quad.first); + + stage->point = setup_point; + stage->line = setup_line; + stage->tri = setup_tri; } -static void setup_end( struct draw_stage *stage ) +static void setup_first_point( struct draw_stage *stage, + struct prim_header *header ) { + setup_begin(stage); + stage->point( stage, header ); +} + +static void setup_first_line( struct draw_stage *stage, + struct prim_header *header ) +{ + setup_begin(stage); + stage->line( stage, header ); +} + + +static void setup_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + setup_begin(stage); + stage->tri( stage, header ); +} + + + +static void setup_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->point = setup_first_point; + stage->line = setup_first_line; + stage->tri = setup_first_tri; } @@ -1224,11 +1230,10 @@ struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe ) setup->softpipe = softpipe; setup->stage.draw = softpipe->draw; - setup->stage.begin = setup_begin; - setup->stage.point = setup_point; - setup->stage.line = setup_line; - setup->stage.tri = setup_tri; - setup->stage.end = setup_end; + setup->stage.point = setup_first_point; + setup->stage.line = setup_first_line; + setup->stage.tri = setup_first_tri; + setup->stage.flush = setup_flush; setup->stage.reset_stipple_counter = reset_stipple_counter; setup->stage.destroy = render_destroy; @@ -1237,87 +1242,3 @@ struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe ) return &setup->stage; } - - -/* Recalculate det. This is only used in the test harness below: - */ -static void calc_det( struct prim_header *header ) -{ - /* Window coords: */ - const float *v0 = header->v[0]->data[0]; - const float *v1 = header->v[1]->data[0]; - const float *v2 = header->v[2]->data[0]; - - /* edge vectors e = v0 - v2, f = v1 - v2 */ - const float ex = v0[0] - v2[0]; - const float ey = v0[1] - v2[1]; - const float fx = v1[0] - v2[0]; - const float fy = v1[1] - v2[1]; - - /* det = cross(e,f).z */ - header->det = ex * fy - ey * fx; -} - - - -/** - * Render buffer of points/lines/triangles. - * Called by vbuf code when the vertex or index buffer is filled. - * - * The big issue at this point is that reset_stipple doesn't make it - * through the interface. Probably need to split primitives at reset - * stipple, perhaps using the ~0 index marker. - */ -void sp_vbuf_render( struct pipe_context *pipe, - unsigned primitive, - const ushort *elements, - unsigned nr_elements, - const void *vertex_buffer, - unsigned nr_vertices ) -{ - struct softpipe_context *softpipe = softpipe_context( pipe ); - struct setup_stage *setup = setup_stage( softpipe->setup ); - struct prim_header prim; - unsigned vertex_size = setup->stage.draw->vertex_info.size * sizeof(float); - unsigned i, j; - - prim.det = 0; - prim.reset_line_stipple = 0; - prim.edgeflags = 0; - prim.pad = 0; - - setup->stage.begin( &setup->stage ); - - switch (primitive) { - case PIPE_PRIM_TRIANGLES: - for (i = 0; i < nr_elements; i += 3) { - for (j = 0; j < 3; j++) - prim.v[j] = (struct vertex_header *)((char *)vertex_buffer + - elements[i+j] * vertex_size); - - calc_det(&prim); - setup->stage.tri( &setup->stage, &prim ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 0; i < nr_elements; i += 2) { - for (j = 0; j < 2; j++) - prim.v[j] = (struct vertex_header *)((char *)vertex_buffer + - elements[i+j] * vertex_size); - - setup->stage.line( &setup->stage, &prim ); - } - break; - - case PIPE_PRIM_POINTS: - for (i = 0; i < nr_elements; i++) { - prim.v[0] = (struct vertex_header *)((char *)vertex_buffer + - elements[i] * vertex_size); - setup->stage.point( &setup->stage, &prim ); - } - break; - } - - setup->stage.end( &setup->stage ); -} diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.h b/src/mesa/pipe/softpipe/sp_prim_setup.h index c16dc634b0..f3e8a79dd9 100644 --- a/src/mesa/pipe/softpipe/sp_prim_setup.h +++ b/src/mesa/pipe/softpipe/sp_prim_setup.h @@ -76,14 +76,4 @@ sp_draw_vbuf_stage( struct draw_context *draw_context, vbuf_draw_func draw ); -extern void -sp_vbuf_render( struct pipe_context *pipe, - unsigned prim, - const ushort *elements, - unsigned nr_elements, - const void *vertex_buffer, - unsigned nr_vertices ); - - - #endif /* SP_PRIM_SETUP_H */ diff --git a/src/mesa/pipe/softpipe/sp_prim_vbuf.c b/src/mesa/pipe/softpipe/sp_prim_vbuf.c index 055cb19f9a..c9089e7eb2 100644 --- a/src/mesa/pipe/softpipe/sp_prim_vbuf.c +++ b/src/mesa/pipe/softpipe/sp_prim_vbuf.c @@ -2,7 +2,7 @@ * * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 @@ -26,299 +26,197 @@ **************************************************************************/ /** - * Build post-transformation, post-clipping vertex buffers and element - * lists by hooking into the end of the primitive pipeline and - * manipulating the vertex_id field in the vertex headers. - * - * Keith Whitwell <keith@tungstengraphics.com> + * Post-transform vertex buffering. This is an optional part of the + * softpipe rendering pipeline. + * Probably not desired in general, but useful for testing/debuggin. + * Enabled/Disabled with SP_VBUF env var. + * + * Authors + * Brian Paul */ #include "sp_context.h" -#include "sp_headers.h" -#include "sp_quad.h" -#include "sp_prim_setup.h" +#include "sp_prim_vbuf.h" +#include "pipe/draw/draw_context.h" #include "pipe/draw/draw_private.h" -#include "pipe/draw/draw_vertex.h" -#include "pipe/p_util.h" - -static void vbuf_flush_elements( struct draw_stage *stage ); +#include "pipe/draw/draw_vbuf.h" -#define VBUF_SIZE (64*1024) -#define IBUF_SIZE (16*1024) +#define SP_MAX_VBUF_INDEXES 1024 +#define SP_MAX_VBUF_SIZE 4096 /** - * Vertex buffer emit stage. + * Subclass of vbuf_render. */ -struct vbuf_stage { - struct draw_stage stage; /**< This must be first (base class) */ - - struct draw_context *draw_context; - struct pipe_context *pipe; - vbuf_draw_func draw; - - /* Vertices are passed in as an array of floats making up each - * attribute in turn. Will eventually convert to hardware format - * in this stage. - */ - char *vertex_map; - char *vertex_ptr; - unsigned vertex_size; - unsigned nr_vertices; - - unsigned max_vertices; - - ushort *element_map; - unsigned nr_elements; - - unsigned prim; - -}; - -/** - * Basically a cast wrapper. - */ -static INLINE struct vbuf_stage *vbuf_stage( struct draw_stage *stage ) +struct softpipe_vbuf_render { - return (struct vbuf_stage *)stage; -} - - + struct vbuf_render base; + struct softpipe_context *softpipe; + uint prim; + uint vertex_size; + void *vertex_buffer; +}; -static boolean overflow( void *map, void *ptr, unsigned bytes, unsigned bufsz ) +/** cast wrapper */ +static struct softpipe_vbuf_render * +softpipe_vbuf_render(struct vbuf_render *vbr) { - unsigned long used = (unsigned long) ((char *) ptr - (char *) map); - return (used + bytes) > bufsz; + return (struct softpipe_vbuf_render *) vbr; } -static boolean check_space( struct vbuf_stage *vbuf ) -{ - if (overflow( vbuf->vertex_map, - vbuf->vertex_ptr, - 4 * vbuf->vertex_size, - VBUF_SIZE )) - return FALSE; - - if (vbuf->nr_elements + 4 > IBUF_SIZE / sizeof(ushort) ) - return FALSE; - - return TRUE; -} - - -static void emit_vertex( struct vbuf_stage *vbuf, - struct vertex_header *vertex ) +static const struct vertex_info * +sp_vbuf_get_vertex_info(struct vbuf_render *vbr) { -// fprintf(stderr, "emit vertex %d to %p\n", -// vbuf->nr_vertices, vbuf->vertex_ptr); - - vertex->vertex_id = vbuf->nr_vertices++; - - //vbuf->emit_vertex( vbuf->vertex_ptr, vertex ); - - /* Note: for softpipe, the vertex includes the vertex header info - * such as clip flags and clip coords. In the future when vbuf is - * always used, we could just copy the vertex attributes/data here. - * The sp_prim_setup.c code doesn't use any of the vertex header info. - */ - memcpy(vbuf->vertex_ptr, vertex, vbuf->vertex_size); - - vbuf->vertex_ptr += vbuf->vertex_size; + struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); + /* XXX check for state changes? */ + assert(!cvbr->softpipe->dirty ); + return &cvbr->softpipe->vertex_info_vbuf; } - -/** - * - */ -static void vbuf_tri( struct draw_stage *stage, - struct prim_header *prim ) +static void * +sp_vbuf_allocate_vertices(struct vbuf_render *vbr, + ushort vertex_size, ushort nr_vertices) { - struct vbuf_stage *vbuf = vbuf_stage( stage ); - unsigned i; - - if (!check_space( vbuf )) - vbuf_flush_elements( stage ); - - for (i = 0; i < 3; i++) { - if (prim->v[i]->vertex_id == UNDEFINED_VERTEX_ID) - emit_vertex( vbuf, prim->v[i] ); - - vbuf->element_map[vbuf->nr_elements++] = (ushort) prim->v[i]->vertex_id; - } + struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); + assert(!cvbr->vertex_buffer); + cvbr->vertex_buffer = align_malloc(vertex_size * nr_vertices, 16); + cvbr->vertex_size = vertex_size; + return cvbr->vertex_buffer; } -static void vbuf_line(struct draw_stage *stage, - struct prim_header *prim) +static void +sp_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices, + unsigned vertex_size, unsigned vertices_used) { - struct vbuf_stage *vbuf = vbuf_stage( stage ); - unsigned i; - - if (!check_space( vbuf )) - vbuf_flush_elements( stage ); - - for (i = 0; i < 2; i++) { - if (prim->v[i]->vertex_id == UNDEFINED_VERTEX_ID) - emit_vertex( vbuf, prim->v[i] ); - - vbuf->element_map[vbuf->nr_elements++] = (ushort) prim->v[i]->vertex_id; - } + struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); + align_free(vertices); + assert(vertices == cvbr->vertex_buffer); + cvbr->vertex_buffer = NULL; } -static void vbuf_point(struct draw_stage *stage, - struct prim_header *prim) +static void +sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) { - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - if (!check_space( vbuf )) - vbuf_flush_elements( stage ); - - if (prim->v[0]->vertex_id == UNDEFINED_VERTEX_ID) - emit_vertex( vbuf, prim->v[0] ); - - vbuf->element_map[vbuf->nr_elements++] = (ushort) prim->v[0]->vertex_id; -} - - -static void vbuf_first_tri( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - vbuf_flush_elements( stage ); - stage->tri = vbuf_tri; - stage->tri( stage, prim ); - vbuf->prim = PIPE_PRIM_TRIANGLES; -} - -static void vbuf_first_line( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - vbuf_flush_elements( stage ); - stage->line = vbuf_line; - stage->line( stage, prim ); - vbuf->prim = PIPE_PRIM_LINES; + struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); + cvbr->prim = prim; } -static void vbuf_first_point( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - vbuf_flush_elements( stage ); - stage->point = vbuf_point; - stage->point( stage, prim ); - vbuf->prim = PIPE_PRIM_POINTS; -} - - - -static void vbuf_flush_elements( struct draw_stage *stage ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - if (vbuf->nr_elements) { - /* - fprintf(stderr, "%s (%d elts)\n", __FUNCTION__, vbuf->nr_elements); - */ - - /* Draw now or add to list of primitives??? - */ - vbuf->draw( vbuf->pipe, - vbuf->prim, - vbuf->element_map, - vbuf->nr_elements, - vbuf->vertex_map, - (unsigned) (vbuf->vertex_ptr - vbuf->vertex_map) / vbuf->vertex_size ); - - vbuf->nr_elements = 0; - - vbuf->vertex_ptr = vbuf->vertex_map; - vbuf->nr_vertices = 0; - - /* Reset vertex ids? Actually, want to not do that unless our - * vertex buffer is full. Would like separate - * flush-on-index-full and flush-on-vb-full, but may raise - * issues uploading vertices if the hardware wants to flush when - * we flush. - */ - draw_reset_vertex_ids( vbuf->draw_context ); +/** + * Recalculate prim's determinant. + * XXX is this needed? + */ +static void +calc_det(struct prim_header *header) +{ + /* Window coords: */ + const float *v0 = header->v[0]->data[0]; + const float *v1 = header->v[1]->data[0]; + const float *v2 = header->v[2]->data[0]; + + /* edge vectors e = v0 - v2, f = v1 - v2 */ + const float ex = v0[0] - v2[0]; + const float ey = v0[1] - v2[1]; + const float fx = v1[0] - v2[0]; + const float fy = v1[1] - v2[1]; + + /* det = cross(e,f).z */ + header->det = ex * fy - ey * fx; +} + + +static void +sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices) +{ + struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); + struct softpipe_context *softpipe = cvbr->softpipe; + struct draw_stage *setup = softpipe->setup; + struct prim_header prim; + unsigned vertex_size = softpipe->vertex_info_vbuf.size * sizeof(float); + unsigned i, j; + void *vertex_buffer = cvbr->vertex_buffer; + + prim.det = 0; + prim.reset_line_stipple = 0; + prim.edgeflags = 0; + prim.pad = 0; + + switch (cvbr->prim) { + case PIPE_PRIM_TRIANGLES: + for (i = 0; i < nr_indices; i += 3) { + for (j = 0; j < 3; j++) + prim.v[j] = (struct vertex_header *)((char *)vertex_buffer + + indices[i+j] * vertex_size); + + calc_det(&prim); + setup->tri( setup, &prim ); + } + break; + + case PIPE_PRIM_LINES: + for (i = 0; i < nr_indices; i += 2) { + for (j = 0; j < 2; j++) + prim.v[j] = (struct vertex_header *)((char *)vertex_buffer + + indices[i+j] * vertex_size); + + setup->line( setup, &prim ); + } + break; + + case PIPE_PRIM_POINTS: + for (i = 0; i < nr_indices; i++) { + prim.v[0] = (struct vertex_header *)((char *)vertex_buffer + + indices[i] * vertex_size); + setup->point( setup, &prim ); + } + break; } - stage->tri = vbuf_first_tri; - stage->line = vbuf_first_line; - stage->point = vbuf_first_point; + setup->flush( setup, 0 ); } -static void vbuf_begin( struct draw_stage *stage ) +static void +sp_vbuf_destroy(struct vbuf_render *vbr) { - struct vbuf_stage *vbuf = vbuf_stage(stage); - - vbuf->vertex_size = vbuf->draw_context->vertex_info.size * sizeof(float); + struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); + cvbr->softpipe->vbuf_render = NULL; + FREE(cvbr); } -static void vbuf_end( struct draw_stage *stage ) -{ - /* Overkill. - */ - vbuf_flush_elements( stage ); -} - - -static void reset_stipple_counter( struct draw_stage *stage ) +/** + * Initialize the post-transform vertex buffer information for the given + * context. + */ +void +sp_init_vbuf(struct softpipe_context *sp) { - /* XXX: This doesn't work. - */ -} + assert(sp->draw); + sp->vbuf_render = CALLOC_STRUCT(softpipe_vbuf_render); -static void vbuf_destroy( struct draw_stage *stage ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); + sp->vbuf_render->base.max_indices = SP_MAX_VBUF_INDEXES; + sp->vbuf_render->base.max_vertex_buffer_bytes = SP_MAX_VBUF_SIZE; - FREE( vbuf->element_map ); - FREE( vbuf->vertex_map ); - FREE( stage ); -} + sp->vbuf_render->base.get_vertex_info = sp_vbuf_get_vertex_info; + sp->vbuf_render->base.allocate_vertices = sp_vbuf_allocate_vertices; + sp->vbuf_render->base.set_primitive = sp_vbuf_set_primitive; + sp->vbuf_render->base.draw = sp_vbuf_draw; + sp->vbuf_render->base.release_vertices = sp_vbuf_release_vertices; + sp->vbuf_render->base.destroy = sp_vbuf_destroy; + sp->vbuf_render->softpipe = sp; -/** - * Create a new primitive vbuf/render stage. - */ -struct draw_stage *sp_draw_vbuf_stage( struct draw_context *draw_context, - struct pipe_context *pipe, - vbuf_draw_func draw ) -{ - struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage); - - vbuf->stage.begin = vbuf_begin; - vbuf->stage.point = vbuf_first_point; - vbuf->stage.line = vbuf_first_line; - vbuf->stage.tri = vbuf_first_tri; - vbuf->stage.end = vbuf_end; - vbuf->stage.reset_stipple_counter = reset_stipple_counter; - vbuf->stage.destroy = vbuf_destroy; - - vbuf->pipe = pipe; - vbuf->draw = draw; - vbuf->draw_context = draw_context; - - vbuf->element_map = MALLOC( IBUF_SIZE ); - vbuf->vertex_map = MALLOC( VBUF_SIZE ); - - vbuf->vertex_ptr = vbuf->vertex_map; - + sp->vbuf = draw_vbuf_stage(sp->draw, &sp->vbuf_render->base); - return &vbuf->stage; + draw_set_rasterize_stage(sp->draw, sp->vbuf); } diff --git a/src/mesa/pipe/softpipe/sp_prim_vbuf.h b/src/mesa/pipe/softpipe/sp_prim_vbuf.h new file mode 100644 index 0000000000..1de9cc2a89 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_prim_vbuf.h @@ -0,0 +1,38 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + +#ifndef SP_VBUF_H +#define SP_VBUF_H + + +struct softpipe_context; + +extern void +sp_init_vbuf(struct softpipe_context *softpipe); + + +#endif /* SP_VBUF_H */ diff --git a/src/mesa/pipe/softpipe/sp_quad.c b/src/mesa/pipe/softpipe/sp_quad.c index a10c9c3e02..6bd468a51c 100644 --- a/src/mesa/pipe/softpipe/sp_quad.c +++ b/src/mesa/pipe/softpipe/sp_quad.c @@ -48,7 +48,7 @@ sp_build_depth_stencil( sp_push_quad_first( sp, sp->quad.stencil_test ); } else if (sp->depth_stencil->depth.enabled && - sp->framebuffer.zbuf) { + sp->framebuffer.zsbuf) { sp_push_quad_first( sp, sp->quad.depth_test ); } } @@ -58,7 +58,7 @@ sp_build_quad_pipeline(struct softpipe_context *sp) { boolean early_depth_test = sp->depth_stencil->depth.enabled && - sp->framebuffer.zbuf && + sp->framebuffer.zsbuf && !sp->depth_stencil->alpha.enabled && sp->fs->shader.output_semantic_name[0] != TGSI_SEMANTIC_POSITION; diff --git a/src/mesa/pipe/softpipe/sp_quad_depth_test.c b/src/mesa/pipe/softpipe/sp_quad_depth_test.c index 1b8a2960af..a9a0754f27 100644 --- a/src/mesa/pipe/softpipe/sp_quad_depth_test.c +++ b/src/mesa/pipe/softpipe/sp_quad_depth_test.c @@ -53,14 +53,14 @@ void sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) { struct softpipe_context *softpipe = qs->softpipe; - struct pipe_surface *ps = softpipe->framebuffer.zbuf; + struct pipe_surface *ps = softpipe->framebuffer.zsbuf; const enum pipe_format format = ps->format; unsigned bzzzz[QUAD_SIZE]; /**< Z values fetched from depth buffer */ unsigned qzzzz[QUAD_SIZE]; /**< Z values from the quad */ unsigned zmask = 0; unsigned j; struct softpipe_cached_tile *tile - = sp_get_cached_tile(softpipe, softpipe->zbuf_cache, quad->x0, quad->y0); + = sp_get_cached_tile(softpipe, softpipe->zsbuf_cache, quad->x0, quad->y0); assert(ps); /* shouldn't get here if there's no zbuffer */ diff --git a/src/mesa/pipe/softpipe/sp_quad_fs.c b/src/mesa/pipe/softpipe/sp_quad_fs.c index 0001c76a80..c9cc8afa0c 100644 --- a/src/mesa/pipe/softpipe/sp_quad_fs.c +++ b/src/mesa/pipe/softpipe/sp_quad_fs.c @@ -356,7 +356,12 @@ struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ) qss->stage.softpipe = softpipe; qss->stage.begin = shade_begin; #ifdef MESA_LLVM + /* disable until ported to accept + * x/y and soa layout qss->stage.run = shade_quad_llvm; + */ + softpipe->use_sse = FALSE; + qss->stage.run = shade_quad; #else qss->stage.run = shade_quad; #endif diff --git a/src/mesa/pipe/softpipe/sp_quad_stencil.c b/src/mesa/pipe/softpipe/sp_quad_stencil.c index 33740883d3..92a0da0083 100644 --- a/src/mesa/pipe/softpipe/sp_quad_stencil.c +++ b/src/mesa/pipe/softpipe/sp_quad_stencil.c @@ -201,12 +201,12 @@ static void stencil_test_quad(struct quad_stage *qs, struct quad_header *quad) { struct softpipe_context *softpipe = qs->softpipe; - struct pipe_surface *ps = softpipe->framebuffer.sbuf; + struct pipe_surface *ps = softpipe->framebuffer.zsbuf; unsigned func, zFailOp, zPassOp, failOp; ubyte ref, wrtMask, valMask; ubyte stencilVals[QUAD_SIZE]; struct softpipe_cached_tile *tile - = sp_get_cached_tile(softpipe, softpipe->sbuf_cache, quad->x0, quad->y0); + = sp_get_cached_tile(softpipe, softpipe->zsbuf_cache, quad->x0, quad->y0); uint j; uint face = quad->facing; diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h index bac7b0876f..af955c1e17 100644 --- a/src/mesa/pipe/softpipe/sp_state.h +++ b/src/mesa/pipe/softpipe/sp_state.h @@ -157,7 +157,7 @@ boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count); boolean softpipe_draw_elements(struct pipe_context *pipe, - struct pipe_buffer_handle *indexBuffer, + struct pipe_buffer *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count); diff --git a/src/mesa/pipe/softpipe/sp_state_derived.c b/src/mesa/pipe/softpipe/sp_state_derived.c index 0f1410e5de..39c3e1afe1 100644 --- a/src/mesa/pipe/softpipe/sp_state_derived.c +++ b/src/mesa/pipe/softpipe/sp_state_derived.c @@ -29,14 +29,31 @@ #include "pipe/p_shader_tokens.h" #include "pipe/draw/draw_context.h" #include "pipe/draw/draw_vertex.h" +#include "pipe/draw/draw_private.h" #include "sp_context.h" #include "sp_state.h" +static int +find_vs_output(const struct pipe_shader_state *vs, + uint semantic_name, + uint semantic_index) +{ + uint i; + for (i = 0; i < vs->num_outputs; i++) { + if (vs->output_semantic_name[i] == semantic_name && + vs->output_semantic_index[i] == semantic_index) + return i; + } + return -1; +} + + + /** - * Determine which post-transform / pre-rasterization vertex attributes - * we need. - * Derived from: fs, setup states. + * Determine how to map vertex program outputs to fragment program inputs. + * Basically, this will be used when computing the triangle interpolation + * coefficients from the post-transform vertex attributes. */ static void calculate_vertex_layout( struct softpipe_context *softpipe ) { @@ -45,76 +62,55 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) const enum interp_mode colorInterp = softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; struct vertex_info *vinfo = &softpipe->vertex_info; - boolean emitBack0 = FALSE, emitBack1 = FALSE, emitPsize = FALSE; - uint front0 = 0, back0 = 0, front1 = 0, back1 = 0; uint i; - int src = 0; - - memset(vinfo, 0, sizeof(*vinfo)); - - if (fs->input_semantic_name[0] == TGSI_SEMANTIC_POSITION) { - /* Need Z if depth test is enabled or the fragment program uses the - * fragment position (XYZW). + if (softpipe->vbuf) { + /* if using the post-transform vertex buffer, tell draw_vbuf to + * simply emit the whole post-xform vertex as-is: */ + struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf; + vinfo_vbuf->num_attribs = 0; + draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0); + vinfo_vbuf->size = 4 * vs->num_outputs + sizeof(struct vertex_header)/4; } - softpipe->psize_slot = -1; - - /* always emit vertex pos */ - draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_LINEAR, src++); - /* - * XXX I think we need to reconcile the vertex shader outputs with - * the fragment shader inputs here to make sure the slots line up. - * Might just be getting lucky so far. - * Or maybe do that in the state tracker? + * Loop over fragment shader inputs, searching for the matching output + * from the vertex shader. */ - - for (i = 0; i < vs->num_outputs; i++) { - switch (vs->output_semantic_name[i]) { - + vinfo->num_attribs = 0; + for (i = 0; i < fs->num_inputs; i++) { + int src; + switch (fs->input_semantic_name[i]) { case TGSI_SEMANTIC_POSITION: - /* vertex programs always emit position, but might not be - * needed for fragment progs. - */ - /* no-op */ + src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0); + assert(src >= 0); + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src); break; case TGSI_SEMANTIC_COLOR: - if (vs->output_semantic_index[i] == 0) { - front0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++); - } - else { - assert(vs->output_semantic_index[i] == 1); - front1 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++); - } - break; - - case TGSI_SEMANTIC_BCOLOR: - if (vs->output_semantic_index[i] == 0) { - emitBack0 = TRUE; - } - else { - assert(vs->output_semantic_index[i] == 1); - emitBack1 = TRUE; - } + src = find_vs_output(vs, TGSI_SEMANTIC_COLOR, + fs->input_semantic_index[i]); + assert(src >= 0); + draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src); break; case TGSI_SEMANTIC_FOG: - draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_PERSPECTIVE, src++); - break; - - case TGSI_SEMANTIC_PSIZE: - /* XXX only emit if drawing points or front/back polygon mode - * is point mode - */ - emitPsize = TRUE; + src = find_vs_output(vs, TGSI_SEMANTIC_FOG, 0); +#if 1 + if (src < 0) /* XXX temp hack, try demos/fogcoord.c with this */ + src = 0; +#endif + assert(src >= 0); + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); break; case TGSI_SEMANTIC_GENERIC: /* this includes texcoords and varying vars */ - draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_PERSPECTIVE, src++); + src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC, + fs->input_semantic_index[i]); + assert(src >= 0); + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); break; default: @@ -122,35 +118,13 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) } } - softpipe->nr_frag_attrs = fs->num_inputs; - - /* We want these after all other attribs since they won't get passed - * to the fragment shader. All prior vertex output attribs should match - * up 1:1 with the fragment shader inputs. - */ - if (emitBack0) { - back0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++); + softpipe->psize_slot = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0); + if (softpipe->psize_slot >= 0) { + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, + softpipe->psize_slot); } - if (emitBack1) { - back1 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++); - } - if (emitPsize) { - softpipe->psize_slot - = draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_CONSTANT, src++); - } - - /* If the attributes have changed, tell the draw module about - * the new vertex layout. - */ - /* XXX we also need to do this when the shading mode (interp modes) change: */ - if (1/*vinfo->attr_mask != softpipe->attr_mask*/) { - /*softpipe->attr_mask = vinfo->attr_mask;*/ - - draw_set_vertex_info( softpipe->draw, vinfo); - draw_set_twoside_attributes(softpipe->draw, - front0, back0, front1, back1); - } + draw_compute_vertex_size(vinfo); } @@ -194,7 +168,9 @@ compute_cliprect(struct softpipe_context *sp) */ void softpipe_update_derived( struct softpipe_context *softpipe ) { - if (softpipe->dirty & (SP_NEW_RASTERIZER | SP_NEW_FS)) + if (softpipe->dirty & (SP_NEW_RASTERIZER | + SP_NEW_FS | + SP_NEW_VS)) calculate_vertex_layout( softpipe ); if (softpipe->dirty & (SP_NEW_SCISSOR | diff --git a/src/mesa/pipe/softpipe/sp_state_fs.c b/src/mesa/pipe/softpipe/sp_state_fs.c index 945c93411f..1430be7869 100644 --- a/src/mesa/pipe/softpipe/sp_state_fs.c +++ b/src/mesa/pipe/softpipe/sp_state_fs.c @@ -30,6 +30,7 @@ #include "pipe/p_defines.h" #include "pipe/p_util.h" +#include "pipe/p_inlines.h" #include "pipe/p_winsys.h" #include "pipe/draw/draw_context.h" #include "pipe/p_shader_tokens.h" @@ -165,9 +166,9 @@ softpipe_set_constant_buffer(struct pipe_context *pipe, assert(index == 0); /* note: reference counting */ - ws->buffer_reference(ws, - &softpipe->constants[shader].buffer, - buf->buffer); + pipe_buffer_reference(ws, + &softpipe->constants[shader].buffer, + buf->buffer); softpipe->constants[shader].size = buf->size; softpipe->dirty |= SP_NEW_CONSTANTS; diff --git a/src/mesa/pipe/softpipe/sp_state_surface.c b/src/mesa/pipe/softpipe/sp_state_surface.c index 4a9a28cc4d..e2c6893e9f 100644 --- a/src/mesa/pipe/softpipe/sp_state_surface.c +++ b/src/mesa/pipe/softpipe/sp_state_surface.c @@ -65,17 +65,18 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, sp->framebuffer.num_cbufs = fb->num_cbufs; /* zbuf changing? */ - if (sp->framebuffer.zbuf != fb->zbuf) { + if (sp->framebuffer.zsbuf != fb->zsbuf) { /* flush old */ - sp_flush_tile_cache(sp, sp->zbuf_cache); + sp_flush_tile_cache(sp, sp->zsbuf_cache); /* assign new */ - sp->framebuffer.zbuf = fb->zbuf; + sp->framebuffer.zsbuf = fb->zsbuf; /* update cache */ - sp_tile_cache_set_surface(sp->zbuf_cache, fb->zbuf); + sp_tile_cache_set_surface(sp->zsbuf_cache, fb->zsbuf); } +#if 0 /* XXX combined depth/stencil here */ /* sbuf changing? */ @@ -98,6 +99,7 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, sp_tile_cache_set_surface(sp->sbuf_cache, fb->sbuf); } } +#endif sp->dirty |= SP_NEW_FRAMEBUFFER; } diff --git a/src/mesa/pipe/softpipe/sp_surface.c b/src/mesa/pipe/softpipe/sp_surface.c index e115705507..5978ee48bd 100644 --- a/src/mesa/pipe/softpipe/sp_surface.c +++ b/src/mesa/pipe/softpipe/sp_surface.c @@ -34,27 +34,6 @@ #include "sp_surface.h" -/* Upload data to a rectangular sub-region. Lots of choices how to do this: - * - * - memcpy by span to current destination - * - upload data as new buffer and blit - * - * Currently always memcpy. - */ -static void -sp_surface_data(struct pipe_context *pipe, - struct pipe_surface *dst, - unsigned dstx, unsigned dsty, - const void *src, unsigned src_pitch, - unsigned srcx, unsigned srcy, unsigned width, unsigned height) -{ - pipe_copy_rect(pipe_surface_map(dst), - dst->cpp, - dst->pitch, - dstx, dsty, width, height, src, src_pitch, srcx, srcy); - - pipe_surface_unmap(dst); -} /* Assumes all values are within bounds -- no checking at this level - * do it higher up if required. @@ -174,10 +153,6 @@ sp_surface_fill(struct pipe_context *pipe, void sp_init_surface_functions(struct softpipe_context *sp) { - sp->pipe.get_tile = pipe_get_tile_raw; - sp->pipe.put_tile = pipe_put_tile_raw; - - sp->pipe.surface_data = sp_surface_data; sp->pipe.surface_copy = sp_surface_copy; sp->pipe.surface_fill = sp_surface_fill; } diff --git a/src/mesa/pipe/softpipe/sp_texture.c b/src/mesa/pipe/softpipe/sp_texture.c index d43a6996e9..172234843d 100644 --- a/src/mesa/pipe/softpipe/sp_texture.c +++ b/src/mesa/pipe/softpipe/sp_texture.c @@ -91,12 +91,9 @@ softpipe_texture_create(struct pipe_context *pipe, struct pipe_texture **pt) softpipe_texture_layout(spt); - spt->buffer = pipe->winsys->buffer_create(pipe->winsys, 32, 0, 0); - - if (spt->buffer) { - pipe->winsys->buffer_data(pipe->winsys, spt->buffer, spt->buffer_size, - NULL, PIPE_BUFFER_USAGE_PIXEL); - } + spt->buffer = pipe->winsys->buffer_create(pipe->winsys, 32, + PIPE_BUFFER_USAGE_PIXEL, + spt->buffer_size); if (!spt->buffer) { FREE(spt); @@ -124,7 +121,7 @@ softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); */ - pipe->winsys->buffer_reference(pipe->winsys, &spt->buffer, NULL); + pipe_buffer_reference(pipe->winsys, &spt->buffer, NULL); FREE(spt); } @@ -147,7 +144,7 @@ softpipe_get_tex_surface(struct pipe_context *pipe, if (ps) { assert(ps->refcount); assert(ps->winsys); - pipe->winsys->buffer_reference(pipe->winsys, &ps->buffer, spt->buffer); + pipe_buffer_reference(pipe->winsys, &ps->buffer, spt->buffer); ps->format = pt->format; ps->cpp = pt->cpp; ps->width = pt->width[level]; diff --git a/src/mesa/pipe/softpipe/sp_texture.h b/src/mesa/pipe/softpipe/sp_texture.h index 0494bf365b..c6cf370351 100644 --- a/src/mesa/pipe/softpipe/sp_texture.h +++ b/src/mesa/pipe/softpipe/sp_texture.h @@ -41,7 +41,7 @@ struct softpipe_texture /* The data is held here: */ - struct pipe_buffer_handle *buffer; + struct pipe_buffer *buffer; unsigned long buffer_size; }; diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.c b/src/mesa/pipe/softpipe/sp_tile_cache.c index 1974f77459..451e157abf 100644 --- a/src/mesa/pipe/softpipe/sp_tile_cache.c +++ b/src/mesa/pipe/softpipe/sp_tile_cache.c @@ -329,7 +329,7 @@ sp_tile_cache_flush_clear(struct pipe_context *pipe, for (y = 0; y < h; y += TILE_SIZE) { for (x = 0; x < w; x += TILE_SIZE) { if (is_clear_flag_set(tc->clear_flags, x, y)) { - pipe->put_tile(pipe, ps, + pipe_put_tile_raw(pipe, ps, x, y, TILE_SIZE, TILE_SIZE, tc->tile.data.color32, 0/*STRIDE*/); @@ -365,7 +365,7 @@ sp_flush_tile_cache(struct softpipe_context *softpipe, struct softpipe_cached_tile *tile = tc->entries + pos; if (tile->x >= 0) { if (tc->depth_stencil) { - pipe->put_tile(pipe, ps, + pipe_put_tile_raw(pipe, ps, tile->x, tile->y, TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } @@ -414,7 +414,7 @@ sp_get_cached_tile(struct softpipe_context *softpipe, if (tile->x != -1) { /* put dirty tile back in framebuffer */ if (tc->depth_stencil) { - pipe->put_tile(pipe, ps, + pipe_put_tile_raw(pipe, ps, tile->x, tile->y, TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } @@ -441,7 +441,7 @@ sp_get_cached_tile(struct softpipe_context *softpipe, else { /* get new tile data from surface */ if (tc->depth_stencil) { - pipe->get_tile(pipe, ps, + pipe_put_tile_raw(pipe, ps, tile->x, tile->y, TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } @@ -538,6 +538,7 @@ void sp_tile_cache_clear(struct softpipe_tile_cache *tc, uint clearValue) { uint r, g, b, a; + uint pos; tc->clear_val = clearValue; @@ -576,4 +577,9 @@ sp_tile_cache_clear(struct softpipe_tile_cache *tc, uint clearValue) /* disable the optimization */ memset(tc->clear_flags, 0, sizeof(tc->clear_flags)); #endif + + for (pos = 0; pos < NUM_ENTRIES; pos++) { + struct softpipe_cached_tile *tile = tc->entries + pos; + tile->x = tile->y = -1; + } } |