1d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian/************************************************************************** 2d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * 3d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * All Rights Reserved. 5d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * 6d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * Permission is hereby granted, free of charge, to any person obtaining a 7d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * copy of this software and associated documentation files (the 8d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * "Software"), to deal in the Software without restriction, including 9d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * without limitation the rights to use, copy, modify, merge, publish, 10d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * distribute, sub license, and/or sell copies of the Software, and to 11d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * permit persons to whom the Software is furnished to do so, subject to 12d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * the following conditions: 13d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * 14d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * The above copyright notice and this permission notice (including the 15d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * next paragraph) shall be included in all copies or substantial portions 16d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * of the Software. 17d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * 18d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * 26d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian **************************************************************************/ 27d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian 28d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian /* 29d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * Authors: 30d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * Brian Paul 31d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian */ 32d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian 3302ea8b81414b50936b8b6b7b8031511e12ef55cdBrian#include "main/imports.h" 3402ea8b81414b50936b8b6b7b8031511e12ef55cdBrian#include "main/image.h" 35f1626f0bfd2b14ad8ca2afaad2ea8afb539e6491Brian Paul#include "main/bufferobj.h" 365e81d3b85300077a0df1f1d77646a7e939d32a7fBrian Paul#include "main/format_pack.h" 37fa1d442879f1279cf510a52a1002367b904d35adBrian#include "main/macros.h" 38edc09358f72cd48cb2315daf23c82e7646aeaea3Vinson Lee#include "main/mfeatures.h" 3920d85865ec75f2cf2ae2a62ed3cf419e9af3eca3Vinson Lee#include "main/mtypes.h" 401c131752c3e07ef91f49d4970dafca6d26585334Brian Paul#include "main/pack.h" 41b70610b9823fc7dc3672735c11be1a75fbb1a2a4Brian Paul#include "main/pbo.h" 423754ebb33dc6bfb3db59f23f0b3690134a71aa15Brian Paul#include "main/readpix.h" 43753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer#include "main/texformat.h" 44ad2999d2113356d526b39774eb8114e974dac048Marek Olšák#include "main/teximage.h" 45e07862d2c949bcae7c71e9fc8e90e4694ed25bb3Brian Paul#include "main/texstore.h" 469ad8f431b2a47060bf05517246ab0fa8d249c800Jordan Justen#include "main/glformats.h" 47ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/program.h" 48ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_print.h" 49cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul#include "program/prog_instruction.h" 50d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian 51d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian#include "st_atom.h" 52de38d9c498b999d80b51679ece6b4caccd80a2b8Brian#include "st_atom_constbuf.h" 53d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian#include "st_cb_drawpixels.h" 54bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian#include "st_cb_readpixels.h" 55bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian#include "st_cb_fbo.h" 56cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul#include "st_context.h" 57cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul#include "st_debug.h" 58f8ab24760d0d3f07e9ee81c98207ddf92dfe74daBrian#include "st_format.h" 59cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul#include "st_program.h" 60753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer#include "st_texture.h" 61e50dd26ca6d0eb0d0f97c2780020ea16e3d4a687Thomas Hellstrom 62d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian#include "pipe/p_context.h" 63d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian#include "pipe/p_defines.h" 641454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell#include "tgsi/tgsi_ureg.h" 65f6cd3778c54c0329c3f497a7368a158087d653d3Brian#include "util/u_draw_quad.h" 660bed834be4a174d20b31a6cbcf066774bf749929Michal Krol#include "util/u_format.h" 67cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul#include "util/u_inlines.h" 68fc3d564daeacdbd76b97de2ffc10e15931a18c7aPatrice Mandin#include "util/u_math.h" 69cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul#include "util/u_tile.h" 70b69dad1683f092e3ce9d0f3f8fb1bdf96bdff0c7Marek Olšák#include "util/u_upload_mgr.h" 71339e7ec6805e6de8794514c0a935081b5d36d38fBrian#include "cso_cache/cso_context.h" 72d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian 73d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian 7414a92b26ff76550c5010ddf8bcbf5226dae5183fChia-I Wu#if FEATURE_drawpix 7514a92b26ff76550c5010ddf8bcbf5226dae5183fChia-I Wu 76fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian/** 77fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian * Check if the given program is: 78fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian * 0: MOVE result.color, fragment.color; 79fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian * 1: END; 80fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian */ 81fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brianstatic GLboolean 82fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brianis_passthrough_program(const struct gl_fragment_program *prog) 83fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian{ 84fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian if (prog->Base.NumInstructions == 2) { 85fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian const struct prog_instruction *inst = prog->Base.Instructions; 86fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian if (inst[0].Opcode == OPCODE_MOV && 87fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian inst[1].Opcode == OPCODE_END && 88fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian inst[0].DstReg.File == PROGRAM_OUTPUT && 898d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul inst[0].DstReg.Index == FRAG_RESULT_COLOR && 90fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian inst[0].DstReg.WriteMask == WRITEMASK_XYZW && 91fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian inst[0].SrcReg[0].File == PROGRAM_INPUT && 92fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian inst[0].SrcReg[0].Index == FRAG_ATTRIB_COL0 && 93fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian inst[0].SrcReg[0].Swizzle == SWIZZLE_XYZW) { 94fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian return GL_TRUE; 95fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian } 96fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian } 97fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian return GL_FALSE; 98fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian} 99fda91cfa4b7b7868172a563da49cb0d7ba6cf5e0Brian 100c19a95510f89401125ac3641725749c957f35d96Brian 101c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain/** 102c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain * Returns a fragment program which implements the current pixel transfer ops. 103c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain */ 104c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cainstatic struct gl_fragment_program * 105c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cainget_glsl_pixel_transfer_program(struct st_context *st, 106c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain struct st_fragment_program *orig) 107c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain{ 108c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain int pixelMaps = 0, scaleAndBias = 0; 109c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain struct gl_context *ctx = st->ctx; 110c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain struct st_fragment_program *fp = (struct st_fragment_program *) 111c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); 112c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 113c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain if (!fp) 114c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain return NULL; 115c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 116c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain if (ctx->Pixel.RedBias != 0.0 || ctx->Pixel.RedScale != 1.0 || 117c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain ctx->Pixel.GreenBias != 0.0 || ctx->Pixel.GreenScale != 1.0 || 118c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain ctx->Pixel.BlueBias != 0.0 || ctx->Pixel.BlueScale != 1.0 || 119c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain ctx->Pixel.AlphaBias != 0.0 || ctx->Pixel.AlphaScale != 1.0) { 120c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain scaleAndBias = 1; 121c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain } 122c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 123c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain pixelMaps = ctx->Pixel.MapColorFlag; 124c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 125c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain if (pixelMaps) { 126c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* create the colormap/texture now if not already done */ 127c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain if (!st->pixel_xfer.pixelmap_texture) { 1289adcab9cd464d659288e31e6767efb5dee3894ffBryan Cain st->pixel_xfer.pixelmap_texture = st_create_color_map_texture(ctx); 129c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain st->pixel_xfer.pixelmap_sampler_view = 130c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain st_create_texture_sampler_view(st->pipe, 131c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain st->pixel_xfer.pixelmap_texture); 132c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain } 133c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain } 134c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 135c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain get_pixel_transfer_visitor(fp, orig->glsl_to_tgsi, 136c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain scaleAndBias, pixelMaps); 137c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 138c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain return &fp->Base; 139c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain} 140c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 141520c71161ad0929a4b43e8e1e75067e10920f596Brian 142520c71161ad0929a4b43e8e1e75067e10920f596Brian/** 143520c71161ad0929a4b43e8e1e75067e10920f596Brian * Make fragment shader for glDraw/CopyPixels. This shader is made 144520c71161ad0929a4b43e8e1e75067e10920f596Brian * by combining the pixel transfer shader with the user-defined shader. 1453d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * \param fpIn the current/incoming fragment program 1463d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * \param fpOut returns the combined fragment program 147520c71161ad0929a4b43e8e1e75067e10920f596Brian */ 1483d203b610045980853d26370ee21fb2ef4aed17eBrian Paulvoid 1493d203b610045980853d26370ee21fb2ef4aed17eBrian Paulst_make_drawpix_fragment_program(struct st_context *st, 1503d203b610045980853d26370ee21fb2ef4aed17eBrian Paul struct gl_fragment_program *fpIn, 1513d203b610045980853d26370ee21fb2ef4aed17eBrian Paul struct gl_fragment_program **fpOut) 152de38d9c498b999d80b51679ece6b4caccd80a2b8Brian{ 1533d203b610045980853d26370ee21fb2ef4aed17eBrian Paul struct gl_program *newProg; 154c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain struct st_fragment_program *stfp = (struct st_fragment_program *) fpIn; 155de38d9c498b999d80b51679ece6b4caccd80a2b8Brian 1563d203b610045980853d26370ee21fb2ef4aed17eBrian Paul if (is_passthrough_program(fpIn)) { 1573d203b610045980853d26370ee21fb2ef4aed17eBrian Paul newProg = (struct gl_program *) _mesa_clone_fragment_program(st->ctx, 1583d203b610045980853d26370ee21fb2ef4aed17eBrian Paul &st->pixel_xfer.program->Base); 159d6a739f6b0658414a81715bf690159f7cfdb4961Brian } 160c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain else if (stfp->glsl_to_tgsi != NULL) { 161c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain newProg = (struct gl_program *) get_glsl_pixel_transfer_program(st, stfp); 162c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain } 163d6a739f6b0658414a81715bf690159f7cfdb4961Brian else { 164070a7446221e26aee5ab6e6e12988ea9c1688ba6Brian Paul#if 0 1653d203b610045980853d26370ee21fb2ef4aed17eBrian Paul /* debug */ 1663d203b610045980853d26370ee21fb2ef4aed17eBrian Paul printf("Base program:\n"); 1673d203b610045980853d26370ee21fb2ef4aed17eBrian Paul _mesa_print_program(&fpIn->Base); 1683d203b610045980853d26370ee21fb2ef4aed17eBrian Paul printf("DrawPix program:\n"); 1693d203b610045980853d26370ee21fb2ef4aed17eBrian Paul _mesa_print_program(&st->pixel_xfer.program->Base.Base); 170070a7446221e26aee5ab6e6e12988ea9c1688ba6Brian Paul#endif 1713d203b610045980853d26370ee21fb2ef4aed17eBrian Paul newProg = _mesa_combine_programs(st->ctx, 1723d203b610045980853d26370ee21fb2ef4aed17eBrian Paul &st->pixel_xfer.program->Base.Base, 1733d203b610045980853d26370ee21fb2ef4aed17eBrian Paul &fpIn->Base); 1743d203b610045980853d26370ee21fb2ef4aed17eBrian Paul } 175ab3f6015aa7227da3137b60456deb3905680f95fBrian 176ab3f6015aa7227da3137b60456deb3905680f95fBrian#if 0 1773d203b610045980853d26370ee21fb2ef4aed17eBrian Paul /* debug */ 1783d203b610045980853d26370ee21fb2ef4aed17eBrian Paul printf("Combined DrawPixels program:\n"); 1793d203b610045980853d26370ee21fb2ef4aed17eBrian Paul _mesa_print_program(newProg); 1803d203b610045980853d26370ee21fb2ef4aed17eBrian Paul printf("InputsRead: 0x%x\n", newProg->InputsRead); 1813d203b610045980853d26370ee21fb2ef4aed17eBrian Paul printf("OutputsWritten: 0x%x\n", newProg->OutputsWritten); 1823d203b610045980853d26370ee21fb2ef4aed17eBrian Paul _mesa_print_parameter_list(newProg->Parameters); 183ab3f6015aa7227da3137b60456deb3905680f95fBrian#endif 184de38d9c498b999d80b51679ece6b4caccd80a2b8Brian 1853d203b610045980853d26370ee21fb2ef4aed17eBrian Paul *fpOut = (struct gl_fragment_program *) newProg; 186de38d9c498b999d80b51679ece6b4caccd80a2b8Brian} 187de38d9c498b999d80b51679ece6b4caccd80a2b8Brian 188de38d9c498b999d80b51679ece6b4caccd80a2b8Brian 189d054331c4788b0a5f13f4d7a9b497d274d267acbBrian/** 1903d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * Create fragment program that does a TEX() instruction to get a Z and/or 19181c27dbfb943df8dc5cf65a2654d96fe5d7c1df4Brian Paul * stencil value value, then writes to FRAG_RESULT_DEPTH/FRAG_RESULT_STENCIL. 19281c27dbfb943df8dc5cf65a2654d96fe5d7c1df4Brian Paul * Used for glDrawPixels(GL_DEPTH_COMPONENT / GL_STENCIL_INDEX). 193563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian * Pass fragment color through as-is. 1943d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * \return pointer to the gl_fragment program 195a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian */ 1963d203b610045980853d26370ee21fb2ef4aed17eBrian Paulstruct gl_fragment_program * 1973d203b610045980853d26370ee21fb2ef4aed17eBrian Paulst_make_drawpix_z_stencil_program(struct st_context *st, 1983d203b610045980853d26370ee21fb2ef4aed17eBrian Paul GLboolean write_depth, 1993d203b610045980853d26370ee21fb2ef4aed17eBrian Paul GLboolean write_stencil) 200a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian{ 201f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg struct gl_context *ctx = st->ctx; 202a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian struct gl_program *p; 2033d203b610045980853d26370ee21fb2ef4aed17eBrian Paul struct gl_fragment_program *fp; 204a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian GLuint ic = 0; 20561a467e515c31eb6b97b039bc3f97dbe6eafa7cbBrian Paul const GLuint shaderIndex = write_depth * 2 + write_stencil; 206a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian 20761a467e515c31eb6b97b039bc3f97dbe6eafa7cbBrian Paul assert(shaderIndex < Elements(st->drawpix.shaders)); 20861a467e515c31eb6b97b039bc3f97dbe6eafa7cbBrian Paul 20961a467e515c31eb6b97b039bc3f97dbe6eafa7cbBrian Paul if (st->drawpix.shaders[shaderIndex]) { 21061a467e515c31eb6b97b039bc3f97dbe6eafa7cbBrian Paul /* already have the proper shader */ 2113d203b610045980853d26370ee21fb2ef4aed17eBrian Paul return st->drawpix.shaders[shaderIndex]; 2125c431c22227fdc552b34a5feabf1d339dcfe9848Brian Paul } 213563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian 2145c431c22227fdc552b34a5feabf1d339dcfe9848Brian Paul /* 2155c431c22227fdc552b34a5feabf1d339dcfe9848Brian Paul * Create shader now 2165c431c22227fdc552b34a5feabf1d339dcfe9848Brian Paul */ 217a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); 218a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian if (!p) 219a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian return NULL; 220a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian 221f677954e07c6c1fd59b13622a7420c97d68a6029Brian Paul p->NumInstructions = write_depth ? 3 : 1; 222ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->NumInstructions += write_stencil ? 1 : 0; 223a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian 224a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian p->Instructions = _mesa_alloc_instructions(p->NumInstructions); 225a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian if (!p->Instructions) { 226a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian ctx->Driver.DeleteProgram(ctx, p); 227a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian return NULL; 228a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian } 229a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian _mesa_init_instructions(p->Instructions, p->NumInstructions); 230a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian 231ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie if (write_depth) { 232cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul /* TEX result.depth, fragment.texcoord[0], texture[0], 2D; */ 233ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->Instructions[ic].Opcode = OPCODE_TEX; 234ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT; 235ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->Instructions[ic].DstReg.Index = FRAG_RESULT_DEPTH; 236ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->Instructions[ic].DstReg.WriteMask = WRITEMASK_Z; 237ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT; 238ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0; 239ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->Instructions[ic].TexSrcUnit = 0; 240ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX; 241ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie ic++; 242f677954e07c6c1fd59b13622a7420c97d68a6029Brian Paul /* MOV result.color, fragment.color; */ 243f677954e07c6c1fd59b13622a7420c97d68a6029Brian Paul p->Instructions[ic].Opcode = OPCODE_MOV; 244f677954e07c6c1fd59b13622a7420c97d68a6029Brian Paul p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT; 245f677954e07c6c1fd59b13622a7420c97d68a6029Brian Paul p->Instructions[ic].DstReg.Index = FRAG_RESULT_COLOR; 246f677954e07c6c1fd59b13622a7420c97d68a6029Brian Paul p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT; 247f677954e07c6c1fd59b13622a7420c97d68a6029Brian Paul p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_COL0; 248f677954e07c6c1fd59b13622a7420c97d68a6029Brian Paul ic++; 249ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie } 250ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie 251ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie if (write_stencil) { 252cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul /* TEX result.stencil, fragment.texcoord[0], texture[0], 2D; */ 253ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->Instructions[ic].Opcode = OPCODE_TEX; 254ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT; 255ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->Instructions[ic].DstReg.Index = FRAG_RESULT_STENCIL; 256ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->Instructions[ic].DstReg.WriteMask = WRITEMASK_Y; 257ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT; 258ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0; 259ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->Instructions[ic].TexSrcUnit = 1; 260ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX; 261ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie ic++; 262ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie } 263a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian 264a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian /* END; */ 265a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian p->Instructions[ic++].Opcode = OPCODE_END; 266a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian 267a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian assert(ic == p->NumInstructions); 268a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian 269a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian p->InputsRead = FRAG_BIT_TEX0 | FRAG_BIT_COL0; 270ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->OutputsWritten = 0; 271f677954e07c6c1fd59b13622a7420c97d68a6029Brian Paul if (write_depth) { 272aa878f94ab77fe3be352d820aaa950b32836c814Brian Paul p->OutputsWritten |= BITFIELD64_BIT(FRAG_RESULT_DEPTH); 273f677954e07c6c1fd59b13622a7420c97d68a6029Brian Paul p->OutputsWritten |= BITFIELD64_BIT(FRAG_RESULT_COLOR); 274f677954e07c6c1fd59b13622a7420c97d68a6029Brian Paul } 275ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie if (write_stencil) 276aa878f94ab77fe3be352d820aaa950b32836c814Brian Paul p->OutputsWritten |= BITFIELD64_BIT(FRAG_RESULT_STENCIL); 277ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie 278ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->SamplersUsed = 0x1; /* sampler 0 (bit 0) is used */ 279ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie if (write_stencil) 280ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie p->SamplersUsed |= 1 << 1; 281a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian 2823d203b610045980853d26370ee21fb2ef4aed17eBrian Paul fp = (struct gl_fragment_program *) p; 28361a467e515c31eb6b97b039bc3f97dbe6eafa7cbBrian Paul 28461a467e515c31eb6b97b039bc3f97dbe6eafa7cbBrian Paul /* save the new shader */ 2853d203b610045980853d26370ee21fb2ef4aed17eBrian Paul st->drawpix.shaders[shaderIndex] = fp; 28661a467e515c31eb6b97b039bc3f97dbe6eafa7cbBrian Paul 2873d203b610045980853d26370ee21fb2ef4aed17eBrian Paul return fp; 288a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian} 289a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian 290a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian 291a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian/** 292d054331c4788b0a5f13f4d7a9b497d274d267acbBrian * Create a simple vertex shader that just passes through the 293563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian * vertex position and texcoord (and optionally, color). 294d054331c4788b0a5f13f4d7a9b497d274d267acbBrian */ 2951454f20a991ddda35f1a2ffda953012078b407baKeith Whitwellstatic void * 29608cfe3ab421491644cf1bebaf47e8bc897e495c5Brian Paulmake_passthrough_vertex_shader(struct st_context *st, 29708cfe3ab421491644cf1bebaf47e8bc897e495c5Brian Paul GLboolean passColor) 298d054331c4788b0a5f13f4d7a9b497d274d267acbBrian{ 2991454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell if (!st->drawpix.vert_shaders[passColor]) { 300cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul struct ureg_program *ureg = ureg_create( TGSI_PROCESSOR_VERTEX ); 3011454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell 3021454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell if (ureg == NULL) 3031454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell return NULL; 3041454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell 3051454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell /* MOV result.pos, vertex.pos; */ 3061454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell ureg_MOV(ureg, 3071454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell ureg_DECL_output( ureg, TGSI_SEMANTIC_POSITION, 0 ), 3081454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell ureg_DECL_vs_input( ureg, 0 )); 3091454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell 310bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul /* MOV result.texcoord0, vertex.attr[1]; */ 3111454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell ureg_MOV(ureg, 3121454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell ureg_DECL_output( ureg, TGSI_SEMANTIC_GENERIC, 0 ), 3131454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell ureg_DECL_vs_input( ureg, 1 )); 3141454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell 3151454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell if (passColor) { 316bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul /* MOV result.color0, vertex.attr[2]; */ 3171454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell ureg_MOV(ureg, 3181454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 ), 3191454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell ureg_DECL_vs_input( ureg, 2 )); 3201454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell } 321d054331c4788b0a5f13f4d7a9b497d274d267acbBrian 3221454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell ureg_END( ureg ); 3231454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell 3241454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell st->drawpix.vert_shaders[passColor] = 3251454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell ureg_create_shader_and_destroy( ureg, st->pipe ); 326ccff14de0d6291aa0866ce5d207af416caec69e7Brian } 327d054331c4788b0a5f13f4d7a9b497d274d267acbBrian 3281454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell return st->drawpix.vert_shaders[passColor]; 329d054331c4788b0a5f13f4d7a9b497d274d267acbBrian} 330d054331c4788b0a5f13f4d7a9b497d274d267acbBrian 331d054331c4788b0a5f13f4d7a9b497d274d267acbBrian 33208cfe3ab421491644cf1bebaf47e8bc897e495c5Brian Paul/** 333e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul * Return a texture internalFormat for drawing/copying an image 334e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul * of the given format and type. 335e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul */ 336e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paulstatic GLenum 337b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšákinternal_format(struct gl_context *ctx, GLenum format, GLenum type) 338e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul{ 339e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul switch (format) { 340e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul case GL_DEPTH_COMPONENT: 341c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák switch (type) { 342c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák case GL_UNSIGNED_SHORT: 343c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák return GL_DEPTH_COMPONENT16; 344c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák 345c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák case GL_UNSIGNED_INT: 346c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák return GL_DEPTH_COMPONENT32; 347c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák 348c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák case GL_FLOAT: 349c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák if (ctx->Extensions.ARB_depth_buffer_float) 350c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák return GL_DEPTH_COMPONENT32F; 351c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák else 352c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák return GL_DEPTH_COMPONENT; 353c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák 354c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák default: 355c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák return GL_DEPTH_COMPONENT; 356c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák } 357c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák 358e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul case GL_DEPTH_STENCIL: 359c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák switch (type) { 360c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 361c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák return GL_DEPTH32F_STENCIL8; 362c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák 363c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák case GL_UNSIGNED_INT_24_8: 364c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák default: 365c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák return GL_DEPTH24_STENCIL8; 366c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák } 367c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák 368e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul case GL_STENCIL_INDEX: 369e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul return GL_STENCIL_INDEX; 370c369fb42ee00598396e16faf1cd98995bf72c0b7Marek Olšák 371e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul default: 3729ad8f431b2a47060bf05517246ab0fa8d249c800Jordan Justen if (_mesa_is_enum_format_integer(format)) { 373e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul switch (type) { 374e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul case GL_BYTE: 375e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul return GL_RGBA8I; 376e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul case GL_UNSIGNED_BYTE: 377e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul return GL_RGBA8UI; 378e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul case GL_SHORT: 379e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul return GL_RGBA16I; 380e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul case GL_UNSIGNED_SHORT: 381e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul return GL_RGBA16UI; 382e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul case GL_INT: 383e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul return GL_RGBA32I; 384e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul case GL_UNSIGNED_INT: 385e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul return GL_RGBA32UI; 386e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul default: 387e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul assert(0 && "Unexpected type in internal_format()"); 388e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul return GL_RGBA_INTEGER; 389e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul } 390e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul } 391e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul else { 392b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák switch (type) { 393b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_UNSIGNED_BYTE: 394b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_UNSIGNED_INT_8_8_8_8: 395b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_UNSIGNED_INT_8_8_8_8_REV: 396b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák default: 397b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák return GL_RGBA8; 398b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák 399b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_UNSIGNED_BYTE_3_3_2: 400b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_UNSIGNED_BYTE_2_3_3_REV: 401738d1ae3b59b073605c7fb58ec6f0a85a185ffd3José Fonseca return GL_R3_G3_B2; 402738d1ae3b59b073605c7fb58ec6f0a85a185ffd3José Fonseca 403b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_UNSIGNED_SHORT_4_4_4_4: 404b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_UNSIGNED_SHORT_4_4_4_4_REV: 405b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák return GL_RGBA4; 406b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák 407b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_UNSIGNED_SHORT_5_6_5: 408b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_UNSIGNED_SHORT_5_6_5_REV: 4091a06e8454ec714e950bc88882cd985534a18bf1fMarek Olšák return GL_RGB565; 4101a06e8454ec714e950bc88882cd985534a18bf1fMarek Olšák 411b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_UNSIGNED_SHORT_5_5_5_1: 412b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_UNSIGNED_SHORT_1_5_5_5_REV: 413b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák return GL_RGB5_A1; 414b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák 415b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_UNSIGNED_INT_10_10_10_2: 416b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_UNSIGNED_INT_2_10_10_10_REV: 417b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák return GL_RGB10_A2; 418b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák 419b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_UNSIGNED_SHORT: 420b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_UNSIGNED_INT: 421b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák return GL_RGBA16; 422b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák 423b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_BYTE: 424b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák return 425b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák ctx->Extensions.EXT_texture_snorm ? GL_RGBA8_SNORM : GL_RGBA8; 426b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák 427b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_SHORT: 428b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_INT: 429b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák return 430b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16; 431b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák 432b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_HALF_FLOAT_ARB: 433b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák return 434b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák ctx->Extensions.ARB_texture_float ? GL_RGBA16F : 435b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16; 436b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák 437b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_FLOAT: 438b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák case GL_DOUBLE: 439b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák return 440b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák ctx->Extensions.ARB_texture_float ? GL_RGBA32F : 441b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16; 4421da44f5923c5715d78a48dc300bbc6cbd3f3ea99Marek Olšák 4431da44f5923c5715d78a48dc300bbc6cbd3f3ea99Marek Olšák case GL_UNSIGNED_INT_5_9_9_9_REV: 4441da44f5923c5715d78a48dc300bbc6cbd3f3ea99Marek Olšák assert(ctx->Extensions.EXT_texture_shared_exponent); 4451da44f5923c5715d78a48dc300bbc6cbd3f3ea99Marek Olšák return GL_RGB9_E5; 446e62530a6c00da71c0f7bf1f4c425fe6c5b452df6Marek Olšák 447e62530a6c00da71c0f7bf1f4c425fe6c5b452df6Marek Olšák case GL_UNSIGNED_INT_10F_11F_11F_REV: 448e62530a6c00da71c0f7bf1f4c425fe6c5b452df6Marek Olšák assert(ctx->Extensions.EXT_packed_float); 449e62530a6c00da71c0f7bf1f4c425fe6c5b452df6Marek Olšák return GL_R11F_G11F_B10F; 450b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák } 451e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul } 452e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul } 453e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul} 454e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul 455e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul 456e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul/** 457a2fe774e0985358a125c5c2e7b89a6b0bc0914d1Brian Paul * Create a temporary texture to hold an image of the given size. 458a2fe774e0985358a125c5c2e7b89a6b0bc0914d1Brian Paul * If width, height are not POT and the driver only handles POT textures, 459a2fe774e0985358a125c5c2e7b89a6b0bc0914d1Brian Paul * allocate the next larger size of texture that is POT. 460a2fe774e0985358a125c5c2e7b89a6b0bc0914d1Brian Paul */ 461287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic struct pipe_resource * 462a2fe774e0985358a125c5c2e7b89a6b0bc0914d1Brian Paulalloc_texture(struct st_context *st, GLsizei width, GLsizei height, 463a2fe774e0985358a125c5c2e7b89a6b0bc0914d1Brian Paul enum pipe_format texFormat) 464a2fe774e0985358a125c5c2e7b89a6b0bc0914d1Brian Paul{ 465287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_resource *pt; 466a2fe774e0985358a125c5c2e7b89a6b0bc0914d1Brian Paul 4673070e0ea41ab4aa24804e8fd26895924a8583830Luca Barbieri pt = st_texture_create(st, st->internal_target, texFormat, 0, 468db3a8af7f900e4970ea18659e86a824b4ebdefc7Brian Paul width, height, 1, 1, PIPE_BIND_SAMPLER_VIEW); 469a2fe774e0985358a125c5c2e7b89a6b0bc0914d1Brian Paul 470a2fe774e0985358a125c5c2e7b89a6b0bc0914d1Brian Paul return pt; 471a2fe774e0985358a125c5c2e7b89a6b0bc0914d1Brian Paul} 472a2fe774e0985358a125c5c2e7b89a6b0bc0914d1Brian Paul 473a2fe774e0985358a125c5c2e7b89a6b0bc0914d1Brian Paul 474a2fe774e0985358a125c5c2e7b89a6b0bc0914d1Brian Paul/** 475753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * Make texture containing an image for glDrawPixels image. 476563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian * If 'pixels' is NULL, leave the texture image data undefined. 477960fe21008eb00bf778f82476e3d00df0a5c34dbBrian */ 478287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic struct pipe_resource * 479753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzermake_texture(struct st_context *st, 480753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer GLsizei width, GLsizei height, GLenum format, GLenum type, 481753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer const struct gl_pixelstore_attrib *unpack, 482753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer const GLvoid *pixels) 483c19a95510f89401125ac3641725749c957f35d96Brian{ 484f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg struct gl_context *ctx = st->ctx; 485e51aa572934c39fe3c99470343f776be4e783f42Brian struct pipe_context *pipe = st->pipe; 4861f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul gl_format mformat; 487287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_resource *pt; 48854fc80ab31f89520d3119196bfa9c6332b35fe2fBrian enum pipe_format pipeFormat; 489ad2999d2113356d526b39774eb8114e974dac048Marek Olšák GLenum baseInternalFormat, intFormat; 490c19a95510f89401125ac3641725749c957f35d96Brian 491b518f4d0ea72dc3872f351250034aa9155756dd3Marek Olšák intFormat = internal_format(ctx, format, type); 492ad2999d2113356d526b39774eb8114e974dac048Marek Olšák baseInternalFormat = _mesa_base_tex_format(ctx, intFormat); 493a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian 494e6ac8d5353dda1b859dbc1219ca4e91c9183ae85Brian Paul mformat = st_ChooseTextureFormat_renderable(ctx, intFormat, 495cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul format, type, GL_FALSE); 4966ccdd5bb15d03b7eadc0f1e3ddba8848de4f146eBrian assert(mformat); 497e51aa572934c39fe3c99470343f776be4e783f42Brian 4981f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul pipeFormat = st_mesa_format_to_pipe_format(mformat); 499c19a95510f89401125ac3641725749c957f35d96Brian assert(pipeFormat); 5006ccdd5bb15d03b7eadc0f1e3ddba8848de4f146eBrian 5011b448c7a5cafa68eeead2a4c45f4362a9883383bBrian Paul pixels = _mesa_map_pbo_source(ctx, unpack, pixels); 502f1626f0bfd2b14ad8ca2afaad2ea8afb539e6491Brian Paul if (!pixels) 503f1626f0bfd2b14ad8ca2afaad2ea8afb539e6491Brian Paul return NULL; 504f1626f0bfd2b14ad8ca2afaad2ea8afb539e6491Brian Paul 505a2fe774e0985358a125c5c2e7b89a6b0bc0914d1Brian Paul /* alloc temporary texture */ 506a2fe774e0985358a125c5c2e7b89a6b0bc0914d1Brian Paul pt = alloc_texture(st, width, height, pipeFormat); 507f1626f0bfd2b14ad8ca2afaad2ea8afb539e6491Brian Paul if (!pt) { 5081b448c7a5cafa68eeead2a4c45f4362a9883383bBrian Paul _mesa_unmap_pbo_source(ctx, unpack); 509960fe21008eb00bf778f82476e3d00df0a5c34dbBrian return NULL; 510c19a95510f89401125ac3641725749c957f35d96Brian } 511563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian 512563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian { 5134617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer struct pipe_transfer *transfer; 514e51aa572934c39fe3c99470343f776be4e783f42Brian GLboolean success; 515e51aa572934c39fe3c99470343f776be4e783f42Brian GLubyte *dest; 516ee70c02b62f7692de6293045928c47168652bd1cBrian const GLbitfield imageTransferStateSave = ctx->_ImageTransferState; 517ee70c02b62f7692de6293045928c47168652bd1cBrian 518ee70c02b62f7692de6293045928c47168652bd1cBrian /* we'll do pixel transfer in a fragment shader */ 519ee70c02b62f7692de6293045928c47168652bd1cBrian ctx->_ImageTransferState = 0x0; 520e51aa572934c39fe3c99470343f776be4e783f42Brian 5214c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger transfer = pipe_get_transfer(st->pipe, pt, 0, 0, 5224c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger PIPE_TRANSFER_WRITE, 0, 0, 5234c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger width, height); 524753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer 5254617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer /* map texture transfer */ 526287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell dest = pipe_transfer_map(pipe, transfer); 527e51aa572934c39fe3c99470343f776be4e783f42Brian 528e07862d2c949bcae7c71e9fc8e90e4694ed25bb3Brian Paul 5294617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer /* Put image into texture transfer. 53012e3bb1a65bbff82dabc64110249c57a711501c1Brian * Note that the image is actually going to be upside down in 53112e3bb1a65bbff82dabc64110249c57a711501c1Brian * the texture. We deal with that with texcoords. 53212e3bb1a65bbff82dabc64110249c57a711501c1Brian */ 5336480210b89dc8ae0990c450d27870c7b7930f251Brian Paul success = _mesa_texstore(ctx, 2, /* dims */ 534ad2999d2113356d526b39774eb8114e974dac048Marek Olšák baseInternalFormat, /* baseInternalFormat */ 535884d1abb2ac1a2ce872a5b09fd4228159defcf26Brian Paul mformat, /* gl_format */ 5366480210b89dc8ae0990c450d27870c7b7930f251Brian Paul transfer->stride, /* dstRowStride, bytes */ 5375253cf98057dad54e25b4b8c36f8cf24f559314cBrian Paul &dest, /* destSlices */ 5386480210b89dc8ae0990c450d27870c7b7930f251Brian Paul width, height, 1, /* size */ 5396480210b89dc8ae0990c450d27870c7b7930f251Brian Paul format, type, /* src format/type */ 5406480210b89dc8ae0990c450d27870c7b7930f251Brian Paul pixels, /* data source */ 5416480210b89dc8ae0990c450d27870c7b7930f251Brian Paul unpack); 542e51aa572934c39fe3c99470343f776be4e783f42Brian 543e51aa572934c39fe3c99470343f776be4e783f42Brian /* unmap */ 544287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_transfer_unmap(pipe, transfer); 545287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe->transfer_destroy(pipe, transfer); 5464984487bc3338fc351a0631eaa4515e4adbb86a9Brian Paul 547e51aa572934c39fe3c99470343f776be4e783f42Brian assert(success); 548ee70c02b62f7692de6293045928c47168652bd1cBrian 549ee70c02b62f7692de6293045928c47168652bd1cBrian /* restore */ 550ee70c02b62f7692de6293045928c47168652bd1cBrian ctx->_ImageTransferState = imageTransferStateSave; 551c19a95510f89401125ac3641725749c957f35d96Brian } 552c19a95510f89401125ac3641725749c957f35d96Brian 5531b448c7a5cafa68eeead2a4c45f4362a9883383bBrian Paul _mesa_unmap_pbo_source(ctx, unpack); 554f1626f0bfd2b14ad8ca2afaad2ea8afb539e6491Brian Paul 555753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer return pt; 556c19a95510f89401125ac3641725749c957f35d96Brian} 557c19a95510f89401125ac3641725749c957f35d96Brian 558c19a95510f89401125ac3641725749c957f35d96Brian 559bc4aa83794c6336358793c5f428973fb22184050Brian/** 560149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul * Draw quad with texcoords and optional color. 561c78ac7fcfa37a78b835fc596441a9fbe1e679e4aBrian Paul * Coords are gallium window coords with y=0=top. 562149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul * \param color may be null 563149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul * \param invertTex if true, flip texcoords vertically 564bc4aa83794c6336358793c5f428973fb22184050Brian */ 565d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brianstatic void 566f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergdraw_quad(struct gl_context *ctx, GLfloat x0, GLfloat y0, GLfloat z, 567149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul GLfloat x1, GLfloat y1, const GLfloat *color, 568fc3d564daeacdbd76b97de2ffc10e15931a18c7aPatrice Mandin GLboolean invertTex, GLfloat maxXcoord, GLfloat maxYcoord) 569d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian{ 5704781c1f45925031a9e4a5f8ebf80cfd821312e3cBrian Paul struct st_context *st = st_context(ctx); 5714781c1f45925031a9e4a5f8ebf80cfd821312e3cBrian Paul struct pipe_context *pipe = st->pipe; 5726c1fbe912f1623cbcf474a0b985841e44122a911Marek Olšák GLfloat (*verts)[3][4]; /* four verts, three attribs, XYZW */ 5736c1fbe912f1623cbcf474a0b985841e44122a911Marek Olšák struct pipe_resource *buf = NULL; 5746c1fbe912f1623cbcf474a0b985841e44122a911Marek Olšák unsigned offset; 5756c1fbe912f1623cbcf474a0b985841e44122a911Marek Olšák 576c760677c85a1019eef67b2ce0ce97e8218918f44Brian Paul if (u_upload_alloc(st->uploader, 0, 4 * sizeof(verts[0]), &offset, 577c760677c85a1019eef67b2ce0ce97e8218918f44Brian Paul &buf, (void **) &verts) != PIPE_OK) { 5786c1fbe912f1623cbcf474a0b985841e44122a911Marek Olšák return; 5796c1fbe912f1623cbcf474a0b985841e44122a911Marek Olšák } 580149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul 581149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul /* setup vertex data */ 582149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul { 583149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul const struct gl_framebuffer *fb = st->ctx->DrawBuffer; 5846c534b830c6f5427c391c5225c34561141c201baMichal Krol const GLfloat fb_width = (GLfloat) fb->Width; 5856c534b830c6f5427c391c5225c34561141c201baMichal Krol const GLfloat fb_height = (GLfloat) fb->Height; 5865c1a78b7a85d23ad1358b34d03a0002a19483655José Fonseca const GLfloat clip_x0 = x0 / fb_width * 2.0f - 1.0f; 5875c1a78b7a85d23ad1358b34d03a0002a19483655José Fonseca const GLfloat clip_y0 = y0 / fb_height * 2.0f - 1.0f; 5885c1a78b7a85d23ad1358b34d03a0002a19483655José Fonseca const GLfloat clip_x1 = x1 / fb_width * 2.0f - 1.0f; 5895c1a78b7a85d23ad1358b34d03a0002a19483655José Fonseca const GLfloat clip_y1 = y1 / fb_height * 2.0f - 1.0f; 590fc3d564daeacdbd76b97de2ffc10e15931a18c7aPatrice Mandin const GLfloat sLeft = 0.0f, sRight = maxXcoord; 591fc3d564daeacdbd76b97de2ffc10e15931a18c7aPatrice Mandin const GLfloat tTop = invertTex ? maxYcoord : 0.0f; 592fc3d564daeacdbd76b97de2ffc10e15931a18c7aPatrice Mandin const GLfloat tBot = invertTex ? 0.0f : maxYcoord; 593bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul GLuint i; 594149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul 595149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul /* upper-left */ 596149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul verts[0][0][0] = clip_x0; /* v[0].attr[0].x */ 597149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul verts[0][0][1] = clip_y0; /* v[0].attr[0].y */ 598149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul 599149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul /* upper-right */ 600149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul verts[1][0][0] = clip_x1; 601149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul verts[1][0][1] = clip_y0; 602149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul 603149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul /* lower-right */ 604149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul verts[2][0][0] = clip_x1; 605149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul verts[2][0][1] = clip_y1; 606149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul 607149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul /* lower-left */ 608149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul verts[3][0][0] = clip_x0; 609149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul verts[3][0][1] = clip_y1; 610149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul 611bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul verts[0][1][0] = sLeft; /* v[0].attr[1].S */ 612bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul verts[0][1][1] = tTop; /* v[0].attr[1].T */ 613bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul verts[1][1][0] = sRight; 614bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul verts[1][1][1] = tTop; 615bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul verts[2][1][0] = sRight; 616bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul verts[2][1][1] = tBot; 617bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul verts[3][1][0] = sLeft; 618bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul verts[3][1][1] = tBot; 619149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul 620149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul /* same for all verts: */ 621149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul if (color) { 622149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul for (i = 0; i < 4; i++) { 623bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul verts[i][0][2] = z; /* v[i].attr[0].z */ 624bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul verts[i][0][3] = 1.0f; /* v[i].attr[0].w */ 625bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul verts[i][2][0] = color[0]; /* v[i].attr[2].r */ 626bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul verts[i][2][1] = color[1]; /* v[i].attr[2].g */ 627bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul verts[i][2][2] = color[2]; /* v[i].attr[2].b */ 628bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul verts[i][2][3] = color[3]; /* v[i].attr[2].a */ 629bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul verts[i][1][2] = 0.0f; /* v[i].attr[1].R */ 630bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul verts[i][1][3] = 1.0f; /* v[i].attr[1].Q */ 631149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul } 632149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul } 633149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul else { 634149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul for (i = 0; i < 4; i++) { 635bab6c0a03527f3d3b5124c6540cc167e3989c068Brian Paul verts[i][0][2] = z; /*Z*/ 6365c1a78b7a85d23ad1358b34d03a0002a19483655José Fonseca verts[i][0][3] = 1.0f; /*W*/ 6375c1a78b7a85d23ad1358b34d03a0002a19483655José Fonseca verts[i][1][2] = 0.0f; /*R*/ 6385c1a78b7a85d23ad1358b34d03a0002a19483655José Fonseca verts[i][1][3] = 1.0f; /*Q*/ 639149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul } 640149a4175fafdb4dfcf31b28377f83092c9edf335Brian Paul } 641ccff14de0d6291aa0866ce5d207af416caec69e7Brian } 642ccff14de0d6291aa0866ce5d207af416caec69e7Brian 6436c1fbe912f1623cbcf474a0b985841e44122a911Marek Olšák u_upload_unmap(st->uploader); 6446c1fbe912f1623cbcf474a0b985841e44122a911Marek Olšák util_draw_vertex_buffer(pipe, st->cso_context, buf, offset, 6456c1fbe912f1623cbcf474a0b985841e44122a911Marek Olšák PIPE_PRIM_QUADS, 6466c1fbe912f1623cbcf474a0b985841e44122a911Marek Olšák 4, /* verts */ 6476c1fbe912f1623cbcf474a0b985841e44122a911Marek Olšák 3); /* attribs/vert */ 6486c1fbe912f1623cbcf474a0b985841e44122a911Marek Olšák pipe_resource_reference(&buf, NULL); 649ccff14de0d6291aa0866ce5d207af416caec69e7Brian} 650ccff14de0d6291aa0866ce5d207af416caec69e7Brian 651ccff14de0d6291aa0866ce5d207af416caec69e7Brian 652ccff14de0d6291aa0866ce5d207af416caec69e7Brian 653ccff14de0d6291aa0866ce5d207af416caec69e7Brianstatic void 654f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergdraw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, 65502ea8b81414b50936b8b6b7b8031511e12ef55cdBrian GLsizei width, GLsizei height, 656b28f4a27d586b3ba3a7e87db761b6d624dd3e672Brian GLfloat zoomX, GLfloat zoomY, 657ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie struct pipe_sampler_view **sv, 658ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie int num_sampler_view, 6591454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell void *driver_vp, 6601454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell void *driver_fp, 661d44e515fd77d088862c5f19ef9a7aa92b04b5f13Brian const GLfloat *color, 662cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul GLboolean invertTex, 663cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul GLboolean write_depth, GLboolean write_stencil) 664d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian{ 6654781c1f45925031a9e4a5f8ebf80cfd821312e3cBrian Paul struct st_context *st = st_context(ctx); 6664781c1f45925031a9e4a5f8ebf80cfd821312e3cBrian Paul struct pipe_context *pipe = st->pipe; 6674781c1f45925031a9e4a5f8ebf80cfd821312e3cBrian Paul struct cso_context *cso = st->cso_context; 668bc4aa83794c6336358793c5f428973fb22184050Brian GLfloat x0, y0, x1, y1; 66918ec140ef27b6488bea9d54e21b08b0a3afbcafeJosé Fonseca GLsizei maxSize; 670ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie boolean normalized = sv[0]->texture->target != PIPE_TEXTURE_RECT; 6718fbd81b4ed59e371aa616b87296e4263d8992bffBrian 6728fbd81b4ed59e371aa616b87296e4263d8992bffBrian /* limit checks */ 6738fbd81b4ed59e371aa616b87296e4263d8992bffBrian /* XXX if DrawPixels image is larger than max texture size, break 6748fbd81b4ed59e371aa616b87296e4263d8992bffBrian * it up into chunks. 6758fbd81b4ed59e371aa616b87296e4263d8992bffBrian */ 676cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul maxSize = 1 << (pipe->screen->get_param(pipe->screen, 677cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1); 678e2feb80a90f3e9300c70a4a4eb3e966131f5c313Brian assert(width <= maxSize); 679e2feb80a90f3e9300c70a4a4eb3e966131f5c313Brian assert(height <= maxSize); 680d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian 6817d95efde0a0e13e13c59444703bc47eb13926385Brian cso_save_rasterizer(cso); 6827d95efde0a0e13e13c59444703bc47eb13926385Brian cso_save_viewport(cso); 683ea6f035ae90895bd4ee3247408eb179dfdf96d22Brian Paul cso_save_samplers(cso, PIPE_SHADER_FRAGMENT); 684ea6f035ae90895bd4ee3247408eb179dfdf96d22Brian Paul cso_save_sampler_views(cso, PIPE_SHADER_FRAGMENT); 68565efe807b9067aa07b382e3c4d9cea6222c5fc6bMichel Dänzer cso_save_fragment_shader(cso); 686c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák cso_save_stream_outputs(cso); 68765efe807b9067aa07b382e3c4d9cea6222c5fc6bMichel Dänzer cso_save_vertex_shader(cso); 688d2633af696f2e4ff98f669061e4e222e8643312cMarek Olšák cso_save_geometry_shader(cso); 689ae7b7bf1edcf6c492b4dcc162bca28a0090f601eRoland Scheidegger cso_save_vertex_elements(cso); 690d5062fb3a315c46d77d5c954a3e3c14be1907d33Marek Olšák cso_save_vertex_buffers(cso); 69120c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul if (write_stencil) { 69220c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul cso_save_depth_stencil_alpha(cso); 69320c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul cso_save_blend(cso); 69420c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul } 6957d95efde0a0e13e13c59444703bc47eb13926385Brian 696f6cd3778c54c0329c3f497a7368a158087d653d3Brian /* rasterizer state: just scissor */ 697e51aa572934c39fe3c99470343f776be4e783f42Brian { 698f6cd3778c54c0329c3f497a7368a158087d653d3Brian struct pipe_rasterizer_state rasterizer; 699f6cd3778c54c0329c3f497a7368a158087d653d3Brian memset(&rasterizer, 0, sizeof(rasterizer)); 700bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák rasterizer.clamp_fragment_color = !st->clamp_frag_color_in_shader && 70103b78ceb50b97611bcaa2d2354ff5b505306b0a1Marek Olšák ctx->Color._ClampFragmentColor && 70203b78ceb50b97611bcaa2d2354ff5b505306b0a1Marek Olšák !ctx->DrawBuffer->_IntegerColor; 703f07fe3c728aec5a715cf615822151e11a00cda44Brian Paul rasterizer.gl_rasterization_rules = 1; 704dc4c821f0817a3db716f965692fb701079f66340Marek Olšák rasterizer.depth_clip = !ctx->Transform.DepthClamp; 705ddc0f91bfc571dcd05c13f094c179b4250e53bccBrian rasterizer.scissor = ctx->Scissor.Enabled; 706f6cd3778c54c0329c3f497a7368a158087d653d3Brian cso_set_rasterizer(cso, &rasterizer); 707e51aa572934c39fe3c99470343f776be4e783f42Brian } 708d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian 70920c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul if (write_stencil) { 71020c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul /* Stencil writing bypasses the normal fragment pipeline to 71120c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul * disable color writing and set stencil test to always pass. 71220c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul */ 713ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie struct pipe_depth_stencil_alpha_state dsa; 71420c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul struct pipe_blend_state blend; 71520c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul 71620c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul /* depth/stencil */ 717ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie memset(&dsa, 0, sizeof(dsa)); 71820c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul dsa.stencil[0].enabled = 1; 71920c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul dsa.stencil[0].func = PIPE_FUNC_ALWAYS; 72020c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul dsa.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff; 72120c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; 722ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie if (write_depth) { 72320c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul /* writing depth+stencil: depth test always passes */ 72420c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul dsa.depth.enabled = 1; 72520c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul dsa.depth.writemask = ctx->Depth.Mask; 72620c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul dsa.depth.func = PIPE_FUNC_ALWAYS; 727ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie } 728ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie cso_set_depth_stencil_alpha(cso, &dsa); 72920c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul 73020c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul /* blend (colormask) */ 73120c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul memset(&blend, 0, sizeof(blend)); 73220c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul cso_set_blend(cso, &blend); 733ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie } 734ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie 735d054331c4788b0a5f13f4d7a9b497d274d267acbBrian /* fragment shader state: TEX lookup program */ 7361454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell cso_set_fragment_shader_handle(cso, driver_fp); 737bc4aa83794c6336358793c5f428973fb22184050Brian 738d054331c4788b0a5f13f4d7a9b497d274d267acbBrian /* vertex shader state: position + texcoord pass-through */ 7391454f20a991ddda35f1a2ffda953012078b407baKeith Whitwell cso_set_vertex_shader_handle(cso, driver_vp); 740339e7ec6805e6de8794514c0a935081b5d36d38fBrian 741d2633af696f2e4ff98f669061e4e222e8643312cMarek Olšák /* geometry shader state: disabled */ 742d2633af696f2e4ff98f669061e4e222e8643312cMarek Olšák cso_set_geometry_shader_handle(cso, NULL); 743d054331c4788b0a5f13f4d7a9b497d274d267acbBrian 744bc4aa83794c6336358793c5f428973fb22184050Brian /* texture sampling state: */ 745bc4aa83794c6336358793c5f428973fb22184050Brian { 746bc4aa83794c6336358793c5f428973fb22184050Brian struct pipe_sampler_state sampler; 747bc4aa83794c6336358793c5f428973fb22184050Brian memset(&sampler, 0, sizeof(sampler)); 74813bfa87b09294607e73d3993878956d5b344bbb3Brian sampler.wrap_s = PIPE_TEX_WRAP_CLAMP; 74913bfa87b09294607e73d3993878956d5b344bbb3Brian sampler.wrap_t = PIPE_TEX_WRAP_CLAMP; 75013bfa87b09294607e73d3993878956d5b344bbb3Brian sampler.wrap_r = PIPE_TEX_WRAP_CLAMP; 751bc4aa83794c6336358793c5f428973fb22184050Brian sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; 752bc4aa83794c6336358793c5f428973fb22184050Brian sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 753bc4aa83794c6336358793c5f428973fb22184050Brian sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 7543070e0ea41ab4aa24804e8fd26895924a8583830Luca Barbieri sampler.normalized_coords = normalized; 755339e7ec6805e6de8794514c0a935081b5d36d38fBrian 756ea6f035ae90895bd4ee3247408eb179dfdf96d22Brian Paul cso_single_sampler(cso, PIPE_SHADER_FRAGMENT, 0, &sampler); 757ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie if (num_sampler_view > 1) { 758ea6f035ae90895bd4ee3247408eb179dfdf96d22Brian Paul cso_single_sampler(cso, PIPE_SHADER_FRAGMENT, 1, &sampler); 7594b822a101680532ce6df52904af91194b78a16baBrian Paul } 760ea6f035ae90895bd4ee3247408eb179dfdf96d22Brian Paul cso_single_sampler_done(cso, PIPE_SHADER_FRAGMENT); 761c19a95510f89401125ac3641725749c957f35d96Brian } 762d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian 763d640198b2d52c104c707522e79d53a36f708ccd0Brian /* viewport state: viewport matching window dims */ 764d640198b2d52c104c707522e79d53a36f708ccd0Brian { 765b154497bef386e5ed0d9a2f6e25a4141759c6846Brian Paul const float w = (float) ctx->DrawBuffer->Width; 766b154497bef386e5ed0d9a2f6e25a4141759c6846Brian Paul const float h = (float) ctx->DrawBuffer->Height; 767d640198b2d52c104c707522e79d53a36f708ccd0Brian struct pipe_viewport_state vp; 768b154497bef386e5ed0d9a2f6e25a4141759c6846Brian Paul vp.scale[0] = 0.5f * w; 769b154497bef386e5ed0d9a2f6e25a4141759c6846Brian Paul vp.scale[1] = -0.5f * h; 770cfdd1ca69521446b5d937d95e7d8bfb27f6d68ebBrian Paul vp.scale[2] = 0.5f; 77118ec140ef27b6488bea9d54e21b08b0a3afbcafeJosé Fonseca vp.scale[3] = 1.0f; 772b154497bef386e5ed0d9a2f6e25a4141759c6846Brian Paul vp.translate[0] = 0.5f * w; 773b154497bef386e5ed0d9a2f6e25a4141759c6846Brian Paul vp.translate[1] = 0.5f * h; 774cfdd1ca69521446b5d937d95e7d8bfb27f6d68ebBrian Paul vp.translate[2] = 0.5f; 77518ec140ef27b6488bea9d54e21b08b0a3afbcafeJosé Fonseca vp.translate[3] = 0.0f; 7767d95efde0a0e13e13c59444703bc47eb13926385Brian cso_set_viewport(cso, &vp); 777d640198b2d52c104c707522e79d53a36f708ccd0Brian } 778d640198b2d52c104c707522e79d53a36f708ccd0Brian 779ae7b7bf1edcf6c492b4dcc162bca28a0090f601eRoland Scheidegger cso_set_vertex_elements(cso, 3, st->velems_util_draw); 780c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák cso_set_stream_outputs(st->cso_context, 0, NULL, 0); 781ae7b7bf1edcf6c492b4dcc162bca28a0090f601eRoland Scheidegger 782753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer /* texture state: */ 783ea6f035ae90895bd4ee3247408eb179dfdf96d22Brian Paul cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, num_sampler_view, sv); 784d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian 785c78ac7fcfa37a78b835fc596441a9fbe1e679e4aBrian Paul /* Compute Gallium window coords (y=0=top) with pixel zoom. 786d054331c4788b0a5f13f4d7a9b497d274d267acbBrian * Recall that these coords are transformed by the current 787d054331c4788b0a5f13f4d7a9b497d274d267acbBrian * vertex shader and viewport transformation. 788d054331c4788b0a5f13f4d7a9b497d274d267acbBrian */ 789c78ac7fcfa37a78b835fc596441a9fbe1e679e4aBrian Paul if (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM) { 790c78ac7fcfa37a78b835fc596441a9fbe1e679e4aBrian Paul y = ctx->DrawBuffer->Height - (int) (y + height * ctx->Pixel.ZoomY); 791c78ac7fcfa37a78b835fc596441a9fbe1e679e4aBrian Paul invertTex = !invertTex; 792c78ac7fcfa37a78b835fc596441a9fbe1e679e4aBrian Paul } 793c78ac7fcfa37a78b835fc596441a9fbe1e679e4aBrian Paul 7946c534b830c6f5427c391c5225c34561141c201baMichal Krol x0 = (GLfloat) x; 795bc4aa83794c6336358793c5f428973fb22184050Brian x1 = x + width * ctx->Pixel.ZoomX; 7966c534b830c6f5427c391c5225c34561141c201baMichal Krol y0 = (GLfloat) y; 797d054331c4788b0a5f13f4d7a9b497d274d267acbBrian y1 = y + height * ctx->Pixel.ZoomY; 79862ef614eb3a9e28c39606657f576e320f158623eBrian Paul 799cfdd1ca69521446b5d937d95e7d8bfb27f6d68ebBrian Paul /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */ 800cfdd1ca69521446b5d937d95e7d8bfb27f6d68ebBrian Paul z = z * 2.0 - 1.0; 801cfdd1ca69521446b5d937d95e7d8bfb27f6d68ebBrian Paul 802fc3d564daeacdbd76b97de2ffc10e15931a18c7aPatrice Mandin draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex, 803ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie normalized ? ((GLfloat) width / sv[0]->texture->width0) : (GLfloat)width, 804ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie normalized ? ((GLfloat) height / sv[0]->texture->height0) : (GLfloat)height); 80562ef614eb3a9e28c39606657f576e320f158623eBrian Paul 806339e7ec6805e6de8794514c0a935081b5d36d38fBrian /* restore state */ 8077d95efde0a0e13e13c59444703bc47eb13926385Brian cso_restore_rasterizer(cso); 8087d95efde0a0e13e13c59444703bc47eb13926385Brian cso_restore_viewport(cso); 809ea6f035ae90895bd4ee3247408eb179dfdf96d22Brian Paul cso_restore_samplers(cso, PIPE_SHADER_FRAGMENT); 810ea6f035ae90895bd4ee3247408eb179dfdf96d22Brian Paul cso_restore_sampler_views(cso, PIPE_SHADER_FRAGMENT); 81165efe807b9067aa07b382e3c4d9cea6222c5fc6bMichel Dänzer cso_restore_fragment_shader(cso); 81265efe807b9067aa07b382e3c4d9cea6222c5fc6bMichel Dänzer cso_restore_vertex_shader(cso); 813d2633af696f2e4ff98f669061e4e222e8643312cMarek Olšák cso_restore_geometry_shader(cso); 814ae7b7bf1edcf6c492b4dcc162bca28a0090f601eRoland Scheidegger cso_restore_vertex_elements(cso); 815d5062fb3a315c46d77d5c954a3e3c14be1907d33Marek Olšák cso_restore_vertex_buffers(cso); 816c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák cso_restore_stream_outputs(cso); 81720c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul if (write_stencil) { 81820c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul cso_restore_depth_stencil_alpha(cso); 81920c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul cso_restore_blend(cso); 82020c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul } 821d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian} 822d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian 823d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian 82481c27dbfb943df8dc5cf65a2654d96fe5d7c1df4Brian Paul/** 82581c27dbfb943df8dc5cf65a2654d96fe5d7c1df4Brian Paul * Software fallback to do glDrawPixels(GL_STENCIL_INDEX) when we 82681c27dbfb943df8dc5cf65a2654d96fe5d7c1df4Brian Paul * can't use a fragment shader to write stencil values. 82781c27dbfb943df8dc5cf65a2654d96fe5d7c1df4Brian Paul */ 828fa1d442879f1279cf510a52a1002367b904d35adBrianstatic void 829f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergdraw_stencil_pixels(struct gl_context *ctx, GLint x, GLint y, 830b7615e5240707b022b81478dde545cec7fb9397fBrian Paul GLsizei width, GLsizei height, GLenum format, GLenum type, 831fa1d442879f1279cf510a52a1002367b904d35adBrian const struct gl_pixelstore_attrib *unpack, 832fa1d442879f1279cf510a52a1002367b904d35adBrian const GLvoid *pixels) 833fa1d442879f1279cf510a52a1002367b904d35adBrian{ 8344781c1f45925031a9e4a5f8ebf80cfd821312e3cBrian Paul struct st_context *st = st_context(ctx); 835fa1d442879f1279cf510a52a1002367b904d35adBrian struct pipe_context *pipe = st->pipe; 836296378b6c8b205048244746e260739448c4ee590Brian Paul struct st_renderbuffer *strb; 83796aca15c9d5b6f03fc9b407f02d6966fffeb4f5dJosé Fonseca enum pipe_transfer_usage usage; 8384617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer struct pipe_transfer *pt; 839fa1d442879f1279cf510a52a1002367b904d35adBrian const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; 840fa1d442879f1279cf510a52a1002367b904d35adBrian ubyte *stmap; 841a0cd2b7029e1ac6699b807baa255e7fd2abe7f54Marek Olšák struct gl_pixelstore_attrib clippedUnpack = *unpack; 84262c69c340e71e97ddeaa757e033b8132399b9438Brian Paul GLubyte *sValues; 84362c69c340e71e97ddeaa757e033b8132399b9438Brian Paul GLuint *zValues; 844a0cd2b7029e1ac6699b807baa255e7fd2abe7f54Marek Olšák 845a0cd2b7029e1ac6699b807baa255e7fd2abe7f54Marek Olšák if (!zoom) { 846a0cd2b7029e1ac6699b807baa255e7fd2abe7f54Marek Olšák if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height, 847a0cd2b7029e1ac6699b807baa255e7fd2abe7f54Marek Olšák &clippedUnpack)) { 848a0cd2b7029e1ac6699b807baa255e7fd2abe7f54Marek Olšák /* totally clipped */ 849a0cd2b7029e1ac6699b807baa255e7fd2abe7f54Marek Olšák return; 850a0cd2b7029e1ac6699b807baa255e7fd2abe7f54Marek Olšák } 851a0cd2b7029e1ac6699b807baa255e7fd2abe7f54Marek Olšák } 852fa1d442879f1279cf510a52a1002367b904d35adBrian 853296378b6c8b205048244746e260739448c4ee590Brian Paul strb = st_renderbuffer(ctx->DrawBuffer-> 854296378b6c8b205048244746e260739448c4ee590Brian Paul Attachment[BUFFER_STENCIL].Renderbuffer); 855b7615e5240707b022b81478dde545cec7fb9397fBrian Paul 856b7615e5240707b022b81478dde545cec7fb9397fBrian Paul if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 857b7615e5240707b022b81478dde545cec7fb9397fBrian Paul y = ctx->DrawBuffer->Height - y - height; 858b7615e5240707b022b81478dde545cec7fb9397fBrian Paul } 859b7615e5240707b022b81478dde545cec7fb9397fBrian Paul 860d765c8ee8c761bb73d634bb274cfc5061892c9a8Brian Paul if (format == GL_STENCIL_INDEX && 861d765c8ee8c761bb73d634bb274cfc5061892c9a8Brian Paul _mesa_is_format_packed_depth_stencil(strb->Base.Format)) { 862d765c8ee8c761bb73d634bb274cfc5061892c9a8Brian Paul /* writing stencil to a combined depth+stencil buffer */ 86396aca15c9d5b6f03fc9b407f02d6966fffeb4f5dJosé Fonseca usage = PIPE_TRANSFER_READ_WRITE; 864d765c8ee8c761bb73d634bb274cfc5061892c9a8Brian Paul } 865d765c8ee8c761bb73d634bb274cfc5061892c9a8Brian Paul else { 86696aca15c9d5b6f03fc9b407f02d6966fffeb4f5dJosé Fonseca usage = PIPE_TRANSFER_WRITE; 867d765c8ee8c761bb73d634bb274cfc5061892c9a8Brian Paul } 868fc3d564daeacdbd76b97de2ffc10e15931a18c7aPatrice Mandin 8693e06803c2c6cf83009708b23d3ebafc0ea3dc525Brian Paul pt = pipe_get_transfer(pipe, strb->texture, 870bf14ab417c6638afd19206e11ee69bdb9fb93d9eBrian Paul strb->rtt_level, strb->rtt_face + strb->rtt_slice, 871bf14ab417c6638afd19206e11ee69bdb9fb93d9eBrian Paul usage, x, y, 872bf14ab417c6638afd19206e11ee69bdb9fb93d9eBrian Paul width, height); 873296378b6c8b205048244746e260739448c4ee590Brian Paul 874287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell stmap = pipe_transfer_map(pipe, pt); 875fa1d442879f1279cf510a52a1002367b904d35adBrian 876a0cd2b7029e1ac6699b807baa255e7fd2abe7f54Marek Olšák pixels = _mesa_map_pbo_source(ctx, &clippedUnpack, pixels); 877f7039fde4f9e1175c3dae534e5b91e22e693124aAlan Hourihane assert(pixels); 878f7039fde4f9e1175c3dae534e5b91e22e693124aAlan Hourihane 87962c69c340e71e97ddeaa757e033b8132399b9438Brian Paul sValues = (GLubyte *) malloc(width * sizeof(GLubyte)); 88062c69c340e71e97ddeaa757e033b8132399b9438Brian Paul zValues = (GLuint *) malloc(width * sizeof(GLuint)); 88162c69c340e71e97ddeaa757e033b8132399b9438Brian Paul 88262c69c340e71e97ddeaa757e033b8132399b9438Brian Paul if (sValues && zValues) { 883fa1d442879f1279cf510a52a1002367b904d35adBrian GLint row; 884fa1d442879f1279cf510a52a1002367b904d35adBrian for (row = 0; row < height; row++) { 885e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák GLfloat *zValuesFloat = (GLfloat*)zValues; 886fa1d442879f1279cf510a52a1002367b904d35adBrian GLenum destType = GL_UNSIGNED_BYTE; 887a0cd2b7029e1ac6699b807baa255e7fd2abe7f54Marek Olšák const GLvoid *source = _mesa_image_address2d(&clippedUnpack, pixels, 888fa1d442879f1279cf510a52a1002367b904d35adBrian width, height, 889b7615e5240707b022b81478dde545cec7fb9397fBrian Paul format, type, 89062c69c340e71e97ddeaa757e033b8132399b9438Brian Paul row, 0); 89162c69c340e71e97ddeaa757e033b8132399b9438Brian Paul _mesa_unpack_stencil_span(ctx, width, destType, sValues, 892a0cd2b7029e1ac6699b807baa255e7fd2abe7f54Marek Olšák type, source, &clippedUnpack, 893fa1d442879f1279cf510a52a1002367b904d35adBrian ctx->_ImageTransferState); 894b7615e5240707b022b81478dde545cec7fb9397fBrian Paul 895b7615e5240707b022b81478dde545cec7fb9397fBrian Paul if (format == GL_DEPTH_STENCIL) { 896e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák GLenum ztype = 897866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie pt->resource->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ? 898e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák GL_FLOAT : GL_UNSIGNED_INT; 899e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák 90062c69c340e71e97ddeaa757e033b8132399b9438Brian Paul _mesa_unpack_depth_span(ctx, width, ztype, zValues, 901a0cd2b7029e1ac6699b807baa255e7fd2abe7f54Marek Olšák (1 << 24) - 1, type, source, 902a0cd2b7029e1ac6699b807baa255e7fd2abe7f54Marek Olšák &clippedUnpack); 903b7615e5240707b022b81478dde545cec7fb9397fBrian Paul } 904b7615e5240707b022b81478dde545cec7fb9397fBrian Paul 905fa1d442879f1279cf510a52a1002367b904d35adBrian if (zoom) { 906b7615e5240707b022b81478dde545cec7fb9397fBrian Paul _mesa_problem(ctx, "Gallium glDrawPixels(GL_STENCIL) with " 907b7615e5240707b022b81478dde545cec7fb9397fBrian Paul "zoom not complete"); 908fa1d442879f1279cf510a52a1002367b904d35adBrian } 909b7615e5240707b022b81478dde545cec7fb9397fBrian Paul 910b7615e5240707b022b81478dde545cec7fb9397fBrian Paul { 911b7615e5240707b022b81478dde545cec7fb9397fBrian Paul GLint spanY; 912b7615e5240707b022b81478dde545cec7fb9397fBrian Paul 913fa1d442879f1279cf510a52a1002367b904d35adBrian if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 914b7615e5240707b022b81478dde545cec7fb9397fBrian Paul spanY = height - row - 1; 915b7615e5240707b022b81478dde545cec7fb9397fBrian Paul } 916b7615e5240707b022b81478dde545cec7fb9397fBrian Paul else { 917b7615e5240707b022b81478dde545cec7fb9397fBrian Paul spanY = row; 918fa1d442879f1279cf510a52a1002367b904d35adBrian } 919fa1d442879f1279cf510a52a1002367b904d35adBrian 920b7615e5240707b022b81478dde545cec7fb9397fBrian Paul /* now pack the stencil (and Z) values in the dest format */ 921287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell switch (pt->resource->format) { 922866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie case PIPE_FORMAT_S8_UINT: 923fa1d442879f1279cf510a52a1002367b904d35adBrian { 92462c69c340e71e97ddeaa757e033b8132399b9438Brian Paul ubyte *dest = stmap + spanY * pt->stride; 92596aca15c9d5b6f03fc9b407f02d6966fffeb4f5dJosé Fonseca assert(usage == PIPE_TRANSFER_WRITE); 92662c69c340e71e97ddeaa757e033b8132399b9438Brian Paul memcpy(dest, sValues, width); 927fa1d442879f1279cf510a52a1002367b904d35adBrian } 928fa1d442879f1279cf510a52a1002367b904d35adBrian break; 929866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie case PIPE_FORMAT_Z24_UNORM_S8_UINT: 930b7615e5240707b022b81478dde545cec7fb9397fBrian Paul if (format == GL_DEPTH_STENCIL) { 93162c69c340e71e97ddeaa757e033b8132399b9438Brian Paul uint *dest = (uint *) (stmap + spanY * pt->stride); 932b7615e5240707b022b81478dde545cec7fb9397fBrian Paul GLint k; 93396aca15c9d5b6f03fc9b407f02d6966fffeb4f5dJosé Fonseca assert(usage == PIPE_TRANSFER_WRITE); 93462c69c340e71e97ddeaa757e033b8132399b9438Brian Paul for (k = 0; k < width; k++) { 935b7615e5240707b022b81478dde545cec7fb9397fBrian Paul dest[k] = zValues[k] | (sValues[k] << 24); 936b7615e5240707b022b81478dde545cec7fb9397fBrian Paul } 937b7615e5240707b022b81478dde545cec7fb9397fBrian Paul } 938b7615e5240707b022b81478dde545cec7fb9397fBrian Paul else { 93962c69c340e71e97ddeaa757e033b8132399b9438Brian Paul uint *dest = (uint *) (stmap + spanY * pt->stride); 940fa1d442879f1279cf510a52a1002367b904d35adBrian GLint k; 94196aca15c9d5b6f03fc9b407f02d6966fffeb4f5dJosé Fonseca assert(usage == PIPE_TRANSFER_READ_WRITE); 94262c69c340e71e97ddeaa757e033b8132399b9438Brian Paul for (k = 0; k < width; k++) { 943b7615e5240707b022b81478dde545cec7fb9397fBrian Paul dest[k] = (dest[k] & 0xffffff) | (sValues[k] << 24); 944fa1d442879f1279cf510a52a1002367b904d35adBrian } 945fa1d442879f1279cf510a52a1002367b904d35adBrian } 946fa1d442879f1279cf510a52a1002367b904d35adBrian break; 947866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie case PIPE_FORMAT_S8_UINT_Z24_UNORM: 948b7615e5240707b022b81478dde545cec7fb9397fBrian Paul if (format == GL_DEPTH_STENCIL) { 94962c69c340e71e97ddeaa757e033b8132399b9438Brian Paul uint *dest = (uint *) (stmap + spanY * pt->stride); 950b7615e5240707b022b81478dde545cec7fb9397fBrian Paul GLint k; 95196aca15c9d5b6f03fc9b407f02d6966fffeb4f5dJosé Fonseca assert(usage == PIPE_TRANSFER_WRITE); 95262c69c340e71e97ddeaa757e033b8132399b9438Brian Paul for (k = 0; k < width; k++) { 9530a4fcabe4451af6472245e2630f8c8834aa9d351José Fonseca dest[k] = (zValues[k] << 8) | (sValues[k] & 0xff); 954b7615e5240707b022b81478dde545cec7fb9397fBrian Paul } 955b7615e5240707b022b81478dde545cec7fb9397fBrian Paul } 956b7615e5240707b022b81478dde545cec7fb9397fBrian Paul else { 95762c69c340e71e97ddeaa757e033b8132399b9438Brian Paul uint *dest = (uint *) (stmap + spanY * pt->stride); 958e0a55dc9dae39384c18dd275081c24b7dce14eebJosé Fonseca GLint k; 95996aca15c9d5b6f03fc9b407f02d6966fffeb4f5dJosé Fonseca assert(usage == PIPE_TRANSFER_READ_WRITE); 96062c69c340e71e97ddeaa757e033b8132399b9438Brian Paul for (k = 0; k < width; k++) { 961b7615e5240707b022b81478dde545cec7fb9397fBrian Paul dest[k] = (dest[k] & 0xffffff00) | (sValues[k] & 0xff); 962e0a55dc9dae39384c18dd275081c24b7dce14eebJosé Fonseca } 963e0a55dc9dae39384c18dd275081c24b7dce14eebJosé Fonseca } 964e0a55dc9dae39384c18dd275081c24b7dce14eebJosé Fonseca break; 965866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 966e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák if (format == GL_DEPTH_STENCIL) { 96762c69c340e71e97ddeaa757e033b8132399b9438Brian Paul uint *dest = (uint *) (stmap + spanY * pt->stride); 968e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák GLfloat *destf = (GLfloat*)dest; 969e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák GLint k; 970e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák assert(usage == PIPE_TRANSFER_WRITE); 97162c69c340e71e97ddeaa757e033b8132399b9438Brian Paul for (k = 0; k < width; k++) { 972e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák destf[k*2] = zValuesFloat[k]; 973e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák dest[k*2+1] = sValues[k] & 0xff; 974e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák } 975e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák } 976e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák else { 97762c69c340e71e97ddeaa757e033b8132399b9438Brian Paul uint *dest = (uint *) (stmap + spanY * pt->stride); 978e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák GLint k; 979e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák assert(usage == PIPE_TRANSFER_READ_WRITE); 98062c69c340e71e97ddeaa757e033b8132399b9438Brian Paul for (k = 0; k < width; k++) { 981e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák dest[k*2+1] = sValues[k] & 0xff; 982e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák } 983e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák } 984e517e5ac7c89b133f341a1075db95e14d0ba23c2Marek Olšák break; 985fa1d442879f1279cf510a52a1002367b904d35adBrian default: 986fa1d442879f1279cf510a52a1002367b904d35adBrian assert(0); 987fa1d442879f1279cf510a52a1002367b904d35adBrian } 988fa1d442879f1279cf510a52a1002367b904d35adBrian } 989fa1d442879f1279cf510a52a1002367b904d35adBrian } 990fa1d442879f1279cf510a52a1002367b904d35adBrian } 99162c69c340e71e97ddeaa757e033b8132399b9438Brian Paul else { 99262c69c340e71e97ddeaa757e033b8132399b9438Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels()"); 99362c69c340e71e97ddeaa757e033b8132399b9438Brian Paul } 99462c69c340e71e97ddeaa757e033b8132399b9438Brian Paul 99562c69c340e71e97ddeaa757e033b8132399b9438Brian Paul free(sValues); 99662c69c340e71e97ddeaa757e033b8132399b9438Brian Paul free(zValues); 997fa1d442879f1279cf510a52a1002367b904d35adBrian 998a0cd2b7029e1ac6699b807baa255e7fd2abe7f54Marek Olšák _mesa_unmap_pbo_source(ctx, &clippedUnpack); 999f7039fde4f9e1175c3dae534e5b91e22e693124aAlan Hourihane 1000fa1d442879f1279cf510a52a1002367b904d35adBrian /* unmap the stencil buffer */ 1001287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_transfer_unmap(pipe, pt); 1002287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe->transfer_destroy(pipe, pt); 1003fa1d442879f1279cf510a52a1002367b904d35adBrian} 1004fa1d442879f1279cf510a52a1002367b904d35adBrian 1005fa1d442879f1279cf510a52a1002367b904d35adBrian 1006d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian/** 10073d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * Get fragment program variant for a glDrawPixels or glCopyPixels 10083d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * command for RGBA data. 10093d203b610045980853d26370ee21fb2ef4aed17eBrian Paul */ 1010aa5ba96d294698809186cc4b59034abbd3076812Brian Paulstatic struct st_fp_variant * 1011aa5ba96d294698809186cc4b59034abbd3076812Brian Paulget_color_fp_variant(struct st_context *st) 10123d203b610045980853d26370ee21fb2ef4aed17eBrian Paul{ 10133d203b610045980853d26370ee21fb2ef4aed17eBrian Paul struct gl_context *ctx = st->ctx; 1014aa5ba96d294698809186cc4b59034abbd3076812Brian Paul struct st_fp_variant_key key; 1015aa5ba96d294698809186cc4b59034abbd3076812Brian Paul struct st_fp_variant *fpv; 10163d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 10173d203b610045980853d26370ee21fb2ef4aed17eBrian Paul memset(&key, 0, sizeof(key)); 10183d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 10193d203b610045980853d26370ee21fb2ef4aed17eBrian Paul key.st = st; 10203d203b610045980853d26370ee21fb2ef4aed17eBrian Paul key.drawpixels = 1; 10213d203b610045980853d26370ee21fb2ef4aed17eBrian Paul key.scaleAndBias = (ctx->Pixel.RedBias != 0.0 || 10223d203b610045980853d26370ee21fb2ef4aed17eBrian Paul ctx->Pixel.RedScale != 1.0 || 10233d203b610045980853d26370ee21fb2ef4aed17eBrian Paul ctx->Pixel.GreenBias != 0.0 || 10243d203b610045980853d26370ee21fb2ef4aed17eBrian Paul ctx->Pixel.GreenScale != 1.0 || 10253d203b610045980853d26370ee21fb2ef4aed17eBrian Paul ctx->Pixel.BlueBias != 0.0 || 10263d203b610045980853d26370ee21fb2ef4aed17eBrian Paul ctx->Pixel.BlueScale != 1.0 || 10273d203b610045980853d26370ee21fb2ef4aed17eBrian Paul ctx->Pixel.AlphaBias != 0.0 || 10283d203b610045980853d26370ee21fb2ef4aed17eBrian Paul ctx->Pixel.AlphaScale != 1.0); 10293d203b610045980853d26370ee21fb2ef4aed17eBrian Paul key.pixelMaps = ctx->Pixel.MapColorFlag; 1030bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák key.clamp_color = st->clamp_frag_color_in_shader && 103103b78ceb50b97611bcaa2d2354ff5b505306b0a1Marek Olšák st->ctx->Color._ClampFragmentColor && 103203b78ceb50b97611bcaa2d2354ff5b505306b0a1Marek Olšák !st->ctx->DrawBuffer->_IntegerColor; 10333d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 1034aa5ba96d294698809186cc4b59034abbd3076812Brian Paul fpv = st_get_fp_variant(st, st->fp, &key); 10353d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 10363d203b610045980853d26370ee21fb2ef4aed17eBrian Paul return fpv; 10373d203b610045980853d26370ee21fb2ef4aed17eBrian Paul} 10383d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 10393d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 10403d203b610045980853d26370ee21fb2ef4aed17eBrian Paul/** 10413d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * Get fragment program variant for a glDrawPixels or glCopyPixels 10423d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * command for depth/stencil data. 10433d203b610045980853d26370ee21fb2ef4aed17eBrian Paul */ 1044aa5ba96d294698809186cc4b59034abbd3076812Brian Paulstatic struct st_fp_variant * 1045aa5ba96d294698809186cc4b59034abbd3076812Brian Paulget_depth_stencil_fp_variant(struct st_context *st, GLboolean write_depth, 10463d203b610045980853d26370ee21fb2ef4aed17eBrian Paul GLboolean write_stencil) 10473d203b610045980853d26370ee21fb2ef4aed17eBrian Paul{ 1048aa5ba96d294698809186cc4b59034abbd3076812Brian Paul struct st_fp_variant_key key; 1049aa5ba96d294698809186cc4b59034abbd3076812Brian Paul struct st_fp_variant *fpv; 10503d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 10513d203b610045980853d26370ee21fb2ef4aed17eBrian Paul memset(&key, 0, sizeof(key)); 10523d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 10533d203b610045980853d26370ee21fb2ef4aed17eBrian Paul key.st = st; 10543d203b610045980853d26370ee21fb2ef4aed17eBrian Paul key.drawpixels = 1; 10553d203b610045980853d26370ee21fb2ef4aed17eBrian Paul key.drawpixels_z = write_depth; 10563d203b610045980853d26370ee21fb2ef4aed17eBrian Paul key.drawpixels_stencil = write_stencil; 10573d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 1058aa5ba96d294698809186cc4b59034abbd3076812Brian Paul fpv = st_get_fp_variant(st, st->fp, &key); 10593d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 10603d203b610045980853d26370ee21fb2ef4aed17eBrian Paul return fpv; 10613d203b610045980853d26370ee21fb2ef4aed17eBrian Paul} 10623d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 10633d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 10643d203b610045980853d26370ee21fb2ef4aed17eBrian Paul/** 1065fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul * Clamp glDrawPixels width and height to the maximum texture size. 1066fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul */ 1067fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paulstatic void 1068fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paulclamp_size(struct pipe_context *pipe, GLsizei *width, GLsizei *height, 1069fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul struct gl_pixelstore_attrib *unpack) 1070fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul{ 1071fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul const unsigned maxSize = 1072fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul 1 << (pipe->screen->get_param(pipe->screen, 1073fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1); 1074fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul 1075fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul if (*width > maxSize) { 1076fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul if (unpack->RowLength == 0) 1077fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul unpack->RowLength = *width; 1078fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul *width = maxSize; 1079fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul } 1080fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul if (*height > maxSize) { 1081fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul *height = maxSize; 1082fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul } 1083fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul} 1084fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul 1085fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul 1086fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul/** 1087d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian * Called via ctx->Driver.DrawPixels() 1088d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian */ 1089d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brianstatic void 1090cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paulst_DrawPixels(struct gl_context *ctx, GLint x, GLint y, 1091cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul GLsizei width, GLsizei height, 1092d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian GLenum format, GLenum type, 1093d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels) 1094d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian{ 1095f4ded0ea5c156a79a78ea62098fa8f9515adb256Brian Paul void *driver_vp, *driver_fp; 10964781c1f45925031a9e4a5f8ebf80cfd821312e3cBrian Paul struct st_context *st = st_context(ctx); 1097a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian const GLfloat *color; 1098ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie struct pipe_context *pipe = st->pipe; 1099ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie GLboolean write_stencil = GL_FALSE, write_depth = GL_FALSE; 1100ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie struct pipe_sampler_view *sv[2]; 1101ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie int num_sampler_view = 1; 1102aa5ba96d294698809186cc4b59034abbd3076812Brian Paul struct st_fp_variant *fpv; 1103fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul struct gl_pixelstore_attrib clippedUnpack; 1104ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie 11057f4786ad29abbbbc4b0ebfcec8114921c1c8f6e3Brian Paul /* Mesa state should be up to date by now */ 11067f4786ad29abbbbc4b0ebfcec8114921c1c8f6e3Brian Paul assert(ctx->NewState == 0x0); 11077f4786ad29abbbbc4b0ebfcec8114921c1c8f6e3Brian Paul 11087f4786ad29abbbbc4b0ebfcec8114921c1c8f6e3Brian Paul st_validate_state(st); 11097f4786ad29abbbbc4b0ebfcec8114921c1c8f6e3Brian Paul 1110fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul /* Limit the size of the glDrawPixels to the max texture size. 1111fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul * Strictly speaking, that's not correct but since we don't handle 1112fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul * larger images yet, this is better than crashing. 1113fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul */ 1114fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul clippedUnpack = *unpack; 1115fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul unpack = &clippedUnpack; 1116fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul clamp_size(st->pipe, &width, &height, &clippedUnpack); 1117fc855ed5d968c6d650df77505540bfbdaa5fb35eBrian Paul 1118ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie if (format == GL_DEPTH_STENCIL) 1119ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie write_stencil = write_depth = GL_TRUE; 1120ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie else if (format == GL_STENCIL_INDEX) 1121ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie write_stencil = GL_TRUE; 1122ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie else if (format == GL_DEPTH_COMPONENT) 1123ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie write_depth = GL_TRUE; 1124ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie 11252df4b6117b27acb4ea46222b47353ffb9f513204Marek Olšák if (write_stencil && 11262df4b6117b27acb4ea46222b47353ffb9f513204Marek Olšák !pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT)) { 11272df4b6117b27acb4ea46222b47353ffb9f513204Marek Olšák /* software fallback */ 11282df4b6117b27acb4ea46222b47353ffb9f513204Marek Olšák draw_stencil_pixels(ctx, x, y, width, height, format, type, 11292df4b6117b27acb4ea46222b47353ffb9f513204Marek Olšák unpack, pixels); 11302df4b6117b27acb4ea46222b47353ffb9f513204Marek Olšák return; 1131fa1d442879f1279cf510a52a1002367b904d35adBrian } 1132fa1d442879f1279cf510a52a1002367b904d35adBrian 11333d203b610045980853d26370ee21fb2ef4aed17eBrian Paul /* 11343d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * Get vertex/fragment shaders 11353d203b610045980853d26370ee21fb2ef4aed17eBrian Paul */ 1136ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie if (write_depth || write_stencil) { 1137aa5ba96d294698809186cc4b59034abbd3076812Brian Paul fpv = get_depth_stencil_fp_variant(st, write_depth, write_stencil); 11383d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 11393d203b610045980853d26370ee21fb2ef4aed17eBrian Paul driver_fp = fpv->driver_shader; 11403d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 114108cfe3ab421491644cf1bebaf47e8bc897e495c5Brian Paul driver_vp = make_passthrough_vertex_shader(st, GL_TRUE); 11423d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 1143a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian color = ctx->Current.RasterColor; 1144d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian } 1145d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian else { 1146aa5ba96d294698809186cc4b59034abbd3076812Brian Paul fpv = get_color_fp_variant(st); 11473d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 11483d203b610045980853d26370ee21fb2ef4aed17eBrian Paul driver_fp = fpv->driver_shader; 11493d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 115008cfe3ab421491644cf1bebaf47e8bc897e495c5Brian Paul driver_vp = make_passthrough_vertex_shader(st, GL_FALSE); 11513d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 1152a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian color = NULL; 1153ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie if (st->pixel_xfer.pixelmap_enabled) { 1154ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie sv[1] = st->pixel_xfer.pixelmap_sampler_view; 1155ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie num_sampler_view++; 1156ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie } 1157d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian } 1158d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian 11593d203b610045980853d26370ee21fb2ef4aed17eBrian Paul /* update fragment program constants */ 11603d203b610045980853d26370ee21fb2ef4aed17eBrian Paul st_upload_constants(st, fpv->parameters, PIPE_SHADER_FRAGMENT); 11613d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 116262ef614eb3a9e28c39606657f576e320f158623eBrian Paul /* draw with textured quad */ 116362ef614eb3a9e28c39606657f576e320f158623eBrian Paul { 1164287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_resource *pt 11654781c1f45925031a9e4a5f8ebf80cfd821312e3cBrian Paul = make_texture(st, width, height, format, type, unpack, pixels); 1166753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (pt) { 1167ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie sv[0] = st_create_texture_sampler_view(st->pipe, pt); 1168ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie 1169ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie if (sv[0]) { 1170ab4d629613d5a7a8a94f3fe3f1acac347f39e2ecMarek Olšák /* Create a second sampler view to read stencil. 1171ab4d629613d5a7a8a94f3fe3f1acac347f39e2ecMarek Olšák * The stencil is written using the shader stencil export 1172ab4d629613d5a7a8a94f3fe3f1acac347f39e2ecMarek Olšák * functionality. */ 1173ab4d629613d5a7a8a94f3fe3f1acac347f39e2ecMarek Olšák if (write_stencil) { 117476db2c121c5436dc37a66d398fcaa9b26478c5ecMarek Olšák enum pipe_format stencil_format = 117576db2c121c5436dc37a66d398fcaa9b26478c5ecMarek Olšák util_format_stencil_only(pt->format); 1176ab4d629613d5a7a8a94f3fe3f1acac347f39e2ecMarek Olšák 117733ca21fc3ca78d9e93d2a750b6da3505346d2b86Morgan Armand sv[1] = st_create_texture_sampler_view_format(st->pipe, pt, 1178cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul stencil_format); 117933ca21fc3ca78d9e93d2a750b6da3505346d2b86Morgan Armand num_sampler_view++; 118033ca21fc3ca78d9e93d2a750b6da3505346d2b86Morgan Armand } 1181b8030c6561e019e079b5be2fe64ec804df4bfa03Michal Krol 1182b8030c6561e019e079b5be2fe64ec804df4bfa03Michal Krol draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2], 1183cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul width, height, 1184cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, 1185b8030c6561e019e079b5be2fe64ec804df4bfa03Michal Krol sv, 1186ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie num_sampler_view, 1187ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie driver_vp, 1188b8030c6561e019e079b5be2fe64ec804df4bfa03Michal Krol driver_fp, 1189ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie color, GL_FALSE, write_depth, write_stencil); 1190ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie pipe_sampler_view_reference(&sv[0], NULL); 1191ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie if (num_sampler_view > 1) 1192ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie pipe_sampler_view_reference(&sv[1], NULL); 1193b8030c6561e019e079b5be2fe64ec804df4bfa03Michal Krol } 1194287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_resource_reference(&pt, NULL); 1195960fe21008eb00bf778f82476e3d00df0a5c34dbBrian } 1196d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian } 1197d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian} 1198d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian 1199d09f4e2007b3043ceb9dd3cb9cfab0dcd0226ba6Brian 1200ccff14de0d6291aa0866ce5d207af416caec69e7Brian 120181c27dbfb943df8dc5cf65a2654d96fe5d7c1df4Brian Paul/** 120281c27dbfb943df8dc5cf65a2654d96fe5d7c1df4Brian Paul * Software fallback for glCopyPixels(GL_STENCIL). 120381c27dbfb943df8dc5cf65a2654d96fe5d7c1df4Brian Paul */ 1204267052c735f25dda7b49ded7b46cc59cb84ecaaaBrianstatic void 1205f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergcopy_stencil_pixels(struct gl_context *ctx, GLint srcx, GLint srcy, 1206bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian GLsizei width, GLsizei height, 1207bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian GLint dstx, GLint dsty) 1208bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian{ 1209f5c810c42f9dfcb660303ea898975b64f060b238Brian Paul struct st_renderbuffer *rbDraw; 121076c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul struct pipe_context *pipe = st_context(ctx)->pipe; 121196aca15c9d5b6f03fc9b407f02d6966fffeb4f5dJosé Fonseca enum pipe_transfer_usage usage; 12124617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer struct pipe_transfer *ptDraw; 121339c06c4336ee44ad2c0ff12705a384dede050beeBrian Paul ubyte *drawMap; 1214bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian ubyte *buffer; 1215bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian int i; 1216bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian 121732f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg buffer = malloc(width * height * sizeof(ubyte)); 1218bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian if (!buffer) { 1219bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels(stencil)"); 1220bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian return; 1221bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian } 1222bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian 122302d12719e356ee9e3348db67ae55ae790dad058fBrian Paul /* Get the dest renderbuffer */ 122402d12719e356ee9e3348db67ae55ae790dad058fBrian Paul rbDraw = st_renderbuffer(ctx->DrawBuffer-> 122502d12719e356ee9e3348db67ae55ae790dad058fBrian Paul Attachment[BUFFER_STENCIL].Renderbuffer); 1226f5c810c42f9dfcb660303ea898975b64f060b238Brian Paul 1227bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian /* this will do stencil pixel transfer ops */ 12283754ebb33dc6bfb3db59f23f0b3690134a71aa15Brian Paul _mesa_readpixels(ctx, srcx, srcy, width, height, 12293754ebb33dc6bfb3db59f23f0b3690134a71aa15Brian Paul GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, 12303754ebb33dc6bfb3db59f23f0b3690134a71aa15Brian Paul &ctx->DefaultPacking, buffer); 1231bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian 123220c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul if (0) { 123320c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul /* debug code: dump stencil values */ 123420c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul GLint row, col; 123520c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul for (row = 0; row < height; row++) { 123620c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul printf("%3d: ", row); 123720c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul for (col = 0; col < width; col++) { 123820c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul printf("%02x ", buffer[col + row * width]); 123920c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul } 124020c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul printf("\n"); 124120c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul } 124220c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul } 124320c2debce82e36166ae0326a3fb94be42d71be4aBrian Paul 1244d765c8ee8c761bb73d634bb274cfc5061892c9a8Brian Paul if (_mesa_is_format_packed_depth_stencil(rbDraw->Base.Format)) 124596aca15c9d5b6f03fc9b407f02d6966fffeb4f5dJosé Fonseca usage = PIPE_TRANSFER_READ_WRITE; 124696aca15c9d5b6f03fc9b407f02d6966fffeb4f5dJosé Fonseca else 124796aca15c9d5b6f03fc9b407f02d6966fffeb4f5dJosé Fonseca usage = PIPE_TRANSFER_WRITE; 12484c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger 1249beb05393c8d92d71ccb0f4af0bcdbe58ae8a9cddBrian Paul if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 1250beb05393c8d92d71ccb0f4af0bcdbe58ae8a9cddBrian Paul dsty = rbDraw->Base.Height - dsty - height; 1251beb05393c8d92d71ccb0f4af0bcdbe58ae8a9cddBrian Paul } 1252fc3d564daeacdbd76b97de2ffc10e15931a18c7aPatrice Mandin 12533e06803c2c6cf83009708b23d3ebafc0ea3dc525Brian Paul ptDraw = pipe_get_transfer(pipe, 1254bf14ab417c6638afd19206e11ee69bdb9fb93d9eBrian Paul rbDraw->texture, 1255bf14ab417c6638afd19206e11ee69bdb9fb93d9eBrian Paul rbDraw->rtt_level, 1256bf14ab417c6638afd19206e11ee69bdb9fb93d9eBrian Paul rbDraw->rtt_face + rbDraw->rtt_slice, 12574c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger usage, dstx, dsty, 12584c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger width, height); 1259296378b6c8b205048244746e260739448c4ee590Brian Paul 1260287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell assert(util_format_get_blockwidth(ptDraw->resource->format) == 1); 1261287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell assert(util_format_get_blockheight(ptDraw->resource->format) == 1); 1262fc3d564daeacdbd76b97de2ffc10e15931a18c7aPatrice Mandin 126339c06c4336ee44ad2c0ff12705a384dede050beeBrian Paul /* map the stencil buffer */ 1264287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell drawMap = pipe_transfer_map(pipe, ptDraw); 126539c06c4336ee44ad2c0ff12705a384dede050beeBrian Paul 1266bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian /* draw */ 1267bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian /* XXX PixelZoom not handled yet */ 1268bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian for (i = 0; i < height; i++) { 1269bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian ubyte *dst; 1270bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian const ubyte *src; 1271bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian int y; 1272bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian 12734617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer y = i; 1274bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian 1275bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 12767c8836e9ef49d938aa55a1c385b95c6371c301f1Michel Dänzer y = height - y - 1; 1277bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian } 1278bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian 12794617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer dst = drawMap + y * ptDraw->stride; 1280bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian src = buffer + i * width; 1281bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian 12825e81d3b85300077a0df1f1d77646a7e939d32a7fBrian Paul _mesa_pack_ubyte_stencil_row(rbDraw->Base.Format, width, src, dst); 1283bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian } 1284bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian 128532f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(buffer); 1286bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian 128739c06c4336ee44ad2c0ff12705a384dede050beeBrian Paul /* unmap the stencil buffer */ 1288287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_transfer_unmap(pipe, ptDraw); 1289287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe->transfer_destroy(pipe, ptDraw); 1290bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian} 1291bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian 1292bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian 12933754ebb33dc6bfb3db59f23f0b3690134a71aa15Brian Paul/** 12943754ebb33dc6bfb3db59f23f0b3690134a71aa15Brian Paul * Return renderbuffer to use for reading color pixels for glCopyPixels 12953754ebb33dc6bfb3db59f23f0b3690134a71aa15Brian Paul */ 12963754ebb33dc6bfb3db59f23f0b3690134a71aa15Brian Paulstatic struct st_renderbuffer * 12973754ebb33dc6bfb3db59f23f0b3690134a71aa15Brian Paulst_get_color_read_renderbuffer(struct gl_context *ctx) 12983754ebb33dc6bfb3db59f23f0b3690134a71aa15Brian Paul{ 12993754ebb33dc6bfb3db59f23f0b3690134a71aa15Brian Paul struct gl_framebuffer *fb = ctx->ReadBuffer; 13003754ebb33dc6bfb3db59f23f0b3690134a71aa15Brian Paul struct st_renderbuffer *strb = 13013754ebb33dc6bfb3db59f23f0b3690134a71aa15Brian Paul st_renderbuffer(fb->_ColorReadBuffer); 13023754ebb33dc6bfb3db59f23f0b3690134a71aa15Brian Paul 13033754ebb33dc6bfb3db59f23f0b3690134a71aa15Brian Paul return strb; 13043754ebb33dc6bfb3db59f23f0b3690134a71aa15Brian Paul} 13053754ebb33dc6bfb3db59f23f0b3690134a71aa15Brian Paul 13063754ebb33dc6bfb3db59f23f0b3690134a71aa15Brian Paul 1307b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul/** Do the src/dest regions overlap? */ 1308b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paulstatic GLboolean 1309b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paulregions_overlap(GLint srcX, GLint srcY, GLint dstX, GLint dstY, 1310b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul GLsizei width, GLsizei height) 1311b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul{ 1312b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul if (srcX + width <= dstX || 1313b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul dstX + width <= srcX || 1314b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul srcY + height <= dstY || 1315b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul dstY + height <= srcY) 1316b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul return GL_FALSE; 1317b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul else 1318b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul return GL_TRUE; 1319b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul} 1320b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul 1321b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul 1322b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul/** 1323b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul * Try to do a glCopyPixels for simple cases with a blit by calling 1324b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul * pipe->resource_copy_region(). 1325b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul * 1326b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul * We can do this when we're copying color pixels (depth/stencil 1327b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul * eventually) with no pixel zoom, no pixel transfer ops, no 1328b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul * per-fragment ops, the src/dest regions don't overlap and the 1329b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul * src/dest pixel formats are the same. 1330b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul */ 1331b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paulstatic GLboolean 1332b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paulblit_copy_pixels(struct gl_context *ctx, GLint srcx, GLint srcy, 1333b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul GLsizei width, GLsizei height, 1334b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul GLint dstx, GLint dsty, GLenum type) 1335b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul{ 1336b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul struct st_context *st = st_context(ctx); 1337b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul struct pipe_context *pipe = st->pipe; 1338b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul struct gl_pixelstore_attrib pack, unpack; 1339b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul GLint readX, readY, readW, readH; 1340b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul 1341b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul if (type == GL_COLOR && 1342b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul ctx->Pixel.ZoomX == 1.0 && 1343b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul ctx->Pixel.ZoomY == 1.0 && 1344b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul ctx->_ImageTransferState == 0x0 && 1345b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul !ctx->Color.BlendEnabled && 1346b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul !ctx->Color.AlphaEnabled && 1347b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul !ctx->Depth.Test && 1348b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul !ctx->Fog.Enabled && 1349b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul !ctx->Stencil.Enabled && 1350b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul !ctx->FragmentProgram.Enabled && 1351b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul !ctx->VertexProgram.Enabled && 1352b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul !ctx->Shader.CurrentFragmentProgram && 135309f14a60867ed902a27307da090e429546d8e838Brian Paul st_fb_orientation(ctx->ReadBuffer) == st_fb_orientation(ctx->DrawBuffer) && 13541b37a41661f791b22f12b8477053a8dff6e33d6dMarek Olšák ctx->DrawBuffer->_NumColorDrawBuffers == 1 && 13551b37a41661f791b22f12b8477053a8dff6e33d6dMarek Olšák !ctx->Query.CondRenderQuery) { 1356b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul struct st_renderbuffer *rbRead, *rbDraw; 1357b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul GLint drawX, drawY; 1358b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul 1359b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul /* 1360b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul * Clip the read region against the src buffer bounds. 1361b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul * We'll still allocate a temporary buffer/texture for the original 1362b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul * src region size but we'll only read the region which is on-screen. 1363b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul * This may mean that we draw garbage pixels into the dest region, but 1364b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul * that's expected. 1365b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul */ 1366b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul readX = srcx; 1367b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul readY = srcy; 1368b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul readW = width; 1369b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul readH = height; 1370b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul pack = ctx->DefaultPacking; 1371b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul if (!_mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack)) 1372b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul return GL_TRUE; /* all done */ 1373b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul 1374b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul /* clip against dest buffer bounds and scissor box */ 1375b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul drawX = dstx + pack.SkipPixels; 1376b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul drawY = dsty + pack.SkipRows; 1377b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul unpack = pack; 1378b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul if (!_mesa_clip_drawpixels(ctx, &drawX, &drawY, &readW, &readH, &unpack)) 1379b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul return GL_TRUE; /* all done */ 1380b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul 1381b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul readX = readX - pack.SkipPixels + unpack.SkipPixels; 1382b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul readY = readY - pack.SkipRows + unpack.SkipRows; 1383b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul 1384b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul rbRead = st_get_color_read_renderbuffer(ctx); 1385b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul rbDraw = st_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]); 1386b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul 1387b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul if ((rbRead != rbDraw || 1388b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul !regions_overlap(readX, readY, drawX, drawY, readW, readH)) && 1389b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul rbRead->Base.Format == rbDraw->Base.Format) { 1390b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul struct pipe_box srcBox; 1391b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul 1392b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul /* flip src/dst position if needed */ 139309f14a60867ed902a27307da090e429546d8e838Brian Paul if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 139409f14a60867ed902a27307da090e429546d8e838Brian Paul /* both buffers will have the same orientation */ 1395b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul readY = ctx->ReadBuffer->Height - readY - readH; 1396b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul drawY = ctx->DrawBuffer->Height - drawY - readH; 139709f14a60867ed902a27307da090e429546d8e838Brian Paul } 1398b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul 1399b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul u_box_2d(readX, readY, readW, readH, &srcBox); 1400b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul 1401b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul pipe->resource_copy_region(pipe, 1402bf14ab417c6638afd19206e11ee69bdb9fb93d9eBrian Paul rbDraw->texture, 1403bf14ab417c6638afd19206e11ee69bdb9fb93d9eBrian Paul rbDraw->rtt_level, drawX, drawY, 0, 1404bf14ab417c6638afd19206e11ee69bdb9fb93d9eBrian Paul rbRead->texture, 1405bf14ab417c6638afd19206e11ee69bdb9fb93d9eBrian Paul rbRead->rtt_level, &srcBox); 1406b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul return GL_TRUE; 1407b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul } 1408b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul } 1409b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul 1410b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul return GL_FALSE; 1411b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul} 1412b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul 1413b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul 1414bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brianstatic void 1415f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergst_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy, 1416267052c735f25dda7b49ded7b46cc59cb84ecaaaBrian GLsizei width, GLsizei height, 1417267052c735f25dda7b49ded7b46cc59cb84ecaaaBrian GLint dstx, GLint dsty, GLenum type) 1418267052c735f25dda7b49ded7b46cc59cb84ecaaaBrian{ 14194781c1f45925031a9e4a5f8ebf80cfd821312e3cBrian Paul struct st_context *st = st_context(ctx); 1420563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian struct pipe_context *pipe = st->pipe; 14216f715dcc219071e574e363a9db4365c9c31ebbd3Brian struct pipe_screen *screen = pipe->screen; 1422563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian struct st_renderbuffer *rbRead; 1423f4ded0ea5c156a79a78ea62098fa8f9515adb256Brian Paul void *driver_vp, *driver_fp; 1424287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_resource *pt; 1425ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie struct pipe_sampler_view *sv[2]; 1426ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie int num_sampler_view = 1; 1427563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian GLfloat *color; 142870126588cf78b8a835dfced2b7ca7f1e05afeb67Brian Paul enum pipe_format srcFormat, texFormat; 1429b60aa251e4fb4dd32db3fe167e078bf0092cb726Brian Paul GLboolean invertTex = GL_FALSE; 14301bfc314596256b039df59f751d59dac82e3ceba1Brian Paul GLint readX, readY, readW, readH; 1431127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger GLuint sample_count; 1432b7e8039132830a2cd7a75691d11750d2ccc0a4e2Brian Paul struct gl_pixelstore_attrib pack = ctx->DefaultPacking; 1433aa5ba96d294698809186cc4b59034abbd3076812Brian Paul struct st_fp_variant *fpv; 1434267052c735f25dda7b49ded7b46cc59cb84ecaaaBrian 1435267052c735f25dda7b49ded7b46cc59cb84ecaaaBrian st_validate_state(st); 1436267052c735f25dda7b49ded7b46cc59cb84ecaaaBrian 1437e99df05cce8a5ecf69fdb634f76898a279456ea4Marek Olšák if (type == GL_DEPTH_STENCIL) { 1438e99df05cce8a5ecf69fdb634f76898a279456ea4Marek Olšák /* XXX make this more efficient */ 1439e99df05cce8a5ecf69fdb634f76898a279456ea4Marek Olšák st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_STENCIL); 1440e99df05cce8a5ecf69fdb634f76898a279456ea4Marek Olšák st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_DEPTH); 1441e99df05cce8a5ecf69fdb634f76898a279456ea4Marek Olšák return; 1442e99df05cce8a5ecf69fdb634f76898a279456ea4Marek Olšák } 1443e99df05cce8a5ecf69fdb634f76898a279456ea4Marek Olšák 1444bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian if (type == GL_STENCIL) { 1445563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian /* can't use texturing to do stencil */ 1446bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty); 1447bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian return; 1448bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian } 1449bdc574c5bd3cf1a493d70863436b773d0a8a73a7Brian 1450b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul if (blit_copy_pixels(ctx, srcx, srcy, width, height, dstx, dsty, type)) 1451b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul return; 1452b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul 1453b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul /* 1454b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul * The subsequent code implements glCopyPixels by copying the source 1455b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul * pixels into a temporary texture that's then applied to a textured quad. 1456b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul * When we draw the textured quad, all the usual per-fragment operations 1457b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul * are handled. 1458b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul */ 1459b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul 1460b736b4a2b5c07b502e15e49ba2a9f10b0c5f3ab7Brian Paul 14613d203b610045980853d26370ee21fb2ef4aed17eBrian Paul /* 14623d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * Get vertex/fragment shaders 14633d203b610045980853d26370ee21fb2ef4aed17eBrian Paul */ 1464563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian if (type == GL_COLOR) { 1465311e40268414649f047ee177ba22a17a2d437843Brian Paul rbRead = st_get_color_read_renderbuffer(ctx); 1466563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian color = NULL; 14673d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 1468aa5ba96d294698809186cc4b59034abbd3076812Brian Paul fpv = get_color_fp_variant(st); 14693d203b610045980853d26370ee21fb2ef4aed17eBrian Paul driver_fp = fpv->driver_shader; 14703d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 147108cfe3ab421491644cf1bebaf47e8bc897e495c5Brian Paul driver_vp = make_passthrough_vertex_shader(st, GL_FALSE); 14723d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 1473ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie if (st->pixel_xfer.pixelmap_enabled) { 1474ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie sv[1] = st->pixel_xfer.pixelmap_sampler_view; 1475ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie num_sampler_view++; 1476ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie } 1477563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian } 1478563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian else { 147970126588cf78b8a835dfced2b7ca7f1e05afeb67Brian Paul assert(type == GL_DEPTH); 148002d12719e356ee9e3348db67ae55ae790dad058fBrian Paul rbRead = st_renderbuffer(ctx->ReadBuffer-> 148102d12719e356ee9e3348db67ae55ae790dad058fBrian Paul Attachment[BUFFER_DEPTH].Renderbuffer); 1482563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; 14833d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 1484aa5ba96d294698809186cc4b59034abbd3076812Brian Paul fpv = get_depth_stencil_fp_variant(st, GL_TRUE, GL_FALSE); 14853d203b610045980853d26370ee21fb2ef4aed17eBrian Paul driver_fp = fpv->driver_shader; 14863d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 148708cfe3ab421491644cf1bebaf47e8bc897e495c5Brian Paul driver_vp = make_passthrough_vertex_shader(st, GL_TRUE); 1488563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian } 1489563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian 14903d203b610045980853d26370ee21fb2ef4aed17eBrian Paul /* update fragment program constants */ 14913d203b610045980853d26370ee21fb2ef4aed17eBrian Paul st_upload_constants(st, fpv->parameters, PIPE_SHADER_FRAGMENT); 14923d203b610045980853d26370ee21fb2ef4aed17eBrian Paul 1493127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger sample_count = rbRead->texture->nr_samples; 1494127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger /* I believe this would be legal, presumably would need to do a resolve 1495127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger for color, and for depth/stencil spec says to just use one of the 1496127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger depth/stencil samples per pixel? Need some transfer clarifications. */ 1497127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger assert(sample_count < 2); 1498127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger 1499296378b6c8b205048244746e260739448c4ee590Brian Paul srcFormat = rbRead->texture->format; 1500a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian 1501cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul if (screen->is_format_supported(screen, srcFormat, st->internal_target, 1502cba65f7e0e0269bbb30efd886dd7868f5e3ccc38Brian Paul sample_count, 1503e968975cb57eb854769292f7c6ff773c64a386c3Marek Olšák PIPE_BIND_SAMPLER_VIEW)) { 150470126588cf78b8a835dfced2b7ca7f1e05afeb67Brian Paul texFormat = srcFormat; 150570126588cf78b8a835dfced2b7ca7f1e05afeb67Brian Paul } 150670126588cf78b8a835dfced2b7ca7f1e05afeb67Brian Paul else { 150770126588cf78b8a835dfced2b7ca7f1e05afeb67Brian Paul /* srcFormat can't be used as a texture format */ 150870126588cf78b8a835dfced2b7ca7f1e05afeb67Brian Paul if (type == GL_DEPTH) { 15092ef1aae1633db98fc52f440ca33b8f2a6f153d45Brian Paul texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT, 15109b5c538726d279c79c1c74047fe19a6caab5321eEmil Velikov GL_NONE, GL_NONE, st->internal_target, 15111a339b6c71ebab6e1a64f05b2e133022d3bbcd15Stéphane Marchesin sample_count, PIPE_BIND_DEPTH_STENCIL); 15121bfc314596256b039df59f751d59dac82e3ceba1Brian Paul assert(texFormat != PIPE_FORMAT_NONE); 151370126588cf78b8a835dfced2b7ca7f1e05afeb67Brian Paul } 151470126588cf78b8a835dfced2b7ca7f1e05afeb67Brian Paul else { 1515e93243cb80ee3ae834a50efe7bacd232d8846305Brian Paul /* default color format */ 15161a339b6c71ebab6e1a64f05b2e133022d3bbcd15Stéphane Marchesin texFormat = st_choose_format(screen, GL_RGBA, 15179b5c538726d279c79c1c74047fe19a6caab5321eEmil Velikov GL_NONE, GL_NONE, st->internal_target, 1518127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger sample_count, PIPE_BIND_SAMPLER_VIEW); 1519e93243cb80ee3ae834a50efe7bacd232d8846305Brian Paul assert(texFormat != PIPE_FORMAT_NONE); 152070126588cf78b8a835dfced2b7ca7f1e05afeb67Brian Paul } 152170126588cf78b8a835dfced2b7ca7f1e05afeb67Brian Paul } 152270126588cf78b8a835dfced2b7ca7f1e05afeb67Brian Paul 15231bfc314596256b039df59f751d59dac82e3ceba1Brian Paul /* Invert src region if needed */ 1524b60aa251e4fb4dd32db3fe167e078bf0092cb726Brian Paul if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1525b60aa251e4fb4dd32db3fe167e078bf0092cb726Brian Paul srcy = ctx->ReadBuffer->Height - srcy - height; 1526b60aa251e4fb4dd32db3fe167e078bf0092cb726Brian Paul invertTex = !invertTex; 1527fc3d564daeacdbd76b97de2ffc10e15931a18c7aPatrice Mandin } 1528fc3d564daeacdbd76b97de2ffc10e15931a18c7aPatrice Mandin 15291bfc314596256b039df59f751d59dac82e3ceba1Brian Paul /* Clip the read region against the src buffer bounds. 15301bfc314596256b039df59f751d59dac82e3ceba1Brian Paul * We'll still allocate a temporary buffer/texture for the original 15311bfc314596256b039df59f751d59dac82e3ceba1Brian Paul * src region size but we'll only read the region which is on-screen. 15321bfc314596256b039df59f751d59dac82e3ceba1Brian Paul * This may mean that we draw garbage pixels into the dest region, but 15331bfc314596256b039df59f751d59dac82e3ceba1Brian Paul * that's expected. 15341bfc314596256b039df59f751d59dac82e3ceba1Brian Paul */ 15351bfc314596256b039df59f751d59dac82e3ceba1Brian Paul readX = srcx; 15361bfc314596256b039df59f751d59dac82e3ceba1Brian Paul readY = srcy; 15371bfc314596256b039df59f751d59dac82e3ceba1Brian Paul readW = width; 15381bfc314596256b039df59f751d59dac82e3ceba1Brian Paul readH = height; 153999ed0b2f9b95a484aa78aeee0277bb669611be5bBrian Paul if (!_mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack)) { 154099ed0b2f9b95a484aa78aeee0277bb669611be5bBrian Paul /* The source region is completely out of bounds. Do nothing. 154199ed0b2f9b95a484aa78aeee0277bb669611be5bBrian Paul * The GL spec says "Results of copies from outside the window, 154299ed0b2f9b95a484aa78aeee0277bb669611be5bBrian Paul * or from regions of the window that are not exposed, are 154399ed0b2f9b95a484aa78aeee0277bb669611be5bBrian Paul * hardware dependent and undefined." 154499ed0b2f9b95a484aa78aeee0277bb669611be5bBrian Paul */ 154599ed0b2f9b95a484aa78aeee0277bb669611be5bBrian Paul return; 154699ed0b2f9b95a484aa78aeee0277bb669611be5bBrian Paul } 154799ed0b2f9b95a484aa78aeee0277bb669611be5bBrian Paul 15481bfc314596256b039df59f751d59dac82e3ceba1Brian Paul readW = MAX2(0, readW); 15491bfc314596256b039df59f751d59dac82e3ceba1Brian Paul readH = MAX2(0, readH); 15501bfc314596256b039df59f751d59dac82e3ceba1Brian Paul 1551a2fe774e0985358a125c5c2e7b89a6b0bc0914d1Brian Paul /* alloc temporary texture */ 1552a2fe774e0985358a125c5c2e7b89a6b0bc0914d1Brian Paul pt = alloc_texture(st, width, height, texFormat); 1553753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer if (!pt) 1554563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian return; 1555a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian 1556ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie sv[0] = st_create_texture_sampler_view(st->pipe, pt); 1557ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie if (!sv[0]) { 1558287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_resource_reference(&pt, NULL); 1559b8030c6561e019e079b5be2fe64ec804df4bfa03Michal Krol return; 1560b8030c6561e019e079b5be2fe64ec804df4bfa03Michal Krol } 1561d44e515fd77d088862c5f19ef9a7aa92b04b5f13Brian 1562b60aa251e4fb4dd32db3fe167e078bf0092cb726Brian Paul /* Make temporary texture which is a copy of the src region. 1563b60aa251e4fb4dd32db3fe167e078bf0092cb726Brian Paul */ 1564a52faa9325db178601811f4bdad6d9747de5f238Brian Paul if (srcFormat == texFormat) { 15654c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger struct pipe_box src_box; 15664c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger u_box_2d(readX, readY, readW, readH, &src_box); 1567de2f25de269894d591b144ac0583a78f5a5e992bBrian Paul /* copy source framebuffer surface into mipmap/texture */ 1568127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger pipe->resource_copy_region(pipe, 1569127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger pt, /* dest tex */ 1570bf14ab417c6638afd19206e11ee69bdb9fb93d9eBrian Paul 0, /* dest lvl */ 1571127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger pack.SkipPixels, pack.SkipRows, 0, /* dest pos */ 1572127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger rbRead->texture, /* src tex */ 1573bf14ab417c6638afd19206e11ee69bdb9fb93d9eBrian Paul rbRead->rtt_level, /* src lvl */ 15744c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger &src_box); 1575b60aa251e4fb4dd32db3fe167e078bf0092cb726Brian Paul 15760007cd7ba0a61fcbcf9c9d19e014408be25ae496Brian } 1577c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell else { 1578296378b6c8b205048244746e260739448c4ee590Brian Paul /* CPU-based fallback/conversion */ 15794617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer struct pipe_transfer *ptRead = 1580d1becefb057ce89eeb93e130cb0d0c63de4be3d8Brian Paul pipe_get_transfer(st->pipe, rbRead->texture, 1581bf14ab417c6638afd19206e11ee69bdb9fb93d9eBrian Paul rbRead->rtt_level, 1582bf14ab417c6638afd19206e11ee69bdb9fb93d9eBrian Paul rbRead->rtt_face + rbRead->rtt_slice, 15834c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger PIPE_TRANSFER_READ, 15844c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger readX, readY, readW, readH); 158571633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer struct pipe_transfer *ptTex; 158671633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer enum pipe_transfer_usage transfer_usage; 1587296378b6c8b205048244746e260739448c4ee590Brian Paul 1588b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell if (ST_DEBUG & DEBUG_FALLBACK) 1589b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell debug_printf("%s: fallback processing\n", __FUNCTION__); 1590b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell 15910bed834be4a174d20b31a6cbcf066774bf749929Michal Krol if (type == GL_DEPTH && util_format_is_depth_and_stencil(pt->format)) 159271633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer transfer_usage = PIPE_TRANSFER_READ_WRITE; 159371633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer else 159471633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer transfer_usage = PIPE_TRANSFER_WRITE; 159571633abafc935c25da9731bab48c228ceb9b4097Michel Dänzer 15964c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger ptTex = pipe_get_transfer(st->pipe, pt, 0, 0, transfer_usage, 15974c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger 0, 0, width, height); 15980007cd7ba0a61fcbcf9c9d19e014408be25ae496Brian 15991bfc314596256b039df59f751d59dac82e3ceba1Brian Paul /* copy image from ptRead surface to ptTex surface */ 1600c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell if (type == GL_COLOR) { 1601c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell /* alternate path using get/put_tile() */ 160232f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); 16039d380f487a4f2628594821a4fed5fe587ce52031Brian Paul enum pipe_format readFormat, drawFormat; 16049d380f487a4f2628594821a4fed5fe587ce52031Brian Paul readFormat = util_format_linear(rbRead->texture->format); 16059d380f487a4f2628594821a4fed5fe587ce52031Brian Paul drawFormat = util_format_linear(pt->format); 1606d1becefb057ce89eeb93e130cb0d0c63de4be3d8Brian Paul pipe_get_tile_rgba_format(pipe, ptRead, 0, 0, readW, readH, 16079d380f487a4f2628594821a4fed5fe587ce52031Brian Paul readFormat, buf); 16089d380f487a4f2628594821a4fed5fe587ce52031Brian Paul pipe_put_tile_rgba_format(pipe, ptTex, pack.SkipPixels, pack.SkipRows, 16099d380f487a4f2628594821a4fed5fe587ce52031Brian Paul readW, readH, drawFormat, buf); 161032f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(buf); 1611c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell } 1612c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell else { 1613c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell /* GL_DEPTH */ 161432f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint)); 1615d1becefb057ce89eeb93e130cb0d0c63de4be3d8Brian Paul pipe_get_tile_z(pipe, ptRead, 0, 0, readW, readH, buf); 1616182c42c8da6edfa66819eef02f4dea310c1f68d7Brian Paul pipe_put_tile_z(pipe, ptTex, pack.SkipPixels, pack.SkipRows, 1617ef92fe85de114cb50ca4b3070d0594aade54526cBrian Paul readW, readH, buf); 161832f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(buf); 1619c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell } 1620a2c8b0e861e7c84d927b636663ac39f8cdc504a3Brian 1621287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe->transfer_destroy(pipe, ptRead); 1622287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe->transfer_destroy(pipe, ptTex); 16234617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer } 1624d0279fc4b38c72356a341173317bcd45d9093f45Michel Dänzer 16251bfc314596256b039df59f751d59dac82e3ceba1Brian Paul /* OK, the texture 'pt' contains the src image/pixels. Now draw a 16261bfc314596256b039df59f751d59dac82e3ceba1Brian Paul * textured quad with that texture. 16271bfc314596256b039df59f751d59dac82e3ceba1Brian Paul */ 1628563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2], 1629563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, 1630ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie sv, 1631ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie num_sampler_view, 163207fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell driver_vp, 1633f4ded0ea5c156a79a78ea62098fa8f9515adb256Brian Paul driver_fp, 1634ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie color, invertTex, GL_FALSE, GL_FALSE); 1635563584a4ee853c45b7a4b60c68ac8dea4d92942dBrian 1636287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_resource_reference(&pt, NULL); 1637ef8bb7ada98f1ddc8e2554a7336af5d669cb1290Dave Airlie pipe_sampler_view_reference(&sv[0], NULL); 1638267052c735f25dda7b49ded7b46cc59cb84ecaaaBrian} 1639267052c735f25dda7b49ded7b46cc59cb84ecaaaBrian 1640267052c735f25dda7b49ded7b46cc59cb84ecaaaBrian 1641498c9e9782186a572885ff9927114706c3d93a22Brian 1642498c9e9782186a572885ff9927114706c3d93a22Brianvoid st_init_drawpixels_functions(struct dd_function_table *functions) 1643498c9e9782186a572885ff9927114706c3d93a22Brian{ 1644498c9e9782186a572885ff9927114706c3d93a22Brian functions->DrawPixels = st_DrawPixels; 1645267052c735f25dda7b49ded7b46cc59cb84ecaaaBrian functions->CopyPixels = st_CopyPixels; 1646498c9e9782186a572885ff9927114706c3d93a22Brian} 16475c431c22227fdc552b34a5feabf1d339dcfe9848Brian Paul 16485c431c22227fdc552b34a5feabf1d339dcfe9848Brian Paul 16495c431c22227fdc552b34a5feabf1d339dcfe9848Brian Paulvoid 16505c431c22227fdc552b34a5feabf1d339dcfe9848Brian Paulst_destroy_drawpix(struct st_context *st) 16515c431c22227fdc552b34a5feabf1d339dcfe9848Brian Paul{ 165261a467e515c31eb6b97b039bc3f97dbe6eafa7cbBrian Paul GLuint i; 165361a467e515c31eb6b97b039bc3f97dbe6eafa7cbBrian Paul 165461a467e515c31eb6b97b039bc3f97dbe6eafa7cbBrian Paul for (i = 0; i < Elements(st->drawpix.shaders); i++) { 165561a467e515c31eb6b97b039bc3f97dbe6eafa7cbBrian Paul if (st->drawpix.shaders[i]) 16563d203b610045980853d26370ee21fb2ef4aed17eBrian Paul _mesa_reference_fragprog(st->ctx, &st->drawpix.shaders[i], NULL); 165761a467e515c31eb6b97b039bc3f97dbe6eafa7cbBrian Paul } 165861a467e515c31eb6b97b039bc3f97dbe6eafa7cbBrian Paul 16595c431c22227fdc552b34a5feabf1d339dcfe9848Brian Paul st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL); 166046c7cd665c9bc93e7254771b16b010fb10ce3707Brian Paul if (st->drawpix.vert_shaders[0]) 1661245edfb0058fdb22ab31a77b18fb045be4aad178Morgan Armand cso_delete_vertex_shader(st->cso_context, st->drawpix.vert_shaders[0]); 166246c7cd665c9bc93e7254771b16b010fb10ce3707Brian Paul if (st->drawpix.vert_shaders[1]) 1663245edfb0058fdb22ab31a77b18fb045be4aad178Morgan Armand cso_delete_vertex_shader(st->cso_context, st->drawpix.vert_shaders[1]); 16645c431c22227fdc552b34a5feabf1d339dcfe9848Brian Paul} 166514a92b26ff76550c5010ddf8bcbf5226dae5183fChia-I Wu 166614a92b26ff76550c5010ddf8bcbf5226dae5183fChia-I Wu#endif /* FEATURE_drawpix */ 1667