X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Fdraw%2Fdraw_pipe_aaline.c;h=f2895ddc3575880c317519a2b01708b891959ed0;hb=877128505431adaf817dc8069172ebe4a1cdf5d8;hp=e96dbecd2624e7c6435ef83e485ae34ec463d021;hpb=0639765b2850739af1678f10fc0c5706d5827776;p=mesa.git diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index e96dbecd262..f2895ddc357 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2007 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,7 +18,7 @@ * 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 + * 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. @@ -54,10 +54,17 @@ #define NUM_NEW_TOKENS 50 +/** + * Size for the alpha texture used for antialiasing + */ +#define TEXTURE_SIZE_LOG2 5 /* 32 x 32 */ + /** * Max texture level for the alpha texture used for antialiasing + * + * Don't use the 1x1 and 2x2 mipmap levels. */ -#define MAX_TEXTURE_LEVEL 5 /* 32 x 32 */ +#define MAX_TEXTURE_LEVEL (TEXTURE_SIZE_LOG2 - 2) /** @@ -100,7 +107,7 @@ struct aaline_stage struct aaline_fragment_shader *fs; struct { void *sampler[PIPE_MAX_SAMPLERS]; - struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view *sampler_views[PIPE_MAX_SHADER_SAMPLER_VIEWS]; } state; /* @@ -111,13 +118,12 @@ struct aaline_stage void (*driver_bind_fs_state)(struct pipe_context *, void *); void (*driver_delete_fs_state)(struct pipe_context *, void *); - void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, - void **); - void (*driver_set_sampler_views)(struct pipe_context *, - unsigned, - struct pipe_sampler_view **); + void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, unsigned, + unsigned, void **); - struct pipe_context *pipe; + void (*driver_set_sampler_views)(struct pipe_context *, unsigned shader, + unsigned start, unsigned count, + struct pipe_sampler_view **); }; @@ -231,12 +237,13 @@ aa_transform_inst(struct tgsi_transform_context *ctx, decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_INPUT; /* XXX this could be linear... */ - decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; + decl.Declaration.Interpolate = 1; decl.Declaration.Semantic = 1; decl.Semantic.Name = TGSI_SEMANTIC_GENERIC; decl.Semantic.Index = aactx->maxGeneric + 1; decl.Range.First = decl.Range.Last = aactx->maxInput + 1; + decl.Interp.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; ctx->emit_declaration(ctx, &decl); /* declare new sampler */ @@ -342,6 +349,7 @@ aa_transform_inst(struct tgsi_transform_context *ctx, static boolean generate_aaline_fs(struct aaline_stage *aaline) { + struct pipe_context *pipe = aaline->stage.draw->pipe; const struct pipe_shader_state *orig_fs = &aaline->fs->state; struct pipe_shader_state aaline_fs; struct aa_transform_context transform; @@ -367,14 +375,15 @@ generate_aaline_fs(struct aaline_stage *aaline) newLen, &transform.base); #if 0 /* DEBUG */ + debug_printf("draw_aaline, orig shader:\n"); tgsi_dump(orig_fs->tokens, 0); + debug_printf("draw_aaline, new shader:\n"); tgsi_dump(aaline_fs.tokens, 0); #endif aaline->fs->sampler_unit = transform.freeSampler; - aaline->fs->aaline_fs - = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs); + aaline->fs->aaline_fs = aaline->driver_create_fs_state(pipe, &aaline_fs); if (aaline->fs->aaline_fs == NULL) goto fail; @@ -394,7 +403,7 @@ fail: static boolean aaline_create_texture(struct aaline_stage *aaline) { - struct pipe_context *pipe = aaline->pipe; + struct pipe_context *pipe = aaline->stage.draw->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_resource texTemp; struct pipe_sampler_view viewTempl; @@ -404,9 +413,10 @@ aaline_create_texture(struct aaline_stage *aaline) texTemp.target = PIPE_TEXTURE_2D; texTemp.format = PIPE_FORMAT_A8_UNORM; /* XXX verify supported by driver! */ texTemp.last_level = MAX_TEXTURE_LEVEL; - texTemp.width0 = 1 << MAX_TEXTURE_LEVEL; - texTemp.height0 = 1 << MAX_TEXTURE_LEVEL; + texTemp.width0 = 1 << TEXTURE_SIZE_LOG2; + texTemp.height0 = 1 << TEXTURE_SIZE_LOG2; texTemp.depth0 = 1; + texTemp.array_size = 1; texTemp.bind = PIPE_BIND_SAMPLER_VIEW; aaline->texture = screen->resource_create(screen, &texTemp); @@ -425,7 +435,8 @@ aaline_create_texture(struct aaline_stage *aaline) /* Fill in mipmap images. * Basically each level is solid opaque, except for the outermost - * texels which are zero. Special case the 1x1 and 2x2 levels. + * texels which are zero. Special case the 1x1 and 2x2 levels + * (though, those levels shouldn't be used - see the max_lod setting). */ for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) { struct pipe_transfer *transfer; @@ -440,13 +451,12 @@ aaline_create_texture(struct aaline_stage *aaline) /* This texture is new, no need to flush. */ - transfer = pipe->get_transfer(pipe, - aaline->texture, - u_subresource(0, level), - PIPE_TRANSFER_WRITE, - &box); + data = pipe->transfer_map(pipe, + aaline->texture, + level, + PIPE_TRANSFER_WRITE, + &box, &transfer); - data = pipe->transfer_map(pipe, transfer); if (data == NULL) return FALSE; @@ -460,7 +470,7 @@ aaline_create_texture(struct aaline_stage *aaline) d = 200; /* tuneable */ } else if (i == 0 || j == 0 || i == size - 1 || j == size - 1) { - d = 0; + d = 35; /* edge texel */ } else { d = 255; @@ -471,7 +481,6 @@ aaline_create_texture(struct aaline_stage *aaline) /* unmap */ pipe->transfer_unmap(pipe, transfer); - pipe->transfer_destroy(pipe, transfer); } return TRUE; } @@ -486,7 +495,7 @@ static boolean aaline_create_sampler(struct aaline_stage *aaline) { struct pipe_sampler_state sampler; - struct pipe_context *pipe = aaline->pipe; + struct pipe_context *pipe = aaline->stage.draw->pipe; memset(&sampler, 0, sizeof(sampler)); sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; @@ -515,13 +524,14 @@ static boolean bind_aaline_fragment_shader(struct aaline_stage *aaline) { struct draw_context *draw = aaline->stage.draw; + struct pipe_context *pipe = draw->pipe; if (!aaline->fs->aaline_fs && !generate_aaline_fs(aaline)) return FALSE; draw->suspend_flushing = TRUE; - aaline->driver_bind_fs_state(aaline->pipe, aaline->fs->aaline_fs); + aaline->driver_bind_fs_state(pipe, aaline->fs->aaline_fs); draw->suspend_flushing = FALSE; return TRUE; @@ -661,13 +671,15 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) { auto struct aaline_stage *aaline = aaline_stage(stage); struct draw_context *draw = stage->draw; - struct pipe_context *pipe = aaline->pipe; + struct pipe_context *pipe = draw->pipe; + const struct pipe_rasterizer_state *rast = draw->rasterizer; uint num_samplers; + void *r; assert(draw->rasterizer->line_smooth); - if (draw->rasterizer->line_width <= 3.0) - aaline->half_line_width = 1.5f; + if (draw->rasterizer->line_width <= 2.2) + aaline->half_line_width = 1.1f; else aaline->half_line_width = 0.5f * draw->rasterizer->line_width; @@ -680,14 +692,7 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) return; } - /* update vertex attrib info */ - aaline->tex_slot = draw_current_shader_outputs(draw); - aaline->pos_slot = draw_current_shader_position_output(draw);; - - /* advertise the extra post-transformed vertex attribute */ - draw->extra_shader_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; - draw->extra_shader_outputs.semantic_index = aaline->fs->generic_attrib; - draw->extra_shader_outputs.slot = aaline->tex_slot; + draw_aaline_prepare_outputs(draw, draw->pipeline.aaline); /* how many samplers? */ /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ @@ -699,8 +704,17 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) aaline->sampler_view); draw->suspend_flushing = TRUE; - aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler); - aaline->driver_set_sampler_views(pipe, num_samplers, aaline->state.sampler_views); + + aaline->driver_bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, + num_samplers, aaline->state.sampler); + + aaline->driver_set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, + num_samplers, aaline->state.sampler_views); + + /* Disable triangle culling, stippling, unfilled mode etc. */ + r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade); + pipe->bind_rasterizer_state(pipe, r); + draw->suspend_flushing = FALSE; /* now really draw first line */ @@ -714,22 +728,31 @@ aaline_flush(struct draw_stage *stage, unsigned flags) { struct draw_context *draw = stage->draw; struct aaline_stage *aaline = aaline_stage(stage); - struct pipe_context *pipe = aaline->pipe; + struct pipe_context *pipe = draw->pipe; stage->line = aaline_first_line; stage->next->flush( stage->next, flags ); /* restore original frag shader, texture, sampler state */ draw->suspend_flushing = TRUE; - aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs); - aaline->driver_bind_sampler_states(pipe, aaline->num_samplers, + aaline->driver_bind_fs_state(pipe, aaline->fs ? aaline->fs->driver_fs : NULL); + + aaline->driver_bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, + aaline->num_samplers, aaline->state.sampler); - aaline->driver_set_sampler_views(pipe, - aaline->num_sampler_views, + + aaline->driver_set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, + aaline->num_samplers, aaline->state.sampler_views); + + /* restore original rasterizer state */ + if (draw->rast_handle) { + pipe->bind_rasterizer_state(pipe, draw->rast_handle); + } + draw->suspend_flushing = FALSE; - draw->extra_shader_outputs.slot = 0; + draw_remove_extra_vertex_attribs(draw); } @@ -744,14 +767,15 @@ static void aaline_destroy(struct draw_stage *stage) { struct aaline_stage *aaline = aaline_stage(stage); + struct pipe_context *pipe = stage->draw->pipe; uint i; - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + for (i = 0; i < PIPE_MAX_SHADER_SAMPLER_VIEWS; i++) { pipe_sampler_view_reference(&aaline->state.sampler_views[i], NULL); } if (aaline->sampler_cso) - aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso); + pipe->delete_sampler_state(pipe, aaline->sampler_cso); if (aaline->texture) pipe_resource_reference(&aaline->texture, NULL); @@ -762,6 +786,14 @@ aaline_destroy(struct draw_stage *stage) draw_free_temp_verts( stage ); + /* restore the old entry points */ + pipe->create_fs_state = aaline->driver_create_fs_state; + pipe->bind_fs_state = aaline->driver_bind_fs_state; + pipe->delete_fs_state = aaline->driver_delete_fs_state; + + pipe->bind_sampler_states = aaline->driver_bind_sampler_states; + pipe->set_sampler_views = aaline->driver_set_sampler_views; + FREE( stage ); } @@ -773,9 +805,6 @@ draw_aaline_stage(struct draw_context *draw) if (aaline == NULL) return NULL; - if (!draw_alloc_temp_verts( &aaline->stage, 8 )) - goto fail; - aaline->stage.draw = draw; aaline->stage.name = "aaline"; aaline->stage.next = NULL; @@ -786,11 +815,14 @@ draw_aaline_stage(struct draw_context *draw) aaline->stage.reset_stipple_counter = aaline_reset_stipple_counter; aaline->stage.destroy = aaline_destroy; + if (!draw_alloc_temp_verts( &aaline->stage, 8 )) + goto fail; + return aaline; fail: if (aaline) - aaline_destroy(&aaline->stage); + aaline->stage.destroy(&aaline->stage); return NULL; } @@ -800,7 +832,12 @@ static struct aaline_stage * aaline_stage_from_pipe(struct pipe_context *pipe) { struct draw_context *draw = (struct draw_context *) pipe->draw; - return aaline_stage(draw->pipeline.aaline); + + if (draw) { + return aaline_stage(draw->pipeline.aaline); + } else { + return NULL; + } } @@ -813,14 +850,20 @@ aaline_create_fs_state(struct pipe_context *pipe, const struct pipe_shader_state *fs) { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); - struct aaline_fragment_shader *aafs = CALLOC_STRUCT(aaline_fragment_shader); + struct aaline_fragment_shader *aafs = NULL; + + if (aaline == NULL) + return NULL; + + aafs = CALLOC_STRUCT(aaline_fragment_shader); + if (aafs == NULL) return NULL; - aafs->state = *fs; + aafs->state.tokens = tgsi_dup_tokens(fs->tokens); /* pass-through */ - aafs->driver_fs = aaline->driver_create_fs_state(aaline->pipe, fs); + aafs->driver_fs = aaline->driver_create_fs_state(pipe, fs); return aafs; } @@ -832,11 +875,14 @@ aaline_bind_fs_state(struct pipe_context *pipe, void *fs) struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs; + if (aaline == NULL) { + return; + } + /* save current */ aaline->fs = aafs; /* pass-through */ - aaline->driver_bind_fs_state(aaline->pipe, - (aafs ? aafs->driver_fs : NULL)); + aaline->driver_bind_fs_state(pipe, (aafs ? aafs->driver_fs : NULL)); } @@ -845,53 +891,92 @@ aaline_delete_fs_state(struct pipe_context *pipe, void *fs) { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs; - /* pass-through */ - aaline->driver_delete_fs_state(aaline->pipe, aafs->driver_fs); - if (aafs->aaline_fs) - aaline->driver_delete_fs_state(aaline->pipe, aafs->aaline_fs); + if (aafs == NULL) { + return; + } + + if (aaline != NULL) { + /* pass-through */ + aaline->driver_delete_fs_state(pipe, aafs->driver_fs); + if (aafs->aaline_fs) + aaline->driver_delete_fs_state(pipe, aafs->aaline_fs); + } + + FREE((void*)aafs->state.tokens); FREE(aafs); } static void -aaline_bind_sampler_states(struct pipe_context *pipe, - unsigned num, void **sampler) +aaline_bind_sampler_states(struct pipe_context *pipe, unsigned shader, + unsigned start, unsigned num, void **sampler) { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); - /* save current */ - memcpy(aaline->state.sampler, sampler, num * sizeof(void *)); - aaline->num_samplers = num; + assert(start == 0); + + if (aaline == NULL) { + return; + } + + if (shader == PIPE_SHADER_FRAGMENT) { + /* save current */ + memcpy(aaline->state.sampler, sampler, num * sizeof(void *)); + aaline->num_samplers = num; + } /* pass-through */ - aaline->driver_bind_sampler_states(aaline->pipe, num, sampler); + aaline->driver_bind_sampler_states(pipe, shader, start, num, sampler); } static void -aaline_set_sampler_views(struct pipe_context *pipe, - unsigned num, +aaline_set_sampler_views(struct pipe_context *pipe, unsigned shader, + unsigned start, unsigned num, struct pipe_sampler_view **views) { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); uint i; - /* save current */ - for (i = 0; i < num; i++) { - pipe_sampler_view_reference(&aaline->state.sampler_views[i], views[i]); + if (aaline == NULL) { + return; } - for ( ; i < PIPE_MAX_SAMPLERS; i++) { - pipe_sampler_view_reference(&aaline->state.sampler_views[i], NULL); + + if (shader == PIPE_SHADER_FRAGMENT) { + /* save current */ + for (i = 0; i < num; i++) { + pipe_sampler_view_reference(&aaline->state.sampler_views[start + i], + views[i]); + } + aaline->num_sampler_views = num; } - aaline->num_sampler_views = num; /* pass-through */ - aaline->driver_set_sampler_views(aaline->pipe, num, views); + aaline->driver_set_sampler_views(pipe, shader, start, num, views); } +void +draw_aaline_prepare_outputs(struct draw_context *draw, + struct draw_stage *stage) +{ + struct aaline_stage *aaline = aaline_stage(stage); + const struct pipe_rasterizer_state *rast = draw->rasterizer; + + /* update vertex attrib info */ + aaline->pos_slot = draw_current_shader_position_output(draw);; + + if (!rast->line_smooth) + return; + + /* allocate the extra post-transformed vertex attribute */ + aaline->tex_slot = draw_alloc_extra_vertex_attrib(draw, + TGSI_SEMANTIC_GENERIC, + aaline->fs->generic_attrib); +} + /** * Called by drivers that want to install this AA line prim stage * into the draw module's pipeline. This will not be used if the @@ -911,8 +996,6 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) if (!aaline) goto fail; - aaline->pipe = pipe; - /* create special texture, sampler state */ if (!aaline_create_texture(aaline)) goto fail; @@ -925,16 +1008,16 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) aaline->driver_bind_fs_state = pipe->bind_fs_state; aaline->driver_delete_fs_state = pipe->delete_fs_state; - aaline->driver_bind_sampler_states = pipe->bind_fragment_sampler_states; - aaline->driver_set_sampler_views = pipe->set_fragment_sampler_views; + aaline->driver_bind_sampler_states = pipe->bind_sampler_states; + aaline->driver_set_sampler_views = pipe->set_sampler_views; /* override the driver's functions */ pipe->create_fs_state = aaline_create_fs_state; pipe->bind_fs_state = aaline_bind_fs_state; pipe->delete_fs_state = aaline_delete_fs_state; - pipe->bind_fragment_sampler_states = aaline_bind_sampler_states; - pipe->set_fragment_sampler_views = aaline_set_sampler_views; + pipe->bind_sampler_states = aaline_bind_sampler_states; + pipe->set_sampler_views = aaline_set_sampler_views; /* Install once everything is known to be OK: */