192ab0639082e893a140c7127e21b7bcf0fe945f
[mesa.git] / src / mesa / state_tracker / st_cb_drawpixels.c
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/imports.h"
34 #include "main/image.h"
35 #include "main/bufferobj.h"
36 #include "main/blit.h"
37 #include "main/format_pack.h"
38 #include "main/macros.h"
39 #include "main/mtypes.h"
40 #include "main/pack.h"
41 #include "main/pbo.h"
42 #include "main/readpix.h"
43 #include "main/texformat.h"
44 #include "main/teximage.h"
45 #include "main/texstore.h"
46 #include "main/glformats.h"
47 #include "program/program.h"
48 #include "program/prog_print.h"
49 #include "program/prog_instruction.h"
50
51 #include "st_atom.h"
52 #include "st_atom_constbuf.h"
53 #include "st_cb_bitmap.h"
54 #include "st_cb_drawpixels.h"
55 #include "st_cb_readpixels.h"
56 #include "st_cb_fbo.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_texture.h"
63
64 #include "pipe/p_context.h"
65 #include "pipe/p_defines.h"
66 #include "tgsi/tgsi_ureg.h"
67 #include "util/u_format.h"
68 #include "util/u_inlines.h"
69 #include "util/u_math.h"
70 #include "util/u_tile.h"
71 #include "cso_cache/cso_context.h"
72
73
74 /**
75 * Create fragment program that does a TEX() instruction to get a Z and/or
76 * stencil value value, then writes to FRAG_RESULT_DEPTH/FRAG_RESULT_STENCIL.
77 * Used for glDrawPixels(GL_DEPTH_COMPONENT / GL_STENCIL_INDEX).
78 * Pass fragment color through as-is.
79 *
80 * \return CSO of the fragment shader.
81 */
82 static void *
83 get_drawpix_z_stencil_program(struct st_context *st,
84 GLboolean write_depth,
85 GLboolean write_stencil)
86 {
87 struct ureg_program *ureg;
88 struct ureg_src depth_sampler, stencil_sampler;
89 struct ureg_src texcoord, color;
90 struct ureg_dst out_color, out_depth, out_stencil;
91 const GLuint shaderIndex = write_depth * 2 + write_stencil;
92 void *cso;
93
94 assert(shaderIndex < ARRAY_SIZE(st->drawpix.zs_shaders));
95
96 if (st->drawpix.zs_shaders[shaderIndex]) {
97 /* already have the proper shader */
98 return st->drawpix.zs_shaders[shaderIndex];
99 }
100
101 ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
102 if (ureg == NULL)
103 return NULL;
104
105 ureg_property(ureg, TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS, TRUE);
106
107 if (write_depth) {
108 color = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_COLOR, 0,
109 TGSI_INTERPOLATE_COLOR);
110 out_color = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
111
112 depth_sampler = ureg_DECL_sampler(ureg, 0);
113 out_depth = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
114 }
115
116 if (write_stencil) {
117 stencil_sampler = ureg_DECL_sampler(ureg, 1);
118 out_stencil = ureg_DECL_output(ureg, TGSI_SEMANTIC_STENCIL, 0);
119 }
120
121 texcoord = ureg_DECL_fs_input(ureg,
122 st->needs_texcoord_semantic ?
123 TGSI_SEMANTIC_TEXCOORD :
124 TGSI_SEMANTIC_GENERIC,
125 0, TGSI_INTERPOLATE_LINEAR);
126
127 if (write_depth) {
128 ureg_TEX(ureg, ureg_writemask(out_depth, TGSI_WRITEMASK_Z),
129 TGSI_TEXTURE_2D, texcoord, depth_sampler);
130 ureg_MOV(ureg, out_color, color);
131 }
132
133 if (write_stencil)
134 ureg_TEX(ureg, ureg_writemask(out_stencil, TGSI_WRITEMASK_Y),
135 TGSI_TEXTURE_2D, texcoord, stencil_sampler);
136
137 ureg_END(ureg);
138 cso = ureg_create_shader_and_destroy(ureg, st->pipe);
139
140 /* save the new shader */
141 st->drawpix.zs_shaders[shaderIndex] = cso;
142 return cso;
143 }
144
145
146 /**
147 * Create a simple vertex shader that just passes through the
148 * vertex position and texcoord (and optionally, color).
149 */
150 static void *
151 make_passthrough_vertex_shader(struct st_context *st,
152 GLboolean passColor)
153 {
154 const unsigned texcoord_semantic = st->needs_texcoord_semantic ?
155 TGSI_SEMANTIC_TEXCOORD : TGSI_SEMANTIC_GENERIC;
156
157 if (!st->drawpix.vert_shaders[passColor]) {
158 struct ureg_program *ureg = ureg_create( TGSI_PROCESSOR_VERTEX );
159
160 if (ureg == NULL)
161 return NULL;
162
163 /* MOV result.pos, vertex.pos; */
164 ureg_MOV(ureg,
165 ureg_DECL_output( ureg, TGSI_SEMANTIC_POSITION, 0 ),
166 ureg_DECL_vs_input( ureg, 0 ));
167
168 if (passColor) {
169 /* MOV result.color0, vertex.attr[1]; */
170 ureg_MOV(ureg,
171 ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 ),
172 ureg_DECL_vs_input( ureg, 1 ));
173 }
174
175 /* MOV result.texcoord0, vertex.attr[2]; */
176 ureg_MOV(ureg,
177 ureg_DECL_output( ureg, texcoord_semantic, 0 ),
178 ureg_DECL_vs_input( ureg, 2 ));
179
180 ureg_END( ureg );
181
182 st->drawpix.vert_shaders[passColor] =
183 ureg_create_shader_and_destroy( ureg, st->pipe );
184 }
185
186 return st->drawpix.vert_shaders[passColor];
187 }
188
189
190 /**
191 * Return a texture internalFormat for drawing/copying an image
192 * of the given format and type.
193 */
194 static GLenum
195 internal_format(struct gl_context *ctx, GLenum format, GLenum type)
196 {
197 switch (format) {
198 case GL_DEPTH_COMPONENT:
199 switch (type) {
200 case GL_UNSIGNED_SHORT:
201 return GL_DEPTH_COMPONENT16;
202
203 case GL_UNSIGNED_INT:
204 return GL_DEPTH_COMPONENT32;
205
206 case GL_FLOAT:
207 if (ctx->Extensions.ARB_depth_buffer_float)
208 return GL_DEPTH_COMPONENT32F;
209 else
210 return GL_DEPTH_COMPONENT;
211
212 default:
213 return GL_DEPTH_COMPONENT;
214 }
215
216 case GL_DEPTH_STENCIL:
217 switch (type) {
218 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
219 return GL_DEPTH32F_STENCIL8;
220
221 case GL_UNSIGNED_INT_24_8:
222 default:
223 return GL_DEPTH24_STENCIL8;
224 }
225
226 case GL_STENCIL_INDEX:
227 return GL_STENCIL_INDEX;
228
229 default:
230 if (_mesa_is_enum_format_integer(format)) {
231 switch (type) {
232 case GL_BYTE:
233 return GL_RGBA8I;
234 case GL_UNSIGNED_BYTE:
235 return GL_RGBA8UI;
236 case GL_SHORT:
237 return GL_RGBA16I;
238 case GL_UNSIGNED_SHORT:
239 return GL_RGBA16UI;
240 case GL_INT:
241 return GL_RGBA32I;
242 case GL_UNSIGNED_INT:
243 return GL_RGBA32UI;
244 default:
245 assert(0 && "Unexpected type in internal_format()");
246 return GL_RGBA_INTEGER;
247 }
248 }
249 else {
250 switch (type) {
251 case GL_UNSIGNED_BYTE:
252 case GL_UNSIGNED_INT_8_8_8_8:
253 case GL_UNSIGNED_INT_8_8_8_8_REV:
254 default:
255 return GL_RGBA8;
256
257 case GL_UNSIGNED_BYTE_3_3_2:
258 case GL_UNSIGNED_BYTE_2_3_3_REV:
259 return GL_R3_G3_B2;
260
261 case GL_UNSIGNED_SHORT_4_4_4_4:
262 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
263 return GL_RGBA4;
264
265 case GL_UNSIGNED_SHORT_5_6_5:
266 case GL_UNSIGNED_SHORT_5_6_5_REV:
267 return GL_RGB565;
268
269 case GL_UNSIGNED_SHORT_5_5_5_1:
270 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
271 return GL_RGB5_A1;
272
273 case GL_UNSIGNED_INT_10_10_10_2:
274 case GL_UNSIGNED_INT_2_10_10_10_REV:
275 return GL_RGB10_A2;
276
277 case GL_UNSIGNED_SHORT:
278 case GL_UNSIGNED_INT:
279 return GL_RGBA16;
280
281 case GL_BYTE:
282 return
283 ctx->Extensions.EXT_texture_snorm ? GL_RGBA8_SNORM : GL_RGBA8;
284
285 case GL_SHORT:
286 case GL_INT:
287 return
288 ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16;
289
290 case GL_HALF_FLOAT_ARB:
291 return
292 ctx->Extensions.ARB_texture_float ? GL_RGBA16F :
293 ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16;
294
295 case GL_FLOAT:
296 case GL_DOUBLE:
297 return
298 ctx->Extensions.ARB_texture_float ? GL_RGBA32F :
299 ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16;
300
301 case GL_UNSIGNED_INT_5_9_9_9_REV:
302 assert(ctx->Extensions.EXT_texture_shared_exponent);
303 return GL_RGB9_E5;
304
305 case GL_UNSIGNED_INT_10F_11F_11F_REV:
306 assert(ctx->Extensions.EXT_packed_float);
307 return GL_R11F_G11F_B10F;
308 }
309 }
310 }
311 }
312
313
314 /**
315 * Create a temporary texture to hold an image of the given size.
316 * If width, height are not POT and the driver only handles POT textures,
317 * allocate the next larger size of texture that is POT.
318 */
319 static struct pipe_resource *
320 alloc_texture(struct st_context *st, GLsizei width, GLsizei height,
321 enum pipe_format texFormat, unsigned bind)
322 {
323 struct pipe_resource *pt;
324
325 pt = st_texture_create(st, st->internal_target, texFormat, 0,
326 width, height, 1, 1, 0, bind);
327
328 return pt;
329 }
330
331
332 /**
333 * Make texture containing an image for glDrawPixels image.
334 * If 'pixels' is NULL, leave the texture image data undefined.
335 */
336 static struct pipe_resource *
337 make_texture(struct st_context *st,
338 GLsizei width, GLsizei height, GLenum format, GLenum type,
339 const struct gl_pixelstore_attrib *unpack,
340 const GLvoid *pixels)
341 {
342 struct gl_context *ctx = st->ctx;
343 struct pipe_context *pipe = st->pipe;
344 mesa_format mformat;
345 struct pipe_resource *pt;
346 enum pipe_format pipeFormat;
347 GLenum baseInternalFormat;
348
349 /* Choose a pixel format for the temp texture which will hold the
350 * image to draw.
351 */
352 pipeFormat = st_choose_matching_format(st, PIPE_BIND_SAMPLER_VIEW,
353 format, type, unpack->SwapBytes);
354
355 if (pipeFormat == PIPE_FORMAT_NONE) {
356 /* Use the generic approach. */
357 GLenum intFormat = internal_format(ctx, format, type);
358
359 pipeFormat = st_choose_format(st, intFormat, format, type,
360 st->internal_target, 0,
361 PIPE_BIND_SAMPLER_VIEW, FALSE);
362 assert(pipeFormat != PIPE_FORMAT_NONE);
363 }
364
365 mformat = st_pipe_format_to_mesa_format(pipeFormat);
366 baseInternalFormat = _mesa_get_format_base_format(mformat);
367
368 pixels = _mesa_map_pbo_source(ctx, unpack, pixels);
369 if (!pixels)
370 return NULL;
371
372 /* alloc temporary texture */
373 pt = alloc_texture(st, width, height, pipeFormat, PIPE_BIND_SAMPLER_VIEW);
374 if (!pt) {
375 _mesa_unmap_pbo_source(ctx, unpack);
376 return NULL;
377 }
378
379 {
380 struct pipe_transfer *transfer;
381 GLboolean success;
382 GLubyte *dest;
383 const GLbitfield imageTransferStateSave = ctx->_ImageTransferState;
384
385 /* we'll do pixel transfer in a fragment shader */
386 ctx->_ImageTransferState = 0x0;
387
388 /* map texture transfer */
389 dest = pipe_transfer_map(pipe, pt, 0, 0,
390 PIPE_TRANSFER_WRITE, 0, 0,
391 width, height, &transfer);
392
393
394 /* Put image into texture transfer.
395 * Note that the image is actually going to be upside down in
396 * the texture. We deal with that with texcoords.
397 */
398 if ((format == GL_RGBA || format == GL_BGRA)
399 && type == GL_UNSIGNED_BYTE) {
400 /* Use a memcpy-based texstore to avoid software pixel swizzling.
401 * We'll do the necessary swizzling with the pipe_sampler_view to
402 * give much better performance.
403 * XXX in the future, expand this to accomodate more format and
404 * type combinations.
405 */
406 _mesa_memcpy_texture(ctx, 2,
407 mformat, /* mesa_format */
408 transfer->stride, /* dstRowStride, bytes */
409 &dest, /* destSlices */
410 width, height, 1, /* size */
411 format, type, /* src format/type */
412 pixels, /* data source */
413 unpack);
414 success = GL_TRUE;
415 }
416 else {
417 success = _mesa_texstore(ctx, 2, /* dims */
418 baseInternalFormat, /* baseInternalFormat */
419 mformat, /* mesa_format */
420 transfer->stride, /* dstRowStride, bytes */
421 &dest, /* destSlices */
422 width, height, 1, /* size */
423 format, type, /* src format/type */
424 pixels, /* data source */
425 unpack);
426 }
427
428 /* unmap */
429 pipe_transfer_unmap(pipe, transfer);
430
431 assert(success);
432
433 /* restore */
434 ctx->_ImageTransferState = imageTransferStateSave;
435 }
436
437 _mesa_unmap_pbo_source(ctx, unpack);
438
439 return pt;
440 }
441
442
443 static void
444 draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
445 GLsizei width, GLsizei height,
446 GLfloat zoomX, GLfloat zoomY,
447 struct pipe_sampler_view **sv,
448 int num_sampler_view,
449 void *driver_vp,
450 void *driver_fp,
451 struct st_fp_variant *fpv,
452 const GLfloat *color,
453 GLboolean invertTex,
454 GLboolean write_depth, GLboolean write_stencil)
455 {
456 struct st_context *st = st_context(ctx);
457 struct pipe_context *pipe = st->pipe;
458 struct cso_context *cso = st->cso_context;
459 GLfloat x0, y0, x1, y1;
460 GLsizei maxSize;
461 boolean normalized = sv[0]->texture->target == PIPE_TEXTURE_2D;
462
463 assert(sv[0]->texture->target == st->internal_target);
464
465 /* limit checks */
466 /* XXX if DrawPixels image is larger than max texture size, break
467 * it up into chunks.
468 */
469 maxSize = 1 << (pipe->screen->get_param(pipe->screen,
470 PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
471 assert(width <= maxSize);
472 assert(height <= maxSize);
473
474 cso_save_rasterizer(cso);
475 cso_save_viewport(cso);
476 cso_save_fragment_samplers(cso);
477 cso_save_fragment_sampler_views(cso);
478 cso_save_fragment_shader(cso);
479 cso_save_stream_outputs(cso);
480 cso_save_vertex_shader(cso);
481 cso_save_tessctrl_shader(cso);
482 cso_save_tesseval_shader(cso);
483 cso_save_geometry_shader(cso);
484 cso_save_vertex_elements(cso);
485 cso_save_aux_vertex_buffer_slot(cso);
486 if (write_stencil) {
487 cso_save_depth_stencil_alpha(cso);
488 cso_save_blend(cso);
489 }
490
491 /* rasterizer state: just scissor */
492 {
493 struct pipe_rasterizer_state rasterizer;
494 memset(&rasterizer, 0, sizeof(rasterizer));
495 rasterizer.clamp_fragment_color = !st->clamp_frag_color_in_shader &&
496 ctx->Color._ClampFragmentColor;
497 rasterizer.half_pixel_center = 1;
498 rasterizer.bottom_edge_rule = 1;
499 rasterizer.depth_clip = !ctx->Transform.DepthClamp;
500 rasterizer.scissor = ctx->Scissor.EnableFlags;
501 cso_set_rasterizer(cso, &rasterizer);
502 }
503
504 if (write_stencil) {
505 /* Stencil writing bypasses the normal fragment pipeline to
506 * disable color writing and set stencil test to always pass.
507 */
508 struct pipe_depth_stencil_alpha_state dsa;
509 struct pipe_blend_state blend;
510
511 /* depth/stencil */
512 memset(&dsa, 0, sizeof(dsa));
513 dsa.stencil[0].enabled = 1;
514 dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
515 dsa.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
516 dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
517 if (write_depth) {
518 /* writing depth+stencil: depth test always passes */
519 dsa.depth.enabled = 1;
520 dsa.depth.writemask = ctx->Depth.Mask;
521 dsa.depth.func = PIPE_FUNC_ALWAYS;
522 }
523 cso_set_depth_stencil_alpha(cso, &dsa);
524
525 /* blend (colormask) */
526 memset(&blend, 0, sizeof(blend));
527 cso_set_blend(cso, &blend);
528 }
529
530 /* fragment shader state: TEX lookup program */
531 cso_set_fragment_shader_handle(cso, driver_fp);
532
533 /* vertex shader state: position + texcoord pass-through */
534 cso_set_vertex_shader_handle(cso, driver_vp);
535
536 /* disable other shaders */
537 cso_set_tessctrl_shader_handle(cso, NULL);
538 cso_set_tesseval_shader_handle(cso, NULL);
539 cso_set_geometry_shader_handle(cso, NULL);
540
541 /* user samplers, plus the drawpix samplers */
542 {
543 struct pipe_sampler_state sampler;
544
545 memset(&sampler, 0, sizeof(sampler));
546 sampler.wrap_s = PIPE_TEX_WRAP_CLAMP;
547 sampler.wrap_t = PIPE_TEX_WRAP_CLAMP;
548 sampler.wrap_r = PIPE_TEX_WRAP_CLAMP;
549 sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
550 sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
551 sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
552 sampler.normalized_coords = normalized;
553
554 if (fpv) {
555 /* drawing a color image */
556 const struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
557 uint num = MAX3(fpv->drawpix_sampler + 1,
558 fpv->pixelmap_sampler + 1,
559 st->state.num_samplers[PIPE_SHADER_FRAGMENT]);
560 uint i;
561
562 for (i = 0; i < st->state.num_samplers[PIPE_SHADER_FRAGMENT]; i++)
563 samplers[i] = &st->state.samplers[PIPE_SHADER_FRAGMENT][i];
564
565 samplers[fpv->drawpix_sampler] = &sampler;
566 if (sv[1])
567 samplers[fpv->pixelmap_sampler] = &sampler;
568
569 cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, num, samplers);
570 } else {
571 /* drawing a depth/stencil image */
572 const struct pipe_sampler_state *samplers[2] = {&sampler, &sampler};
573
574 cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, num_sampler_view, samplers);
575 }
576 }
577
578 /* user textures, plus the drawpix textures */
579 if (fpv) {
580 /* drawing a color image */
581 struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
582 uint num = MAX3(fpv->drawpix_sampler + 1,
583 fpv->pixelmap_sampler + 1,
584 st->state.num_sampler_views[PIPE_SHADER_FRAGMENT]);
585
586 memcpy(sampler_views, st->state.sampler_views[PIPE_SHADER_FRAGMENT],
587 sizeof(sampler_views));
588
589 sampler_views[fpv->drawpix_sampler] = sv[0];
590 if (sv[1])
591 sampler_views[fpv->pixelmap_sampler] = sv[1];
592 cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, num, sampler_views);
593 } else {
594 /* drawing a depth/stencil image */
595 cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, num_sampler_view, sv);
596 }
597
598 /* viewport state: viewport matching window dims */
599 {
600 const float w = (float) ctx->DrawBuffer->Width;
601 const float h = (float) ctx->DrawBuffer->Height;
602 struct pipe_viewport_state vp;
603 vp.scale[0] = 0.5f * w;
604 vp.scale[1] = -0.5f * h;
605 vp.scale[2] = 0.5f;
606 vp.translate[0] = 0.5f * w;
607 vp.translate[1] = 0.5f * h;
608 vp.translate[2] = 0.5f;
609 cso_set_viewport(cso, &vp);
610 }
611
612 cso_set_vertex_elements(cso, 3, st->util_velems);
613 cso_set_stream_outputs(cso, 0, NULL, NULL);
614
615 /* Compute Gallium window coords (y=0=top) with pixel zoom.
616 * Recall that these coords are transformed by the current
617 * vertex shader and viewport transformation.
618 */
619 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM) {
620 y = ctx->DrawBuffer->Height - (int) (y + height * ctx->Pixel.ZoomY);
621 invertTex = !invertTex;
622 }
623
624 x0 = (GLfloat) x;
625 x1 = x + width * ctx->Pixel.ZoomX;
626 y0 = (GLfloat) y;
627 y1 = y + height * ctx->Pixel.ZoomY;
628
629 /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
630 z = z * 2.0f - 1.0f;
631
632 {
633 const struct gl_framebuffer *fb = ctx->DrawBuffer;
634 const float fb_width = (float) fb->Width;
635 const float fb_height = (float) fb->Height;
636 const float clip_x0 = x0 / fb_width * 2.0f - 1.0f;
637 const float clip_y0 = y0 / fb_height * 2.0f - 1.0f;
638 const float clip_x1 = x1 / fb_width * 2.0f - 1.0f;
639 const float clip_y1 = y1 / fb_height * 2.0f - 1.0f;
640 const float maxXcoord = normalized ?
641 ((float) width / sv[0]->texture->width0) : (float) width;
642 const float maxYcoord = normalized
643 ? ((float) height / sv[0]->texture->height0) : (float) height;
644 const float sLeft = 0.0f, sRight = maxXcoord;
645 const float tTop = invertTex ? maxYcoord : 0.0f;
646 const float tBot = invertTex ? 0.0f : maxYcoord;
647
648 if (!st_draw_quad(ctx->st, clip_x0, clip_y0, clip_x1, clip_y1, z,
649 sLeft, tBot, sRight, tTop, color, 0)) {
650 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
651 }
652 }
653
654 /* restore state */
655 cso_restore_rasterizer(cso);
656 cso_restore_viewport(cso);
657 cso_restore_fragment_samplers(cso);
658 cso_restore_fragment_sampler_views(cso);
659 cso_restore_fragment_shader(cso);
660 cso_restore_vertex_shader(cso);
661 cso_restore_tessctrl_shader(cso);
662 cso_restore_tesseval_shader(cso);
663 cso_restore_geometry_shader(cso);
664 cso_restore_vertex_elements(cso);
665 cso_restore_aux_vertex_buffer_slot(cso);
666 cso_restore_stream_outputs(cso);
667 if (write_stencil) {
668 cso_restore_depth_stencil_alpha(cso);
669 cso_restore_blend(cso);
670 }
671 }
672
673
674 /**
675 * Software fallback to do glDrawPixels(GL_STENCIL_INDEX) when we
676 * can't use a fragment shader to write stencil values.
677 */
678 static void
679 draw_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
680 GLsizei width, GLsizei height, GLenum format, GLenum type,
681 const struct gl_pixelstore_attrib *unpack,
682 const GLvoid *pixels)
683 {
684 struct st_context *st = st_context(ctx);
685 struct pipe_context *pipe = st->pipe;
686 struct st_renderbuffer *strb;
687 enum pipe_transfer_usage usage;
688 struct pipe_transfer *pt;
689 const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
690 ubyte *stmap;
691 struct gl_pixelstore_attrib clippedUnpack = *unpack;
692 GLubyte *sValues;
693 GLuint *zValues;
694
695 if (!zoom) {
696 if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height,
697 &clippedUnpack)) {
698 /* totally clipped */
699 return;
700 }
701 }
702
703 strb = st_renderbuffer(ctx->DrawBuffer->
704 Attachment[BUFFER_STENCIL].Renderbuffer);
705
706 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
707 y = ctx->DrawBuffer->Height - y - height;
708 }
709
710 if (format == GL_STENCIL_INDEX &&
711 _mesa_is_format_packed_depth_stencil(strb->Base.Format)) {
712 /* writing stencil to a combined depth+stencil buffer */
713 usage = PIPE_TRANSFER_READ_WRITE;
714 }
715 else {
716 usage = PIPE_TRANSFER_WRITE;
717 }
718
719 stmap = pipe_transfer_map(pipe, strb->texture,
720 strb->surface->u.tex.level,
721 strb->surface->u.tex.first_layer,
722 usage, x, y,
723 width, height, &pt);
724
725 pixels = _mesa_map_pbo_source(ctx, &clippedUnpack, pixels);
726 assert(pixels);
727
728 sValues = malloc(width * sizeof(GLubyte));
729 zValues = malloc(width * sizeof(GLuint));
730
731 if (sValues && zValues) {
732 GLint row;
733 for (row = 0; row < height; row++) {
734 GLfloat *zValuesFloat = (GLfloat*)zValues;
735 GLenum destType = GL_UNSIGNED_BYTE;
736 const GLvoid *source = _mesa_image_address2d(&clippedUnpack, pixels,
737 width, height,
738 format, type,
739 row, 0);
740 _mesa_unpack_stencil_span(ctx, width, destType, sValues,
741 type, source, &clippedUnpack,
742 ctx->_ImageTransferState);
743
744 if (format == GL_DEPTH_STENCIL) {
745 GLenum ztype =
746 pt->resource->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ?
747 GL_FLOAT : GL_UNSIGNED_INT;
748
749 _mesa_unpack_depth_span(ctx, width, ztype, zValues,
750 (1 << 24) - 1, type, source,
751 &clippedUnpack);
752 }
753
754 if (zoom) {
755 _mesa_problem(ctx, "Gallium glDrawPixels(GL_STENCIL) with "
756 "zoom not complete");
757 }
758
759 {
760 GLint spanY;
761
762 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
763 spanY = height - row - 1;
764 }
765 else {
766 spanY = row;
767 }
768
769 /* now pack the stencil (and Z) values in the dest format */
770 switch (pt->resource->format) {
771 case PIPE_FORMAT_S8_UINT:
772 {
773 ubyte *dest = stmap + spanY * pt->stride;
774 assert(usage == PIPE_TRANSFER_WRITE);
775 memcpy(dest, sValues, width);
776 }
777 break;
778 case PIPE_FORMAT_Z24_UNORM_S8_UINT:
779 if (format == GL_DEPTH_STENCIL) {
780 uint *dest = (uint *) (stmap + spanY * pt->stride);
781 GLint k;
782 assert(usage == PIPE_TRANSFER_WRITE);
783 for (k = 0; k < width; k++) {
784 dest[k] = zValues[k] | (sValues[k] << 24);
785 }
786 }
787 else {
788 uint *dest = (uint *) (stmap + spanY * pt->stride);
789 GLint k;
790 assert(usage == PIPE_TRANSFER_READ_WRITE);
791 for (k = 0; k < width; k++) {
792 dest[k] = (dest[k] & 0xffffff) | (sValues[k] << 24);
793 }
794 }
795 break;
796 case PIPE_FORMAT_S8_UINT_Z24_UNORM:
797 if (format == GL_DEPTH_STENCIL) {
798 uint *dest = (uint *) (stmap + spanY * pt->stride);
799 GLint k;
800 assert(usage == PIPE_TRANSFER_WRITE);
801 for (k = 0; k < width; k++) {
802 dest[k] = (zValues[k] << 8) | (sValues[k] & 0xff);
803 }
804 }
805 else {
806 uint *dest = (uint *) (stmap + spanY * pt->stride);
807 GLint k;
808 assert(usage == PIPE_TRANSFER_READ_WRITE);
809 for (k = 0; k < width; k++) {
810 dest[k] = (dest[k] & 0xffffff00) | (sValues[k] & 0xff);
811 }
812 }
813 break;
814 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
815 if (format == GL_DEPTH_STENCIL) {
816 uint *dest = (uint *) (stmap + spanY * pt->stride);
817 GLfloat *destf = (GLfloat*)dest;
818 GLint k;
819 assert(usage == PIPE_TRANSFER_WRITE);
820 for (k = 0; k < width; k++) {
821 destf[k*2] = zValuesFloat[k];
822 dest[k*2+1] = sValues[k] & 0xff;
823 }
824 }
825 else {
826 uint *dest = (uint *) (stmap + spanY * pt->stride);
827 GLint k;
828 assert(usage == PIPE_TRANSFER_READ_WRITE);
829 for (k = 0; k < width; k++) {
830 dest[k*2+1] = sValues[k] & 0xff;
831 }
832 }
833 break;
834 default:
835 assert(0);
836 }
837 }
838 }
839 }
840 else {
841 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels()");
842 }
843
844 free(sValues);
845 free(zValues);
846
847 _mesa_unmap_pbo_source(ctx, &clippedUnpack);
848
849 /* unmap the stencil buffer */
850 pipe_transfer_unmap(pipe, pt);
851 }
852
853
854 /**
855 * Get fragment program variant for a glDrawPixels or glCopyPixels
856 * command for RGBA data.
857 */
858 static struct st_fp_variant *
859 get_color_fp_variant(struct st_context *st)
860 {
861 struct gl_context *ctx = st->ctx;
862 struct st_fp_variant_key key;
863 struct st_fp_variant *fpv;
864
865 memset(&key, 0, sizeof(key));
866
867 key.st = st->has_shareable_shaders ? NULL : st;
868 key.drawpixels = 1;
869 key.scaleAndBias = (ctx->Pixel.RedBias != 0.0 ||
870 ctx->Pixel.RedScale != 1.0 ||
871 ctx->Pixel.GreenBias != 0.0 ||
872 ctx->Pixel.GreenScale != 1.0 ||
873 ctx->Pixel.BlueBias != 0.0 ||
874 ctx->Pixel.BlueScale != 1.0 ||
875 ctx->Pixel.AlphaBias != 0.0 ||
876 ctx->Pixel.AlphaScale != 1.0);
877 key.pixelMaps = ctx->Pixel.MapColorFlag;
878 key.clamp_color = st->clamp_frag_color_in_shader &&
879 st->ctx->Color._ClampFragmentColor;
880
881 fpv = st_get_fp_variant(st, st->fp, &key);
882
883 return fpv;
884 }
885
886
887 /**
888 * Clamp glDrawPixels width and height to the maximum texture size.
889 */
890 static void
891 clamp_size(struct pipe_context *pipe, GLsizei *width, GLsizei *height,
892 struct gl_pixelstore_attrib *unpack)
893 {
894 const int maxSize =
895 1 << (pipe->screen->get_param(pipe->screen,
896 PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
897
898 if (*width > maxSize) {
899 if (unpack->RowLength == 0)
900 unpack->RowLength = *width;
901 *width = maxSize;
902 }
903 if (*height > maxSize) {
904 *height = maxSize;
905 }
906 }
907
908
909 /**
910 * Search the array of 4 swizzle components for the named component and return
911 * its position.
912 */
913 static unsigned
914 search_swizzle(const unsigned char swizzle[4], unsigned component)
915 {
916 unsigned i;
917 for (i = 0; i < 4; i++) {
918 if (swizzle[i] == component)
919 return i;
920 }
921 assert(!"search_swizzle() failed");
922 return 0;
923 }
924
925
926 /**
927 * Set the sampler view's swizzle terms. This is used to handle RGBA
928 * swizzling when the incoming image format isn't an exact match for
929 * the actual texture format. For example, if we have glDrawPixels(
930 * GL_RGBA, GL_UNSIGNED_BYTE) and we chose the texture format
931 * PIPE_FORMAT_B8G8R8A8 then we can do use the sampler view swizzle to
932 * avoid swizzling all the pixels in software in the texstore code.
933 */
934 static void
935 setup_sampler_swizzle(struct pipe_sampler_view *sv, GLenum format, GLenum type)
936 {
937 if ((format == GL_RGBA || format == GL_BGRA) && type == GL_UNSIGNED_BYTE) {
938 const struct util_format_description *desc =
939 util_format_description(sv->texture->format);
940 unsigned c0, c1, c2, c3;
941
942 /* Every gallium driver supports at least one 32-bit packed RGBA format.
943 * We must have chosen one for (GL_RGBA, GL_UNSIGNED_BYTE).
944 */
945 assert(desc->block.bits == 32);
946
947 /* invert the format's swizzle to setup the sampler's swizzle */
948 if (format == GL_RGBA) {
949 c0 = UTIL_FORMAT_SWIZZLE_X;
950 c1 = UTIL_FORMAT_SWIZZLE_Y;
951 c2 = UTIL_FORMAT_SWIZZLE_Z;
952 c3 = UTIL_FORMAT_SWIZZLE_W;
953 }
954 else {
955 assert(format == GL_BGRA);
956 c0 = UTIL_FORMAT_SWIZZLE_Z;
957 c1 = UTIL_FORMAT_SWIZZLE_Y;
958 c2 = UTIL_FORMAT_SWIZZLE_X;
959 c3 = UTIL_FORMAT_SWIZZLE_W;
960 }
961 sv->swizzle_r = search_swizzle(desc->swizzle, c0);
962 sv->swizzle_g = search_swizzle(desc->swizzle, c1);
963 sv->swizzle_b = search_swizzle(desc->swizzle, c2);
964 sv->swizzle_a = search_swizzle(desc->swizzle, c3);
965 }
966 else {
967 /* use the default sampler swizzle */
968 }
969 }
970
971
972 /**
973 * Called via ctx->Driver.DrawPixels()
974 */
975 static void
976 st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
977 GLsizei width, GLsizei height,
978 GLenum format, GLenum type,
979 const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels)
980 {
981 void *driver_vp, *driver_fp;
982 struct st_context *st = st_context(ctx);
983 struct pipe_context *pipe = st->pipe;
984 GLboolean write_stencil = GL_FALSE, write_depth = GL_FALSE;
985 struct pipe_sampler_view *sv[2] = { NULL };
986 int num_sampler_view = 1;
987 struct gl_pixelstore_attrib clippedUnpack;
988 struct st_fp_variant *fpv = NULL;
989 struct pipe_resource *pt;
990
991 /* Mesa state should be up to date by now */
992 assert(ctx->NewState == 0x0);
993
994 st_flush_bitmap_cache(st);
995
996 st_validate_state(st, ST_PIPELINE_RENDER);
997
998 /* Limit the size of the glDrawPixels to the max texture size.
999 * Strictly speaking, that's not correct but since we don't handle
1000 * larger images yet, this is better than crashing.
1001 */
1002 clippedUnpack = *unpack;
1003 unpack = &clippedUnpack;
1004 clamp_size(st->pipe, &width, &height, &clippedUnpack);
1005
1006 if (format == GL_DEPTH_STENCIL)
1007 write_stencil = write_depth = GL_TRUE;
1008 else if (format == GL_STENCIL_INDEX)
1009 write_stencil = GL_TRUE;
1010 else if (format == GL_DEPTH_COMPONENT)
1011 write_depth = GL_TRUE;
1012
1013 if (write_stencil &&
1014 !pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT)) {
1015 /* software fallback */
1016 draw_stencil_pixels(ctx, x, y, width, height, format, type,
1017 unpack, pixels);
1018 return;
1019 }
1020
1021 /*
1022 * Get vertex/fragment shaders
1023 */
1024 if (write_depth || write_stencil) {
1025 driver_fp = get_drawpix_z_stencil_program(st, write_depth,
1026 write_stencil);
1027 driver_vp = make_passthrough_vertex_shader(st, GL_TRUE);
1028 }
1029 else {
1030 fpv = get_color_fp_variant(st);
1031
1032 driver_fp = fpv->driver_shader;
1033 driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
1034
1035 if (ctx->Pixel.MapColorFlag) {
1036 pipe_sampler_view_reference(&sv[1],
1037 st->pixel_xfer.pixelmap_sampler_view);
1038 num_sampler_view++;
1039 }
1040
1041 /* compiling a new fragment shader variant added new state constants
1042 * into the constant buffer, we need to update them
1043 */
1044 st_upload_constants(st, st->fp->Base.Base.Parameters,
1045 PIPE_SHADER_FRAGMENT);
1046 }
1047
1048 /* Put glDrawPixels image into a texture */
1049 pt = make_texture(st, width, height, format, type, unpack, pixels);
1050 if (!pt) {
1051 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
1052 return;
1053 }
1054
1055 /* create sampler view for the image */
1056 sv[0] = st_create_texture_sampler_view(st->pipe, pt);
1057 if (!sv[0]) {
1058 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
1059 pipe_resource_reference(&pt, NULL);
1060 return;
1061 }
1062
1063 /* Set up the sampler view's swizzle */
1064 setup_sampler_swizzle(sv[0], format, type);
1065
1066 /* Create a second sampler view to read stencil. The stencil is
1067 * written using the shader stencil export functionality.
1068 */
1069 if (write_stencil) {
1070 enum pipe_format stencil_format =
1071 util_format_stencil_only(pt->format);
1072 /* we should not be doing pixel map/transfer (see above) */
1073 assert(num_sampler_view == 1);
1074 sv[1] = st_create_texture_sampler_view_format(st->pipe, pt,
1075 stencil_format);
1076 if (!sv[1]) {
1077 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
1078 pipe_resource_reference(&pt, NULL);
1079 pipe_sampler_view_reference(&sv[0], NULL);
1080 return;
1081 }
1082 num_sampler_view++;
1083 }
1084
1085 draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
1086 width, height,
1087 ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
1088 sv,
1089 num_sampler_view,
1090 driver_vp,
1091 driver_fp, fpv,
1092 ctx->Current.RasterColor,
1093 GL_FALSE, write_depth, write_stencil);
1094 pipe_sampler_view_reference(&sv[0], NULL);
1095 if (num_sampler_view > 1)
1096 pipe_sampler_view_reference(&sv[1], NULL);
1097
1098 pipe_resource_reference(&pt, NULL);
1099 }
1100
1101
1102
1103 /**
1104 * Software fallback for glCopyPixels(GL_STENCIL).
1105 */
1106 static void
1107 copy_stencil_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
1108 GLsizei width, GLsizei height,
1109 GLint dstx, GLint dsty)
1110 {
1111 struct st_renderbuffer *rbDraw;
1112 struct pipe_context *pipe = st_context(ctx)->pipe;
1113 enum pipe_transfer_usage usage;
1114 struct pipe_transfer *ptDraw;
1115 ubyte *drawMap;
1116 ubyte *buffer;
1117 int i;
1118
1119 buffer = malloc(width * height * sizeof(ubyte));
1120 if (!buffer) {
1121 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels(stencil)");
1122 return;
1123 }
1124
1125 /* Get the dest renderbuffer */
1126 rbDraw = st_renderbuffer(ctx->DrawBuffer->
1127 Attachment[BUFFER_STENCIL].Renderbuffer);
1128
1129 /* this will do stencil pixel transfer ops */
1130 _mesa_readpixels(ctx, srcx, srcy, width, height,
1131 GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
1132 &ctx->DefaultPacking, buffer);
1133
1134 if (0) {
1135 /* debug code: dump stencil values */
1136 GLint row, col;
1137 for (row = 0; row < height; row++) {
1138 printf("%3d: ", row);
1139 for (col = 0; col < width; col++) {
1140 printf("%02x ", buffer[col + row * width]);
1141 }
1142 printf("\n");
1143 }
1144 }
1145
1146 if (_mesa_is_format_packed_depth_stencil(rbDraw->Base.Format))
1147 usage = PIPE_TRANSFER_READ_WRITE;
1148 else
1149 usage = PIPE_TRANSFER_WRITE;
1150
1151 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
1152 dsty = rbDraw->Base.Height - dsty - height;
1153 }
1154
1155 assert(util_format_get_blockwidth(rbDraw->texture->format) == 1);
1156 assert(util_format_get_blockheight(rbDraw->texture->format) == 1);
1157
1158 /* map the stencil buffer */
1159 drawMap = pipe_transfer_map(pipe,
1160 rbDraw->texture,
1161 rbDraw->surface->u.tex.level,
1162 rbDraw->surface->u.tex.first_layer,
1163 usage, dstx, dsty,
1164 width, height, &ptDraw);
1165
1166 /* draw */
1167 /* XXX PixelZoom not handled yet */
1168 for (i = 0; i < height; i++) {
1169 ubyte *dst;
1170 const ubyte *src;
1171 int y;
1172
1173 y = i;
1174
1175 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
1176 y = height - y - 1;
1177 }
1178
1179 dst = drawMap + y * ptDraw->stride;
1180 src = buffer + i * width;
1181
1182 _mesa_pack_ubyte_stencil_row(rbDraw->Base.Format, width, src, dst);
1183 }
1184
1185 free(buffer);
1186
1187 /* unmap the stencil buffer */
1188 pipe_transfer_unmap(pipe, ptDraw);
1189 }
1190
1191
1192 /**
1193 * Return renderbuffer to use for reading color pixels for glCopyPixels
1194 */
1195 static struct st_renderbuffer *
1196 st_get_color_read_renderbuffer(struct gl_context *ctx)
1197 {
1198 struct gl_framebuffer *fb = ctx->ReadBuffer;
1199 struct st_renderbuffer *strb =
1200 st_renderbuffer(fb->_ColorReadBuffer);
1201
1202 return strb;
1203 }
1204
1205
1206 /**
1207 * Try to do a glCopyPixels for simple cases with a blit by calling
1208 * pipe->blit().
1209 *
1210 * We can do this when we're copying color pixels (depth/stencil
1211 * eventually) with no pixel zoom, no pixel transfer ops, no
1212 * per-fragment ops, and the src/dest regions don't overlap.
1213 */
1214 static GLboolean
1215 blit_copy_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
1216 GLsizei width, GLsizei height,
1217 GLint dstx, GLint dsty, GLenum type)
1218 {
1219 struct st_context *st = st_context(ctx);
1220 struct pipe_context *pipe = st->pipe;
1221 struct pipe_screen *screen = pipe->screen;
1222 struct gl_pixelstore_attrib pack, unpack;
1223 GLint readX, readY, readW, readH, drawX, drawY, drawW, drawH;
1224
1225 if (type == GL_COLOR &&
1226 ctx->Pixel.ZoomX == 1.0 &&
1227 ctx->Pixel.ZoomY == 1.0 &&
1228 ctx->_ImageTransferState == 0x0 &&
1229 !ctx->Color.BlendEnabled &&
1230 !ctx->Color.AlphaEnabled &&
1231 (!ctx->Color.ColorLogicOpEnabled || ctx->Color.LogicOp == GL_COPY) &&
1232 !ctx->Depth.Test &&
1233 !ctx->Fog.Enabled &&
1234 !ctx->Stencil.Enabled &&
1235 !ctx->FragmentProgram.Enabled &&
1236 !ctx->VertexProgram.Enabled &&
1237 !ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT] &&
1238 ctx->DrawBuffer->_NumColorDrawBuffers == 1 &&
1239 !ctx->Query.CondRenderQuery &&
1240 !ctx->Query.CurrentOcclusionObject) {
1241 struct st_renderbuffer *rbRead, *rbDraw;
1242
1243 /*
1244 * Clip the read region against the src buffer bounds.
1245 * We'll still allocate a temporary buffer/texture for the original
1246 * src region size but we'll only read the region which is on-screen.
1247 * This may mean that we draw garbage pixels into the dest region, but
1248 * that's expected.
1249 */
1250 readX = srcx;
1251 readY = srcy;
1252 readW = width;
1253 readH = height;
1254 pack = ctx->DefaultPacking;
1255 if (!_mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack))
1256 return GL_TRUE; /* all done */
1257
1258 /* clip against dest buffer bounds and scissor box */
1259 drawX = dstx + pack.SkipPixels;
1260 drawY = dsty + pack.SkipRows;
1261 unpack = pack;
1262 if (!_mesa_clip_drawpixels(ctx, &drawX, &drawY, &readW, &readH, &unpack))
1263 return GL_TRUE; /* all done */
1264
1265 readX = readX - pack.SkipPixels + unpack.SkipPixels;
1266 readY = readY - pack.SkipRows + unpack.SkipRows;
1267
1268 drawW = readW;
1269 drawH = readH;
1270
1271 rbRead = st_get_color_read_renderbuffer(ctx);
1272 rbDraw = st_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
1273
1274 /* Flip src/dst position depending on the orientation of buffers. */
1275 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1276 readY = rbRead->Base.Height - readY;
1277 readH = -readH;
1278 }
1279
1280 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
1281 /* We can't flip the destination for pipe->blit, so we only adjust
1282 * its position and flip the source.
1283 */
1284 drawY = rbDraw->Base.Height - drawY - drawH;
1285 readY += readH;
1286 readH = -readH;
1287 }
1288
1289 if (rbRead != rbDraw ||
1290 !_mesa_regions_overlap(readX, readY, readX + readW, readY + readH,
1291 drawX, drawY, drawX + drawW, drawY + drawH)) {
1292 struct pipe_blit_info blit;
1293
1294 memset(&blit, 0, sizeof(blit));
1295 blit.src.resource = rbRead->texture;
1296 blit.src.level = rbRead->surface->u.tex.level;
1297 blit.src.format = rbRead->texture->format;
1298 blit.src.box.x = readX;
1299 blit.src.box.y = readY;
1300 blit.src.box.z = rbRead->surface->u.tex.first_layer;
1301 blit.src.box.width = readW;
1302 blit.src.box.height = readH;
1303 blit.src.box.depth = 1;
1304 blit.dst.resource = rbDraw->texture;
1305 blit.dst.level = rbDraw->surface->u.tex.level;
1306 blit.dst.format = rbDraw->texture->format;
1307 blit.dst.box.x = drawX;
1308 blit.dst.box.y = drawY;
1309 blit.dst.box.z = rbDraw->surface->u.tex.first_layer;
1310 blit.dst.box.width = drawW;
1311 blit.dst.box.height = drawH;
1312 blit.dst.box.depth = 1;
1313 blit.mask = PIPE_MASK_RGBA;
1314 blit.filter = PIPE_TEX_FILTER_NEAREST;
1315
1316 if (screen->is_format_supported(screen, blit.src.format,
1317 blit.src.resource->target,
1318 blit.src.resource->nr_samples,
1319 PIPE_BIND_SAMPLER_VIEW) &&
1320 screen->is_format_supported(screen, blit.dst.format,
1321 blit.dst.resource->target,
1322 blit.dst.resource->nr_samples,
1323 PIPE_BIND_RENDER_TARGET)) {
1324 pipe->blit(pipe, &blit);
1325 return GL_TRUE;
1326 }
1327 }
1328 }
1329
1330 return GL_FALSE;
1331 }
1332
1333
1334 static void
1335 st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
1336 GLsizei width, GLsizei height,
1337 GLint dstx, GLint dsty, GLenum type)
1338 {
1339 struct st_context *st = st_context(ctx);
1340 struct pipe_context *pipe = st->pipe;
1341 struct pipe_screen *screen = pipe->screen;
1342 struct st_renderbuffer *rbRead;
1343 void *driver_vp, *driver_fp;
1344 struct pipe_resource *pt;
1345 struct pipe_sampler_view *sv[2] = { NULL };
1346 struct st_fp_variant *fpv = NULL;
1347 int num_sampler_view = 1;
1348 enum pipe_format srcFormat;
1349 unsigned srcBind;
1350 GLboolean invertTex = GL_FALSE;
1351 GLint readX, readY, readW, readH;
1352 struct gl_pixelstore_attrib pack = ctx->DefaultPacking;
1353
1354 st_flush_bitmap_cache(st);
1355
1356 st_validate_state(st, ST_PIPELINE_RENDER);
1357
1358 if (type == GL_DEPTH_STENCIL) {
1359 /* XXX make this more efficient */
1360 st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_STENCIL);
1361 st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_DEPTH);
1362 return;
1363 }
1364
1365 if (type == GL_STENCIL) {
1366 /* can't use texturing to do stencil */
1367 copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty);
1368 return;
1369 }
1370
1371 if (blit_copy_pixels(ctx, srcx, srcy, width, height, dstx, dsty, type))
1372 return;
1373
1374 /*
1375 * The subsequent code implements glCopyPixels by copying the source
1376 * pixels into a temporary texture that's then applied to a textured quad.
1377 * When we draw the textured quad, all the usual per-fragment operations
1378 * are handled.
1379 */
1380
1381
1382 /*
1383 * Get vertex/fragment shaders
1384 */
1385 if (type == GL_COLOR) {
1386 fpv = get_color_fp_variant(st);
1387
1388 rbRead = st_get_color_read_renderbuffer(ctx);
1389
1390 driver_fp = fpv->driver_shader;
1391 driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
1392
1393 if (ctx->Pixel.MapColorFlag) {
1394 pipe_sampler_view_reference(&sv[1],
1395 st->pixel_xfer.pixelmap_sampler_view);
1396 num_sampler_view++;
1397 }
1398
1399 /* compiling a new fragment shader variant added new state constants
1400 * into the constant buffer, we need to update them
1401 */
1402 st_upload_constants(st, st->fp->Base.Base.Parameters,
1403 PIPE_SHADER_FRAGMENT);
1404 }
1405 else {
1406 assert(type == GL_DEPTH);
1407 rbRead = st_renderbuffer(ctx->ReadBuffer->
1408 Attachment[BUFFER_DEPTH].Renderbuffer);
1409
1410 driver_fp = get_drawpix_z_stencil_program(st, GL_TRUE, GL_FALSE);
1411 driver_vp = make_passthrough_vertex_shader(st, GL_TRUE);
1412 }
1413
1414 /* Choose the format for the temporary texture. */
1415 srcFormat = rbRead->texture->format;
1416 srcBind = PIPE_BIND_SAMPLER_VIEW |
1417 (type == GL_COLOR ? PIPE_BIND_RENDER_TARGET : PIPE_BIND_DEPTH_STENCIL);
1418
1419 if (!screen->is_format_supported(screen, srcFormat, st->internal_target, 0,
1420 srcBind)) {
1421 /* srcFormat is non-renderable. Find a compatible renderable format. */
1422 if (type == GL_DEPTH) {
1423 srcFormat = st_choose_format(st, GL_DEPTH_COMPONENT, GL_NONE,
1424 GL_NONE, st->internal_target, 0,
1425 srcBind, FALSE);
1426 }
1427 else {
1428 assert(type == GL_COLOR);
1429
1430 if (util_format_is_float(srcFormat)) {
1431 srcFormat = st_choose_format(st, GL_RGBA32F, GL_NONE,
1432 GL_NONE, st->internal_target, 0,
1433 srcBind, FALSE);
1434 }
1435 else if (util_format_is_pure_sint(srcFormat)) {
1436 srcFormat = st_choose_format(st, GL_RGBA32I, GL_NONE,
1437 GL_NONE, st->internal_target, 0,
1438 srcBind, FALSE);
1439 }
1440 else if (util_format_is_pure_uint(srcFormat)) {
1441 srcFormat = st_choose_format(st, GL_RGBA32UI, GL_NONE,
1442 GL_NONE, st->internal_target, 0,
1443 srcBind, FALSE);
1444 }
1445 else if (util_format_is_snorm(srcFormat)) {
1446 srcFormat = st_choose_format(st, GL_RGBA16_SNORM, GL_NONE,
1447 GL_NONE, st->internal_target, 0,
1448 srcBind, FALSE);
1449 }
1450 else {
1451 srcFormat = st_choose_format(st, GL_RGBA, GL_NONE,
1452 GL_NONE, st->internal_target, 0,
1453 srcBind, FALSE);
1454 }
1455 }
1456
1457 if (srcFormat == PIPE_FORMAT_NONE) {
1458 assert(0 && "cannot choose a format for src of CopyPixels");
1459 return;
1460 }
1461 }
1462
1463 /* Invert src region if needed */
1464 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1465 srcy = ctx->ReadBuffer->Height - srcy - height;
1466 invertTex = !invertTex;
1467 }
1468
1469 /* Clip the read region against the src buffer bounds.
1470 * We'll still allocate a temporary buffer/texture for the original
1471 * src region size but we'll only read the region which is on-screen.
1472 * This may mean that we draw garbage pixels into the dest region, but
1473 * that's expected.
1474 */
1475 readX = srcx;
1476 readY = srcy;
1477 readW = width;
1478 readH = height;
1479 if (!_mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack)) {
1480 /* The source region is completely out of bounds. Do nothing.
1481 * The GL spec says "Results of copies from outside the window,
1482 * or from regions of the window that are not exposed, are
1483 * hardware dependent and undefined."
1484 */
1485 return;
1486 }
1487
1488 readW = MAX2(0, readW);
1489 readH = MAX2(0, readH);
1490
1491 /* Allocate the temporary texture. */
1492 pt = alloc_texture(st, width, height, srcFormat, srcBind);
1493 if (!pt)
1494 return;
1495
1496 sv[0] = st_create_texture_sampler_view(st->pipe, pt);
1497 if (!sv[0]) {
1498 pipe_resource_reference(&pt, NULL);
1499 return;
1500 }
1501
1502 /* Copy the src region to the temporary texture. */
1503 {
1504 struct pipe_blit_info blit;
1505
1506 memset(&blit, 0, sizeof(blit));
1507 blit.src.resource = rbRead->texture;
1508 blit.src.level = rbRead->surface->u.tex.level;
1509 blit.src.format = rbRead->texture->format;
1510 blit.src.box.x = readX;
1511 blit.src.box.y = readY;
1512 blit.src.box.z = rbRead->surface->u.tex.first_layer;
1513 blit.src.box.width = readW;
1514 blit.src.box.height = readH;
1515 blit.src.box.depth = 1;
1516 blit.dst.resource = pt;
1517 blit.dst.level = 0;
1518 blit.dst.format = pt->format;
1519 blit.dst.box.x = pack.SkipPixels;
1520 blit.dst.box.y = pack.SkipRows;
1521 blit.dst.box.z = 0;
1522 blit.dst.box.width = readW;
1523 blit.dst.box.height = readH;
1524 blit.dst.box.depth = 1;
1525 blit.mask = util_format_get_mask(pt->format) & ~PIPE_MASK_S;
1526 blit.filter = PIPE_TEX_FILTER_NEAREST;
1527
1528 pipe->blit(pipe, &blit);
1529 }
1530
1531 /* OK, the texture 'pt' contains the src image/pixels. Now draw a
1532 * textured quad with that texture.
1533 */
1534 draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
1535 width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
1536 sv,
1537 num_sampler_view,
1538 driver_vp,
1539 driver_fp, fpv,
1540 ctx->Current.Attrib[VERT_ATTRIB_COLOR0],
1541 invertTex, GL_FALSE, GL_FALSE);
1542
1543 pipe_resource_reference(&pt, NULL);
1544 pipe_sampler_view_reference(&sv[0], NULL);
1545 }
1546
1547
1548
1549 void st_init_drawpixels_functions(struct dd_function_table *functions)
1550 {
1551 functions->DrawPixels = st_DrawPixels;
1552 functions->CopyPixels = st_CopyPixels;
1553 }
1554
1555
1556 void
1557 st_destroy_drawpix(struct st_context *st)
1558 {
1559 GLuint i;
1560
1561 for (i = 0; i < ARRAY_SIZE(st->drawpix.zs_shaders); i++) {
1562 if (st->drawpix.zs_shaders[i])
1563 cso_delete_fragment_shader(st->cso_context,
1564 st->drawpix.zs_shaders[i]);
1565 }
1566
1567 if (st->drawpix.vert_shaders[0])
1568 cso_delete_vertex_shader(st->cso_context, st->drawpix.vert_shaders[0]);
1569 if (st->drawpix.vert_shaders[1])
1570 cso_delete_vertex_shader(st->cso_context, st->drawpix.vert_shaders[1]);
1571 }