[Mesa-dev] [Piglit] [PATCH] mesa/state_tracker: Fix draw-pixel-with-texture piglit test.
Emil Velikov
emil.l.velikov at gmail.com
Sat Mar 28 16:41:18 PDT 2015
Hi Matthew
I'm suspecting that this patch was meant for mesa-dev ?
-Emil
On 28/03/15 17:07, Matthew Dawson wrote:
> When glDrawPixels was used with an external texture, the pixels passed in
> were sampled instead of the texture. Change gallium to instead move the user
> texture to a new sampler below the glDrawPixels samplers and use the texture
> coordinates from the raster position.
>
> This uses a uniform for the texture coordinates instead passing it through
> the vertex shader as the texture coordinates are constant for the entire
> operation. While working the vertex shader would be possible, implementing
> that solution would break several assumptions throughout the glDrawPixels
> implementation as well as helper functions used by other code paths, increasing
> the chance for breakage.
>
> Tested on llvmpipe, r600, and radeonsi.
>
> V2: Complete everything missing from V1.
>
> v3:
> - Fix style issues.
> - Add comments about how the texture references are fixed up to be valid.
> ---
> src/mesa/state_tracker/st_cb_drawpixels.c | 39 ++++++++++++++++++++++++++---
> src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 40 ++++++++++++++++++++++++++++++
> 2 files changed, 76 insertions(+), 3 deletions(-)
>
> diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
> index 3edf31b..47abd16 100644
> --- a/src/mesa/state_tracker/st_cb_drawpixels.c
> +++ b/src/mesa/state_tracker/st_cb_drawpixels.c
> @@ -44,6 +44,7 @@
> #include "main/texstore.h"
> #include "main/glformats.h"
> #include "program/program.h"
> +#include "program/prog_parameter.h"
> #include "program/prog_print.h"
> #include "program/prog_instruction.h"
>
> @@ -676,6 +677,8 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
> GLfloat x0, y0, x1, y1;
> GLsizei maxSize;
> boolean normalized = sv[0]->texture->target != PIPE_TEXTURE_RECT;
> + GLuint num_user_samplers = st->state.num_samplers[PIPE_SHADER_FRAGMENT];
> + unsigned int i;
>
> /* limit checks */
> /* XXX if DrawPixels image is larger than max texture size, break
> @@ -765,6 +768,10 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
> if (num_sampler_view > 1) {
> cso_single_sampler(cso, PIPE_SHADER_FRAGMENT, 1, &sampler);
> }
> + for (i = 0; i < num_user_samplers; ++i) {
> + cso_single_sampler(cso, PIPE_SHADER_FRAGMENT, i+num_sampler_view,
> + &st->state.samplers[PIPE_SHADER_FRAGMENT][i]);
> + }
> cso_single_sampler_done(cso, PIPE_SHADER_FRAGMENT);
> }
>
> @@ -786,7 +793,14 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
> cso_set_stream_outputs(st->cso_context, 0, NULL, NULL);
>
> /* texture state: */
> - cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, num_sampler_view, sv);
> + {
> + struct pipe_sampler_view *lsv[PIPE_MAX_SAMPLERS];
> + memcpy(lsv, sv, num_sampler_view*sizeof(struct pipe_sampler_view*));
> + memcpy(lsv+num_sampler_view, st->state.sampler_views[PIPE_SHADER_FRAGMENT],
> + num_user_samplers*sizeof(struct pipe_sampler_view*));
> + cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT,
> + num_sampler_view+num_user_samplers, lsv);
> + }
>
> /* Compute Gallium window coords (y=0=top) with pixel zoom.
> * Recall that these coords are transformed by the current
> @@ -1160,8 +1174,27 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
> }
> }
>
> - /* update fragment program constants */
> - st_upload_constants(st, fpv->parameters, PIPE_SHADER_FRAGMENT);
> + /* updated texture coordinates and fragment program constants. */
> + {
> + int i;
> + struct gl_program_parameter_list *parameters = fpv->parameters;
> + /* Update the texture coordinates from all the used texture units, using
> + * the values associated with the raster position */
> + for (i = 0; i < parameters->NumParameters; ++i) {
> + const char *name = parameters->Parameters[i].Name;
> + /* Any texture coordinate will use the parameter name texcoord_, where
> + * _ is the texture units id added to the ascii character 'A'. This
> + * checks if a parameter matches this patterns, and updates the
> + * parameter's value with the appropriate raster position texture
> + * coordinate. */
> + if (strncmp("texcoord", name, 8) == 0 && strlen(name) == 9) {
> + memcpy(parameters->ParameterValues[i],
> + st->ctx->Current.RasterTexCoords[name[8] - 'A'],
> + sizeof(GL_FLOAT) * 4);
> + }
> + }
> + st_upload_constants(st, parameters, PIPE_SHADER_FRAGMENT);
> + }
>
> /* draw with textured quad */
> {
> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> index e97ab83..b2f6e6e 100644
> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> @@ -4256,6 +4256,7 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
> st_src_reg coord, src0;
> st_dst_reg dst0;
> glsl_to_tgsi_instruction *inst;
> + unsigned int count_samplers_used = 0;
>
> /* Copy attributes of the glsl_to_tgsi_visitor in the original shader. */
> v->ctx = original->ctx;
> @@ -4286,6 +4287,7 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
> prog->InputsRead |= VARYING_BIT_TEX0;
> prog->SamplersUsed |= (1 << 0); /* mark sampler 0 as used */
> v->samplers_used |= (1 << 0);
> + count_samplers_used++;
>
> if (scale_and_bias) {
> static const gl_state_index scale_state[STATE_LENGTH] =
> @@ -4333,6 +4335,7 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
>
> prog->SamplersUsed |= (1 << 1); /* mark sampler 1 as used */
> v->samplers_used |= (1 << 1);
> + count_samplers_used++;
>
> /* MOV colorTemp, temp; */
> inst = v->emit(NULL, TGSI_OPCODE_MOV, dst0, temp);
> @@ -4361,6 +4364,43 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
> newinst = v->emit(NULL, inst->op, inst->dst[0], src_regs[0], src_regs[1], src_regs[2]);
> newinst->tex_target = inst->tex_target;
> newinst->sampler_array_size = inst->sampler_array_size;
> +
> + /* If the original fragment shader (either user supplied, or generated from
> + * the fixed function pipeline) references a texture, fix up the instruction
> + * here to not conflict with the DrawPixels shader. */
> + if (newinst->tex_target != 0) {
> + int new_sampler_index;
> + char name[10];
> + GLint param;
> +
> + /* Grab the original sampler, and move it up by the number of samplers
> + * used by the DrawPixels shader. */
> + newinst->sampler = inst->sampler;
> + new_sampler_index = newinst->sampler.index + count_samplers_used;
> +
> + /* This name records what texture coordinates are need for this parameter.
> + * This is used later to update the texture coordinates as appropriate. */
> + memcpy(name, "texcoord_", 10);
> + name[8] = 'A' + newinst->sampler.index; // Replaces the underscore from above, while keeping the null byte.
> +
> + if ((prog->SamplersUsed & (1 << new_sampler_index)) == 0) {
> + /* If this is the first instruction referencing it, create a uniform
> + * to store its texture coordinate, which will be a constant for the
> + * whole drawn area */
> + param = _mesa_add_parameter(params, PROGRAM_UNIFORM, name, 4, GL_FLOAT, (const gl_constant_value*)st->ctx->Current.RasterTexCoords[newinst->sampler.index], 0);
> + } else {
> + /* Otherwise get its parameter index to use below */
> + param = _mesa_lookup_parameter_index(params, -1, name);
> + }
> + /* Update the new instruction with the new sampler index and texture
> + * coordinate parameter. */
> + newinst->src[0] = st_src_reg(PROGRAM_UNIFORM, param, GLSL_TYPE_FLOAT);
> + newinst->sampler.index = new_sampler_index;
> +
> + /* And mark the sampler as used */
> + prog->SamplersUsed |= (1 << new_sampler_index);
> + v->samplers_used |= (1 << new_sampler_index);
> + }
> }
>
> /* Make modifications to fragment program info. */
>
More information about the mesa-dev
mailing list