[Mesa-dev] [PATCH 1/2] draw: simplify (and correct) aaline fallback (v2)
Jose Fonseca
jfonseca at vmware.com
Wed Mar 7 10:34:37 UTC 2018
On 06/03/18 20:52, Brian Paul wrote:
> Looks good. That certainly does simplify things. Two minor
> suggestions below.
>
> In any case, for both, Reviewed-by: Brian Paul <brianp at vmware.com>
Looks great cleanup to me too. Just minor issues inline. Both are
Reviewed-by: Jose Fonseca <jfonseca at vmware.com>
>
> On 03/06/2018 01:34 PM, sroland at vmware.com wrote:
>> From: Roland Scheidegger <sroland at vmware.com>
>>
>> The motivation actually was to get rid of the additional tex
>> instruction, since that requires the draw fallback code to intercept
>> all sampler / view calls (even if the fallback is never hit).
>> Basically, the idea is to use coverage of the pixel to calculate
>> the alpha value, and coverage is simply based on the distance
>> to the center of the line (in both line direction, which is useful
>> for wide lines, as well as perpendicular to the line).
>> This is much closer to what hw supporting this natively actually does.
>> It also fixes an issue with line width not quite being correct, as
>> well as endpoints getting stretched too far (in line direction) with
>> wide lines, which is apparent with mesa demo line-width.
>> (For llvmpipe, it would probably make sense to do something like this
>> directly when drawing lines, since rendering two tris is twice as
>> expensive as a line, but it would need some changes with state
>> management.)
>> Since we're no longer relying on mipmapping to get the alpha value,
>> we also don't need to draw 3 rects (6 tris), one is sufficient.
>>
>> There's still issues (as before):
>> - quite sure it's not correct without half_pixel_center, but can't test
>> this with GL.
>> - aaline + line stipple is incorrect (evident with line-width demo).
>> Looking at the spec the stipple pattern should actually be based on
>> distance (not just dx or dy for x/y major lines as without aa).
>> - outputs (other than pos + the one used for line aa) should be
>> reinterpolated since we actually increase line length by half a pixel
>> (but there's no tests which would care).
>>
>> v2: simplify the math (should be equivalent), don't need immediate
>> ---
>> src/gallium/auxiliary/draw/draw_pipe_aaline.c | 504
>> +++++---------------------
>> 1 file changed, 100 insertions(+), 404 deletions(-)
>>
>> diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c
>> b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
>> index a859dbc..591e2a3 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 VMware, Inc.
>> + * Copyright 2007-2018 VMware, Inc.
>> * All Rights Reserved.
>> *
>> * Permission is hereby granted, free of charge, to any person
>> obtaining a
>> @@ -26,7 +26,7 @@
>> **************************************************************************/
>> /**
>> - * AA line stage: AA lines are converted to texture mapped triangles.
>> + * AA line stage: AA lines are converted triangles (with extra
>> generic)
>> *
>> * Authors: Brian Paul
>> */
>> @@ -40,7 +40,6 @@
>> #include "util/u_format.h"
>> #include "util/u_math.h"
>> #include "util/u_memory.h"
>> -#include "util/u_sampler.h"
>> #include "tgsi/tgsi_transform.h"
>> #include "tgsi/tgsi_dump.h"
>> @@ -55,19 +54,6 @@
>> /**
>> - * 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 (TEXTURE_SIZE_LOG2 - 2)
>> -
>> -
>> -/**
>> * Subclass of pipe_shader_state to carry extra fragment shader info.
>> */
>> struct aaline_fragment_shader
>> @@ -75,8 +61,7 @@ struct aaline_fragment_shader
>> struct pipe_shader_state state;
>> void *driver_fs;
>> void *aaline_fs;
>> - uint sampler_unit;
>> - int generic_attrib; /**< texcoord/generic used for texture */
>> + int generic_attrib; /**< generic used for distance */
>> };
>> @@ -89,26 +74,16 @@ struct aaline_stage
>> float half_line_width;
>> - /** For AA lines, this is the vertex attrib slot for the new
>> texcoords */
>> - uint tex_slot;
>> + /** For AA lines, this is the vertex attrib slot for new generic */
>> + uint coord_slot;
>> /** position, not necessarily output zero */
>> uint pos_slot;
>> - void *sampler_cso;
>> - struct pipe_resource *texture;
>> - struct pipe_sampler_view *sampler_view;
>> - uint num_samplers;
>> - uint num_sampler_views;
>> -
>> /*
>> * Currently bound state
>> */
>> struct aaline_fragment_shader *fs;
>> - struct {
>> - void *sampler[PIPE_MAX_SAMPLERS];
>> - struct pipe_sampler_view
>> *sampler_views[PIPE_MAX_SHADER_SAMPLER_VIEWS];
>> - } state;
>> /*
>> * Driver interface/override functions
>> @@ -117,15 +92,6 @@ struct aaline_stage
>> const struct pipe_shader_state *);
>> 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 *,
>> - enum pipe_shader_type, unsigned,
>> - unsigned, void **);
>> -
>> - void (*driver_set_sampler_views)(struct pipe_context *,
>> - enum pipe_shader_type shader,
>> - unsigned start, unsigned count,
>> - struct pipe_sampler_view **);
>> };
>> @@ -136,41 +102,27 @@ struct aaline_stage
>> */
>> struct aa_transform_context {
>> struct tgsi_transform_context base;
>> - uint tempsUsed; /**< bitmask */
>> + uint64_t tempsUsed; /**< bitmask */
>> int colorOutput; /**< which output is the primary color */
>> - uint samplersUsed; /**< bitfield of samplers used */
>> - bool hasSview;
>> - int freeSampler; /** an available sampler for the pstipple */
>> int maxInput, maxGeneric; /**< max input index found */
>> - int colorTemp, texTemp; /**< temp registers */
>> + int colorTemp, aaTemp; /**< temp registers */
>> };
>> -
>> /**
>> * TGSI declaration transform callback.
>> - * Look for a free sampler, a free input attrib, and two free temp
>> regs.
>> + * Look for a free input attrib, and two free temp regs.
>> */
>> static void
>> aa_transform_decl(struct tgsi_transform_context *ctx,
>> struct tgsi_full_declaration *decl)
>> {
>> - struct aa_transform_context *aactx = (struct aa_transform_context
>> *) ctx;
>> + struct aa_transform_context *aactx = (struct aa_transform_context
>> *)ctx;
>> if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
>> decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
>> decl->Semantic.Index == 0) {
>> aactx->colorOutput = decl->Range.First;
>> }
>> - else if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
>> - uint i;
>> - for (i = decl->Range.First;
>> - i <= decl->Range.Last; i++) {
>> - aactx->samplersUsed |= 1u << i;
>> - }
>> - }
>> - else if (decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) {
>> - aactx->hasSview = true;
>> - }
>> else if (decl->Declaration.File == TGSI_FILE_INPUT) {
>> if ((int) decl->Range.Last > aactx->maxInput)
>> aactx->maxInput = decl->Range.Last;
>> @@ -183,7 +135,10 @@ aa_transform_decl(struct tgsi_transform_context
>> *ctx,
>> uint i;
>> for (i = decl->Range.First;
>> i <= decl->Range.Last; i++) {
>> - aactx->tempsUsed |= (1 << i);
>> + /*
>> + * XXX this bitfield doesn't cut it...
>> + */
>> + aactx->tempsUsed |= (1ULL << i);
UINT64_C(1)
>> }
>> }
>> @@ -192,16 +147,6 @@ aa_transform_decl(struct
>> tgsi_transform_context *ctx,
>> /**
>> - * Find the lowest zero bit in the given word, or -1 if bitfield is
>> all ones.
>> - */
>> -static int
>> -free_bit(uint bitfield)
>> -{
>> - return ffs(~bitfield) - 1;
>> -}
>> -
>> -
>> -/**
>> * TGSI transform prolog callback.
>> */
>> static void
>> @@ -210,49 +155,29 @@ aa_transform_prolog(struct
>> tgsi_transform_context *ctx)
>> struct aa_transform_context *aactx = (struct
>> aa_transform_context *) ctx;
>> uint i;
>> - STATIC_ASSERT(sizeof(aactx->samplersUsed) * 8 >=
>> PIPE_MAX_SAMPLERS);
>> -
>> - /* find free sampler */
>> - aactx->freeSampler = free_bit(aactx->samplersUsed);
>> - if (aactx->freeSampler < 0 || aactx->freeSampler >=
>> PIPE_MAX_SAMPLERS)
>> - aactx->freeSampler = PIPE_MAX_SAMPLERS - 1;
>> /* find two free temp regs */
>> - for (i = 0; i < 32; i++) {
>> + for (i = 0; i < 64; i++) {
>> if ((aactx->tempsUsed & (1 << i)) == 0) {
>> /* found a free temp */
>> if (aactx->colorTemp < 0)
>> aactx->colorTemp = i;
>> - else if (aactx->texTemp < 0)
>> - aactx->texTemp = i;
>> + else if (aactx->aaTemp < 0)
>> + aactx->aaTemp = i;
>> else
>> break;
>> }
>> }
>
> The loop could probably be eliminated and replaced with a couple
> ffsll(~tempsUsed) calls.
>
>
>> assert(aactx->colorTemp >= 0);
>> - assert(aactx->texTemp >= 0);
>> + assert(aactx->aaTemp >= 0);
>> /* declare new generic input/texcoord */
>> tgsi_transform_input_decl(ctx, aactx->maxInput + 1,
>> TGSI_SEMANTIC_GENERIC,
>> aactx->maxGeneric + 1,
>> TGSI_INTERPOLATE_LINEAR);
>> - /* declare new sampler */
>> - tgsi_transform_sampler_decl(ctx, aactx->freeSampler);
>> -
>> - /* if the src shader has SVIEW decl's for each SAMP decl, we
>> - * need to continue the trend and ensure there is a matching
>> - * SVIEW for the new SAMP we just created
>> - */
>> - if (aactx->hasSview) {
>> - tgsi_transform_sampler_view_decl(ctx,
>> - aactx->freeSampler,
>> - TGSI_TEXTURE_2D,
>> - TGSI_RETURN_TYPE_FLOAT);
>> - }
>> -
>> /* declare new temp regs */
>> - tgsi_transform_temp_decl(ctx, aactx->texTemp);
>> + tgsi_transform_temp_decl(ctx, aactx->aaTemp);
>> tgsi_transform_temp_decl(ctx, aactx->colorTemp);
>> }
>> @@ -266,13 +191,41 @@ aa_transform_epilog(struct
>> tgsi_transform_context *ctx)
>> struct aa_transform_context *aactx = (struct
>> aa_transform_context *) ctx;
>> if (aactx->colorOutput != -1) {
>> - /* insert texture sampling code for antialiasing. */
>> -
>> - /* TEX texTemp, input_coord, sampler, 2D */
>> - tgsi_transform_tex_inst(ctx,
>> - TGSI_FILE_TEMPORARY, aactx->texTemp,
>> - TGSI_FILE_INPUT, aactx->maxInput + 1,
>> - TGSI_TEXTURE_2D, aactx->freeSampler);
>> + struct tgsi_full_instruction inst;
>> + /* insert distance-based coverage code for antialiasing. */
>> +
>> + /* saturate(linewidth - fabs(interpx), linelength -
>> fabs(interpz) */
>> + inst = tgsi_default_full_instruction();
>> + inst.Instruction.Saturate = true;
>> + inst.Instruction.Opcode = TGSI_OPCODE_ADD;
>> + inst.Instruction.NumDstRegs = 1;
>> + tgsi_transform_dst_reg(&inst.Dst[0], TGSI_FILE_TEMPORARY,
>> + aactx->aaTemp, TGSI_WRITEMASK_XZ);
>> + inst.Instruction.NumSrcRegs = 2;
>> + tgsi_transform_src_reg(&inst.Src[1], TGSI_FILE_INPUT,
>> aactx->maxInput + 1,
>> + TGSI_SWIZZLE_X, TGSI_SWIZZLE_X,
>> + TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z);
>> + tgsi_transform_src_reg(&inst.Src[0], TGSI_FILE_INPUT,
>> aactx->maxInput + 1,
>> + TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Y,
>> + TGSI_SWIZZLE_W, TGSI_SWIZZLE_W);
>> + inst.Src[1].Register.Absolute = true;
>> + inst.Src[1].Register.Negate = true;
>> + ctx->emit_instruction(ctx, &inst);
>> +
>> + /* MUL width / height alpha */
>> + inst = tgsi_default_full_instruction();
>> + inst.Instruction.Opcode = TGSI_OPCODE_MUL;
>> + inst.Instruction.NumDstRegs = 1;
>> + tgsi_transform_dst_reg(&inst.Dst[0], TGSI_FILE_TEMPORARY,
>> + aactx->aaTemp, TGSI_WRITEMASK_W);
>> + inst.Instruction.NumSrcRegs = 2;
>> + tgsi_transform_src_reg(&inst.Src[0], TGSI_FILE_TEMPORARY,
>> aactx->aaTemp,
>> + TGSI_SWIZZLE_X, TGSI_SWIZZLE_X,
>> + TGSI_SWIZZLE_X, TGSI_SWIZZLE_X);
>> + tgsi_transform_src_reg(&inst.Src[1], TGSI_FILE_TEMPORARY,
>> aactx->aaTemp,
>> + TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z,
>> + TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z);
>> + ctx->emit_instruction(ctx, &inst);
>
> I think you might be able to use tgsi_transform_op2_swz_inst() here.
>
>
>> /* MOV rgb */
>> tgsi_transform_op1_inst(ctx, TGSI_OPCODE_MOV,
>> @@ -285,7 +238,7 @@ aa_transform_epilog(struct tgsi_transform_context
>> *ctx)
>> TGSI_FILE_OUTPUT, aactx->colorOutput,
>> TGSI_WRITEMASK_W,
>> TGSI_FILE_TEMPORARY, aactx->colorTemp,
>> - TGSI_FILE_TEMPORARY, aactx->texTemp,
>> false);
>> + TGSI_FILE_TEMPORARY, aactx->aaTemp,
>> false);
>> }
>> }
>> @@ -319,7 +272,7 @@ aa_transform_inst(struct tgsi_transform_context
>> *ctx,
>> /**
>> * Generate the frag shader we'll use for drawing AA lines.
>> - * This will be the user's shader plus some texture/modulate
>> instructions.
>> + * This will be the user's shader plus some arithmetic instructions.
>> */
>> static boolean
>> generate_aaline_fs(struct aaline_stage *aaline)
>> @@ -340,7 +293,7 @@ generate_aaline_fs(struct aaline_stage *aaline)
>> transform.maxInput = -1;
>> transform.maxGeneric = -1;
>> transform.colorTemp = -1;
>> - transform.texTemp = -1;
>> + transform.aaTemp = -1;
>> transform.base.prolog = aa_transform_prolog;
>> transform.base.epilog = aa_transform_epilog;
>> transform.base.transform_instruction = aa_transform_inst;
>> @@ -357,8 +310,6 @@ generate_aaline_fs(struct aaline_stage *aaline)
>> tgsi_dump(aaline_fs.tokens, 0);
>> #endif
>> - aaline->fs->sampler_unit = transform.freeSampler;
>> -
>> aaline->fs->aaline_fs = aaline->driver_create_fs_state(pipe,
>> &aaline_fs);
>> if (aaline->fs->aaline_fs == NULL)
>> goto fail;
>> @@ -374,125 +325,6 @@ fail:
>> /**
>> - * Create the texture map we'll use for antialiasing the lines.
>> - */
>> -static boolean
>> -aaline_create_texture(struct aaline_stage *aaline)
>> -{
>> - struct pipe_context *pipe = aaline->stage.draw->pipe;
>> - struct pipe_screen *screen = pipe->screen;
>> - struct pipe_resource texTemp;
>> - struct pipe_sampler_view viewTempl;
>> - uint level;
>> -
>> - memset(&texTemp, 0, sizeof(texTemp));
>> - 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 << 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);
>> - if (!aaline->texture)
>> - return FALSE;
>> -
>> - u_sampler_view_default_template(&viewTempl,
>> - aaline->texture,
>> - aaline->texture->format);
>> - aaline->sampler_view = pipe->create_sampler_view(pipe,
>> - aaline->texture,
>> - &viewTempl);
>> - if (!aaline->sampler_view) {
>> - return FALSE;
>> - }
>> -
>> - /* 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
>> - * (though, those levels shouldn't be used - see the max_lod
>> setting).
>> - */
>> - for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) {
>> - struct pipe_transfer *transfer;
>> - struct pipe_box box;
>> - const uint size = u_minify(aaline->texture->width0, level);
>> - ubyte *data;
>> - uint i, j;
>> -
>> - assert(aaline->texture->width0 == aaline->texture->height0);
>> -
>> - u_box_origin_2d(size, size, &box);
>> -
>> - /* This texture is new, no need to flush.
>> - */
>> - data = pipe->transfer_map(pipe,
>> - aaline->texture,
>> - level,
>> - PIPE_TRANSFER_WRITE,
>> - &box, &transfer);
>> -
>> - if (!data)
>> - return FALSE;
>> -
>> - for (i = 0; i < size; i++) {
>> - for (j = 0; j < size; j++) {
>> - ubyte d;
>> - if (size == 1) {
>> - d = 255;
>> - }
>> - else if (size == 2) {
>> - d = 200; /* tuneable */
>> - }
>> - else if (i == 0 || j == 0 || i == size - 1 || j == size
>> - 1) {
>> - d = 35; /* edge texel */
>> - }
>> - else {
>> - d = 255;
>> - }
>> - data[i * transfer->stride + j] = d;
>> - }
>> - }
>> -
>> - /* unmap */
>> - pipe->transfer_unmap(pipe, transfer);
>> - }
>> - return TRUE;
>> -}
>> -
>> -
>> -/**
>> - * Create the sampler CSO that'll be used for antialiasing.
>> - * By using a mipmapped texture, we don't have to generate a different
>> - * texture image for each line size.
>> - */
>> -static boolean
>> -aaline_create_sampler(struct aaline_stage *aaline)
>> -{
>> - struct pipe_sampler_state sampler;
>> - struct pipe_context *pipe = aaline->stage.draw->pipe;
>> -
>> - memset(&sampler, 0, sizeof(sampler));
>> - sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
>> - sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
>> - sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
>> - sampler.min_mip_filter = PIPE_TEX_MIPFILTER_LINEAR;
>> - sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
>> - sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
>> - sampler.normalized_coords = 1;
>> - sampler.min_lod = 0.0f;
>> - sampler.max_lod = MAX_TEXTURE_LEVEL;
>> -
>> - aaline->sampler_cso = pipe->create_sampler_state(pipe, &sampler);
>> - if (aaline->sampler_cso == NULL)
>> - return FALSE;
>> -
>> - return TRUE;
>> -}
>> -
>> -
>> -/**
>> * When we're about to draw our first AA line in a batch, this
>> function is
>> * called to tell the driver to bind our modified fragment shader.
>> */
>> @@ -532,112 +364,83 @@ aaline_line(struct draw_stage *stage, struct
>> prim_header *header)
>> const float half_width = aaline->half_line_width;
>> struct prim_header tri;
>> struct vertex_header *v[8];
>> - uint texPos = aaline->tex_slot;
>> + uint coordPos = aaline->coord_slot;
>> uint posPos = aaline->pos_slot;
>> float *pos, *tex;
>> float dx = header->v[1]->data[posPos][0] -
>> header->v[0]->data[posPos][0];
>> float dy = header->v[1]->data[posPos][1] -
>> header->v[0]->data[posPos][1];
>> double a = atan2(dy, dx);
>> float c_a = (float) cos(a), s_a = (float) sin(a);
>> + float half_length;
>> + float t_l, t_w;
>> uint i;
>> - /* XXX the ends of lines aren't quite perfect yet, but probably
>> passable */
>> - dx = 0.5F * half_width;
>> - dy = half_width;
>> + half_length = sqrtf(dx * dx + dy * dy) / 2.0f + 0.5f;
0.5f * ... ?
>> +
>> + t_w = half_width;
>> + t_l = 0.5f;
>> /* allocate/dup new verts */
>> - for (i = 0; i < 8; i++) {
>> - v[i] = dup_vert(stage, header->v[i/4], i);
>> + for (i = 0; i < 4; i++) {
>> + v[i] = dup_vert(stage, header->v[i/2], i);
>> }
>> /*
>> * Quad strip for line from v0 to v1 (*=endpoints):
>> *
>> - * 1 3 5 7
>> - * +---+---------------------+---+
>> + * 1 3
>> + * +-----------------------------+
>> * | |
>> * | *v0 v1* |
>> * | |
>> - * +---+---------------------+---+
>> - * 0 2 4 6
>> + * +-----------------------------+
>> + * 0 2
>> + */
>> +
>> + /*
>> + * We increase line length by 0.5 pixels (at each endpoint),
>> + * and calculate the tri endpoints by moving them half-width
>> + * distance away perpendicular to the line.
>> + * XXX: since we change line endpoints (by 0.5 pixel), should
>> + * actually re-interpolate all other values?
>> */
>> /* new verts */
>> pos = v[0]->data[posPos];
>> - pos[0] += (-dx * c_a - dy * s_a);
>> - pos[1] += (-dx * s_a + dy * c_a);
>> + pos[0] += (-t_l * c_a - t_w * s_a);
>> + pos[1] += (-t_l * s_a + t_w * c_a);
>> pos = v[1]->data[posPos];
>> - pos[0] += (-dx * c_a - -dy * s_a);
>> - pos[1] += (-dx * s_a + -dy * c_a);
>> + pos[0] += (-t_l * c_a - -t_w * s_a);
>> + pos[1] += (-t_l * s_a + -t_w * c_a);
>> pos = v[2]->data[posPos];
>> - pos[0] += (dx * c_a - dy * s_a);
>> - pos[1] += (dx * s_a + dy * c_a);
>> + pos[0] += (t_l * c_a - t_w * s_a);
>> + pos[1] += (t_l * s_a + t_w * c_a);
>> pos = v[3]->data[posPos];
>> - pos[0] += (dx * c_a - -dy * s_a);
>> - pos[1] += (dx * s_a + -dy * c_a);
>> -
>> - pos = v[4]->data[posPos];
>> - pos[0] += (-dx * c_a - dy * s_a);
>> - pos[1] += (-dx * s_a + dy * c_a);
>> -
>> - pos = v[5]->data[posPos];
>> - pos[0] += (-dx * c_a - -dy * s_a);
>> - pos[1] += (-dx * s_a + -dy * c_a);
>> -
>> - pos = v[6]->data[posPos];
>> - pos[0] += (dx * c_a - dy * s_a);
>> - pos[1] += (dx * s_a + dy * c_a);
>> -
>> - pos = v[7]->data[posPos];
>> - pos[0] += (dx * c_a - -dy * s_a);
>> - pos[1] += (dx * s_a + -dy * c_a);
>> + pos[0] += (t_l * c_a - -t_w * s_a);
>> + pos[1] += (t_l * s_a + -t_w * c_a);
>> /* new texcoords */
>> - tex = v[0]->data[texPos];
>> - ASSIGN_4V(tex, 0, 0, 0, 1);
>> -
>> - tex = v[1]->data[texPos];
>> - ASSIGN_4V(tex, 0, 1, 0, 1);
>> -
>> - tex = v[2]->data[texPos];
>> - ASSIGN_4V(tex, .5, 0, 0, 1);
>> + tex = v[0]->data[coordPos];
>> + /* XXX need to adjust for pixel center? */
You could just check for pixel_center and write an warning.
+ ASSIGN_4V(tex, -half_width, half_width, -half_length, half_length);
>> - tex = v[3]->data[texPos];
>> - ASSIGN_4V(tex, .5, 1, 0, 1);
>> + tex = v[1]->data[coordPos];
>> + ASSIGN_4V(tex, half_width, half_width, -half_length, half_length);
>> - tex = v[4]->data[texPos];
>> - ASSIGN_4V(tex, .5, 0, 0, 1);
>> + tex = v[2]->data[coordPos];
>> + ASSIGN_4V(tex, -half_width, half_width, half_length, half_length);
>> - tex = v[5]->data[texPos];
>> - ASSIGN_4V(tex, .5, 1, 0, 1);
>> + tex = v[3]->data[coordPos];
>> + ASSIGN_4V(tex, half_width, half_width, half_length, half_length);
>> - tex = v[6]->data[texPos];
>> - ASSIGN_4V(tex, 1, 0, 0, 1);
>> -
>> - tex = v[7]->data[texPos];
>> - ASSIGN_4V(tex, 1, 1, 0, 1);
>> -
>> - /* emit 6 tris for the quad strip */
>> tri.v[0] = v[2]; tri.v[1] = v[1]; tri.v[2] = v[0];
>> stage->next->tri(stage->next, &tri);
>> tri.v[0] = v[3]; tri.v[1] = v[1]; tri.v[2] = v[2];
>> stage->next->tri(stage->next, &tri);
>> -
>> - tri.v[0] = v[4]; tri.v[1] = v[3]; tri.v[2] = v[2];
>> - stage->next->tri(stage->next, &tri);
>> -
>> - tri.v[0] = v[5]; tri.v[1] = v[3]; tri.v[2] = v[4];
>> - stage->next->tri(stage->next, &tri);
>> -
>> - tri.v[0] = v[6]; tri.v[1] = v[5]; tri.v[2] = v[4];
>> - stage->next->tri(stage->next, &tri);
>> -
>> - tri.v[0] = v[7]; tri.v[1] = v[5]; tri.v[2] = v[6];
>> - stage->next->tri(stage->next, &tri);
>> }
>> @@ -648,19 +451,17 @@ aaline_first_line(struct draw_stage *stage,
>> struct prim_header *header)
>> struct draw_context *draw = stage->draw;
>> struct pipe_context *pipe = draw->pipe;
>> const struct pipe_rasterizer_state *rast = draw->rasterizer;
>> - uint num_samplers;
>> - uint num_sampler_views;
>> void *r;
>> assert(draw->rasterizer->line_smooth);
>> - if (draw->rasterizer->line_width <= 2.2)
>> - aaline->half_line_width = 1.1f;
>> + if (draw->rasterizer->line_width <= 1.0)
>> + aaline->half_line_width = 1.0;
>> else
>> - aaline->half_line_width = 0.5f * draw->rasterizer->line_width;
>> + aaline->half_line_width = 0.5f * draw->rasterizer->line_width
>> + 0.5f;
>> /*
>> - * Bind (generate) our fragprog, sampler and texture
>> + * Bind (generate) our fragprog
>> */
>> if (!bind_aaline_fragment_shader(aaline)) {
>> stage->line = draw_pipe_passthrough_line;
>> @@ -670,23 +471,8 @@ aaline_first_line(struct draw_stage *stage,
>> struct prim_header *header)
>> draw_aaline_prepare_outputs(draw, draw->pipeline.aaline);
>> - /* how many samplers? */
>> - /* we'll use sampler/texture[aaline->sampler_unit] for the alpha
>> texture */
>> - num_samplers = MAX2(aaline->num_samplers,
>> aaline->fs->sampler_unit + 1);
>> - num_sampler_views = MAX2(num_samplers, aaline->num_sampler_views);
>> -
>> - aaline->state.sampler[aaline->fs->sampler_unit] =
>> aaline->sampler_cso;
>> -
>> pipe_sampler_view_reference(&aaline->state.sampler_views[aaline->fs->sampler_unit],
>> - aaline->sampler_view);
>> -
>> draw->suspend_flushing = TRUE;
>> - 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_sampler_views,
>> 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);
>> @@ -709,18 +495,10 @@ aaline_flush(struct draw_stage *stage, unsigned
>> flags)
>> stage->line = aaline_first_line;
>> stage->next->flush(stage->next, flags);
>> - /* restore original frag shader, texture, sampler state */
>> + /* restore original frag shader */
>> draw->suspend_flushing = TRUE;
>> 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, 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);
>> @@ -744,21 +522,6 @@ 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_SHADER_SAMPLER_VIEWS; i++) {
>> - pipe_sampler_view_reference(&aaline->state.sampler_views[i], NULL);
>> - }
>> -
>> - if (aaline->sampler_cso)
>> - pipe->delete_sampler_state(pipe, aaline->sampler_cso);
>> -
>> - if (aaline->texture)
>> - pipe_resource_reference(&aaline->texture, NULL);
>> -
>> - if (aaline->sampler_view) {
>> - pipe_sampler_view_reference(&aaline->sampler_view, NULL);
>> - }
>> draw_free_temp_verts(stage);
>> @@ -767,9 +530,6 @@ aaline_destroy(struct draw_stage *stage)
>> 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);
>> }
>> @@ -884,57 +644,6 @@ aaline_delete_fs_state(struct pipe_context
>> *pipe, void *fs)
>> }
>> -static void
>> -aaline_bind_sampler_states(struct pipe_context *pipe,
>> - enum pipe_shader_type shader,
>> - unsigned start, unsigned num, void
>> **sampler)
>> -{
>> - struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
>> -
>> - assert(start == 0);
>> -
>> - if (!aaline) {
>> - 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(pipe, shader, start, num,
>> sampler);
>> -}
>> -
>> -
>> -static void
>> -aaline_set_sampler_views(struct pipe_context *pipe,
>> - enum pipe_shader_type shader,
>> - unsigned start, unsigned num,
>> - struct pipe_sampler_view **views)
>> -{
>> - struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
>> - uint i;
>> -
>> - if (!aaline) {
>> - return;
>> - }
>> -
>> - 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;
>> - }
>> -
>> - /* pass-through */
>> - aaline->driver_set_sampler_views(pipe, shader, start, num, views);
>> -}
>> -
>> -
>> void
>> draw_aaline_prepare_outputs(struct draw_context *draw,
>> struct draw_stage *stage)
>> @@ -949,7 +658,7 @@ draw_aaline_prepare_outputs(struct draw_context
>> *draw,
>> return;
>> /* allocate the extra post-transformed vertex attribute */
>> - aaline->tex_slot = draw_alloc_extra_vertex_attrib(draw,
>> + aaline->coord_slot = draw_alloc_extra_vertex_attrib(draw,
>> TGSI_SEMANTIC_GENERIC,
>> aaline->fs->generic_attrib);
>> }
>> @@ -978,24 +687,11 @@ 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_sampler_states;
>> - aaline->driver_set_sampler_views = pipe->set_sampler_views;
>> -
>> - /* create special texture, sampler state */
>> - if (!aaline_create_texture(aaline))
>> - goto fail;
>> -
>> - if (!aaline_create_sampler(aaline))
>> - goto fail;
>> -
>> /* 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_sampler_states = aaline_bind_sampler_states;
>> - pipe->set_sampler_views = aaline_set_sampler_views;
>> -
>> /* Install once everything is known to be OK:
>> */
>> draw->pipeline.aaline = &aaline->stage;
>>
>
More information about the mesa-dev
mailing list