1 /**************************************************************************
2 *
3 * Copyright 2007 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 /*
29 * Authors:
30 * Brian Paul
31 */
32
33 #include "main/errors.h"
34
35 #include "main/image.h"
36 #include "main/bufferobj.h"
37 #include "main/blit.h"
38 #include "main/format_pack.h"
39 #include "main/framebuffer.h"
40 #include "main/macros.h"
41 #include "main/mtypes.h"
42 #include "main/pack.h"
43 #include "main/pbo.h"
44 #include "main/readpix.h"
45 #include "main/state.h"
46 #include "main/teximage.h"
47 #include "main/texstore.h"
48 #include "main/glformats.h"
49 #include "program/program.h"
50 #include "program/prog_print.h"
51 #include "program/prog_instruction.h"
52
53 #include "st_atom.h"
54 #include "st_atom_constbuf.h"
55 #include "st_cb_bitmap.h"
56 #include "st_cb_drawpixels.h"
57 #include "st_context.h"
58 #include "st_debug.h"
59 #include "st_draw.h"
60 #include "st_format.h"
61 #include "st_program.h"
62 #include "st_sampler_view.h"
63 #include "st_scissor.h"
64 #include "st_texture.h"
65 #include "st_util.h"
66 #include "st_nir.h"
67
68 #include "pipe/p_context.h"
69 #include "pipe/p_defines.h"
70 #include "util/format/u_format.h"
71 #include "util/u_inlines.h"
72 #include "util/u_math.h"
73 #include "util/u_tile.h"
74 #include "cso_cache/cso_context.h"
75
76 #include "compiler/nir/nir_builder.h"
77
78 /**
79 * We have a simple glDrawPixels cache to try to optimize the case where the
80 * same image is drawn over and over again. It basically works as follows:
81 *
82 * 1. After we construct a texture map with the image and draw it, we do
83 * not discard the texture. We keep it around, plus we note the
84 * glDrawPixels width, height, format, etc. parameters and keep a copy
85 * of the image in a malloc'd buffer.
86 *
87 * 2. On the next glDrawPixels we check if the parameters match the previous
88 * call. If those match, we check if the image matches the previous image
89 * via a memcmp() call. If everything matches, we re-use the previous
90 * texture, thereby avoiding the cost creating a new texture and copying
91 * the image to it.
92 *
93 * The effectiveness of this cache depends upon:
94 * 1. If the memcmp() finds a difference, it happens relatively quickly.
95 Hopefully, not just the last pixels differ!
96 * 2. If the memcmp() finds no difference, doing that check is faster than
97 * creating and loading a texture.
98 *
99 * Notes:
100 * 1. We don't support any pixel unpacking parameters.
101 * 2. We don't try to cache images in Pixel Buffer Objects.
102 * 3. Instead of saving the whole image, perhaps some sort of reliable
103 * checksum function could be used instead.
104 */
105 #define USE_DRAWPIXELS_CACHE 1
106
107 static nir_def *
sample_via_nir(nir_builder * b,nir_variable * texcoord,const char * name,int sampler,enum glsl_base_type base_type,nir_alu_type alu_type)108 sample_via_nir(nir_builder *b, nir_variable *texcoord,
109 const char *name, int sampler, enum glsl_base_type base_type,
110 nir_alu_type alu_type)
111 {
112 const struct glsl_type *sampler2D =
113 glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, false, base_type);
114
115 nir_variable *var =
116 nir_variable_create(b->shader, nir_var_uniform, sampler2D, name);
117 var->data.binding = sampler;
118 var->data.explicit_binding = true;
119
120 nir_deref_instr *deref = nir_build_deref_var(b, var);
121
122 nir_tex_instr *tex = nir_tex_instr_create(b->shader, 3);
123 tex->op = nir_texop_tex;
124 tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
125 tex->coord_components = 2;
126 tex->dest_type = alu_type;
127 tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_texture_deref,
128 &deref->def);
129 tex->src[1] = nir_tex_src_for_ssa(nir_tex_src_sampler_deref,
130 &deref->def);
131 tex->src[2] =
132 nir_tex_src_for_ssa(nir_tex_src_coord,
133 nir_trim_vector(b, nir_load_var(b, texcoord),
134 tex->coord_components));
135
136 nir_def_init(&tex->instr, &tex->def, 4, 32);
137 nir_builder_instr_insert(b, &tex->instr);
138 return nir_channel(b, &tex->def, 0);
139 }
140
141 static void *
make_drawpix_z_stencil_program_nir(struct st_context * st,bool write_depth,bool write_stencil)142 make_drawpix_z_stencil_program_nir(struct st_context *st,
143 bool write_depth,
144 bool write_stencil)
145 {
146 const nir_shader_compiler_options *options =
147 st_get_nir_compiler_options(st, MESA_SHADER_FRAGMENT);
148
149 nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, options,
150 "drawpixels %s%s",
151 write_depth ? "Z" : "",
152 write_stencil ? "S" : "");
153
154 nir_variable *texcoord =
155 nir_create_variable_with_location(b.shader, nir_var_shader_in,
156 VARYING_SLOT_TEX0, glsl_vec_type(2));
157
158 if (write_depth) {
159 nir_variable *out =
160 nir_create_variable_with_location(b.shader, nir_var_shader_out,
161 FRAG_RESULT_DEPTH, glsl_float_type());
162 nir_def *depth = sample_via_nir(&b, texcoord, "depth", 0,
163 GLSL_TYPE_FLOAT, nir_type_float32);
164 nir_store_var(&b, out, depth, 0x1);
165
166 /* Also copy color */
167 nir_copy_var(&b,
168 nir_create_variable_with_location(b.shader, nir_var_shader_out,
169 FRAG_RESULT_COLOR, glsl_vec4_type()),
170 nir_create_variable_with_location(b.shader, nir_var_shader_in,
171 VARYING_SLOT_COL0, glsl_vec4_type()));
172 }
173
174 if (write_stencil) {
175 nir_variable *out =
176 nir_create_variable_with_location(b.shader, nir_var_shader_out,
177 FRAG_RESULT_STENCIL, glsl_uint_type());
178 nir_def *stencil = sample_via_nir(&b, texcoord, "stencil", 1,
179 GLSL_TYPE_UINT, nir_type_uint32);
180 nir_store_var(&b, out, stencil, 0x1);
181 }
182
183 return st_nir_finish_builtin_shader(st, b.shader);
184 }
185
186 static void *
make_drawpix_zs_to_color_program_nir(struct st_context * st,bool rgba)187 make_drawpix_zs_to_color_program_nir(struct st_context *st,
188 bool rgba)
189 {
190 const nir_shader_compiler_options *options =
191 st_get_nir_compiler_options(st, MESA_SHADER_FRAGMENT);
192
193 nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, options,
194 "copypixels ZStoC");
195
196 nir_variable *texcoord =
197 nir_create_variable_with_location(b.shader, nir_var_shader_in,
198 VARYING_SLOT_TEX0, glsl_vec_type(2));
199
200 /* Sample depth and stencil */
201 nir_def *depth = sample_via_nir(&b, texcoord, "depth", 0,
202 GLSL_TYPE_FLOAT, nir_type_float32);
203 nir_def *stencil = sample_via_nir(&b, texcoord, "stencil", 1,
204 GLSL_TYPE_UINT, nir_type_uint32);
205
206 /* Create the variable to store the output color */
207 nir_variable *color_out =
208 nir_create_variable_with_location(b.shader, nir_var_shader_out,
209 FRAG_RESULT_COLOR, glsl_vec_type(4));
210
211 nir_def *shifted_depth = nir_fmul(&b,nir_f2f64(&b, depth), nir_imm_double(&b,0xffffff));
212 nir_def *int_depth = nir_f2u32(&b,shifted_depth);
213
214 nir_def *ds[4];
215 ds[0] = nir_ubitfield_extract(&b, stencil, nir_imm_int(&b, 0), nir_imm_int(&b,8));
216 ds[1] = nir_ubitfield_extract(&b, int_depth, nir_imm_int(&b, 0), nir_imm_int(&b,8));
217 ds[2] = nir_ubitfield_extract(&b, int_depth, nir_imm_int(&b, 8), nir_imm_int(&b,8));
218 ds[3] = nir_ubitfield_extract(&b, int_depth, nir_imm_int(&b, 16), nir_imm_int(&b,8));
219
220 nir_def *ds_comp[4];
221 ds_comp[0] = nir_fsat(&b, nir_fmul_imm(&b, nir_u2f32(&b, ds[3]), 1.0/255.0));
222 ds_comp[1] = nir_fsat(&b, nir_fmul_imm(&b, nir_u2f32(&b, ds[2]), 1.0/255.0));
223 ds_comp[2] = nir_fsat(&b, nir_fmul_imm(&b, nir_u2f32(&b, ds[1]), 1.0/255.0));
224 ds_comp[3] = nir_fsat(&b, nir_fmul_imm(&b, nir_u2f32(&b, ds[0]), 1.0/255.0));
225
226 nir_def *unpacked_ds = nir_vec4(&b, ds_comp[0], ds_comp[1], ds_comp[2], ds_comp[3]);
227
228 if (rgba) {
229 nir_store_var(&b, color_out, unpacked_ds, 0xf);
230 }
231 else {
232 unsigned zyxw[4] = { 2, 1, 0, 3 };
233 nir_def *swizzled_ds= nir_swizzle(&b, unpacked_ds, zyxw, 4);
234 nir_store_var(&b, color_out, swizzled_ds, 0xf);
235 }
236
237 return st_nir_finish_builtin_shader(st, b.shader);
238 }
239
240
241 /**
242 * Create fragment program that does a TEX() instruction to get a Z and/or
243 * stencil value value, then writes to FRAG_RESULT_DEPTH/FRAG_RESULT_STENCIL.
244 * Used for glDrawPixels(GL_DEPTH_COMPONENT / GL_STENCIL_INDEX).
245 * Pass fragment color through as-is.
246 *
247 * \return CSO of the fragment shader.
248 */
249 static void *
get_drawpix_z_stencil_program(struct st_context * st,bool write_depth,bool write_stencil)250 get_drawpix_z_stencil_program(struct st_context *st,
251 bool write_depth,
252 bool write_stencil)
253 {
254 const GLuint shaderIndex = write_depth * 2 + write_stencil;
255 void *cso;
256
257 assert(shaderIndex < ARRAY_SIZE(st->drawpix.zs_shaders));
258
259 if (st->drawpix.zs_shaders[shaderIndex]) {
260 /* already have the proper shader */
261 return st->drawpix.zs_shaders[shaderIndex];
262 }
263
264 cso = make_drawpix_z_stencil_program_nir(st, write_depth, write_stencil);
265
266 /* save the new shader */
267 st->drawpix.zs_shaders[shaderIndex] = cso;
268 return cso;
269 }
270
271 /**
272 * Create fragment program that does a TEX() instruction to get a Z and
273 * stencil value value, then writes to FRAG_RESULT_COLOR.
274 * Used for glCopyPixels(GL_DEPTH_STENCIL_TO_RGBA_NV / GL_DEPTH_STENCIL_TO_BGRA_NV).
275 *
276 * \return CSO of the fragment shader.
277 */
278 static void *
get_drawpix_zs_to_color_program(struct st_context * st,bool rgba)279 get_drawpix_zs_to_color_program(struct st_context *st,
280 bool rgba)
281 {
282 void *cso;
283 GLuint shaderIndex;
284
285 if (rgba)
286 shaderIndex = 4;
287 else
288 shaderIndex = 5;
289
290 assert(shaderIndex < ARRAY_SIZE(st->drawpix.zs_shaders));
291
292 if (st->drawpix.zs_shaders[shaderIndex]) {
293 /* already have the proper shader */
294 return st->drawpix.zs_shaders[shaderIndex];
295 }
296
297 cso = make_drawpix_zs_to_color_program_nir(st, rgba);
298
299 /* save the new shader */
300 st->drawpix.zs_shaders[shaderIndex] = cso;
301 return cso;
302 }
303
304 /**
305 * Create a simple vertex shader that just passes through the
306 * vertex position, texcoord, and color.
307 */
308 void
st_make_passthrough_vertex_shader(struct st_context * st)309 st_make_passthrough_vertex_shader(struct st_context *st)
310 {
311 if (st->passthrough_vs)
312 return;
313
314 unsigned inputs[] =
315 { VERT_ATTRIB_POS, VERT_ATTRIB_COLOR0, VERT_ATTRIB_GENERIC0 };
316 gl_varying_slot outputs[] =
317 { VARYING_SLOT_POS, VARYING_SLOT_COL0, VARYING_SLOT_TEX0 };
318
319 st->passthrough_vs =
320 st_nir_make_passthrough_shader(st, "drawpixels VS",
321 MESA_SHADER_VERTEX, 3,
322 inputs, outputs, NULL, 0);
323 }
324
325
326 /**
327 * Return a texture internalFormat for drawing/copying an image
328 * of the given format and type.
329 */
330 static GLenum
internal_format(struct gl_context * ctx,GLenum format,GLenum type)331 internal_format(struct gl_context *ctx, GLenum format, GLenum type)
332 {
333 switch (format) {
334 case GL_DEPTH_COMPONENT:
335 switch (type) {
336 case GL_UNSIGNED_SHORT:
337 return GL_DEPTH_COMPONENT16;
338
339 case GL_UNSIGNED_INT:
340 return GL_DEPTH_COMPONENT32;
341
342 case GL_FLOAT:
343 if (ctx->Extensions.ARB_depth_buffer_float)
344 return GL_DEPTH_COMPONENT32F;
345 else
346 return GL_DEPTH_COMPONENT;
347
348 default:
349 return GL_DEPTH_COMPONENT;
350 }
351
352 case GL_DEPTH_STENCIL:
353 switch (type) {
354 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
355 return GL_DEPTH32F_STENCIL8;
356
357 case GL_UNSIGNED_INT_24_8:
358 default:
359 return GL_DEPTH24_STENCIL8;
360 }
361
362 case GL_STENCIL_INDEX:
363 return GL_STENCIL_INDEX;
364
365 default:
366 if (_mesa_is_enum_format_integer(format)) {
367 switch (type) {
368 case GL_BYTE:
369 return GL_RGBA8I;
370 case GL_UNSIGNED_BYTE:
371 return GL_RGBA8UI;
372 case GL_SHORT:
373 return GL_RGBA16I;
374 case GL_UNSIGNED_SHORT:
375 return GL_RGBA16UI;
376 case GL_INT:
377 return GL_RGBA32I;
378 case GL_UNSIGNED_INT:
379 return GL_RGBA32UI;
380 default:
381 assert(0 && "Unexpected type in internal_format()");
382 return GL_RGBA_INTEGER;
383 }
384 }
385 else {
386 switch (type) {
387 case GL_UNSIGNED_BYTE:
388 case GL_UNSIGNED_INT_8_8_8_8:
389 case GL_UNSIGNED_INT_8_8_8_8_REV:
390 default:
391 return GL_RGBA8;
392
393 case GL_UNSIGNED_BYTE_3_3_2:
394 case GL_UNSIGNED_BYTE_2_3_3_REV:
395 return GL_R3_G3_B2;
396
397 case GL_UNSIGNED_SHORT_4_4_4_4:
398 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
399 return GL_RGBA4;
400
401 case GL_UNSIGNED_SHORT_5_6_5:
402 case GL_UNSIGNED_SHORT_5_6_5_REV:
403 return GL_RGB565;
404
405 case GL_UNSIGNED_SHORT_5_5_5_1:
406 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
407 return GL_RGB5_A1;
408
409 case GL_UNSIGNED_INT_10_10_10_2:
410 case GL_UNSIGNED_INT_2_10_10_10_REV:
411 return GL_RGB10_A2;
412
413 case GL_UNSIGNED_SHORT:
414 case GL_UNSIGNED_INT:
415 return GL_RGBA16;
416
417 case GL_BYTE:
418 return
419 ctx->Extensions.EXT_texture_snorm ? GL_RGBA8_SNORM : GL_RGBA8;
420
421 case GL_SHORT:
422 case GL_INT:
423 return
424 ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16;
425
426 case GL_HALF_FLOAT_ARB:
427 return
428 ctx->Extensions.ARB_texture_float ? GL_RGBA16F :
429 ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16;
430
431 case GL_FLOAT:
432 case GL_DOUBLE:
433 return
434 ctx->Extensions.ARB_texture_float ? GL_RGBA32F :
435 ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16;
436
437 case GL_UNSIGNED_INT_5_9_9_9_REV:
438 assert(ctx->Extensions.EXT_texture_shared_exponent);
439 return GL_RGB9_E5;
440
441 case GL_UNSIGNED_INT_10F_11F_11F_REV:
442 assert(ctx->Extensions.EXT_packed_float);
443 return GL_R11F_G11F_B10F;
444 }
445 }
446 }
447 }
448
449
450 /**
451 * Create a temporary texture to hold an image of the given size.
452 * If width, height are not POT and the driver only handles POT textures,
453 * allocate the next larger size of texture that is POT.
454 */
455 static struct pipe_resource *
alloc_texture(struct st_context * st,GLsizei width,GLsizei height,enum pipe_format texFormat,unsigned bind)456 alloc_texture(struct st_context *st, GLsizei width, GLsizei height,
457 enum pipe_format texFormat, unsigned bind)
458 {
459 struct pipe_resource *pt;
460
461 pt = st_texture_create(st, st->internal_target, texFormat, 0,
462 width, height, 1, 1, 0, bind, false,
463 PIPE_COMPRESSION_FIXED_RATE_NONE);
464
465 return pt;
466 }
467
468
469 /**
470 * Search the cache for an image which matches the given parameters.
471 * \return pipe_resource pointer if found, NULL if not found.
472 */
473 static struct pipe_resource *
search_drawpixels_cache(struct st_context * st,GLsizei width,GLsizei height,GLenum format,GLenum type,const struct gl_pixelstore_attrib * unpack,const void * pixels)474 search_drawpixels_cache(struct st_context *st,
475 GLsizei width, GLsizei height,
476 GLenum format, GLenum type,
477 const struct gl_pixelstore_attrib *unpack,
478 const void *pixels)
479 {
480 struct pipe_resource *pt = NULL;
481 const GLint bpp = _mesa_bytes_per_pixel(format, type);
482 unsigned i;
483
484 if ((unpack->RowLength != 0 && unpack->RowLength != width) ||
485 unpack->SkipPixels != 0 ||
486 unpack->SkipRows != 0 ||
487 unpack->SwapBytes ||
488 unpack->BufferObj) {
489 /* we don't allow non-default pixel unpacking values */
490 return NULL;
491 }
492
493 /* Search cache entries for a match */
494 for (i = 0; i < ARRAY_SIZE(st->drawpix_cache.entries); i++) {
495 struct drawpix_cache_entry *entry = &st->drawpix_cache.entries[i];
496
497 if (width == entry->width &&
498 height == entry->height &&
499 format == entry->format &&
500 type == entry->type &&
501 pixels == entry->user_pointer &&
502 entry->image) {
503 assert(entry->texture);
504
505 /* check if the pixel data is the same */
506 if (memcmp(pixels, entry->image, width * height * bpp) == 0) {
507 /* Success - found a cache match */
508 pipe_resource_reference(&pt, entry->texture);
509 /* refcount of returned texture should be at least two here. One
510 * reference for the cache to hold on to, one for the caller (which
511 * it will release), and possibly more held by the driver.
512 */
513 assert(pt->reference.count >= 2);
514
515 /* update the age of this entry */
516 entry->age = ++st->drawpix_cache.age;
517
518 return pt;
519 }
520 }
521 }
522
523 /* no cache match found */
524 return NULL;
525 }
526
527
528 /**
529 * Find the oldest entry in the glDrawPixels cache. We'll replace this
530 * one when we need to store a new image.
531 */
532 static struct drawpix_cache_entry *
find_oldest_drawpixels_cache_entry(struct st_context * st)533 find_oldest_drawpixels_cache_entry(struct st_context *st)
534 {
535 unsigned oldest_age = ~0u, oldest_index = ~0u;
536 unsigned i;
537
538 /* Find entry with oldest (lowest) age */
539 for (i = 0; i < ARRAY_SIZE(st->drawpix_cache.entries); i++) {
540 const struct drawpix_cache_entry *entry = &st->drawpix_cache.entries[i];
541 if (entry->age < oldest_age) {
542 oldest_age = entry->age;
543 oldest_index = i;
544 }
545 }
546
547 assert(oldest_index != ~0u);
548
549 return &st->drawpix_cache.entries[oldest_index];
550 }
551
552
553 /**
554 * Try to save the given glDrawPixels image in the cache.
555 */
556 static void
cache_drawpixels_image(struct st_context * st,GLsizei width,GLsizei height,GLenum format,GLenum type,const struct gl_pixelstore_attrib * unpack,const void * pixels,struct pipe_resource * pt)557 cache_drawpixels_image(struct st_context *st,
558 GLsizei width, GLsizei height,
559 GLenum format, GLenum type,
560 const struct gl_pixelstore_attrib *unpack,
561 const void *pixels,
562 struct pipe_resource *pt)
563 {
564 if ((unpack->RowLength == 0 || unpack->RowLength == width) &&
565 unpack->SkipPixels == 0 &&
566 unpack->SkipRows == 0) {
567 const GLint bpp = _mesa_bytes_per_pixel(format, type);
568 struct drawpix_cache_entry *entry =
569 find_oldest_drawpixels_cache_entry(st);
570 assert(entry);
571 entry->width = width;
572 entry->height = height;
573 entry->format = format;
574 entry->type = type;
575 entry->user_pointer = pixels;
576 free(entry->image);
577 entry->image = malloc(width * height * bpp);
578 if (entry->image) {
579 memcpy(entry->image, pixels, width * height * bpp);
580 pipe_resource_reference(&entry->texture, pt);
581 entry->age = ++st->drawpix_cache.age;
582 }
583 else {
584 /* out of memory, free/disable cached texture */
585 entry->width = 0;
586 entry->height = 0;
587 pipe_resource_reference(&entry->texture, NULL);
588 }
589 }
590 }
591
592
593 /**
594 * Make texture containing an image for glDrawPixels image.
595 * If 'pixels' is NULL, leave the texture image data undefined.
596 */
597 static struct pipe_resource *
make_texture(struct st_context * st,GLsizei width,GLsizei height,GLenum format,GLenum type,const struct gl_pixelstore_attrib * unpack,const void * pixels)598 make_texture(struct st_context *st,
599 GLsizei width, GLsizei height, GLenum format, GLenum type,
600 const struct gl_pixelstore_attrib *unpack,
601 const void *pixels)
602 {
603 struct gl_context *ctx = st->ctx;
604 struct pipe_context *pipe = st->pipe;
605 mesa_format mformat;
606 struct pipe_resource *pt = NULL;
607 enum pipe_format pipeFormat;
608 GLenum baseInternalFormat;
609
610 #if USE_DRAWPIXELS_CACHE
611 pt = search_drawpixels_cache(st, width, height, format, type,
612 unpack, pixels);
613 if (pt) {
614 return pt;
615 }
616 #endif
617
618 /* Choose a pixel format for the temp texture which will hold the
619 * image to draw.
620 */
621 pipeFormat = st_choose_matching_format(st, PIPE_BIND_SAMPLER_VIEW,
622 format, type, unpack->SwapBytes);
623
624 if (pipeFormat == PIPE_FORMAT_NONE) {
625 /* Use the generic approach. */
626 GLenum intFormat = internal_format(ctx, format, type);
627
628 pipeFormat = st_choose_format(st, intFormat, format, type,
629 st->internal_target, 0, 0,
630 PIPE_BIND_SAMPLER_VIEW,
631 false, false);
632 assert(pipeFormat != PIPE_FORMAT_NONE);
633 }
634
635 mformat = st_pipe_format_to_mesa_format(pipeFormat);
636 baseInternalFormat = _mesa_get_format_base_format(mformat);
637
638 pixels = _mesa_map_pbo_source(ctx, unpack, pixels);
639 if (!pixels)
640 return NULL;
641
642 /* alloc temporary texture */
643 pt = alloc_texture(st, width, height, pipeFormat, PIPE_BIND_SAMPLER_VIEW);
644 if (!pt) {
645 _mesa_unmap_pbo_source(ctx, unpack);
646 return NULL;
647 }
648
649 {
650 struct pipe_transfer *transfer;
651 GLubyte *dest;
652 const GLbitfield imageTransferStateSave = ctx->_ImageTransferState;
653
654 /* we'll do pixel transfer in a fragment shader */
655 ctx->_ImageTransferState = 0x0;
656
657 /* map texture transfer */
658 dest = pipe_texture_map(pipe, pt, 0, 0,
659 PIPE_MAP_WRITE | PIPE_MAP_DISCARD_WHOLE_RESOURCE,
660 0, 0, width, height, &transfer);
661 if (!dest) {
662 pipe_resource_reference(&pt, NULL);
663 _mesa_unmap_pbo_source(ctx, unpack);
664 return NULL;
665 }
666
667 /* Put image into texture transfer.
668 * Note that the image is actually going to be upside down in
669 * the texture. We deal with that with texcoords.
670 */
671 if ((format == GL_RGBA || format == GL_BGRA)
672 && type == GL_UNSIGNED_BYTE) {
673 /* Use a memcpy-based texstore to avoid software pixel swizzling.
674 * We'll do the necessary swizzling with the pipe_sampler_view to
675 * give much better performance.
676 * XXX in the future, expand this to accomodate more format and
677 * type combinations.
678 */
679 _mesa_memcpy_texture(ctx, 2,
680 mformat, /* mesa_format */
681 transfer->stride, /* dstRowStride, bytes */
682 &dest, /* destSlices */
683 width, height, 1, /* size */
684 format, type, /* src format/type */
685 pixels, /* data source */
686 unpack);
687 }
688 else {
689 ASSERTED bool success;
690 success = _mesa_texstore(ctx, 2, /* dims */
691 baseInternalFormat, /* baseInternalFormat */
692 mformat, /* mesa_format */
693 transfer->stride, /* dstRowStride, bytes */
694 &dest, /* destSlices */
695 width, height, 1, /* size */
696 format, type, /* src format/type */
697 pixels, /* data source */
698 unpack);
699
700 assert(success);
701 }
702
703 /* unmap */
704 pipe_texture_unmap(pipe, transfer);
705
706 /* restore */
707 ctx->_ImageTransferState = imageTransferStateSave;
708 }
709
710 #if USE_DRAWPIXELS_CACHE
711 cache_drawpixels_image(st, width, height, format, type, unpack, pixels, pt);
712 #endif
713
714 _mesa_unmap_pbo_source(ctx, unpack);
715
716 return pt;
717 }
718
719
720 static void
draw_textured_quad(struct gl_context * ctx,GLint x,GLint y,GLfloat z,GLsizei width,GLsizei height,GLfloat zoomX,GLfloat zoomY,struct pipe_sampler_view ** sv,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)721 draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
722 GLsizei width, GLsizei height,
723 GLfloat zoomX, GLfloat zoomY,
724 struct pipe_sampler_view **sv,
725 int num_sampler_view,
726 void *driver_vp,
727 void *driver_fp,
728 struct st_fp_variant *fpv,
729 const GLfloat *color,
730 GLboolean invertTex,
731 GLboolean write_depth, GLboolean write_stencil)
732 {
733 struct st_context *st = st_context(ctx);
734 struct pipe_context *pipe = st->pipe;
735 struct cso_context *cso = st->cso_context;
736 const unsigned fb_width = _mesa_geometric_width(ctx->DrawBuffer);
737 const unsigned fb_height = _mesa_geometric_height(ctx->DrawBuffer);
738 GLfloat x0, y0, x1, y1;
739 ASSERTED GLsizei maxSize;
740 bool normalized = sv[0]->texture->target == PIPE_TEXTURE_2D ||
741 (sv[0]->texture->target == PIPE_TEXTURE_RECT && st->lower_rect_tex);
742 unsigned cso_state_mask;
743
744 assert(sv[0]->texture->target == st->internal_target);
745
746 /* limit checks */
747 /* XXX if DrawPixels image is larger than max texture size, break
748 * it up into chunks.
749 */
750 maxSize = st->screen->get_param(st->screen,
751 PIPE_CAP_MAX_TEXTURE_2D_SIZE);
752 assert(width <= maxSize);
753 assert(height <= maxSize);
754
755 cso_state_mask = (CSO_BIT_RASTERIZER |
756 CSO_BIT_VIEWPORT |
757 CSO_BIT_FRAGMENT_SAMPLERS |
758 CSO_BIT_STREAM_OUTPUTS |
759 CSO_BIT_VERTEX_ELEMENTS |
760 CSO_BITS_ALL_SHADERS);
761 if (write_stencil) {
762 cso_state_mask |= (CSO_BIT_DEPTH_STENCIL_ALPHA |
763 CSO_BIT_BLEND);
764 }
765 cso_save_state(cso, cso_state_mask);
766
767 /* rasterizer state: just scissor */
768 {
769 struct pipe_rasterizer_state rasterizer;
770 memset(&rasterizer, 0, sizeof(rasterizer));
771 rasterizer.clamp_fragment_color = !st->clamp_frag_color_in_shader &&
772 ctx->Color._ClampFragmentColor;
773 rasterizer.half_pixel_center = 1;
774 rasterizer.bottom_edge_rule = 1;
775 rasterizer.depth_clip_near = !ctx->Transform.DepthClampNear;
776 rasterizer.depth_clip_far = !ctx->Transform.DepthClampFar;
777 rasterizer.depth_clamp = !rasterizer.depth_clip_far;
778 rasterizer.scissor = ctx->Scissor.EnableFlags;
779 cso_set_rasterizer(cso, &rasterizer);
780 }
781
782 if (write_stencil) {
783 /* Stencil writing bypasses the normal fragment pipeline to
784 * disable color writing and set stencil test to always pass.
785 */
786 struct pipe_depth_stencil_alpha_state dsa;
787 struct pipe_blend_state blend;
788
789 /* depth/stencil */
790 memset(&dsa, 0, sizeof(dsa));
791 dsa.stencil[0].enabled = 1;
792 dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
793 dsa.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
794 dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
795 if (write_depth) {
796 /* writing depth+stencil: depth test always passes */
797 dsa.depth_enabled = 1;
798 dsa.depth_writemask = ctx->Depth.Mask;
799 dsa.depth_func = PIPE_FUNC_ALWAYS;
800 }
801 cso_set_depth_stencil_alpha(cso, &dsa);
802
803 /* blend (colormask) */
804 memset(&blend, 0, sizeof(blend));
805 cso_set_blend(cso, &blend);
806 }
807
808 /* fragment shader state: TEX lookup program */
809 cso_set_fragment_shader_handle(cso, driver_fp);
810
811 /* vertex shader state: position + texcoord pass-through */
812 cso_set_vertex_shader_handle(cso, driver_vp);
813
814 /* disable other shaders */
815 cso_set_tessctrl_shader_handle(cso, NULL);
816 cso_set_tesseval_shader_handle(cso, NULL);
817 cso_set_geometry_shader_handle(cso, NULL);
818
819 /* user samplers, plus the drawpix samplers */
820 {
821 struct pipe_sampler_state sampler;
822
823 memset(&sampler, 0, sizeof(sampler));
824 sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
825 sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
826 sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
827 sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
828 sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
829 sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
830 sampler.unnormalized_coords = !normalized;
831
832 if (fpv) {
833 /* drawing a color image */
834 const struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
835 uint num = MAX3(fpv->drawpix_sampler + 1,
836 fpv->pixelmap_sampler + 1,
837 st->state.num_frag_samplers);
838 uint i;
839
840 for (i = 0; i < st->state.num_frag_samplers; i++)
841 samplers[i] = &st->state.frag_samplers[i];
842
843 samplers[fpv->drawpix_sampler] = &sampler;
844 if (sv[1])
845 samplers[fpv->pixelmap_sampler] = &sampler;
846
847 cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, num, samplers);
848 } else {
849 /* drawing a depth/stencil image */
850 const struct pipe_sampler_state *samplers[2] = {&sampler, &sampler};
851
852 cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, num_sampler_view, samplers);
853 }
854 }
855
856 unsigned tex_width = sv[0]->texture->width0;
857 unsigned tex_height = sv[0]->texture->height0;
858
859 /* user textures, plus the drawpix textures */
860 if (fpv) {
861 /* drawing a color image */
862 struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
863 unsigned num_views =
864 st_get_sampler_views(st, PIPE_SHADER_FRAGMENT,
865 ctx->FragmentProgram._Current, sampler_views);
866
867 num_views = MAX3(fpv->drawpix_sampler + 1, fpv->pixelmap_sampler + 1,
868 num_views);
869
870 sampler_views[fpv->drawpix_sampler] = sv[0];
871 if (sv[1])
872 sampler_views[fpv->pixelmap_sampler] = sv[1];
873 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, num_views, 0,
874 true, sampler_views);
875 st->state.num_sampler_views[PIPE_SHADER_FRAGMENT] = num_views;
876 } else {
877 /* drawing a depth/stencil image */
878 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, num_sampler_view,
879 0, false, sv);
880 st->state.num_sampler_views[PIPE_SHADER_FRAGMENT] =
881 MAX2(st->state.num_sampler_views[PIPE_SHADER_FRAGMENT], num_sampler_view);
882
883 for (unsigned i = 0; i < num_sampler_view; i++)
884 pipe_sampler_view_reference(&sv[i], NULL);
885 }
886
887 /* viewport state: viewport matching window dims */
888 cso_set_viewport_dims(cso, fb_width, fb_height, true);
889
890 st->util_velems.count = 3;
891 cso_set_vertex_elements(cso, &st->util_velems);
892 cso_set_stream_outputs(cso, 0, NULL, NULL);
893
894 /* Compute Gallium window coords (y=0=top) with pixel zoom.
895 * Recall that these coords are transformed by the current
896 * vertex shader and viewport transformation.
897 */
898 if (_mesa_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM) {
899 y = fb_height - (int) (y + height * ctx->Pixel.ZoomY);
900 invertTex = !invertTex;
901 }
902
903 x0 = (GLfloat) x;
904 x1 = x + width * ctx->Pixel.ZoomX;
905 y0 = (GLfloat) y;
906 y1 = y + height * ctx->Pixel.ZoomY;
907
908 /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
909 z = z * 2.0f - 1.0f;
910
911 {
912 const float clip_x0 = x0 / (float) fb_width * 2.0f - 1.0f;
913 const float clip_y0 = y0 / (float) fb_height * 2.0f - 1.0f;
914 const float clip_x1 = x1 / (float) fb_width * 2.0f - 1.0f;
915 const float clip_y1 = y1 / (float) fb_height * 2.0f - 1.0f;
916 const float maxXcoord = normalized ?
917 ((float) width / tex_width) : (float) width;
918 const float maxYcoord = normalized
919 ? ((float) height / tex_height) : (float) height;
920 const float sLeft = 0.0f, sRight = maxXcoord;
921 const float tTop = invertTex ? maxYcoord : 0.0f;
922 const float tBot = invertTex ? 0.0f : maxYcoord;
923
924 if (!st_draw_quad(st, clip_x0, clip_y0, clip_x1, clip_y1, z,
925 sLeft, tBot, sRight, tTop, color, 0)) {
926 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
927 }
928 }
929
930 /* restore state */
931 /* Unbind all because st/mesa won't do it if the current shader doesn't
932 * use them.
933 */
934 cso_restore_state(cso, CSO_UNBIND_FS_SAMPLERVIEWS);
935 st->state.num_sampler_views[PIPE_SHADER_FRAGMENT] = 0;
936
937 ctx->Array.NewVertexElements = true;
938 ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS |
939 ST_NEW_FS_SAMPLER_VIEWS;
940 }
941
942
943 /**
944 * Software fallback to do glDrawPixels(GL_STENCIL_INDEX) when we
945 * can't use a fragment shader to write stencil values.
946 */
947 static void
draw_stencil_pixels(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,const struct gl_pixelstore_attrib * unpack,const void * pixels)948 draw_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
949 GLsizei width, GLsizei height, GLenum format, GLenum type,
950 const struct gl_pixelstore_attrib *unpack,
951 const void *pixels)
952 {
953 struct st_context *st = st_context(ctx);
954 struct pipe_context *pipe = st->pipe;
955 struct gl_renderbuffer *rb;
956 enum pipe_map_flags usage;
957 struct pipe_transfer *pt;
958 const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
959 uint8_t *stmap;
960 struct gl_pixelstore_attrib clippedUnpack = *unpack;
961 GLubyte *sValues;
962 GLuint *zValues;
963
964 rb = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
965
966 if (_mesa_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
967 y = ctx->DrawBuffer->Height - y - height;
968 }
969
970 if (format == GL_STENCIL_INDEX &&
971 _mesa_is_format_packed_depth_stencil(rb->Format)) {
972 /* writing stencil to a combined depth+stencil buffer */
973 usage = PIPE_MAP_READ_WRITE;
974 }
975 else {
976 usage = PIPE_MAP_WRITE;
977 }
978
979 stmap = pipe_texture_map(pipe, rb->texture,
980 rb->surface->u.tex.level,
981 rb->surface->u.tex.first_layer,
982 usage, x, y,
983 width, height, &pt);
984
985 pixels = _mesa_map_pbo_source(ctx, &clippedUnpack, pixels);
986 assert(pixels);
987
988 sValues = malloc(width * sizeof(GLubyte));
989 zValues = malloc(width * sizeof(GLuint));
990
991 if (sValues && zValues) {
992 GLint row;
993 for (row = 0; row < height; row++) {
994 GLfloat *zValuesFloat = (GLfloat*)zValues;
995 GLenum destType = GL_UNSIGNED_BYTE;
996 const void *source = _mesa_image_address2d(&clippedUnpack, pixels,
997 width, height,
998 format, type,
999 row, 0);
1000 _mesa_unpack_stencil_span(ctx, width, destType, sValues,
1001 type, source, &clippedUnpack,
1002 ctx->_ImageTransferState);
1003
1004 if (format == GL_DEPTH_STENCIL) {
1005 GLenum ztype =
1006 pt->resource->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ?
1007 GL_FLOAT : GL_UNSIGNED_INT;
1008
1009 _mesa_unpack_depth_span(ctx, width, ztype, zValues,
1010 (1 << 24) - 1, type, source,
1011 &clippedUnpack);
1012 }
1013
1014 if (zoom) {
1015 _mesa_problem(ctx, "Gallium glDrawPixels(GL_STENCIL) with "
1016 "zoom not complete");
1017 }
1018
1019 {
1020 GLint spanY;
1021
1022 if (_mesa_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
1023 spanY = height - row - 1;
1024 }
1025 else {
1026 spanY = row;
1027 }
1028
1029 /* now pack the stencil (and Z) values in the dest format */
1030 switch (pt->resource->format) {
1031 case PIPE_FORMAT_S8_UINT:
1032 {
1033 uint8_t *dest = stmap + spanY * pt->stride;
1034 assert(usage == PIPE_MAP_WRITE);
1035 memcpy(dest, sValues, width);
1036 }
1037 break;
1038 case PIPE_FORMAT_Z24_UNORM_S8_UINT:
1039 if (format == GL_DEPTH_STENCIL) {
1040 uint *dest = (uint *) (stmap + spanY * pt->stride);
1041 GLint k;
1042 assert(usage == PIPE_MAP_WRITE);
1043 for (k = 0; k < width; k++) {
1044 dest[k] = zValues[k] | (sValues[k] << 24);
1045 }
1046 }
1047 else {
1048 uint *dest = (uint *) (stmap + spanY * pt->stride);
1049 GLint k;
1050 assert(usage == PIPE_MAP_READ_WRITE);
1051 for (k = 0; k < width; k++) {
1052 dest[k] = (dest[k] & 0xffffff) | (sValues[k] << 24);
1053 }
1054 }
1055 break;
1056 case PIPE_FORMAT_S8_UINT_Z24_UNORM:
1057 if (format == GL_DEPTH_STENCIL) {
1058 uint *dest = (uint *) (stmap + spanY * pt->stride);
1059 GLint k;
1060 assert(usage == PIPE_MAP_WRITE);
1061 for (k = 0; k < width; k++) {
1062 dest[k] = (zValues[k] << 8) | (sValues[k] & 0xff);
1063 }
1064 }
1065 else {
1066 uint *dest = (uint *) (stmap + spanY * pt->stride);
1067 GLint k;
1068 assert(usage == PIPE_MAP_READ_WRITE);
1069 for (k = 0; k < width; k++) {
1070 dest[k] = (dest[k] & 0xffffff00) | (sValues[k] & 0xff);
1071 }
1072 }
1073 break;
1074 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
1075 if (format == GL_DEPTH_STENCIL) {
1076 uint *dest = (uint *) (stmap + spanY * pt->stride);
1077 GLfloat *destf = (GLfloat*)dest;
1078 GLint k;
1079 assert(usage == PIPE_MAP_WRITE);
1080 for (k = 0; k < width; k++) {
1081 destf[k*2] = zValuesFloat[k];
1082 dest[k*2+1] = sValues[k] & 0xff;
1083 }
1084 }
1085 else {
1086 uint *dest = (uint *) (stmap + spanY * pt->stride);
1087 GLint k;
1088 assert(usage == PIPE_MAP_READ_WRITE);
1089 for (k = 0; k < width; k++) {
1090 dest[k*2+1] = sValues[k] & 0xff;
1091 }
1092 }
1093 break;
1094 default:
1095 assert(0);
1096 }
1097 }
1098 }
1099 }
1100 else {
1101 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels()");
1102 }
1103
1104 free(sValues);
1105 free(zValues);
1106
1107 _mesa_unmap_pbo_source(ctx, &clippedUnpack);
1108
1109 /* unmap the stencil buffer */
1110 pipe_texture_unmap(pipe, pt);
1111 }
1112
1113
1114 /**
1115 * Get fragment program variant for a glDrawPixels or glCopyPixels
1116 * command for RGBA data.
1117 */
1118 static struct st_fp_variant *
get_color_fp_variant(struct st_context * st)1119 get_color_fp_variant(struct st_context *st)
1120 {
1121 struct gl_context *ctx = st->ctx;
1122 struct st_fp_variant_key key;
1123 struct st_fp_variant *fpv;
1124
1125 memset(&key, 0, sizeof(key));
1126
1127 key.st = st->has_shareable_shaders ? NULL : st;
1128 key.drawpixels = 1;
1129 key.scaleAndBias = (ctx->Pixel.RedBias != 0.0 ||
1130 ctx->Pixel.RedScale != 1.0 ||
1131 ctx->Pixel.GreenBias != 0.0 ||
1132 ctx->Pixel.GreenScale != 1.0 ||
1133 ctx->Pixel.BlueBias != 0.0 ||
1134 ctx->Pixel.BlueScale != 1.0 ||
1135 ctx->Pixel.AlphaBias != 0.0 ||
1136 ctx->Pixel.AlphaScale != 1.0);
1137 key.pixelMaps = ctx->Pixel.MapColorFlag;
1138 key.clamp_color = st->clamp_frag_color_in_shader &&
1139 ctx->Color._ClampFragmentColor;
1140 key.lower_alpha_func = COMPARE_FUNC_ALWAYS;
1141
1142 fpv = st_get_fp_variant(st, ctx->FragmentProgram._Current, &key);
1143
1144 return fpv;
1145 }
1146
1147 /**
1148 * Get fragment program variant for a glDrawPixels command
1149 * for COLOR_INDEX data
1150 */
1151 static struct st_fp_variant *
get_color_index_fp_variant(struct st_context * st)1152 get_color_index_fp_variant(struct st_context *st)
1153 {
1154 struct gl_context *ctx = st->ctx;
1155 struct st_fp_variant_key key;
1156 struct st_fp_variant *fpv;
1157
1158 memset(&key, 0, sizeof(key));
1159
1160 key.st = st->has_shareable_shaders ? NULL : st;
1161 key.drawpixels = 1;
1162 /* Since GL is always in RGBA mode MapColorFlag does not
1163 * affect GL_COLOR_INDEX format.
1164 * Scale and bias also never affect GL_COLOR_INDEX format.
1165 */
1166 key.scaleAndBias = 0;
1167 key.pixelMaps = 0;
1168 key.clamp_color = st->clamp_frag_color_in_shader &&
1169 ctx->Color._ClampFragmentColor;
1170 key.lower_alpha_func = COMPARE_FUNC_ALWAYS;
1171
1172 fpv = st_get_fp_variant(st, ctx->FragmentProgram._Current, &key);
1173
1174 return fpv;
1175 }
1176
1177
1178 /**
1179 * Clamp glDrawPixels width and height to the maximum texture size.
1180 */
1181 static void
clamp_size(struct st_context * st,GLsizei * width,GLsizei * height,struct gl_pixelstore_attrib * unpack)1182 clamp_size(struct st_context *st, GLsizei *width, GLsizei *height,
1183 struct gl_pixelstore_attrib *unpack)
1184 {
1185 const int maxSize = st->screen->get_param(st->screen,
1186 PIPE_CAP_MAX_TEXTURE_2D_SIZE);
1187
1188 if (*width > maxSize) {
1189 if (unpack->RowLength == 0)
1190 unpack->RowLength = *width;
1191 *width = maxSize;
1192 }
1193 if (*height > maxSize) {
1194 *height = maxSize;
1195 }
1196 }
1197
1198
1199 /**
1200 * Search the array of 4 swizzle components for the named component and return
1201 * its position.
1202 */
1203 static unsigned
search_swizzle(const unsigned char swizzle[4],unsigned component)1204 search_swizzle(const unsigned char swizzle[4], unsigned component)
1205 {
1206 unsigned i;
1207 for (i = 0; i < 4; i++) {
1208 if (swizzle[i] == component)
1209 return i;
1210 }
1211 assert(!"search_swizzle() failed");
1212 return 0;
1213 }
1214
1215
1216 /**
1217 * Set the sampler view's swizzle terms. This is used to handle RGBA
1218 * swizzling when the incoming image format isn't an exact match for
1219 * the actual texture format. For example, if we have glDrawPixels(
1220 * GL_RGBA, GL_UNSIGNED_BYTE) and we chose the texture format
1221 * PIPE_FORMAT_B8G8R8A8 then we can do use the sampler view swizzle to
1222 * avoid swizzling all the pixels in software in the texstore code.
1223 */
1224 static void
setup_sampler_swizzle(struct pipe_sampler_view * sv,GLenum format,GLenum type)1225 setup_sampler_swizzle(struct pipe_sampler_view *sv, GLenum format, GLenum type)
1226 {
1227 if ((format == GL_RGBA || format == GL_BGRA) && type == GL_UNSIGNED_BYTE) {
1228 const struct util_format_description *desc =
1229 util_format_description(sv->format);
1230 unsigned c0, c1, c2, c3;
1231
1232 /* Every gallium driver supports at least one 32-bit packed RGBA format.
1233 * We must have chosen one for (GL_RGBA, GL_UNSIGNED_BYTE).
1234 */
1235 assert(desc->block.bits == 32);
1236
1237 /* invert the format's swizzle to setup the sampler's swizzle */
1238 if (format == GL_RGBA) {
1239 c0 = PIPE_SWIZZLE_X;
1240 c1 = PIPE_SWIZZLE_Y;
1241 c2 = PIPE_SWIZZLE_Z;
1242 c3 = PIPE_SWIZZLE_W;
1243 }
1244 else {
1245 assert(format == GL_BGRA);
1246 c0 = PIPE_SWIZZLE_Z;
1247 c1 = PIPE_SWIZZLE_Y;
1248 c2 = PIPE_SWIZZLE_X;
1249 c3 = PIPE_SWIZZLE_W;
1250 }
1251 sv->swizzle_r = search_swizzle(desc->swizzle, c0);
1252 sv->swizzle_g = search_swizzle(desc->swizzle, c1);
1253 sv->swizzle_b = search_swizzle(desc->swizzle, c2);
1254 sv->swizzle_a = search_swizzle(desc->swizzle, c3);
1255 }
1256 else {
1257 /* use the default sampler swizzle */
1258 }
1259 }
1260
1261 void
st_DrawPixels(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,const struct gl_pixelstore_attrib * unpack,const void * pixels)1262 st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
1263 GLsizei width, GLsizei height,
1264 GLenum format, GLenum type,
1265 const struct gl_pixelstore_attrib *unpack, const void *pixels)
1266 {
1267 void *driver_fp;
1268 struct st_context *st = st_context(ctx);
1269 GLboolean write_stencil = GL_FALSE, write_depth = GL_FALSE;
1270 struct pipe_sampler_view *sv[2] = { NULL };
1271 int num_sampler_view = 1;
1272 struct gl_pixelstore_attrib clippedUnpack;
1273 struct st_fp_variant *fpv = NULL;
1274 struct pipe_resource *pt;
1275
1276 /* Mesa state should be up to date by now */
1277 assert(ctx->NewState == 0x0);
1278
1279 _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
1280
1281 st_flush_bitmap_cache(st);
1282 st_invalidate_readpix_cache(st);
1283
1284 st_validate_state(st, ST_PIPELINE_META_STATE_MASK);
1285
1286 clippedUnpack = *unpack;
1287 unpack = &clippedUnpack;
1288
1289 /* Skip totally clipped DrawPixels. */
1290 if (ctx->Pixel.ZoomX == 1 && ctx->Pixel.ZoomY == 1 &&
1291 !_mesa_clip_drawpixels(ctx, &x, &y, &width, &height, &clippedUnpack))
1292 return;
1293
1294 /* Limit the size of the glDrawPixels to the max texture size.
1295 * Strictly speaking, that's not correct but since we don't handle
1296 * larger images yet, this is better than crashing.
1297 */
1298 clamp_size(st, &width, &height, &clippedUnpack);
1299
1300 if (format == GL_DEPTH_STENCIL)
1301 write_stencil = write_depth = GL_TRUE;
1302 else if (format == GL_STENCIL_INDEX)
1303 write_stencil = GL_TRUE;
1304 else if (format == GL_DEPTH_COMPONENT)
1305 write_depth = GL_TRUE;
1306
1307 if (write_stencil &&
1308 !st->has_stencil_export) {
1309 /* software fallback */
1310 draw_stencil_pixels(ctx, x, y, width, height, format, type,
1311 unpack, pixels);
1312 return;
1313 }
1314
1315 /* Put glDrawPixels image into a texture */
1316 pt = make_texture(st, width, height, format, type, unpack, pixels);
1317 if (!pt) {
1318 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
1319 return;
1320 }
1321
1322 st_make_passthrough_vertex_shader(st);
1323
1324 /*
1325 * Get vertex/fragment shaders
1326 */
1327 if (write_depth || write_stencil) {
1328 driver_fp = get_drawpix_z_stencil_program(st, write_depth,
1329 write_stencil);
1330 }
1331 else {
1332 fpv = (format != GL_COLOR_INDEX) ? get_color_fp_variant(st) :
1333 get_color_index_fp_variant(st);
1334
1335 driver_fp = fpv->base.driver_shader;
1336
1337 if (ctx->Pixel.MapColorFlag && format != GL_COLOR_INDEX) {
1338 pipe_sampler_view_reference(&sv[1],
1339 st->pixel_xfer.pixelmap_sampler_view);
1340 num_sampler_view++;
1341 }
1342
1343 /* compiling a new fragment shader variant added new state constants
1344 * into the constant buffer, we need to update them
1345 */
1346 st_upload_constants(st, ctx->FragmentProgram._Current, MESA_SHADER_FRAGMENT);
1347 }
1348
1349 {
1350 /* create sampler view for the image */
1351 struct pipe_sampler_view templ;
1352
1353 u_sampler_view_default_template(&templ, pt, pt->format);
1354 /* Set up the sampler view's swizzle */
1355 setup_sampler_swizzle(&templ, format, type);
1356
1357 sv[0] = st->pipe->create_sampler_view(st->pipe, pt, &templ);
1358 }
1359 if (!sv[0]) {
1360 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
1361 pipe_resource_reference(&pt, NULL);
1362 return;
1363 }
1364
1365 /* Create a second sampler view to read stencil. The stencil is
1366 * written using the shader stencil export functionality.
1367 */
1368 if (write_stencil) {
1369 enum pipe_format stencil_format =
1370 util_format_stencil_only(pt->format);
1371 /* we should not be doing pixel map/transfer (see above) */
1372 assert(num_sampler_view == 1);
1373 sv[1] = st_create_texture_sampler_view_format(st->pipe, pt,
1374 stencil_format);
1375 if (!sv[1]) {
1376 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
1377 pipe_resource_reference(&pt, NULL);
1378 pipe_sampler_view_reference(&sv[0], NULL);
1379 return;
1380 }
1381 num_sampler_view++;
1382 }
1383
1384 draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
1385 width, height,
1386 ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
1387 sv,
1388 num_sampler_view,
1389 st->passthrough_vs,
1390 driver_fp, fpv,
1391 ctx->Current.RasterColor,
1392 GL_FALSE, write_depth, write_stencil);
1393
1394 /* free the texture (but may persist in the cache) */
1395 pipe_resource_reference(&pt, NULL);
1396 }
1397
1398
1399
1400 /**
1401 * Software fallback for glCopyPixels(GL_STENCIL).
1402 */
1403 static void
copy_stencil_pixels(struct gl_context * ctx,GLint srcx,GLint srcy,GLsizei width,GLsizei height,GLint dstx,GLint dsty)1404 copy_stencil_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
1405 GLsizei width, GLsizei height,
1406 GLint dstx, GLint dsty)
1407 {
1408 struct gl_renderbuffer *rbDraw;
1409 struct pipe_context *pipe = st_context(ctx)->pipe;
1410 enum pipe_map_flags usage;
1411 struct pipe_transfer *ptDraw;
1412 uint8_t *drawMap;
1413 uint8_t *buffer;
1414 int i;
1415
1416 buffer = malloc(width * height * sizeof(uint8_t));
1417 if (!buffer) {
1418 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels(stencil)");
1419 return;
1420 }
1421
1422 /* Get the dest renderbuffer */
1423 rbDraw = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
1424
1425 /* this will do stencil pixel transfer ops */
1426 _mesa_readpixels(ctx, srcx, srcy, width, height,
1427 GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
1428 &ctx->DefaultPacking, buffer);
1429
1430 if (0) {
1431 /* debug code: dump stencil values */
1432 GLint row, col;
1433 for (row = 0; row < height; row++) {
1434 printf("%3d: ", row);
1435 for (col = 0; col < width; col++) {
1436 printf("%02x ", buffer[col + row * width]);
1437 }
1438 printf("\n");
1439 }
1440 }
1441
1442 if (_mesa_is_format_packed_depth_stencil(rbDraw->Format))
1443 usage = PIPE_MAP_READ_WRITE;
1444 else
1445 usage = PIPE_MAP_WRITE;
1446
1447 if (_mesa_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
1448 dsty = rbDraw->Height - dsty - height;
1449 }
1450
1451 assert(util_format_get_blockwidth(rbDraw->texture->format) == 1);
1452 assert(util_format_get_blockheight(rbDraw->texture->format) == 1);
1453
1454 /* map the stencil buffer */
1455 drawMap = pipe_texture_map(pipe,
1456 rbDraw->texture,
1457 rbDraw->surface->u.tex.level,
1458 rbDraw->surface->u.tex.first_layer,
1459 usage, dstx, dsty,
1460 width, height, &ptDraw);
1461
1462 /* draw */
1463 /* XXX PixelZoom not handled yet */
1464 for (i = 0; i < height; i++) {
1465 uint8_t *dst;
1466 const uint8_t *src;
1467 int y;
1468
1469 y = i;
1470
1471 if (_mesa_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
1472 y = height - y - 1;
1473 }
1474
1475 dst = drawMap + y * ptDraw->stride;
1476 src = buffer + i * width;
1477
1478 _mesa_pack_ubyte_stencil_row(rbDraw->Format, width, src, dst);
1479 }
1480
1481 free(buffer);
1482
1483 /* unmap the stencil buffer */
1484 pipe_texture_unmap(pipe, ptDraw);
1485 }
1486
1487
1488 /**
1489 * Return renderbuffer to use for reading color pixels for glCopyPixels
1490 */
1491 static struct gl_renderbuffer *
st_get_color_read_renderbuffer(struct gl_context * ctx)1492 st_get_color_read_renderbuffer(struct gl_context *ctx)
1493 {
1494 struct gl_framebuffer *fb = ctx->ReadBuffer;
1495 return fb->_ColorReadBuffer;
1496 }
1497
1498
1499 /**
1500 * Try to do a glCopyPixels for simple cases with a blit by calling
1501 * pipe->blit().
1502 *
1503 * We can do this when we're copying color pixels (depth/stencil
1504 * eventually) with no pixel zoom, no pixel transfer ops, no
1505 * per-fragment ops, and the src/dest regions don't overlap.
1506 */
1507 static GLboolean
blit_copy_pixels(struct gl_context * ctx,GLint srcx,GLint srcy,GLsizei width,GLsizei height,GLint dstx,GLint dsty,GLenum type)1508 blit_copy_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
1509 GLsizei width, GLsizei height,
1510 GLint dstx, GLint dsty, GLenum type)
1511 {
1512 struct st_context *st = st_context(ctx);
1513 struct pipe_context *pipe = st->pipe;
1514 struct pipe_screen *screen = st->screen;
1515 struct gl_pixelstore_attrib pack, unpack;
1516 GLint readX, readY, readW, readH, drawX, drawY, drawW, drawH;
1517
1518 if (type == GL_DEPTH_STENCIL_TO_RGBA_NV || type == GL_DEPTH_STENCIL_TO_BGRA_NV)
1519 return GL_FALSE;
1520
1521 if (ctx->Pixel.ZoomX == 1.0 &&
1522 ctx->Pixel.ZoomY == 1.0 &&
1523 (type != GL_COLOR ||
1524 (ctx->_ImageTransferState == 0x0 &&
1525 !ctx->Color.BlendEnabled &&
1526 !ctx->Color.AlphaEnabled &&
1527 (!ctx->Color.ColorLogicOpEnabled || ctx->Color.LogicOp == GL_COPY) &&
1528 !ctx->Depth.BoundsTest &&
1529 (!ctx->Depth.Test || (ctx->Depth.Func == GL_ALWAYS && !ctx->Depth.Mask)) &&
1530 !ctx->Fog.Enabled &&
1531 (!ctx->Stencil.Enabled ||
1532 (ctx->Stencil.FailFunc[0] == GL_KEEP &&
1533 ctx->Stencil.ZPassFunc[0] == GL_KEEP &&
1534 ctx->Stencil.ZFailFunc[0] == GL_KEEP)) &&
1535 !ctx->FragmentProgram.Enabled &&
1536 !ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT] &&
1537 !_mesa_ati_fragment_shader_enabled(ctx) &&
1538 ctx->DrawBuffer->_NumColorDrawBuffers == 1)) &&
1539 !ctx->Query.CurrentOcclusionObject) {
1540 struct gl_renderbuffer *rbRead, *rbDraw;
1541
1542 /*
1543 * Clip the read region against the src buffer bounds.
1544 * We'll still allocate a temporary buffer/texture for the original
1545 * src region size but we'll only read the region which is on-screen.
1546 * This may mean that we draw garbage pixels into the dest region, but
1547 * that's expected.
1548 */
1549 readX = srcx;
1550 readY = srcy;
1551 readW = width;
1552 readH = height;
1553 pack = ctx->DefaultPacking;
1554 if (!_mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack))
1555 return GL_TRUE; /* all done */
1556
1557 /* clip against dest buffer bounds and scissor box */
1558 drawX = dstx + pack.SkipPixels;
1559 drawY = dsty + pack.SkipRows;
1560 unpack = pack;
1561 if (!_mesa_clip_drawpixels(ctx, &drawX, &drawY, &readW, &readH, &unpack))
1562 return GL_TRUE; /* all done */
1563
1564 readX = readX - pack.SkipPixels + unpack.SkipPixels;
1565 readY = readY - pack.SkipRows + unpack.SkipRows;
1566
1567 drawW = readW;
1568 drawH = readH;
1569
1570 if (type == GL_COLOR) {
1571 rbRead = st_get_color_read_renderbuffer(ctx);
1572 rbDraw = ctx->DrawBuffer->_ColorDrawBuffers[0];
1573 } else if (type == GL_DEPTH || type == GL_DEPTH_STENCIL) {
1574 rbRead = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
1575 rbDraw = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
1576 } else if (type == GL_STENCIL) {
1577 rbRead = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
1578 rbDraw = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
1579 } else {
1580 return false;
1581 }
1582
1583 /* Flip src/dst position depending on the orientation of buffers. */
1584 if (_mesa_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1585 readY = rbRead->Height - readY;
1586 readH = -readH;
1587 }
1588
1589 if (_mesa_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
1590 /* We can't flip the destination for pipe->blit, so we only adjust
1591 * its position and flip the source.
1592 */
1593 drawY = rbDraw->Height - drawY - drawH;
1594 readY += readH;
1595 readH = -readH;
1596 }
1597
1598 if (rbRead != rbDraw ||
1599 !_mesa_regions_overlap(readX, readY, readX + readW, readY + readH,
1600 drawX, drawY, drawX + drawW, drawY + drawH)) {
1601 struct pipe_blit_info blit;
1602
1603 memset(&blit, 0, sizeof(blit));
1604 blit.src.resource = rbRead->texture;
1605 blit.src.level = rbRead->surface->u.tex.level;
1606 blit.src.format = rbRead->texture->format;
1607 blit.src.box.x = readX;
1608 blit.src.box.y = readY;
1609 blit.src.box.z = rbRead->surface->u.tex.first_layer;
1610 blit.src.box.width = readW;
1611 blit.src.box.height = readH;
1612 blit.src.box.depth = 1;
1613 blit.dst.resource = rbDraw->texture;
1614 blit.dst.level = rbDraw->surface->u.tex.level;
1615 blit.dst.format = rbDraw->texture->format;
1616 blit.dst.box.x = drawX;
1617 blit.dst.box.y = drawY;
1618 blit.dst.box.z = rbDraw->surface->u.tex.first_layer;
1619 blit.dst.box.width = drawW;
1620 blit.dst.box.height = drawH;
1621 blit.dst.box.depth = 1;
1622 blit.filter = PIPE_TEX_FILTER_NEAREST;
1623 blit.render_condition_enable = ctx->Query.CondRenderQuery != NULL;
1624
1625 if (type == GL_COLOR)
1626 blit.mask |= PIPE_MASK_RGBA;
1627 if (type == GL_DEPTH)
1628 blit.mask |= PIPE_MASK_Z;
1629 if (type == GL_STENCIL)
1630 blit.mask |= PIPE_MASK_S;
1631 if (type == GL_DEPTH_STENCIL)
1632 blit.mask |= PIPE_MASK_ZS;
1633
1634 if (ctx->DrawBuffer != ctx->WinSysDrawBuffer)
1635 st_window_rectangles_to_blit(ctx, &blit);
1636
1637 if (screen->is_format_supported(screen, blit.src.format,
1638 blit.src.resource->target,
1639 blit.src.resource->nr_samples,
1640 blit.src.resource->nr_storage_samples,
1641 PIPE_BIND_SAMPLER_VIEW) &&
1642 screen->is_format_supported(screen, blit.dst.format,
1643 blit.dst.resource->target,
1644 blit.dst.resource->nr_samples,
1645 blit.dst.resource->nr_storage_samples,
1646 PIPE_BIND_RENDER_TARGET)) {
1647 pipe->blit(pipe, &blit);
1648 return GL_TRUE;
1649 }
1650 }
1651 }
1652
1653 return GL_FALSE;
1654 }
1655
1656 void
st_CopyPixels(struct gl_context * ctx,GLint srcx,GLint srcy,GLsizei width,GLsizei height,GLint dstx,GLint dsty,GLenum type)1657 st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
1658 GLsizei width, GLsizei height,
1659 GLint dstx, GLint dsty, GLenum type)
1660 {
1661 struct st_context *st = st_context(ctx);
1662 struct pipe_context *pipe = st->pipe;
1663 struct pipe_screen *screen = st->screen;
1664 struct gl_renderbuffer *rbRead;
1665 void *driver_fp;
1666 struct pipe_resource *pt;
1667 struct pipe_sampler_view *sv[2] = { NULL };
1668 struct st_fp_variant *fpv = NULL;
1669 int num_sampler_view = 1;
1670 enum pipe_format srcFormat;
1671 unsigned srcBind;
1672 GLboolean invertTex = GL_FALSE;
1673 GLint readX, readY, readW, readH;
1674 struct gl_pixelstore_attrib pack = ctx->DefaultPacking;
1675 GLboolean write_stencil = GL_FALSE;
1676 GLboolean write_depth = GL_FALSE;
1677
1678 _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
1679
1680 st_flush_bitmap_cache(st);
1681 st_invalidate_readpix_cache(st);
1682
1683 st_validate_state(st, ST_PIPELINE_META_STATE_MASK);
1684
1685 if (blit_copy_pixels(ctx, srcx, srcy, width, height, dstx, dsty, type))
1686 return;
1687
1688 /* fallback if the driver can't do stencil exports */
1689 if (type == GL_DEPTH_STENCIL &&
1690 !st->has_stencil_export) {
1691 st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_STENCIL);
1692 st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_DEPTH);
1693 return;
1694 }
1695
1696 /* fallback if the driver can't do stencil exports */
1697 if (type == GL_STENCIL &&
1698 !st->has_stencil_export) {
1699 copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty);
1700 return;
1701 }
1702
1703 /*
1704 * The subsequent code implements glCopyPixels by copying the source
1705 * pixels into a temporary texture that's then applied to a textured quad.
1706 * When we draw the textured quad, all the usual per-fragment operations
1707 * are handled.
1708 */
1709
1710 st_make_passthrough_vertex_shader(st);
1711
1712 /*
1713 * Get vertex/fragment shaders
1714 */
1715 if (type == GL_COLOR) {
1716 fpv = get_color_fp_variant(st);
1717
1718 rbRead = st_get_color_read_renderbuffer(ctx);
1719
1720 driver_fp = fpv->base.driver_shader;
1721
1722 if (ctx->Pixel.MapColorFlag) {
1723 pipe_sampler_view_reference(&sv[1],
1724 st->pixel_xfer.pixelmap_sampler_view);
1725 num_sampler_view++;
1726 }
1727
1728 /* compiling a new fragment shader variant added new state constants
1729 * into the constant buffer, we need to update them
1730 */
1731 st_upload_constants(st, ctx->FragmentProgram._Current, MESA_SHADER_FRAGMENT);
1732 } else if (type == GL_DEPTH) {
1733 rbRead = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
1734 driver_fp = get_drawpix_z_stencil_program(st, GL_TRUE, GL_FALSE);
1735 } else if (type == GL_STENCIL) {
1736 rbRead = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
1737 driver_fp = get_drawpix_z_stencil_program(st, GL_FALSE, GL_TRUE);
1738 } else if (type == GL_DEPTH_STENCIL) {
1739 rbRead = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
1740 driver_fp = get_drawpix_z_stencil_program(st, GL_TRUE, GL_TRUE);
1741 } else {
1742 assert(type == GL_DEPTH_STENCIL_TO_RGBA_NV || type == GL_DEPTH_STENCIL_TO_BGRA_NV);
1743 rbRead = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
1744 if (type == GL_DEPTH_STENCIL_TO_RGBA_NV)
1745 driver_fp = get_drawpix_zs_to_color_program(st, GL_TRUE);
1746 else
1747 driver_fp = get_drawpix_zs_to_color_program(st, GL_FALSE);
1748 if (!driver_fp) {
1749 assert(0 && "operation not supported by CopyPixels implemetation");
1750 return;
1751 }
1752 }
1753
1754
1755 /* Choose the format for the temporary texture. */
1756 srcFormat = rbRead->texture->format;
1757 srcBind = PIPE_BIND_SAMPLER_VIEW |
1758 (type == GL_COLOR ? PIPE_BIND_RENDER_TARGET : PIPE_BIND_DEPTH_STENCIL);
1759
1760 if (!screen->is_format_supported(screen, srcFormat, st->internal_target, 0,
1761 0, srcBind)) {
1762 /* srcFormat is non-renderable. Find a compatible renderable format. */
1763 if (type == GL_DEPTH) {
1764 srcFormat = st_choose_format(st, GL_DEPTH_COMPONENT, GL_NONE,
1765 GL_NONE, st->internal_target, 0, 0,
1766 srcBind, false, false);
1767 }
1768 else if (type == GL_STENCIL) {
1769 /* can't use texturing, fallback to copy */
1770 copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty);
1771 return;
1772 }
1773 else {
1774 assert(type == GL_COLOR);
1775
1776 if (util_format_is_float(srcFormat)) {
1777 srcFormat = st_choose_format(st, GL_RGBA32F, GL_NONE,
1778 GL_NONE, st->internal_target, 0, 0,
1779 srcBind, false, false);
1780 }
1781 else if (util_format_is_pure_sint(srcFormat)) {
1782 srcFormat = st_choose_format(st, GL_RGBA32I, GL_NONE,
1783 GL_NONE, st->internal_target, 0, 0,
1784 srcBind, false, false);
1785 }
1786 else if (util_format_is_pure_uint(srcFormat)) {
1787 srcFormat = st_choose_format(st, GL_RGBA32UI, GL_NONE,
1788 GL_NONE, st->internal_target, 0, 0,
1789 srcBind, false, false);
1790 }
1791 else if (util_format_is_snorm(srcFormat)) {
1792 srcFormat = st_choose_format(st, GL_RGBA16_SNORM, GL_NONE,
1793 GL_NONE, st->internal_target, 0, 0,
1794 srcBind, false, false);
1795 }
1796 else {
1797 srcFormat = st_choose_format(st, GL_RGBA, GL_NONE,
1798 GL_NONE, st->internal_target, 0, 0,
1799 srcBind, false, false);
1800 }
1801 }
1802
1803 if (srcFormat == PIPE_FORMAT_NONE) {
1804 assert(0 && "cannot choose a format for src of CopyPixels");
1805 return;
1806 }
1807 }
1808
1809 /* Invert src region if needed */
1810 if (_mesa_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1811 srcy = ctx->ReadBuffer->Height - srcy - height;
1812 invertTex = !invertTex;
1813 }
1814
1815 /* Clip the read region against the src buffer bounds.
1816 * We'll still allocate a temporary buffer/texture for the original
1817 * src region size but we'll only read the region which is on-screen.
1818 * This may mean that we draw garbage pixels into the dest region, but
1819 * that's expected.
1820 */
1821 readX = srcx;
1822 readY = srcy;
1823 readW = width;
1824 readH = height;
1825 if (!_mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack)) {
1826 /* The source region is completely out of bounds. Do nothing.
1827 * The GL spec says "Results of copies from outside the window,
1828 * or from regions of the window that are not exposed, are
1829 * hardware dependent and undefined."
1830 */
1831 return;
1832 }
1833
1834 readW = MAX2(0, readW);
1835 readH = MAX2(0, readH);
1836
1837 /* Allocate the temporary texture. */
1838 pt = alloc_texture(st, width, height, srcFormat, srcBind);
1839 if (!pt)
1840 return;
1841
1842 sv[0] = st_create_texture_sampler_view(st->pipe, pt);
1843 if (!sv[0]) {
1844 pipe_resource_reference(&pt, NULL);
1845 return;
1846 }
1847
1848 /* Create a second sampler view to read stencil */
1849 if (type == GL_STENCIL || type == GL_DEPTH_STENCIL ||
1850 type == GL_DEPTH_STENCIL_TO_RGBA_NV || type == GL_DEPTH_STENCIL_TO_BGRA_NV) {
1851 write_stencil = GL_TRUE;
1852 if (type == GL_DEPTH_STENCIL)
1853 write_depth = GL_TRUE;
1854 if (type == GL_DEPTH_STENCIL_TO_RGBA_NV || type == GL_DEPTH_STENCIL_TO_BGRA_NV) {
1855 write_depth = false;
1856 write_stencil = false;
1857 }
1858
1859 enum pipe_format stencil_format =
1860 util_format_stencil_only(pt->format);
1861 /* we should not be doing pixel map/transfer (see above) */
1862 assert(num_sampler_view == 1);
1863 sv[1] = st_create_texture_sampler_view_format(st->pipe, pt,
1864 stencil_format);
1865 if (!sv[1]) {
1866 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
1867 pipe_resource_reference(&pt, NULL);
1868 pipe_sampler_view_reference(&sv[0], NULL);
1869 return;
1870 }
1871 num_sampler_view++;
1872 }
1873 /* Copy the src region to the temporary texture. */
1874 {
1875 struct pipe_blit_info blit;
1876
1877 memset(&blit, 0, sizeof(blit));
1878 blit.src.resource = rbRead->texture;
1879 blit.src.level = rbRead->surface->u.tex.level;
1880 blit.src.format = rbRead->texture->format;
1881 blit.src.box.x = readX;
1882 blit.src.box.y = readY;
1883 blit.src.box.z = rbRead->surface->u.tex.first_layer;
1884 blit.src.box.width = readW;
1885 blit.src.box.height = readH;
1886 blit.src.box.depth = 1;
1887 blit.dst.resource = pt;
1888 blit.dst.level = 0;
1889 blit.dst.format = pt->format;
1890 blit.dst.box.x = pack.SkipPixels;
1891 blit.dst.box.y = pack.SkipRows;
1892 blit.dst.box.z = 0;
1893 blit.dst.box.width = readW;
1894 blit.dst.box.height = readH;
1895 blit.dst.box.depth = 1;
1896 if (type == GL_DEPTH)
1897 blit.mask = util_format_get_mask(pt->format) & ~PIPE_MASK_S;
1898 else if (type == GL_STENCIL)
1899 blit.mask = util_format_get_mask(pt->format) & ~PIPE_MASK_Z;
1900 else
1901 blit.mask = util_format_get_mask(pt->format);
1902 blit.filter = PIPE_TEX_FILTER_NEAREST;
1903
1904 pipe->blit(pipe, &blit);
1905 }
1906
1907 /* OK, the texture 'pt' contains the src image/pixels. Now draw a
1908 * textured quad with that texture.
1909 */
1910
1911 draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
1912 width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
1913 sv,
1914 num_sampler_view,
1915 st->passthrough_vs,
1916 driver_fp, fpv,
1917 ctx->Current.Attrib[VERT_ATTRIB_COLOR0],
1918 invertTex, write_depth, write_stencil);
1919
1920 pipe_resource_reference(&pt, NULL);
1921 }
1922
1923 void
st_destroy_drawpix(struct st_context * st)1924 st_destroy_drawpix(struct st_context *st)
1925 {
1926 GLuint i;
1927
1928 for (i = 0; i < ARRAY_SIZE(st->drawpix.zs_shaders); i++) {
1929 if (st->drawpix.zs_shaders[i])
1930 st->pipe->delete_fs_state(st->pipe, st->drawpix.zs_shaders[i]);
1931 }
1932
1933 if (st->passthrough_vs)
1934 st->pipe->delete_vs_state(st->pipe, st->passthrough_vs);
1935
1936 /* Free cache data */
1937 for (i = 0; i < ARRAY_SIZE(st->drawpix_cache.entries); i++) {
1938 struct drawpix_cache_entry *entry = &st->drawpix_cache.entries[i];
1939 free(entry->image);
1940 pipe_resource_reference(&entry->texture, NULL);
1941 }
1942 }
1943