st/mesa: implement DrawPixels shader transformation using tgsi_transform_shader
Reviewed-by: Dave Airlie <airlied@redhat.com> Reviewed-by: Brian Paul <brianp@vmware.com> Tested-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
@@ -426,6 +426,7 @@ STATETRACKER_FILES = \
|
||||
state_tracker/st_cb_condrender.h \
|
||||
state_tracker/st_cb_drawpixels.c \
|
||||
state_tracker/st_cb_drawpixels.h \
|
||||
state_tracker/st_cb_drawpixels_shader.c \
|
||||
state_tracker/st_cb_drawtex.c \
|
||||
state_tracker/st_cb_drawtex.h \
|
||||
state_tracker/st_cb_eglimage.c \
|
||||
|
@@ -25,65 +25,17 @@
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Generate fragment programs to implement pixel transfer ops, such as
|
||||
* scale/bias, colortable, convolution...
|
||||
*
|
||||
* Authors:
|
||||
/* Authors:
|
||||
* Brian Paul
|
||||
*/
|
||||
|
||||
#include "main/imports.h"
|
||||
#include "main/image.h"
|
||||
#include "main/macros.h"
|
||||
#include "program/program.h"
|
||||
#include "program/prog_cache.h"
|
||||
#include "program/prog_instruction.h"
|
||||
#include "program/prog_parameter.h"
|
||||
#include "program/prog_print.h"
|
||||
|
||||
#include "st_context.h"
|
||||
#include "st_format.h"
|
||||
#include "st_texture.h"
|
||||
|
||||
#include "pipe/p_screen.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_pack_color.h"
|
||||
|
||||
|
||||
struct state_key
|
||||
{
|
||||
GLuint scaleAndBias:1;
|
||||
GLuint pixelMaps:1;
|
||||
|
||||
#if 0
|
||||
GLfloat Maps[3][256][4];
|
||||
int NumMaps;
|
||||
GLint NumStages;
|
||||
pipeline_stage Stages[STAGE_MAX];
|
||||
GLboolean StagesUsed[STAGE_MAX];
|
||||
GLfloat Scale1[4], Bias1[4];
|
||||
GLfloat Scale2[4], Bias2[4];
|
||||
#endif
|
||||
};
|
||||
|
||||
static void
|
||||
make_state_key(struct gl_context *ctx, struct state_key *key)
|
||||
{
|
||||
memset(key, 0, sizeof(*key));
|
||||
|
||||
if (ctx->Pixel.RedBias != 0.0 || ctx->Pixel.RedScale != 1.0 ||
|
||||
ctx->Pixel.GreenBias != 0.0 || ctx->Pixel.GreenScale != 1.0 ||
|
||||
ctx->Pixel.BlueBias != 0.0 || ctx->Pixel.BlueScale != 1.0 ||
|
||||
ctx->Pixel.AlphaBias != 0.0 || ctx->Pixel.AlphaScale != 1.0) {
|
||||
key->scaleAndBias = 1;
|
||||
}
|
||||
|
||||
key->pixelMaps = ctx->Pixel.MapColorFlag;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the pixelmap texture with the contents of the R/G/B/A pixel maps.
|
||||
*/
|
||||
@@ -128,74 +80,15 @@ load_color_map_texture(struct gl_context *ctx, struct pipe_resource *pt)
|
||||
pipe_transfer_unmap(pipe, transfer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define MAX_INST 100
|
||||
|
||||
/**
|
||||
* Returns a fragment program which implements the current pixel transfer ops.
|
||||
* Upload the pixel transfer color map texture.
|
||||
*/
|
||||
static struct gl_fragment_program *
|
||||
get_pixel_transfer_program(struct gl_context *ctx, const struct state_key *key)
|
||||
static void
|
||||
update_pixel_transfer(struct st_context *st)
|
||||
{
|
||||
struct st_context *st = st_context(ctx);
|
||||
struct prog_instruction inst[MAX_INST];
|
||||
struct gl_program_parameter_list *params;
|
||||
struct gl_fragment_program *fp;
|
||||
GLuint ic = 0;
|
||||
const GLuint colorTemp = 0;
|
||||
|
||||
fp = (struct gl_fragment_program *)
|
||||
ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
|
||||
if (!fp)
|
||||
return NULL;
|
||||
|
||||
params = _mesa_new_parameter_list();
|
||||
|
||||
/*
|
||||
* Get initial pixel color from the texture.
|
||||
* TEX colorTemp, fragment.texcoord[0], texture[0], 2D;
|
||||
*/
|
||||
_mesa_init_instructions(inst + ic, 1);
|
||||
inst[ic].Opcode = OPCODE_TEX;
|
||||
inst[ic].DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst[ic].DstReg.Index = colorTemp;
|
||||
inst[ic].SrcReg[0].File = PROGRAM_INPUT;
|
||||
inst[ic].SrcReg[0].Index = VARYING_SLOT_TEX0;
|
||||
inst[ic].TexSrcUnit = 0;
|
||||
inst[ic].TexSrcTarget = TEXTURE_2D_INDEX;
|
||||
ic++;
|
||||
fp->Base.InputsRead = BITFIELD64_BIT(VARYING_SLOT_TEX0);
|
||||
fp->Base.OutputsWritten = BITFIELD64_BIT(FRAG_RESULT_COLOR);
|
||||
fp->Base.SamplersUsed = 0x1; /* sampler 0 (bit 0) is used */
|
||||
|
||||
if (key->scaleAndBias) {
|
||||
static const gl_state_index scale_state[STATE_LENGTH] =
|
||||
{ STATE_INTERNAL, STATE_PT_SCALE, 0, 0, 0 };
|
||||
static const gl_state_index bias_state[STATE_LENGTH] =
|
||||
{ STATE_INTERNAL, STATE_PT_BIAS, 0, 0, 0 };
|
||||
GLint scale_p, bias_p;
|
||||
|
||||
scale_p = _mesa_add_state_reference(params, scale_state);
|
||||
bias_p = _mesa_add_state_reference(params, bias_state);
|
||||
|
||||
/* MAD colorTemp, colorTemp, scale, bias; */
|
||||
_mesa_init_instructions(inst + ic, 1);
|
||||
inst[ic].Opcode = OPCODE_MAD;
|
||||
inst[ic].DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst[ic].DstReg.Index = colorTemp;
|
||||
inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
inst[ic].SrcReg[0].Index = colorTemp;
|
||||
inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR;
|
||||
inst[ic].SrcReg[1].Index = scale_p;
|
||||
inst[ic].SrcReg[2].File = PROGRAM_STATE_VAR;
|
||||
inst[ic].SrcReg[2].Index = bias_p;
|
||||
ic++;
|
||||
}
|
||||
|
||||
if (key->pixelMaps) {
|
||||
const GLuint temp = 1;
|
||||
struct gl_context *ctx = st->ctx;
|
||||
|
||||
if (ctx->Pixel.MapColorFlag) {
|
||||
/* create the colormap/texture now if not already done */
|
||||
if (!st->pixel_xfer.pixelmap_texture) {
|
||||
st->pixel_xfer.pixelmap_texture = st_create_color_map_texture(ctx);
|
||||
@@ -203,117 +96,11 @@ get_pixel_transfer_program(struct gl_context *ctx, const struct state_key *key)
|
||||
st_create_texture_sampler_view(st->pipe,
|
||||
st->pixel_xfer.pixelmap_texture);
|
||||
}
|
||||
|
||||
/* with a little effort, we can do four pixel map look-ups with
|
||||
* two TEX instructions:
|
||||
*/
|
||||
|
||||
/* TEX temp.rg, colorTemp.rgba, texture[1], 2D; */
|
||||
_mesa_init_instructions(inst + ic, 1);
|
||||
inst[ic].Opcode = OPCODE_TEX;
|
||||
inst[ic].DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst[ic].DstReg.Index = temp;
|
||||
inst[ic].DstReg.WriteMask = WRITEMASK_XY; /* write R,G */
|
||||
inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
inst[ic].SrcReg[0].Index = colorTemp;
|
||||
inst[ic].TexSrcUnit = 1;
|
||||
inst[ic].TexSrcTarget = TEXTURE_2D_INDEX;
|
||||
ic++;
|
||||
|
||||
/* TEX temp.ba, colorTemp.baba, texture[1], 2D; */
|
||||
_mesa_init_instructions(inst + ic, 1);
|
||||
inst[ic].Opcode = OPCODE_TEX;
|
||||
inst[ic].DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst[ic].DstReg.Index = temp;
|
||||
inst[ic].DstReg.WriteMask = WRITEMASK_ZW; /* write B,A */
|
||||
inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
inst[ic].SrcReg[0].Index = colorTemp;
|
||||
inst[ic].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W,
|
||||
SWIZZLE_Z, SWIZZLE_W);
|
||||
inst[ic].TexSrcUnit = 1;
|
||||
inst[ic].TexSrcTarget = TEXTURE_2D_INDEX;
|
||||
ic++;
|
||||
|
||||
/* MOV colorTemp, temp; */
|
||||
_mesa_init_instructions(inst + ic, 1);
|
||||
inst[ic].Opcode = OPCODE_MOV;
|
||||
inst[ic].DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst[ic].DstReg.Index = colorTemp;
|
||||
inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
inst[ic].SrcReg[0].Index = temp;
|
||||
ic++;
|
||||
|
||||
fp->Base.SamplersUsed |= (1 << 1); /* sampler 1 is used */
|
||||
}
|
||||
|
||||
/* Modify last instruction's dst reg to write to result.color */
|
||||
{
|
||||
struct prog_instruction *last = &inst[ic - 1];
|
||||
last->DstReg.File = PROGRAM_OUTPUT;
|
||||
last->DstReg.Index = FRAG_RESULT_COLOR;
|
||||
}
|
||||
|
||||
/* END; */
|
||||
_mesa_init_instructions(inst + ic, 1);
|
||||
inst[ic].Opcode = OPCODE_END;
|
||||
ic++;
|
||||
|
||||
assert(ic <= MAX_INST);
|
||||
|
||||
|
||||
fp->Base.Instructions = _mesa_alloc_instructions(ic);
|
||||
if (!fp->Base.Instructions) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY,
|
||||
"generating pixel transfer program");
|
||||
_mesa_free_parameter_list(params);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_mesa_copy_instructions(fp->Base.Instructions, inst, ic);
|
||||
fp->Base.NumInstructions = ic;
|
||||
fp->Base.Parameters = params;
|
||||
|
||||
#if 0
|
||||
printf("========= pixel transfer prog\n");
|
||||
_mesa_print_program(&fp->Base);
|
||||
_mesa_print_parameter_list(fp->Base.Parameters);
|
||||
#endif
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Update st->pixel_xfer.program in response to new pixel-transfer state.
|
||||
*/
|
||||
static void
|
||||
update_pixel_transfer(struct st_context *st)
|
||||
{
|
||||
struct gl_context *ctx = st->ctx;
|
||||
struct state_key key;
|
||||
struct gl_fragment_program *fp;
|
||||
|
||||
make_state_key(st->ctx, &key);
|
||||
|
||||
fp = (struct gl_fragment_program *)
|
||||
_mesa_search_program_cache(st->pixel_xfer.cache, &key, sizeof(key));
|
||||
if (!fp) {
|
||||
fp = get_pixel_transfer_program(st->ctx, &key);
|
||||
_mesa_program_cache_insert(st->ctx, st->pixel_xfer.cache,
|
||||
&key, sizeof(key), &fp->Base);
|
||||
}
|
||||
|
||||
if (ctx->Pixel.MapColorFlag) {
|
||||
load_color_map_texture(ctx, st->pixel_xfer.pixelmap_texture);
|
||||
}
|
||||
st->pixel_xfer.pixelmap_enabled = ctx->Pixel.MapColorFlag;
|
||||
|
||||
st->pixel_xfer.program = (struct st_fragment_program *) fp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const struct st_tracked_state st_update_pixel_transfer = {
|
||||
"st_update_pixel_transfer", /* name */
|
||||
{ /* dirty */
|
||||
|
@@ -71,119 +71,6 @@
|
||||
#include "cso_cache/cso_context.h"
|
||||
|
||||
|
||||
/**
|
||||
* Check if the given program is:
|
||||
* 0: MOVE result.color, fragment.color;
|
||||
* 1: END;
|
||||
*/
|
||||
static GLboolean
|
||||
is_passthrough_program(const struct gl_fragment_program *prog)
|
||||
{
|
||||
if (prog->Base.NumInstructions == 2) {
|
||||
const struct prog_instruction *inst = prog->Base.Instructions;
|
||||
if (inst[0].Opcode == OPCODE_MOV &&
|
||||
inst[1].Opcode == OPCODE_END &&
|
||||
inst[0].DstReg.File == PROGRAM_OUTPUT &&
|
||||
inst[0].DstReg.Index == FRAG_RESULT_COLOR &&
|
||||
inst[0].DstReg.WriteMask == WRITEMASK_XYZW &&
|
||||
inst[0].SrcReg[0].File == PROGRAM_INPUT &&
|
||||
inst[0].SrcReg[0].Index == VARYING_SLOT_COL0 &&
|
||||
inst[0].SrcReg[0].Swizzle == SWIZZLE_XYZW) {
|
||||
return GL_TRUE;
|
||||
}
|
||||
}
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a fragment program which implements the current pixel transfer ops.
|
||||
*/
|
||||
static struct gl_fragment_program *
|
||||
get_glsl_pixel_transfer_program(struct st_context *st,
|
||||
struct st_fragment_program *orig)
|
||||
{
|
||||
int pixelMaps = 0, scaleAndBias = 0;
|
||||
struct gl_context *ctx = st->ctx;
|
||||
struct st_fragment_program *fp = (struct st_fragment_program *)
|
||||
ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
|
||||
|
||||
if (!fp)
|
||||
return NULL;
|
||||
|
||||
if (ctx->Pixel.RedBias != 0.0 || ctx->Pixel.RedScale != 1.0 ||
|
||||
ctx->Pixel.GreenBias != 0.0 || ctx->Pixel.GreenScale != 1.0 ||
|
||||
ctx->Pixel.BlueBias != 0.0 || ctx->Pixel.BlueScale != 1.0 ||
|
||||
ctx->Pixel.AlphaBias != 0.0 || ctx->Pixel.AlphaScale != 1.0) {
|
||||
scaleAndBias = 1;
|
||||
}
|
||||
|
||||
pixelMaps = ctx->Pixel.MapColorFlag;
|
||||
|
||||
if (pixelMaps) {
|
||||
/* create the colormap/texture now if not already done */
|
||||
if (!st->pixel_xfer.pixelmap_texture) {
|
||||
st->pixel_xfer.pixelmap_texture = st_create_color_map_texture(ctx);
|
||||
st->pixel_xfer.pixelmap_sampler_view =
|
||||
st_create_texture_sampler_view(st->pipe,
|
||||
st->pixel_xfer.pixelmap_texture);
|
||||
}
|
||||
}
|
||||
|
||||
get_pixel_transfer_visitor(fp, orig->glsl_to_tgsi,
|
||||
scaleAndBias, pixelMaps);
|
||||
|
||||
return &fp->Base;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make fragment shader for glDraw/CopyPixels. This shader is made
|
||||
* by combining the pixel transfer shader with the user-defined shader.
|
||||
* \param fpIn the current/incoming fragment program
|
||||
* \param fpOut returns the combined fragment program
|
||||
*/
|
||||
void
|
||||
st_make_drawpix_fragment_program(struct st_context *st,
|
||||
struct gl_fragment_program *fpIn,
|
||||
struct gl_fragment_program **fpOut)
|
||||
{
|
||||
struct gl_program *newProg;
|
||||
struct st_fragment_program *stfp = (struct st_fragment_program *) fpIn;
|
||||
|
||||
if (is_passthrough_program(fpIn)) {
|
||||
newProg = (struct gl_program *) _mesa_clone_fragment_program(st->ctx,
|
||||
&st->pixel_xfer.program->Base);
|
||||
}
|
||||
else if (stfp->glsl_to_tgsi != NULL) {
|
||||
newProg = (struct gl_program *) get_glsl_pixel_transfer_program(st, stfp);
|
||||
}
|
||||
else {
|
||||
#if 0
|
||||
/* debug */
|
||||
printf("Base program:\n");
|
||||
_mesa_print_program(&fpIn->Base);
|
||||
printf("DrawPix program:\n");
|
||||
_mesa_print_program(&st->pixel_xfer.program->Base.Base);
|
||||
#endif
|
||||
newProg = _mesa_combine_programs(st->ctx,
|
||||
&st->pixel_xfer.program->Base.Base,
|
||||
&fpIn->Base);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* debug */
|
||||
printf("Combined DrawPixels program:\n");
|
||||
_mesa_print_program(newProg);
|
||||
printf("InputsRead: 0x%x\n", newProg->InputsRead);
|
||||
printf("OutputsWritten: 0x%x\n", newProg->OutputsWritten);
|
||||
_mesa_print_parameter_list(newProg->Parameters);
|
||||
#endif
|
||||
|
||||
*fpOut = (struct gl_fragment_program *) newProg;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create fragment program that does a TEX() instruction to get a Z and/or
|
||||
* stencil value value, then writes to FRAG_RESULT_DEPTH/FRAG_RESULT_STENCIL.
|
||||
@@ -1101,7 +988,7 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
|
||||
driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
|
||||
|
||||
color = NULL;
|
||||
if (st->pixel_xfer.pixelmap_enabled) {
|
||||
if (ctx->Pixel.MapColorFlag) {
|
||||
pipe_sampler_view_reference(&sv[1],
|
||||
st->pixel_xfer.pixelmap_sampler_view);
|
||||
num_sampler_view++;
|
||||
@@ -1439,7 +1326,7 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
|
||||
driver_fp = fpv->driver_shader;
|
||||
driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
|
||||
|
||||
if (st->pixel_xfer.pixelmap_enabled) {
|
||||
if (ctx->Pixel.MapColorFlag) {
|
||||
pipe_sampler_view_reference(&sv[1],
|
||||
st->pixel_xfer.pixelmap_sampler_view);
|
||||
num_sampler_view++;
|
||||
@@ -1610,7 +1497,6 @@ st_destroy_drawpix(struct st_context *st)
|
||||
st->drawpix.zs_shaders[i]);
|
||||
}
|
||||
|
||||
st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL);
|
||||
if (st->drawpix.vert_shaders[0])
|
||||
cso_delete_vertex_shader(st->cso_context, st->drawpix.vert_shaders[0]);
|
||||
if (st->drawpix.vert_shaders[1])
|
||||
|
@@ -31,6 +31,7 @@
|
||||
|
||||
|
||||
#include "main/compiler.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
struct dd_function_table;
|
||||
struct st_context;
|
||||
@@ -40,9 +41,9 @@ extern void st_init_drawpixels_functions(struct dd_function_table *functions);
|
||||
extern void
|
||||
st_destroy_drawpix(struct st_context *st);
|
||||
|
||||
extern void
|
||||
st_make_drawpix_fragment_program(struct st_context *st,
|
||||
struct gl_fragment_program *fpIn,
|
||||
struct gl_fragment_program **fpOut);
|
||||
extern const struct tgsi_token *
|
||||
st_get_drawpix_shader(const struct tgsi_token *tokens, bool use_texcoord,
|
||||
bool scale_and_bias, unsigned scale_const,
|
||||
unsigned bias_const, bool pixel_maps);
|
||||
|
||||
#endif /* ST_CB_DRAWPIXELS_H */
|
||||
|
255
src/mesa/state_tracker/st_cb_drawpixels_shader.c
Normal file
255
src/mesa/state_tracker/st_cb_drawpixels_shader.c
Normal file
@@ -0,0 +1,255 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Advanced Micro Devices, Inc.
|
||||
* Copyright 2007 VMware, Inc.
|
||||
* 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 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "st_cb_drawpixels.h"
|
||||
#include "tgsi/tgsi_transform.h"
|
||||
#include "tgsi/tgsi_scan.h"
|
||||
|
||||
struct tgsi_drawpix_transform {
|
||||
struct tgsi_transform_context base;
|
||||
struct tgsi_shader_info info;
|
||||
bool use_texcoord;
|
||||
bool scale_and_bias;
|
||||
bool pixel_maps;
|
||||
bool first_instruction_emitted;
|
||||
unsigned scale_const;
|
||||
unsigned bias_const;
|
||||
unsigned color_temp;
|
||||
};
|
||||
|
||||
static inline struct tgsi_drawpix_transform *
|
||||
tgsi_drawpix_transform(struct tgsi_transform_context *tctx)
|
||||
{
|
||||
return (struct tgsi_drawpix_transform *)tctx;
|
||||
}
|
||||
|
||||
static void
|
||||
set_src(struct tgsi_full_instruction *inst, unsigned i, unsigned file, unsigned index,
|
||||
unsigned x, unsigned y, unsigned z, unsigned w)
|
||||
{
|
||||
inst->Src[i].Register.File = file;
|
||||
inst->Src[i].Register.Index = index;
|
||||
inst->Src[i].Register.SwizzleX = x;
|
||||
inst->Src[i].Register.SwizzleY = y;
|
||||
inst->Src[i].Register.SwizzleZ = z;
|
||||
inst->Src[i].Register.SwizzleW = w;
|
||||
}
|
||||
|
||||
#define SET_SRC(inst, i, file, index, x, y, z, w) \
|
||||
set_src(inst, i, file, index, TGSI_SWIZZLE_##x, TGSI_SWIZZLE_##y, \
|
||||
TGSI_SWIZZLE_##z, TGSI_SWIZZLE_##w)
|
||||
|
||||
static void
|
||||
transform_instr(struct tgsi_transform_context *tctx,
|
||||
struct tgsi_full_instruction *current_inst)
|
||||
{
|
||||
struct tgsi_drawpix_transform *ctx = tgsi_drawpix_transform(tctx);
|
||||
struct tgsi_full_declaration decl;
|
||||
struct tgsi_full_instruction inst;
|
||||
unsigned i, semantic;
|
||||
int texcoord_index = -1;
|
||||
|
||||
if (ctx->first_instruction_emitted)
|
||||
goto transform_inst;
|
||||
|
||||
ctx->first_instruction_emitted = true;
|
||||
|
||||
/* Add scale and bias constants. */
|
||||
if (ctx->scale_and_bias) {
|
||||
if (ctx->info.const_file_max[0] < (int)ctx->scale_const) {
|
||||
decl = tgsi_default_full_declaration();
|
||||
decl.Declaration.File = TGSI_FILE_CONSTANT;
|
||||
decl.Range.First = decl.Range.Last = ctx->scale_const;
|
||||
tctx->emit_declaration(tctx, &decl);
|
||||
}
|
||||
|
||||
if (ctx->info.const_file_max[0] < (int)ctx->bias_const) {
|
||||
decl = tgsi_default_full_declaration();
|
||||
decl.Declaration.File = TGSI_FILE_CONSTANT;
|
||||
decl.Range.First = decl.Range.Last = ctx->bias_const;
|
||||
tctx->emit_declaration(tctx, &decl);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a new temp. */
|
||||
ctx->color_temp = ctx->info.file_max[TGSI_FILE_TEMPORARY] + 1;
|
||||
decl = tgsi_default_full_declaration();
|
||||
decl.Declaration.File = TGSI_FILE_TEMPORARY;
|
||||
decl.Range.First = decl.Range.Last = ctx->color_temp;
|
||||
tctx->emit_declaration(tctx, &decl);
|
||||
|
||||
/* Add TEXCOORD[0] if it's missing. */
|
||||
semantic = ctx->use_texcoord ? TGSI_SEMANTIC_TEXCOORD :
|
||||
TGSI_SEMANTIC_GENERIC;
|
||||
for (i = 0; i < ctx->info.num_inputs; i++) {
|
||||
if (ctx->info.input_semantic_name[i] == semantic &&
|
||||
ctx->info.input_semantic_index[i] == 0) {
|
||||
texcoord_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (texcoord_index == -1) {
|
||||
decl = tgsi_default_full_declaration();
|
||||
decl.Declaration.File = TGSI_FILE_INPUT;
|
||||
decl.Declaration.Semantic = 1;
|
||||
decl.Semantic.Name = semantic;
|
||||
decl.Declaration.Interpolate = 1;
|
||||
decl.Interp.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
|
||||
decl.Range.First = decl.Range.Last = ctx->info.num_inputs;
|
||||
texcoord_index = ctx->info.num_inputs;
|
||||
tctx->emit_declaration(tctx, &decl);
|
||||
}
|
||||
|
||||
/* Declare the drawpix sampler if it's missing. */
|
||||
if (ctx->info.file_max[TGSI_FILE_SAMPLER] == -1) {
|
||||
decl = tgsi_default_full_declaration();
|
||||
decl.Declaration.File = TGSI_FILE_SAMPLER;
|
||||
tctx->emit_declaration(tctx, &decl);
|
||||
}
|
||||
|
||||
/* Declare the pixel map sampler if it's missing. */
|
||||
if (ctx->info.file_max[TGSI_FILE_SAMPLER] <= 0) {
|
||||
decl = tgsi_default_full_declaration();
|
||||
decl.Declaration.File = TGSI_FILE_SAMPLER;
|
||||
decl.Range.First = decl.Range.Last = 1;
|
||||
tctx->emit_declaration(tctx, &decl);
|
||||
}
|
||||
|
||||
/* Get initial pixel color from the texture.
|
||||
* TEX temp, fragment.texcoord[0], texture[0], 2D;
|
||||
*/
|
||||
inst = tgsi_default_full_instruction();
|
||||
inst.Instruction.Opcode = TGSI_OPCODE_TEX;
|
||||
inst.Instruction.Texture = 1;
|
||||
inst.Texture.Texture = TGSI_TEXTURE_2D;
|
||||
|
||||
inst.Instruction.NumDstRegs = 1;
|
||||
inst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
|
||||
inst.Dst[0].Register.Index = ctx->color_temp;
|
||||
inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW;
|
||||
|
||||
inst.Instruction.NumSrcRegs = 2;
|
||||
SET_SRC(&inst, 0, TGSI_FILE_INPUT, texcoord_index, X, Y, Z, W);
|
||||
inst.Src[1].Register.File = TGSI_FILE_SAMPLER;
|
||||
inst.Src[1].Register.Index = 0;
|
||||
|
||||
tctx->emit_instruction(tctx, &inst);
|
||||
|
||||
/* Apply the scale and bias. */
|
||||
if (ctx->scale_and_bias) {
|
||||
/* MAD temp, temp, scale, bias; */
|
||||
inst = tgsi_default_full_instruction();
|
||||
inst.Instruction.Opcode = TGSI_OPCODE_MAD;
|
||||
|
||||
inst.Instruction.NumDstRegs = 1;
|
||||
inst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
|
||||
inst.Dst[0].Register.Index = ctx->color_temp;
|
||||
inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW;
|
||||
|
||||
inst.Instruction.NumSrcRegs = 3;
|
||||
SET_SRC(&inst, 0, TGSI_FILE_TEMPORARY, ctx->color_temp, X, Y, Z, W);
|
||||
SET_SRC(&inst, 1, TGSI_FILE_CONSTANT, ctx->scale_const, X, Y, Z, W);
|
||||
SET_SRC(&inst, 2, TGSI_FILE_CONSTANT, ctx->bias_const, X, Y, Z, W);
|
||||
|
||||
tctx->emit_instruction(tctx, &inst);
|
||||
}
|
||||
|
||||
if (ctx->pixel_maps) {
|
||||
/* do four pixel map look-ups with two TEX instructions: */
|
||||
|
||||
/* TEX temp.xy, temp.xyyy, texture[1], 2D; */
|
||||
inst = tgsi_default_full_instruction();
|
||||
inst.Instruction.Opcode = TGSI_OPCODE_TEX;
|
||||
inst.Instruction.Texture = 1;
|
||||
inst.Texture.Texture = TGSI_TEXTURE_2D;
|
||||
|
||||
inst.Instruction.NumDstRegs = 1;
|
||||
inst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
|
||||
inst.Dst[0].Register.Index = ctx->color_temp;
|
||||
inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XY;
|
||||
|
||||
inst.Instruction.NumSrcRegs = 2;
|
||||
SET_SRC(&inst, 0, TGSI_FILE_TEMPORARY, ctx->color_temp, X, Y, Y, Y);
|
||||
inst.Src[1].Register.File = TGSI_FILE_SAMPLER;
|
||||
inst.Src[1].Register.Index = 1;
|
||||
|
||||
tctx->emit_instruction(tctx, &inst);
|
||||
|
||||
/* TEX temp.zw, temp.zwww, texture[1], 2D; */
|
||||
inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_ZW;
|
||||
SET_SRC(&inst, 0, TGSI_FILE_TEMPORARY, ctx->color_temp, Z, W, W, W);
|
||||
tctx->emit_instruction(tctx, &inst);
|
||||
}
|
||||
|
||||
/* Now, "color_temp" should be used in place of IN:COLOR0 */
|
||||
|
||||
transform_inst:
|
||||
|
||||
for (i = 0; i < current_inst->Instruction.NumSrcRegs; i++) {
|
||||
struct tgsi_full_src_register *src = ¤t_inst->Src[i];
|
||||
unsigned reg = src->Register.Index;
|
||||
|
||||
if (src->Register.File == TGSI_FILE_INPUT &&
|
||||
!src->Register.Indirect &&
|
||||
ctx->info.input_semantic_name[reg] == TGSI_SEMANTIC_COLOR &&
|
||||
ctx->info.input_semantic_index[reg] == 0) {
|
||||
src->Register.File = TGSI_FILE_TEMPORARY;
|
||||
src->Register.Index = ctx->color_temp;
|
||||
}
|
||||
}
|
||||
|
||||
tctx->emit_instruction(tctx, current_inst);
|
||||
}
|
||||
|
||||
const struct tgsi_token *
|
||||
st_get_drawpix_shader(const struct tgsi_token *tokens, bool use_texcoord,
|
||||
bool scale_and_bias, unsigned scale_const,
|
||||
unsigned bias_const, bool pixel_maps)
|
||||
{
|
||||
struct tgsi_drawpix_transform ctx;
|
||||
struct tgsi_token *newtoks;
|
||||
int newlen;
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
ctx.base.transform_instruction = transform_instr;
|
||||
ctx.use_texcoord = use_texcoord;
|
||||
ctx.scale_and_bias = scale_and_bias;
|
||||
ctx.scale_const = scale_const;
|
||||
ctx.bias_const = bias_const;
|
||||
ctx.pixel_maps = pixel_maps;
|
||||
tgsi_scan_shader(tokens, &ctx.info);
|
||||
|
||||
newlen = tgsi_num_tokens(tokens) + 30;
|
||||
newtoks = tgsi_alloc_tokens(newlen);
|
||||
if (!newtoks)
|
||||
return NULL;
|
||||
|
||||
tgsi_transform_shader(tokens, newtoks, newlen, &ctx.base);
|
||||
return newtoks;
|
||||
}
|
@@ -224,8 +224,6 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe,
|
||||
|
||||
st->ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
|
||||
|
||||
st->pixel_xfer.cache = _mesa_new_program_cache();
|
||||
|
||||
st->has_stencil_export =
|
||||
screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT);
|
||||
st->has_shader_model3 = screen->get_param(screen, PIPE_CAP_SM3);
|
||||
@@ -386,8 +384,8 @@ void st_destroy_context( struct st_context *st )
|
||||
pipe_surface_reference(&st->state.framebuffer.cbufs[i], NULL);
|
||||
}
|
||||
pipe_surface_reference(&st->state.framebuffer.zsbuf, NULL);
|
||||
|
||||
_mesa_delete_program_cache(st->ctx, st->pixel_xfer.cache);
|
||||
pipe_sampler_view_reference(&st->pixel_xfer.pixelmap_sampler_view, NULL);
|
||||
pipe_resource_reference(&st->pixel_xfer.pixelmap_texture, NULL);
|
||||
|
||||
_vbo_DestroyContext(st->ctx);
|
||||
|
||||
|
@@ -162,15 +162,8 @@ struct st_context
|
||||
struct gl_texture_object *default_texture;
|
||||
|
||||
struct {
|
||||
struct gl_program_cache *cache;
|
||||
struct st_fragment_program *program; /**< cur pixel transfer prog */
|
||||
GLuint xfer_prog_sn; /**< pixel xfer program serial no. */
|
||||
GLuint user_prog_sn; /**< user fragment program serial no. */
|
||||
struct st_fragment_program *combined_prog;
|
||||
GLuint combined_prog_sn;
|
||||
struct pipe_resource *pixelmap_texture;
|
||||
struct pipe_sampler_view *pixelmap_sampler_view;
|
||||
boolean pixelmap_enabled; /**< use the pixelmap texture? */
|
||||
} pixel_xfer;
|
||||
|
||||
/** for glBitmap */
|
||||
|
@@ -4334,138 +4334,6 @@ glsl_to_tgsi_visitor::renumber_registers(void)
|
||||
ralloc_free(first_reads);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fragment program which implements the current pixel transfer ops.
|
||||
* Based on get_pixel_transfer_program in st_atom_pixeltransfer.c.
|
||||
*/
|
||||
extern "C" void
|
||||
get_pixel_transfer_visitor(struct st_fragment_program *fp,
|
||||
glsl_to_tgsi_visitor *original,
|
||||
int scale_and_bias, int pixel_maps)
|
||||
{
|
||||
glsl_to_tgsi_visitor *v = new glsl_to_tgsi_visitor();
|
||||
struct st_context *st = st_context(original->ctx);
|
||||
struct gl_program *prog = &fp->Base.Base;
|
||||
struct gl_program_parameter_list *params = _mesa_new_parameter_list();
|
||||
st_src_reg coord, src0;
|
||||
st_dst_reg dst0;
|
||||
glsl_to_tgsi_instruction *inst;
|
||||
|
||||
/* Copy attributes of the glsl_to_tgsi_visitor in the original shader. */
|
||||
v->ctx = original->ctx;
|
||||
v->prog = prog;
|
||||
v->shader_program = NULL;
|
||||
v->shader = NULL;
|
||||
v->glsl_version = original->glsl_version;
|
||||
v->native_integers = original->native_integers;
|
||||
v->options = original->options;
|
||||
v->next_temp = original->next_temp;
|
||||
v->num_address_regs = original->num_address_regs;
|
||||
v->samplers_used = prog->SamplersUsed = original->samplers_used;
|
||||
v->indirect_addr_consts = original->indirect_addr_consts;
|
||||
memcpy(&v->immediates, &original->immediates, sizeof(v->immediates));
|
||||
v->num_immediates = original->num_immediates;
|
||||
|
||||
/*
|
||||
* Get initial pixel color from the texture.
|
||||
* TEX colorTemp, fragment.texcoord[0], texture[0], 2D;
|
||||
*/
|
||||
coord = st_src_reg(PROGRAM_INPUT, VARYING_SLOT_TEX0, glsl_type::vec2_type);
|
||||
src0 = v->get_temp(glsl_type::vec4_type);
|
||||
dst0 = st_dst_reg(src0);
|
||||
inst = v->emit_asm(NULL, TGSI_OPCODE_TEX, dst0, coord);
|
||||
inst->sampler_array_size = 1;
|
||||
inst->tex_target = TEXTURE_2D_INDEX;
|
||||
|
||||
prog->InputsRead |= VARYING_BIT_TEX0;
|
||||
prog->SamplersUsed |= (1 << 0); /* mark sampler 0 as used */
|
||||
v->samplers_used |= (1 << 0);
|
||||
|
||||
if (scale_and_bias) {
|
||||
static const gl_state_index scale_state[STATE_LENGTH] =
|
||||
{ STATE_INTERNAL, STATE_PT_SCALE,
|
||||
(gl_state_index) 0, (gl_state_index) 0, (gl_state_index) 0 };
|
||||
static const gl_state_index bias_state[STATE_LENGTH] =
|
||||
{ STATE_INTERNAL, STATE_PT_BIAS,
|
||||
(gl_state_index) 0, (gl_state_index) 0, (gl_state_index) 0 };
|
||||
GLint scale_p, bias_p;
|
||||
st_src_reg scale, bias;
|
||||
|
||||
scale_p = _mesa_add_state_reference(params, scale_state);
|
||||
bias_p = _mesa_add_state_reference(params, bias_state);
|
||||
|
||||
/* MAD colorTemp, colorTemp, scale, bias; */
|
||||
scale = st_src_reg(PROGRAM_STATE_VAR, scale_p, GLSL_TYPE_FLOAT);
|
||||
bias = st_src_reg(PROGRAM_STATE_VAR, bias_p, GLSL_TYPE_FLOAT);
|
||||
inst = v->emit_asm(NULL, TGSI_OPCODE_MAD, dst0, src0, scale, bias);
|
||||
}
|
||||
|
||||
if (pixel_maps) {
|
||||
st_src_reg temp = v->get_temp(glsl_type::vec4_type);
|
||||
st_dst_reg temp_dst = st_dst_reg(temp);
|
||||
|
||||
assert(st->pixel_xfer.pixelmap_texture);
|
||||
(void) st;
|
||||
|
||||
/* With a little effort, we can do four pixel map look-ups with
|
||||
* two TEX instructions:
|
||||
*/
|
||||
|
||||
/* TEX temp.rg, colorTemp.rgba, texture[1], 2D; */
|
||||
temp_dst.writemask = WRITEMASK_XY; /* write R,G */
|
||||
inst = v->emit_asm(NULL, TGSI_OPCODE_TEX, temp_dst, src0);
|
||||
inst->sampler.index = 1;
|
||||
inst->sampler_array_size = 1;
|
||||
inst->tex_target = TEXTURE_2D_INDEX;
|
||||
|
||||
/* TEX temp.ba, colorTemp.baba, texture[1], 2D; */
|
||||
src0.swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_Z, SWIZZLE_W);
|
||||
temp_dst.writemask = WRITEMASK_ZW; /* write B,A */
|
||||
inst = v->emit_asm(NULL, TGSI_OPCODE_TEX, temp_dst, src0);
|
||||
inst->sampler.index = 1;
|
||||
inst->sampler_array_size = 1;
|
||||
inst->tex_target = TEXTURE_2D_INDEX;
|
||||
|
||||
prog->SamplersUsed |= (1 << 1); /* mark sampler 1 as used */
|
||||
v->samplers_used |= (1 << 1);
|
||||
|
||||
/* MOV colorTemp, temp; */
|
||||
inst = v->emit_asm(NULL, TGSI_OPCODE_MOV, dst0, temp);
|
||||
}
|
||||
|
||||
/* Now copy the instructions from the original glsl_to_tgsi_visitor into the
|
||||
* new visitor. */
|
||||
foreach_in_list(glsl_to_tgsi_instruction, inst, &original->instructions) {
|
||||
glsl_to_tgsi_instruction *newinst;
|
||||
st_src_reg src_regs[4];
|
||||
|
||||
if (inst->dst[0].file == PROGRAM_OUTPUT)
|
||||
prog->OutputsWritten |= BITFIELD64_BIT(inst->dst[0].index);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
src_regs[i] = inst->src[i];
|
||||
if (src_regs[i].file == PROGRAM_INPUT &&
|
||||
src_regs[i].index == VARYING_SLOT_COL0) {
|
||||
src_regs[i].file = PROGRAM_TEMPORARY;
|
||||
src_regs[i].index = src0.index;
|
||||
}
|
||||
else if (src_regs[i].file == PROGRAM_INPUT)
|
||||
prog->InputsRead |= BITFIELD64_BIT(src_regs[i].index);
|
||||
}
|
||||
|
||||
newinst = v->emit_asm(NULL, inst->op, inst->dst[0], src_regs[0], src_regs[1], src_regs[2], src_regs[3]);
|
||||
newinst->tex_target = inst->tex_target;
|
||||
newinst->sampler_array_size = inst->sampler_array_size;
|
||||
}
|
||||
|
||||
/* Make modifications to fragment program info. */
|
||||
prog->Parameters = _mesa_combine_parameter_lists(params,
|
||||
original->prog->Parameters);
|
||||
_mesa_free_parameter_list(params);
|
||||
count_resources(v, prog);
|
||||
fp->glsl_to_tgsi = v;
|
||||
}
|
||||
|
||||
/* ------------------------- TGSI conversion stuff -------------------------- */
|
||||
struct label {
|
||||
unsigned branch_target;
|
||||
|
@@ -55,9 +55,6 @@ enum pipe_error st_translate_program(
|
||||
const ubyte outputSemanticIndex[]);
|
||||
|
||||
void free_glsl_to_tgsi_visitor(struct glsl_to_tgsi_visitor *v);
|
||||
void get_pixel_transfer_visitor(struct st_fragment_program *fp,
|
||||
struct glsl_to_tgsi_visitor *original,
|
||||
int scale_and_bias, int pixel_maps);
|
||||
|
||||
GLboolean st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);
|
||||
|
||||
|
@@ -540,8 +540,6 @@ st_translate_fragment_program(struct st_context *st,
|
||||
{
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
struct st_fp_variant *variant = CALLOC_STRUCT(st_fp_variant);
|
||||
GLboolean deleteFP = GL_FALSE;
|
||||
|
||||
GLuint outputMapping[FRAG_RESULT_MAX];
|
||||
GLuint inputMapping[VARYING_SLOT_MAX];
|
||||
GLuint inputSlotToAttr[VARYING_SLOT_MAX];
|
||||
@@ -567,16 +565,6 @@ st_translate_fragment_program(struct st_context *st,
|
||||
assert(!(key->bitmap && key->drawpixels));
|
||||
memset(inputSlotToAttr, ~0, sizeof(inputSlotToAttr));
|
||||
|
||||
if (key->drawpixels) {
|
||||
/* glDrawPixels color drawing */
|
||||
struct gl_fragment_program *fp; /* we free this temp program below */
|
||||
|
||||
st_make_drawpix_fragment_program(st, &stfp->Base, &fp);
|
||||
variant->parameters = _mesa_clone_parameter_list(fp->Base.Parameters);
|
||||
deleteFP = GL_TRUE;
|
||||
stfp = st_fragment_program(fp);
|
||||
}
|
||||
|
||||
if (!stfp->glsl_to_tgsi)
|
||||
_mesa_remove_output_reads(&stfp->Base.Base, PROGRAM_OUTPUT);
|
||||
|
||||
@@ -895,6 +883,38 @@ st_translate_fragment_program(struct st_context *st,
|
||||
fprintf(stderr, "mesa: cannot create a shader for glBitmap\n");
|
||||
}
|
||||
|
||||
/* glDrawPixels (color only) */
|
||||
if (key->drawpixels) {
|
||||
const struct tgsi_token *tokens;
|
||||
unsigned scale_const = 0, bias_const = 0;
|
||||
|
||||
variant->parameters =
|
||||
_mesa_clone_parameter_list(stfp->Base.Base.Parameters);
|
||||
|
||||
if (key->scaleAndBias) {
|
||||
static const gl_state_index scale_state[STATE_LENGTH] =
|
||||
{ STATE_INTERNAL, STATE_PT_SCALE };
|
||||
static const gl_state_index bias_state[STATE_LENGTH] =
|
||||
{ STATE_INTERNAL, STATE_PT_BIAS };
|
||||
|
||||
scale_const = _mesa_add_state_reference(variant->parameters,
|
||||
scale_state);
|
||||
bias_const = _mesa_add_state_reference(variant->parameters,
|
||||
bias_state);
|
||||
}
|
||||
|
||||
tokens = st_get_drawpix_shader(variant->tgsi.tokens,
|
||||
st->needs_texcoord_semantic,
|
||||
key->scaleAndBias, scale_const,
|
||||
bias_const, key->pixelMaps);
|
||||
|
||||
if (tokens) {
|
||||
tgsi_free_tokens(variant->tgsi.tokens);
|
||||
variant->tgsi.tokens = tokens;
|
||||
} else
|
||||
fprintf(stderr, "mesa: cannot create a shader for glDrawPixels\n");
|
||||
}
|
||||
|
||||
if (ST_DEBUG & DEBUG_TGSI) {
|
||||
tgsi_dump(variant->tgsi.tokens, 0/*TGSI_DUMP_VERBOSE*/);
|
||||
debug_printf("\n");
|
||||
@@ -903,13 +923,6 @@ st_translate_fragment_program(struct st_context *st,
|
||||
/* fill in variant */
|
||||
variant->driver_shader = pipe->create_fs_state(pipe, &variant->tgsi);
|
||||
variant->key = *key;
|
||||
|
||||
if (deleteFP) {
|
||||
/* Free the temporary program made above */
|
||||
struct gl_fragment_program *fp = &stfp->Base;
|
||||
_mesa_reference_fragprog(st->ctx, &fp, NULL);
|
||||
}
|
||||
|
||||
return variant;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user