diff options
Diffstat (limited to 'src/gallium/drivers/softpipe')
-rw-r--r-- | src/gallium/drivers/softpipe/sp_context.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_draw_arrays.c | 30 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_fs_sse.c | 24 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_prim_vbuf.c | 229 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_quad_fs.c | 30 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_quad_pipe.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_query.c | 5 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_screen.c | 8 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_setup.c | 7 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_tex_sample.c | 102 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_texture.c | 21 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_tile_cache.c | 10 |
12 files changed, 312 insertions, 157 deletions
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index dffc15a4f1..7888c2f644 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -92,6 +92,7 @@ struct softpipe_context { * queries. */ uint64_t occlusion_count; + unsigned active_query_count; /** Mapped vertex buffers */ ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS]; diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index ba2766ff13..d4045816d0 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -35,6 +35,7 @@ #include "pipe/p_context.h" #include "pipe/internal/p_winsys_screen.h" #include "pipe/p_inlines.h" +#include "util/u_prim.h" #include "sp_context.h" #include "sp_state.h" @@ -65,6 +66,7 @@ softpipe_map_constant_buffers(struct softpipe_context *sp) size); } + static void softpipe_unmap_constant_buffers(struct softpipe_context *sp) { @@ -86,20 +88,6 @@ softpipe_unmap_constant_buffers(struct softpipe_context *sp) } -static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { - PIPE_PRIM_POINTS, - PIPE_PRIM_LINES, - PIPE_PRIM_LINES, - PIPE_PRIM_LINES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES -}; - - boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) @@ -108,15 +96,11 @@ softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, } - /** * Draw vertex arrays, with optional indexing. * Basically, map the vertex buffers (and drawing surfaces), then hand off * the drawing to the 'draw' module. - * - * XXX should the element buffer be specified/bound with a separate function? */ - boolean softpipe_draw_range_elements(struct pipe_context *pipe, struct pipe_buffer *indexBuffer, @@ -129,7 +113,7 @@ softpipe_draw_range_elements(struct pipe_context *pipe, struct draw_context *draw = sp->draw; unsigned i; - sp->reduced_api_prim = reduced_prim[mode]; + sp->reduced_api_prim = u_reduced_prim(mode); if (sp->dirty) softpipe_update_derived( sp ); @@ -147,6 +131,7 @@ softpipe_draw_range_elements(struct pipe_context *pipe, PIPE_BUFFER_USAGE_CPU_READ); draw_set_mapped_vertex_buffer(draw, i, buf); } + /* Map index buffer, if present */ if (indexBuffer) { void *mapped_indexes @@ -159,10 +144,10 @@ softpipe_draw_range_elements(struct pipe_context *pipe, } else { /* no index/element buffer */ - draw_set_mapped_element_buffer_range(draw, 0, start, start + count - 1, NULL); + draw_set_mapped_element_buffer_range(draw, 0, start, + start + count - 1, NULL); } - /* draw! */ draw_arrays(draw, mode, start, count); @@ -187,6 +172,7 @@ softpipe_draw_range_elements(struct pipe_context *pipe, return TRUE; } + boolean softpipe_draw_elements(struct pipe_context *pipe, struct pipe_buffer *indexBuffer, @@ -200,11 +186,9 @@ softpipe_draw_elements(struct pipe_context *pipe, } - void softpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags) { struct softpipe_context *sp = softpipe_context(pipe); draw_set_edgeflags(sp->draw, edgeflags); } - diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index 31c3ca21c5..f4fa0905d7 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -45,17 +45,6 @@ #include "rtasm/rtasm_x86sse.h" -/* Surely this should be defined somewhere in a tgsi header: - */ -typedef void (PIPE_CDECL *codegen_function)( - const struct tgsi_exec_vector *input, - struct tgsi_exec_vector *output, - const float (*constant)[4], - struct tgsi_exec_vector *temporary, - const struct tgsi_interp_coef *coef, - float (*immediates)[4] - //, const struct tgsi_exec_vector *quadPos - ); /** @@ -65,7 +54,7 @@ struct sp_sse_fragment_shader { struct sp_fragment_shader base; struct x86_function sse2_program; - codegen_function func; + tgsi_sse2_fs_function func; float immediates[TGSI_EXEC_NUM_IMMEDIATES][4]; }; @@ -83,6 +72,7 @@ fs_sse_prepare( const struct sp_fragment_shader *base, struct tgsi_exec_machine *machine, struct tgsi_sampler **samplers ) { + machine->Samplers = samplers; } @@ -107,12 +97,10 @@ fs_sse_run( const struct sp_fragment_shader *base, tgsi_set_kill_mask(machine, 0x0); tgsi_set_exec_mask(machine, 1, 1, 1, 1); - shader->func( machine->Inputs, - machine->Outputs, + shader->func( machine, machine->Consts, - machine->Temps, - machine->InterpCoefs, - shader->immediates + (const float (*)[4])shader->immediates, + machine->InterpCoefs // , &machine->QuadPos ); @@ -151,7 +139,7 @@ softpipe_create_fs_sse(struct softpipe_context *softpipe, return NULL; } - shader->func = (codegen_function) x86_get_func( &shader->sse2_program ); + shader->func = (tgsi_sse2_fs_function) x86_get_func( &shader->sse2_program ); if (!shader->func) { x86_release_func( &shader->sse2_program ); FREE(shader); diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 06725fd09b..42021789ea 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -238,65 +238,117 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) case PIPE_PRIM_TRIANGLES: for (i = 2; i < nr; i += 3) { - setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride)); + if (softpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-2], stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } } break; case PIPE_PRIM_TRIANGLE_STRIP: for (i = 2; i < nr; i += 1) { - setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i+(i&1)-2], stride), - get_vert(vertex_buffer, indices[i-(i&1)-1], stride), - get_vert(vertex_buffer, indices[i-0], stride)); + if (softpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i+(i&1)-1], stride), + get_vert(vertex_buffer, indices[i-(i&1)], stride), + get_vert(vertex_buffer, indices[i-2], stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i+(i&1)-2], stride), + get_vert(vertex_buffer, indices[i-(i&1)-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } } break; case PIPE_PRIM_TRIANGLE_FAN: for (i = 2; i < nr; i += 1) { - setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[0], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride)); + if (softpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[0], stride), + get_vert(vertex_buffer, indices[i-1], stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[0], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } } break; case PIPE_PRIM_QUADS: for (i = 3; i < nr; i += 4) { - setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-3], stride), - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-0], stride)); - - setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride)); + if (softpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-3], stride) ); + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-3], stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } } break; case PIPE_PRIM_QUAD_STRIP: for (i = 3; i < nr; i += 2) { - setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-3], stride), - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-0], stride)); - - setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-3], stride), - get_vert(vertex_buffer, indices[i-0], stride)); + if (softpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-3], stride)); + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-3], stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } } break; case PIPE_PRIM_POLYGON: + /* Almost same as tri fan but the _first_ vertex specifies the flat + * shading color. Note that the first polygon vertex is passed as + * the last triangle vertex here. + * flatshade_first state makes no difference. + */ for (i = 2; i < nr; i += 1) { setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[0-1], stride), get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[0], stride)); + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[0], stride) ); } break; @@ -368,58 +420,104 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) } break; - case PIPE_PRIM_TRIANGLES: for (i = 2; i < nr; i += 3) { - setup_tri( setup_ctx, - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride)); + if (softpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-2, stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } } break; case PIPE_PRIM_TRIANGLE_STRIP: - for (i = 2; i < nr; i += 1) { - setup_tri( setup_ctx, - get_vert(vertex_buffer, i+(i&1)-2, stride), - get_vert(vertex_buffer, i-(i&1)-1, stride), - get_vert(vertex_buffer, i-0, stride)); + for (i = 2; i < nr; i++) { + if (softpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i+(i&1)-1, stride), + get_vert(vertex_buffer, i-(i&1), stride), + get_vert(vertex_buffer, i-2, stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i+(i&1)-2, stride), + get_vert(vertex_buffer, i-(i&1)-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } } break; case PIPE_PRIM_TRIANGLE_FAN: for (i = 2; i < nr; i += 1) { - setup_tri( setup_ctx, - get_vert(vertex_buffer, 0, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride)); + if (softpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, 0, stride), + get_vert(vertex_buffer, i-1, stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, 0, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } } break; case PIPE_PRIM_QUADS: for (i = 3; i < nr; i += 4) { - setup_tri( setup_ctx, - get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-0, stride)); - - setup_tri( setup_ctx, - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride)); + if (softpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-3, stride) ); + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-3, stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-0, stride) ); + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } } break; + case PIPE_PRIM_QUAD_STRIP: for (i = 3; i < nr; i += 2) { - setup_tri( setup_ctx, - get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-0, stride)); - - setup_tri( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-0, stride)); + if (softpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-3, stride) ); + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-3, stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-0, stride) ); + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-0, stride) ); + } } break; @@ -427,12 +525,13 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) /* Almost same as tri fan but the _first_ vertex specifies the flat * shading color. Note that the first polygon vertex is passed as * the last triangle vertex here. + * flatshade_first state makes no difference. */ for (i = 2; i < nr; i += 1) { setup_tri( setup_ctx, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, 0, stride)); + get_vert(vertex_buffer, 0, stride) ); } break; diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index ca637a1d6a..28f8d1a60e 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -52,7 +52,7 @@ struct quad_shade_stage { struct quad_stage stage; /**< base class */ - struct tgsi_exec_machine machine; + struct tgsi_exec_machine *machine; struct tgsi_exec_vector *inputs, *outputs; }; @@ -73,7 +73,7 @@ shade_quad(struct quad_stage *qs, struct quad_header *quad) { struct quad_shade_stage *qss = quad_shade_stage( qs ); struct softpipe_context *softpipe = qs->softpipe; - struct tgsi_exec_machine *machine = &qss->machine; + struct tgsi_exec_machine *machine = qss->machine; boolean z_written; /* Consts do not require 16 byte alignment. */ @@ -146,7 +146,7 @@ shade_begin(struct quad_stage *qs) struct softpipe_context *softpipe = qs->softpipe; softpipe->fs->prepare( softpipe->fs, - &qss->machine, + qss->machine, (struct tgsi_sampler **) softpipe->tgsi.frag_samplers_list ); @@ -159,9 +159,8 @@ shade_destroy(struct quad_stage *qs) { struct quad_shade_stage *qss = (struct quad_shade_stage *) qs; - tgsi_exec_machine_free_data(&qss->machine); - FREE( qss->inputs ); - FREE( qss->outputs ); + tgsi_exec_machine_destroy(qss->machine); + FREE( qs ); } @@ -170,19 +169,24 @@ struct quad_stage * sp_quad_shade_stage( struct softpipe_context *softpipe ) { struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage); - - /* allocate storage for program inputs/outputs, aligned to 16 bytes */ - qss->inputs = MALLOC(PIPE_MAX_ATTRIBS * sizeof(*qss->inputs) + 16); - qss->outputs = MALLOC(PIPE_MAX_ATTRIBS * sizeof(*qss->outputs) + 16); - qss->machine.Inputs = align16(qss->inputs); - qss->machine.Outputs = align16(qss->outputs); + if (!qss) + goto fail; qss->stage.softpipe = softpipe; qss->stage.begin = shade_begin; qss->stage.run = shade_quad; qss->stage.destroy = shade_destroy; - tgsi_exec_machine_init( &qss->machine ); + qss->machine = tgsi_exec_machine_create(); + if (!qss->machine) + goto fail; return &qss->stage; + +fail: + if (qss && qss->machine) + tgsi_exec_machine_destroy(qss->machine); + + FREE(qss); + return NULL; } diff --git a/src/gallium/drivers/softpipe/sp_quad_pipe.c b/src/gallium/drivers/softpipe/sp_quad_pipe.c index 892ef87ee9..b5f69b7426 100644 --- a/src/gallium/drivers/softpipe/sp_quad_pipe.c +++ b/src/gallium/drivers/softpipe/sp_quad_pipe.c @@ -80,7 +80,7 @@ sp_build_quad_pipeline(struct softpipe_context *sp) sp_push_quad_first( sp, sp->quad[i].blend, i ); } - if (sp->depth_stencil->depth.occlusion_count) { + if (sp->active_query_count) { sp_push_quad_first( sp, sp->quad[i].occlusion, i ); } diff --git a/src/gallium/drivers/softpipe/sp_query.c b/src/gallium/drivers/softpipe/sp_query.c index 93dab236d6..379cf4ad06 100644 --- a/src/gallium/drivers/softpipe/sp_query.c +++ b/src/gallium/drivers/softpipe/sp_query.c @@ -34,6 +34,7 @@ #include "util/u_memory.h" #include "sp_context.h" #include "sp_query.h" +#include "sp_state.h" struct softpipe_query { uint64_t start; @@ -69,6 +70,8 @@ softpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q) struct softpipe_query *sq = softpipe_query(q); sq->start = softpipe->occlusion_count; + softpipe->active_query_count++; + softpipe->dirty |= SP_NEW_QUERY; } @@ -78,7 +81,9 @@ softpipe_end_query(struct pipe_context *pipe, struct pipe_query *q) struct softpipe_context *softpipe = softpipe_context( pipe ); struct softpipe_query *sq = softpipe_query(q); + softpipe->active_query_count--; sq->end = softpipe->occlusion_count; + softpipe->dirty |= SP_NEW_QUERY; } diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 2e2668dfe4..769425bd12 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -82,13 +82,15 @@ softpipe_get_param(struct pipe_screen *screen, int param) case PIPE_CAP_TEXTURE_SHADOW_MAP: return 1; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: - return 12; /* max 2Kx2K */ + return 13; /* max 4Kx4K */ case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: return 9; /* max 256x256x256 */ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: - return 12; /* max 2Kx2K */ + return 13; /* max 4Kx4K */ case PIPE_CAP_TGSI_CONT_SUPPORTED: return 1; + case PIPE_CAP_BLEND_EQUATION_SEPARATE: + return 1; default: return 0; } @@ -108,7 +110,7 @@ softpipe_get_paramf(struct pipe_screen *screen, int param) case PIPE_CAP_MAX_POINT_WIDTH_AA: return 255.0; /* arbitrary */ case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: - return 0.0; + return 16.0; /* not actually signficant at this time */ case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: return 16.0; /* arbitrary */ default: diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 1eb23cd6b6..de3ae3c369 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -507,6 +507,8 @@ static void print_vertex(const struct setup_context *setup, #endif /** + * Sort the vertices from top to bottom order, setting up the triangle + * edge fields (ebot, emaj, etop). * \return FALSE if coords are inf/nan (cull the tri), TRUE otherwise */ static boolean setup_sort_vertices( struct setup_context *setup, @@ -1051,7 +1053,10 @@ setup_line_coefficients(struct setup_context *setup, float area; /* use setup->vmin, vmax to point to vertices */ - setup->vprovoke = v1; + if (softpipe->rasterizer->flatshade_first) + setup->vprovoke = v0; + else + setup->vprovoke = v1; setup->vmin = v0; setup->vmax = v1; diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 81793ef736..f99a30277d 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -705,15 +705,18 @@ get_texel(const struct tgsi_sampler *tgsi_sampler, * Compare texcoord 'p' (aka R) against texture value 'rgba[0]' * When we sampled the depth texture, the depth value was put into all * RGBA channels. We look at the red channel here. + * \param rgba quad of (depth) texel values + * \param p texture 'P' components for four pixels in quad + * \param j which pixel in the quad to test [0..3] */ static INLINE void -shadow_compare(uint compare_func, +shadow_compare(const struct pipe_sampler_state *sampler, float rgba[NUM_CHANNELS][QUAD_SIZE], const float p[QUAD_SIZE], uint j) { int k; - switch (compare_func) { + switch (sampler->compare_func) { case PIPE_FUNC_LESS: k = p[j] < rgba[0][j]; break; @@ -751,6 +754,78 @@ shadow_compare(uint compare_func, /** + * As above, but do four z/texture comparisons. + */ +static INLINE void +shadow_compare4(const struct pipe_sampler_state *sampler, + float rgba[NUM_CHANNELS][QUAD_SIZE], + const float p[QUAD_SIZE]) +{ + int j, k0, k1, k2, k3; + float val; + + /* compare four texcoords vs. four texture samples */ + switch (sampler->compare_func) { + case PIPE_FUNC_LESS: + k0 = p[0] < rgba[0][0]; + k1 = p[1] < rgba[0][1]; + k2 = p[2] < rgba[0][2]; + k3 = p[3] < rgba[0][3]; + break; + case PIPE_FUNC_LEQUAL: + k0 = p[0] <= rgba[0][0]; + k1 = p[1] <= rgba[0][1]; + k2 = p[2] <= rgba[0][2]; + k3 = p[3] <= rgba[0][3]; + break; + case PIPE_FUNC_GREATER: + k0 = p[0] > rgba[0][0]; + k1 = p[1] > rgba[0][1]; + k2 = p[2] > rgba[0][2]; + k3 = p[3] > rgba[0][3]; + break; + case PIPE_FUNC_GEQUAL: + k0 = p[0] >= rgba[0][0]; + k1 = p[1] >= rgba[0][1]; + k2 = p[2] >= rgba[0][2]; + k3 = p[3] >= rgba[0][3]; + break; + case PIPE_FUNC_EQUAL: + k0 = p[0] == rgba[0][0]; + k1 = p[1] == rgba[0][1]; + k2 = p[2] == rgba[0][2]; + k3 = p[3] == rgba[0][3]; + break; + case PIPE_FUNC_NOTEQUAL: + k0 = p[0] != rgba[0][0]; + k1 = p[1] != rgba[0][1]; + k2 = p[2] != rgba[0][2]; + k3 = p[3] != rgba[0][3]; + break; + case PIPE_FUNC_ALWAYS: + k0 = k1 = k2 = k3 = 1; + break; + case PIPE_FUNC_NEVER: + k0 = k1 = k2 = k3 = 0; + break; + default: + k0 = k1 = k2 = k3 = 0; + assert(0); + break; + } + + /* convert four pass/fail values to an intensity in [0,1] */ + val = 0.25F * (k0 + k1 + k2 + k3); + + /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */ + for (j = 0; j < 4; j++) { + rgba[0][j] = rgba[1][j] = rgba[2][j] = val; + rgba[3][j] = 1.0F; + } +} + + +/** * Common code for sampling 1D/2D/cube textures. * Could probably extend for 3D... */ @@ -769,7 +844,6 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler, const uint unit = samp->unit; const struct pipe_texture *texture = sp->texture[unit]; const struct pipe_sampler_state *sampler = sp->sampler[unit]; - const uint compare_func = sampler->compare_func; unsigned level0, level1, j, imgFilter; int width, height; float levelBlend; @@ -794,7 +868,7 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler, for (j = 0; j < QUAD_SIZE; j++) { get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j); if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { - shadow_compare(compare_func, rgba, p, j); + shadow_compare(sampler, rgba, p, j); } if (level0 != level1) { @@ -806,7 +880,7 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler, get_texel(tgsi_sampler, faces[j], level1, x[j], y[j], 0, rgba2, j); if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ - shadow_compare(compare_func, rgba2, p, j); + shadow_compare(sampler, rgba2, p, j); } for (c = 0; c < NUM_CHANNELS; c++) { @@ -833,10 +907,7 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler, get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2); get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3); if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { - shadow_compare(compare_func, tx, p, 0); - shadow_compare(compare_func, tx, p, 1); - shadow_compare(compare_func, tx, p, 2); - shadow_compare(compare_func, tx, p, 3); + shadow_compare4(sampler, tx, p); } /* interpolate R, G, B, A */ @@ -858,10 +929,7 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler, get_texel(tgsi_sampler, faces[j], level1, x0[j], y1[j], 0, tx, 2); get_texel(tgsi_sampler, faces[j], level1, x1[j], y1[j], 0, tx, 3); if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ - shadow_compare(compare_func, tx, p, 0); - shadow_compare(compare_func, tx, p, 1); - shadow_compare(compare_func, tx, p, 2); - shadow_compare(compare_func, tx, p, 3); + shadow_compare4(sampler, tx, p); } /* interpolate R, G, B, A */ @@ -1076,7 +1144,6 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler, const struct pipe_texture *texture = sp->texture[unit]; const struct pipe_sampler_state *sampler = sp->sampler[unit]; const uint face = 0; - const uint compare_func = sampler->compare_func; unsigned level0, level1, j, imgFilter; int width, height; float levelBlend; @@ -1101,7 +1168,7 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler, for (j = 0; j < QUAD_SIZE; j++) { get_texel(tgsi_sampler, face, level0, x[j], y[j], 0, rgba, j); if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { - shadow_compare(compare_func, rgba, p, j); + shadow_compare(sampler, rgba, p, j); } } } @@ -1121,10 +1188,7 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler, get_texel(tgsi_sampler, face, level0, x0[j], y1[j], 0, tx, 2); get_texel(tgsi_sampler, face, level0, x1[j], y1[j], 0, tx, 3); if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { - shadow_compare(compare_func, tx, p, 0); - shadow_compare(compare_func, tx, p, 1); - shadow_compare(compare_func, tx, p, 2); - shadow_compare(compare_func, tx, p, 3); + shadow_compare4(sampler, tx, p); } for (c = 0; c < 4; c++) { rgba[c][j] = lerp_2d(xw[j], yw[j], diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 7a533dad9f..70f0932431 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -48,11 +48,6 @@ /* Simple, maximally packed layout. */ -static unsigned minify( unsigned d ) -{ - return MAX2(1, d>>1); -} - /* Conventional allocation path for non-display textures: */ @@ -100,6 +95,7 @@ softpipe_displaytarget_layout(struct pipe_screen *screen, { unsigned usage = (PIPE_BUFFER_USAGE_CPU_READ_WRITE | PIPE_BUFFER_USAGE_GPU_READ_WRITE); + unsigned tex_usage = spt->base.tex_usage; spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]); spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]); @@ -109,6 +105,7 @@ softpipe_displaytarget_layout(struct pipe_screen *screen, spt->base.height[0], spt->base.format, usage, + tex_usage, &spt->stride[0]); return spt->buffer != NULL; @@ -130,7 +127,8 @@ softpipe_texture_create(struct pipe_screen *screen, pipe_reference_init(&spt->base.reference, 1); spt->base.screen = screen; - if (spt->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { + if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | + PIPE_TEXTURE_USAGE_PRIMARY)) { if (!softpipe_displaytarget_layout(screen, spt)) goto fail; } @@ -224,12 +222,6 @@ softpipe_get_tex_surface(struct pipe_screen *screen, if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ) ps->usage |= PIPE_BUFFER_USAGE_CPU_READ; - if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_GPU_WRITE)) { - /* Mark the surface as dirty. The tile cache will look for this. */ - spt->modified = TRUE; - } - ps->face = face; ps->level = level; ps->zslice = zslice; @@ -376,6 +368,11 @@ softpipe_transfer_unmap(struct pipe_screen *screen, spt = softpipe_texture(transfer->texture); pipe_buffer_unmap( screen, spt->buffer ); + + if (transfer->usage != PIPE_TRANSFER_READ) { + /* Mark the texture as dirty to expire the tile caches. */ + spt->modified = TRUE; + } } diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 1f9b8f1f4f..461cbb9f95 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -44,8 +44,8 @@ /** XXX move these */ -#define MAX_WIDTH 2048 -#define MAX_HEIGHT 2048 +#define MAX_WIDTH 4096 +#define MAX_HEIGHT 4096 struct softpipe_tile_cache @@ -116,6 +116,12 @@ sp_create_tile_cache( struct pipe_screen *screen ) { struct softpipe_tile_cache *tc; uint pos; + int maxLevels, maxTexSize; + + /* sanity checking: max sure MAX_WIDTH/HEIGHT >= largest texture image */ + maxLevels = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS); + maxTexSize = 1 << (maxLevels - 1); + assert(MAX_WIDTH >= maxTexSize); tc = CALLOC_STRUCT( softpipe_tile_cache ); if (tc) { |