int num_sampler_view,
void *driver_vp,
void *driver_fp,
+ struct st_fp_variant *fpv,
const GLfloat *color,
GLboolean invertTex,
GLboolean write_depth, GLboolean write_stencil)
cso_set_tesseval_shader_handle(cso, NULL);
cso_set_geometry_shader_handle(cso, NULL);
- /* texture sampling state: */
+ /* user samplers, plus the drawpix samplers */
{
struct pipe_sampler_state sampler;
- const struct pipe_sampler_state *states[2] = {&sampler, &sampler};
memset(&sampler, 0, sizeof(sampler));
sampler.wrap_s = PIPE_TEX_WRAP_CLAMP;
sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
sampler.normalized_coords = normalized;
- cso_set_samplers(cso, PIPE_SHADER_FRAGMENT,
- num_sampler_view > 1 ? 2 : 1, states);
+ if (fpv) {
+ const struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
+ uint num = MAX2(MAX2(fpv->drawpix_sampler, fpv->pixelmap_sampler) + 1,
+ st->state.num_samplers[PIPE_SHADER_FRAGMENT]);
+ uint i;
+
+ for (i = 0; i < st->state.num_samplers[PIPE_SHADER_FRAGMENT]; i++)
+ samplers[i] = &st->state.samplers[PIPE_SHADER_FRAGMENT][i];
+
+ samplers[fpv->drawpix_sampler] = &sampler;
+ if (sv[1])
+ samplers[fpv->pixelmap_sampler] = &sampler;
+
+ cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, num, samplers);
+ } else {
+ const struct pipe_sampler_state *samplers[2] = {&sampler, &sampler};
+
+ cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, num_sampler_view, samplers);
+ }
}
/* viewport state: viewport matching window dims */
cso_set_vertex_elements(cso, 3, st->velems_util_draw);
cso_set_stream_outputs(st->cso_context, 0, NULL, NULL);
- /* texture state: */
- cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, num_sampler_view, sv);
+ /* user textures, plus the drawpix textures */
+ if (fpv) {
+ struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
+ uint num = MAX2(MAX2(fpv->drawpix_sampler, fpv->pixelmap_sampler) + 1,
+ st->state.num_sampler_views[PIPE_SHADER_FRAGMENT]);
+
+ memcpy(sampler_views, st->state.sampler_views[PIPE_SHADER_FRAGMENT],
+ sizeof(sampler_views));
+
+ sampler_views[fpv->drawpix_sampler] = sv[0];
+ if (sv[1])
+ sampler_views[fpv->pixelmap_sampler] = sv[1];
+ cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, num, sampler_views);
+ } else
+ cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, num_sampler_view, sv);
/* Compute Gallium window coords (y=0=top) with pixel zoom.
* Recall that these coords are transformed by the current
struct pipe_sampler_view *sv[2] = { NULL };
int num_sampler_view = 1;
struct gl_pixelstore_attrib clippedUnpack;
+ struct st_fp_variant *fpv = NULL;
/* Mesa state should be up to date by now */
assert(ctx->NewState == 0x0);
color = ctx->Current.RasterColor;
}
else {
- struct st_fp_variant *fpv = get_color_fp_variant(st);
+ fpv = get_color_fp_variant(st);
driver_fp = fpv->driver_shader;
driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
sv,
num_sampler_view,
driver_vp,
- driver_fp,
+ driver_fp, fpv,
color, GL_FALSE, write_depth, write_stencil);
pipe_sampler_view_reference(&sv[0], NULL);
if (num_sampler_view > 1)
void *driver_vp, *driver_fp;
struct pipe_resource *pt;
struct pipe_sampler_view *sv[2] = { NULL };
+ struct st_fp_variant *fpv = NULL;
int num_sampler_view = 1;
GLfloat *color;
enum pipe_format srcFormat;
* Get vertex/fragment shaders
*/
if (type == GL_COLOR) {
- struct st_fp_variant *fpv = get_color_fp_variant(st);
+ fpv = get_color_fp_variant(st);
rbRead = st_get_color_read_renderbuffer(ctx);
color = NULL;
sv,
num_sampler_view,
driver_vp,
- driver_fp,
+ driver_fp, fpv,
color, invertTex, GL_FALSE, GL_FALSE);
pipe_resource_reference(&pt, NULL);
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);
+ unsigned bias_const, bool pixel_maps,
+ unsigned drawpix_sampler, unsigned pixelmap_sampler,
+ unsigned texcoord_const);
#endif /* ST_CB_DRAWPIXELS_H */
unsigned scale_const;
unsigned bias_const;
unsigned color_temp;
+ unsigned drawpix_sampler;
+ unsigned pixelmap_sampler;
+ unsigned texcoord_const;
};
static inline struct tgsi_drawpix_transform *
struct tgsi_drawpix_transform *ctx = tgsi_drawpix_transform(tctx);
struct tgsi_full_declaration decl;
struct tgsi_full_instruction inst;
- unsigned i, semantic;
+ unsigned i, sem_texcoord = ctx->use_texcoord ? TGSI_SEMANTIC_TEXCOORD :
+ TGSI_SEMANTIC_GENERIC;
int texcoord_index = -1;
if (ctx->first_instruction_emitted)
}
}
+ if (ctx->info.const_file_max[0] < (int)ctx->texcoord_const) {
+ decl = tgsi_default_full_declaration();
+ decl.Declaration.File = TGSI_FILE_CONSTANT;
+ decl.Range.First = decl.Range.Last = ctx->texcoord_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.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;
+ /* Add TEXCOORD[texcoord_slot] if it's missing. */
for (i = 0; i < ctx->info.num_inputs; i++) {
- if (ctx->info.input_semantic_name[i] == semantic &&
+ if (ctx->info.input_semantic_name[i] == sem_texcoord &&
ctx->info.input_semantic_index[i] == 0) {
texcoord_index = i;
break;
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_INPUT;
decl.Declaration.Semantic = 1;
- decl.Semantic.Name = semantic;
+ decl.Semantic.Name = sem_texcoord;
decl.Declaration.Interpolate = 1;
decl.Interp.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
decl.Range.First = decl.Range.Last = ctx->info.num_inputs;
}
/* Declare the drawpix sampler if it's missing. */
- if (ctx->info.file_max[TGSI_FILE_SAMPLER] == -1) {
+ if (!(ctx->info.samplers_declared & (1 << ctx->drawpix_sampler))) {
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_SAMPLER;
+ decl.Range.First = decl.Range.Last = ctx->drawpix_sampler;
tctx->emit_declaration(tctx, &decl);
}
/* Declare the pixel map sampler if it's missing. */
- if (ctx->info.file_max[TGSI_FILE_SAMPLER] <= 0) {
+ if (ctx->pixel_maps &&
+ !(ctx->info.samplers_declared & (1 << ctx->pixelmap_sampler))) {
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_SAMPLER;
- decl.Range.First = decl.Range.Last = 1;
+ decl.Range.First = decl.Range.Last = ctx->pixelmap_sampler;
tctx->emit_declaration(tctx, &decl);
}
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;
+ inst.Src[1].Register.Index = ctx->drawpix_sampler;
tctx->emit_instruction(tctx, &inst);
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;
+ inst.Src[1].Register.Index = ctx->pixelmap_sampler;
tctx->emit_instruction(tctx, &inst);
tctx->emit_instruction(tctx, &inst);
}
- /* Now, "color_temp" should be used in place of IN:COLOR0 */
+ /* Now, "color_temp" should be used in place of IN:COLOR0,
+ * and CONST[texcoord_slot] should be used in place of IN:TEXCOORD0.
+ */
transform_inst:
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 &&
+ if (src->Register.File != TGSI_FILE_INPUT || src->Register.Indirect)
+ continue;
+
+ if (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;
+ } else if (ctx->info.input_semantic_name[reg] == sem_texcoord &&
+ ctx->info.input_semantic_index[reg] == 0) {
+ src->Register.File = TGSI_FILE_CONSTANT;
+ src->Register.Index = ctx->texcoord_const;
}
}
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)
+ unsigned bias_const, bool pixel_maps,
+ unsigned drawpix_sampler, unsigned pixelmap_sampler,
+ unsigned texcoord_const)
{
struct tgsi_drawpix_transform ctx;
struct tgsi_token *newtoks;
ctx.scale_const = scale_const;
ctx.bias_const = bias_const;
ctx.pixel_maps = pixel_maps;
+ ctx.drawpix_sampler = drawpix_sampler;
+ ctx.pixelmap_sampler = pixelmap_sampler;
+ ctx.texcoord_const = texcoord_const;
tgsi_scan_shader(tokens, &ctx.info);
newlen = tgsi_num_tokens(tokens) + 30;
/* glDrawPixels (color only) */
if (key->drawpixels) {
const struct tgsi_token *tokens;
- unsigned scale_const = 0, bias_const = 0;
+ unsigned scale_const = 0, bias_const = 0, texcoord_const = 0;
+
+ /* Find the first unused slot. */
+ variant->drawpix_sampler = ffs(~stfp->Base.Base.SamplersUsed) - 1;
+
+ if (key->pixelMaps) {
+ unsigned samplers_used = stfp->Base.Base.SamplersUsed |
+ (1 << variant->drawpix_sampler);
+
+ variant->pixelmap_sampler = ffs(~samplers_used) - 1;
+ }
variant->parameters =
_mesa_clone_parameter_list(stfp->Base.Base.Parameters);
bias_state);
}
+ {
+ static const gl_state_index state[STATE_LENGTH] =
+ { STATE_INTERNAL, STATE_CURRENT_ATTRIB, VERT_ATTRIB_TEX0 };
+
+ texcoord_const = _mesa_add_state_reference(variant->parameters,
+ state);
+ }
+
tokens = st_get_drawpix_shader(variant->tgsi.tokens,
st->needs_texcoord_semantic,
key->scaleAndBias, scale_const,
- bias_const, key->pixelMaps);
+ bias_const, key->pixelMaps,
+ variant->drawpix_sampler,
+ variant->pixelmap_sampler,
+ texcoord_const);
if (tokens) {
tgsi_free_tokens(variant->tgsi.tokens);
struct gl_program_parameter_list *parameters;
uint bitmap_sampler;
+ /** For glDrawPixels variants */
+ unsigned drawpix_sampler;
+ unsigned pixelmap_sampler;
+
/** next in linked list */
struct st_fp_variant *next;
};