st_cb_drawpixels.c revision b69dad1683f092e3ce9d0f3f8fb1bdf96bdff0c7
12861e737e84e4884109b9526ac645194ba892a74Michal Krol/************************************************************************** 22861e737e84e4884109b9526ac645194ba892a74Michal Krol * 3942ee025908a95afc57990c57d6754ca1a626b04Brian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 42861e737e84e4884109b9526ac645194ba892a74Michal Krol * All Rights Reserved. 5942ee025908a95afc57990c57d6754ca1a626b04Brian * 62861e737e84e4884109b9526ac645194ba892a74Michal Krol * Permission is hereby granted, free of charge, to any person obtaining a 72861e737e84e4884109b9526ac645194ba892a74Michal Krol * copy of this software and associated documentation files (the 82861e737e84e4884109b9526ac645194ba892a74Michal Krol * "Software"), to deal in the Software without restriction, including 92861e737e84e4884109b9526ac645194ba892a74Michal Krol * without limitation the rights to use, copy, modify, merge, publish, 102861e737e84e4884109b9526ac645194ba892a74Michal Krol * distribute, sub license, and/or sell copies of the Software, and to 112861e737e84e4884109b9526ac645194ba892a74Michal Krol * permit persons to whom the Software is furnished to do so, subject to 122861e737e84e4884109b9526ac645194ba892a74Michal Krol * the following conditions: 132861e737e84e4884109b9526ac645194ba892a74Michal Krol * 142861e737e84e4884109b9526ac645194ba892a74Michal Krol * The above copyright notice and this permission notice (including the 152861e737e84e4884109b9526ac645194ba892a74Michal Krol * next paragraph) shall be included in all copies or substantial portions 162861e737e84e4884109b9526ac645194ba892a74Michal Krol * of the Software. 172861e737e84e4884109b9526ac645194ba892a74Michal Krol * 182861e737e84e4884109b9526ac645194ba892a74Michal Krol * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 192861e737e84e4884109b9526ac645194ba892a74Michal Krol * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 202861e737e84e4884109b9526ac645194ba892a74Michal Krol * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 212861e737e84e4884109b9526ac645194ba892a74Michal Krol * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 222861e737e84e4884109b9526ac645194ba892a74Michal Krol * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 232861e737e84e4884109b9526ac645194ba892a74Michal Krol * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 242861e737e84e4884109b9526ac645194ba892a74Michal Krol * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 252861e737e84e4884109b9526ac645194ba892a74Michal Krol * 262861e737e84e4884109b9526ac645194ba892a74Michal Krol **************************************************************************/ 272861e737e84e4884109b9526ac645194ba892a74Michal Krol 282861e737e84e4884109b9526ac645194ba892a74Michal Krol /* 292861e737e84e4884109b9526ac645194ba892a74Michal Krol * Authors: 302861e737e84e4884109b9526ac645194ba892a74Michal Krol * Brian Paul 312861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 32101d1a658a614d1e2ec02b1e697f6161291af653José Fonseca 33101d1a658a614d1e2ec02b1e697f6161291af653José Fonseca#include "main/imports.h" 34101d1a658a614d1e2ec02b1e697f6161291af653José Fonseca#include "main/image.h" 350560d81ce94d27f2162d77d981468cea1b2bbd8aBrian#include "main/bufferobj.h" 36b26aae67f5fe4194b48a5d3ddf704797b804b58cBrian#include "main/format_pack.h" 370560d81ce94d27f2162d77d981468cea1b2bbd8aBrian#include "main/macros.h" 380560d81ce94d27f2162d77d981468cea1b2bbd8aBrian#include "main/mfeatures.h" 392861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "main/mtypes.h" 402861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "main/pack.h" 41942ee025908a95afc57990c57d6754ca1a626b04Brian#include "main/pbo.h" 42942ee025908a95afc57990c57d6754ca1a626b04Brian#include "main/readpix.h" 43765f1a12c6256282fe175ec92a0d01b45e4322c7Brian Paul#include "main/texformat.h" 44765f1a12c6256282fe175ec92a0d01b45e4322c7Brian Paul#include "main/teximage.h" 45122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul#include "main/texstore.h" 46765f1a12c6256282fe175ec92a0d01b45e4322c7Brian Paul#include "program/program.h" 47765f1a12c6256282fe175ec92a0d01b45e4322c7Brian Paul#include "program/prog_print.h" 482861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "program/prog_instruction.h" 4921841f0ae5ca9b55ee23ecaa3513e91b6752aa16Brian Paul 502861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "st_atom.h" 512861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "st_atom_constbuf.h" 522861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "st_cb_drawpixels.h" 532861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "st_cb_readpixels.h" 542861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "st_cb_fbo.h" 552861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "st_context.h" 565b2f8dc01300058d43d8043aa897722f39657e93Brian Paul#include "st_debug.h" 575b2f8dc01300058d43d8043aa897722f39657e93Brian Paul#include "st_format.h" 585b2f8dc01300058d43d8043aa897722f39657e93Brian Paul#include "st_program.h" 595b2f8dc01300058d43d8043aa897722f39657e93Brian Paul#include "st_texture.h" 605b2f8dc01300058d43d8043aa897722f39657e93Brian Paul 615b2f8dc01300058d43d8043aa897722f39657e93Brian Paul#include "pipe/p_context.h" 625b2f8dc01300058d43d8043aa897722f39657e93Brian Paul#include "pipe/p_defines.h" 635b2f8dc01300058d43d8043aa897722f39657e93Brian Paul#include "tgsi/tgsi_ureg.h" 645b2f8dc01300058d43d8043aa897722f39657e93Brian Paul#include "util/u_draw_quad.h" 65dd528f0ec18cfbd6f0a5b23b8cb46a97b96ab965Brian Paul#include "util/u_format.h" 66dd528f0ec18cfbd6f0a5b23b8cb46a97b96ab965Brian Paul#include "util/u_inlines.h" 67dd528f0ec18cfbd6f0a5b23b8cb46a97b96ab965Brian Paul#include "util/u_math.h" 68dd528f0ec18cfbd6f0a5b23b8cb46a97b96ab965Brian Paul#include "util/u_tile.h" 69dd528f0ec18cfbd6f0a5b23b8cb46a97b96ab965Brian Paul#include "util/u_upload_mgr.h" 70dd528f0ec18cfbd6f0a5b23b8cb46a97b96ab965Brian Paul#include "cso_cache/cso_context.h" 712861e737e84e4884109b9526ac645194ba892a74Michal Krol 722861e737e84e4884109b9526ac645194ba892a74Michal Krol 732861e737e84e4884109b9526ac645194ba892a74Michal Krol#if FEATURE_drawpix 742861e737e84e4884109b9526ac645194ba892a74Michal Krol 752861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 76af3d9dba562813ffed71691bffd7faf6665c4487Brian Paul * Check if the given program is: 77af3d9dba562813ffed71691bffd7faf6665c4487Brian Paul * 0: MOVE result.color, fragment.color; 78af3d9dba562813ffed71691bffd7faf6665c4487Brian Paul * 1: END; 792861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 80af3d9dba562813ffed71691bffd7faf6665c4487Brian Paulstatic GLboolean 812861e737e84e4884109b9526ac645194ba892a74Michal Krolis_passthrough_program(const struct gl_fragment_program *prog) 82df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian{ 83df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian if (prog->Base.NumInstructions == 2) { 842861e737e84e4884109b9526ac645194ba892a74Michal Krol const struct prog_instruction *inst = prog->Base.Instructions; 852861e737e84e4884109b9526ac645194ba892a74Michal Krol if (inst[0].Opcode == OPCODE_MOV && 862861e737e84e4884109b9526ac645194ba892a74Michal Krol inst[1].Opcode == OPCODE_END && 872861e737e84e4884109b9526ac645194ba892a74Michal Krol inst[0].DstReg.File == PROGRAM_OUTPUT && 882861e737e84e4884109b9526ac645194ba892a74Michal Krol inst[0].DstReg.Index == FRAG_RESULT_COLOR && 89b26aae67f5fe4194b48a5d3ddf704797b804b58cBrian inst[0].DstReg.WriteMask == WRITEMASK_XYZW && 902861e737e84e4884109b9526ac645194ba892a74Michal Krol inst[0].SrcReg[0].File == PROGRAM_INPUT && 912861e737e84e4884109b9526ac645194ba892a74Michal Krol inst[0].SrcReg[0].Index == FRAG_ATTRIB_COL0 && 922861e737e84e4884109b9526ac645194ba892a74Michal Krol inst[0].SrcReg[0].Swizzle == SWIZZLE_XYZW) { 932861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 94df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian } 95df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian } 962861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 97b26aae67f5fe4194b48a5d3ddf704797b804b58cBrian} 982861e737e84e4884109b9526ac645194ba892a74Michal Krol 997f752fed993e5e9423abac200dd59141edbada56Dave Airlie 100b26aae67f5fe4194b48a5d3ddf704797b804b58cBrian/** 10163d683091fe3a9600b65ae7ef3b554168b805406Brian Paul * Returns a fragment program which implements the current pixel transfer ops. 1027f752fed993e5e9423abac200dd59141edbada56Dave Airlie */ 1037f752fed993e5e9423abac200dd59141edbada56Dave Airliestatic struct gl_fragment_program * 104b7eea9a1ce9f3a28b74d77db19dcd859b6638a41Brian Paulget_glsl_pixel_transfer_program(struct st_context *st, 1057f752fed993e5e9423abac200dd59141edbada56Dave Airlie struct st_fragment_program *orig) 10663d683091fe3a9600b65ae7ef3b554168b805406Brian Paul{ 1077f752fed993e5e9423abac200dd59141edbada56Dave Airlie int pixelMaps = 0, scaleAndBias = 0; 1082861e737e84e4884109b9526ac645194ba892a74Michal Krol struct gl_context *ctx = st->ctx; 1092861e737e84e4884109b9526ac645194ba892a74Michal Krol struct st_fragment_program *fp = (struct st_fragment_program *) 1102861e737e84e4884109b9526ac645194ba892a74Michal Krol ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); 1112861e737e84e4884109b9526ac645194ba892a74Michal Krol 11221841f0ae5ca9b55ee23ecaa3513e91b6752aa16Brian Paul if (!fp) 11321841f0ae5ca9b55ee23ecaa3513e91b6752aa16Brian Paul return NULL; 11421841f0ae5ca9b55ee23ecaa3513e91b6752aa16Brian Paul 11521841f0ae5ca9b55ee23ecaa3513e91b6752aa16Brian Paul if (ctx->Pixel.RedBias != 0.0 || ctx->Pixel.RedScale != 1.0 || 11621841f0ae5ca9b55ee23ecaa3513e91b6752aa16Brian Paul ctx->Pixel.GreenBias != 0.0 || ctx->Pixel.GreenScale != 1.0 || 11793da673904d4c520d3fbd2210e53777bf1598ac6Roland Scheidegger ctx->Pixel.BlueBias != 0.0 || ctx->Pixel.BlueScale != 1.0 || 118df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian ctx->Pixel.AlphaBias != 0.0 || ctx->Pixel.AlphaScale != 1.0) { 1191631a9513d32ddcc5467225ad25d0e7a154af895Brian scaleAndBias = 1; 12021841f0ae5ca9b55ee23ecaa3513e91b6752aa16Brian Paul } 12193da673904d4c520d3fbd2210e53777bf1598ac6Roland Scheidegger 122df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian pixelMaps = ctx->Pixel.MapColorFlag; 1231631a9513d32ddcc5467225ad25d0e7a154af895Brian 12421841f0ae5ca9b55ee23ecaa3513e91b6752aa16Brian Paul if (pixelMaps) { 12563d683091fe3a9600b65ae7ef3b554168b805406Brian Paul /* create the colormap/texture now if not already done */ 1267f752fed993e5e9423abac200dd59141edbada56Dave Airlie if (!st->pixel_xfer.pixelmap_texture) { 1277f752fed993e5e9423abac200dd59141edbada56Dave Airlie st->pixel_xfer.pixelmap_texture = st_create_color_map_texture(ctx); 12863d683091fe3a9600b65ae7ef3b554168b805406Brian Paul st->pixel_xfer.pixelmap_sampler_view = 12963d683091fe3a9600b65ae7ef3b554168b805406Brian Paul st_create_texture_sampler_view(st->pipe, 13063d683091fe3a9600b65ae7ef3b554168b805406Brian Paul st->pixel_xfer.pixelmap_texture); 13163d683091fe3a9600b65ae7ef3b554168b805406Brian Paul } 1327f752fed993e5e9423abac200dd59141edbada56Dave Airlie } 1337f752fed993e5e9423abac200dd59141edbada56Dave Airlie 13421841f0ae5ca9b55ee23ecaa3513e91b6752aa16Brian Paul get_pixel_transfer_visitor(fp, orig->glsl_to_tgsi, 13521841f0ae5ca9b55ee23ecaa3513e91b6752aa16Brian Paul scaleAndBias, pixelMaps); 13621841f0ae5ca9b55ee23ecaa3513e91b6752aa16Brian Paul 13721841f0ae5ca9b55ee23ecaa3513e91b6752aa16Brian Paul return &fp->Base; 1384b654d41da08b3b5475144c027e97a3ae7ab5696Brian} 1394b654d41da08b3b5475144c027e97a3ae7ab5696Brian 140d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle 1414b654d41da08b3b5475144c027e97a3ae7ab5696Brian/** 1424b654d41da08b3b5475144c027e97a3ae7ab5696Brian * Make fragment shader for glDraw/CopyPixels. This shader is made 1434b654d41da08b3b5475144c027e97a3ae7ab5696Brian * by combining the pixel transfer shader with the user-defined shader. 1444b654d41da08b3b5475144c027e97a3ae7ab5696Brian * \param fpIn the current/incoming fragment program 1454b654d41da08b3b5475144c027e97a3ae7ab5696Brian * \param fpOut returns the combined fragment program 1464b654d41da08b3b5475144c027e97a3ae7ab5696Brian */ 14757e222d6e5ef5744491d093475e1136aedf81810Brian Paulvoid 14857e222d6e5ef5744491d093475e1136aedf81810Brian Paulst_make_drawpix_fragment_program(struct st_context *st, 14957e222d6e5ef5744491d093475e1136aedf81810Brian Paul struct gl_fragment_program *fpIn, 1504b654d41da08b3b5475144c027e97a3ae7ab5696Brian struct gl_fragment_program **fpOut) 1514b654d41da08b3b5475144c027e97a3ae7ab5696Brian{ 1524b654d41da08b3b5475144c027e97a3ae7ab5696Brian struct gl_program *newProg; 1534b654d41da08b3b5475144c027e97a3ae7ab5696Brian struct st_fragment_program *stfp = (struct st_fragment_program *) fpIn; 15457e222d6e5ef5744491d093475e1136aedf81810Brian Paul 15557e222d6e5ef5744491d093475e1136aedf81810Brian Paul if (is_passthrough_program(fpIn)) { 15657e222d6e5ef5744491d093475e1136aedf81810Brian Paul newProg = (struct gl_program *) _mesa_clone_fragment_program(st->ctx, 1574b654d41da08b3b5475144c027e97a3ae7ab5696Brian &st->pixel_xfer.program->Base); 1584b654d41da08b3b5475144c027e97a3ae7ab5696Brian } 1594b654d41da08b3b5475144c027e97a3ae7ab5696Brian else if (stfp->glsl_to_tgsi != NULL) { 1604b654d41da08b3b5475144c027e97a3ae7ab5696Brian newProg = (struct gl_program *) get_glsl_pixel_transfer_program(st, stfp); 1614b654d41da08b3b5475144c027e97a3ae7ab5696Brian } 1624b654d41da08b3b5475144c027e97a3ae7ab5696Brian else { 1634b654d41da08b3b5475144c027e97a3ae7ab5696Brian#if 0 1644b654d41da08b3b5475144c027e97a3ae7ab5696Brian /* debug */ 1654b654d41da08b3b5475144c027e97a3ae7ab5696Brian printf("Base program:\n"); 1664b654d41da08b3b5475144c027e97a3ae7ab5696Brian _mesa_print_program(&fpIn->Base); 1674b654d41da08b3b5475144c027e97a3ae7ab5696Brian printf("DrawPix program:\n"); 1684b654d41da08b3b5475144c027e97a3ae7ab5696Brian _mesa_print_program(&st->pixel_xfer.program->Base.Base); 1694b654d41da08b3b5475144c027e97a3ae7ab5696Brian#endif 1704b654d41da08b3b5475144c027e97a3ae7ab5696Brian newProg = _mesa_combine_programs(st->ctx, 1714b654d41da08b3b5475144c027e97a3ae7ab5696Brian &st->pixel_xfer.program->Base.Base, 1724b654d41da08b3b5475144c027e97a3ae7ab5696Brian &fpIn->Base); 17321841f0ae5ca9b55ee23ecaa3513e91b6752aa16Brian Paul } 17421841f0ae5ca9b55ee23ecaa3513e91b6752aa16Brian Paul 17521841f0ae5ca9b55ee23ecaa3513e91b6752aa16Brian Paul#if 0 1762861e737e84e4884109b9526ac645194ba892a74Michal Krol /* debug */ 1772861e737e84e4884109b9526ac645194ba892a74Michal Krol printf("Combined DrawPixels program:\n"); 1782861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_print_program(newProg); 1792861e737e84e4884109b9526ac645194ba892a74Michal Krol printf("InputsRead: 0x%x\n", newProg->InputsRead); 1802861e737e84e4884109b9526ac645194ba892a74Michal Krol printf("OutputsWritten: 0x%x\n", newProg->OutputsWritten); 1812861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_print_parameter_list(newProg->Parameters); 1822861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif 1832861e737e84e4884109b9526ac645194ba892a74Michal Krol 1842861e737e84e4884109b9526ac645194ba892a74Michal Krol *fpOut = (struct gl_fragment_program *) newProg; 1852861e737e84e4884109b9526ac645194ba892a74Michal Krol} 1862861e737e84e4884109b9526ac645194ba892a74Michal Krol 1872861e737e84e4884109b9526ac645194ba892a74Michal Krol 1882861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 1892861e737e84e4884109b9526ac645194ba892a74Michal Krol * Create fragment program that does a TEX() instruction to get a Z and/or 1902861e737e84e4884109b9526ac645194ba892a74Michal Krol * stencil value value, then writes to FRAG_RESULT_DEPTH/FRAG_RESULT_STENCIL. 1912861e737e84e4884109b9526ac645194ba892a74Michal Krol * Used for glDrawPixels(GL_DEPTH_COMPONENT / GL_STENCIL_INDEX). 1922861e737e84e4884109b9526ac645194ba892a74Michal Krol * Pass fragment color through as-is. 1932861e737e84e4884109b9526ac645194ba892a74Michal Krol * \return pointer to the gl_fragment program 1942861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 1952861e737e84e4884109b9526ac645194ba892a74Michal Krolstruct gl_fragment_program * 1962861e737e84e4884109b9526ac645194ba892a74Michal Krolst_make_drawpix_z_stencil_program(struct st_context *st, 1972861e737e84e4884109b9526ac645194ba892a74Michal Krol GLboolean write_depth, 1982861e737e84e4884109b9526ac645194ba892a74Michal Krol GLboolean write_stencil) 1992861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 2002861e737e84e4884109b9526ac645194ba892a74Michal Krol struct gl_context *ctx = st->ctx; 2012861e737e84e4884109b9526ac645194ba892a74Michal Krol struct gl_program *p; 2022861e737e84e4884109b9526ac645194ba892a74Michal Krol struct gl_fragment_program *fp; 2032861e737e84e4884109b9526ac645194ba892a74Michal Krol GLuint ic = 0; 2042861e737e84e4884109b9526ac645194ba892a74Michal Krol const GLuint shaderIndex = write_depth * 2 + write_stencil; 2052861e737e84e4884109b9526ac645194ba892a74Michal Krol 2062861e737e84e4884109b9526ac645194ba892a74Michal Krol assert(shaderIndex < Elements(st->drawpix.shaders)); 2072861e737e84e4884109b9526ac645194ba892a74Michal Krol 2082861e737e84e4884109b9526ac645194ba892a74Michal Krol if (st->drawpix.shaders[shaderIndex]) { 2092861e737e84e4884109b9526ac645194ba892a74Michal Krol /* already have the proper shader */ 2102861e737e84e4884109b9526ac645194ba892a74Michal Krol return st->drawpix.shaders[shaderIndex]; 2112861e737e84e4884109b9526ac645194ba892a74Michal Krol } 2122861e737e84e4884109b9526ac645194ba892a74Michal Krol 2132861e737e84e4884109b9526ac645194ba892a74Michal Krol /* 2142861e737e84e4884109b9526ac645194ba892a74Michal Krol * Create shader now 2152861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 2162861e737e84e4884109b9526ac645194ba892a74Michal Krol p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); 2172861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!p) 2182861e737e84e4884109b9526ac645194ba892a74Michal Krol return NULL; 2192861e737e84e4884109b9526ac645194ba892a74Michal Krol 2202861e737e84e4884109b9526ac645194ba892a74Michal Krol p->NumInstructions = write_depth ? 2 : 1; 2212861e737e84e4884109b9526ac645194ba892a74Michal Krol p->NumInstructions += write_stencil ? 1 : 0; 2222861e737e84e4884109b9526ac645194ba892a74Michal Krol 2232861e737e84e4884109b9526ac645194ba892a74Michal Krol p->Instructions = _mesa_alloc_instructions(p->NumInstructions); 2242861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!p->Instructions) { 2252861e737e84e4884109b9526ac645194ba892a74Michal Krol ctx->Driver.DeleteProgram(ctx, p); 2262861e737e84e4884109b9526ac645194ba892a74Michal Krol return NULL; 2272861e737e84e4884109b9526ac645194ba892a74Michal Krol } 2282861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_init_instructions(p->Instructions, p->NumInstructions); 2292861e737e84e4884109b9526ac645194ba892a74Michal Krol 2302861e737e84e4884109b9526ac645194ba892a74Michal Krol if (write_depth) { 2312861e737e84e4884109b9526ac645194ba892a74Michal Krol /* TEX result.depth, fragment.texcoord[0], texture[0], 2D; */ 2322861e737e84e4884109b9526ac645194ba892a74Michal Krol p->Instructions[ic].Opcode = OPCODE_TEX; 233765f1a12c6256282fe175ec92a0d01b45e4322c7Brian Paul p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT; 234765f1a12c6256282fe175ec92a0d01b45e4322c7Brian Paul p->Instructions[ic].DstReg.Index = FRAG_RESULT_DEPTH; 235765f1a12c6256282fe175ec92a0d01b45e4322c7Brian Paul p->Instructions[ic].DstReg.WriteMask = WRITEMASK_Z; 236122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT; 237122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0; 238765f1a12c6256282fe175ec92a0d01b45e4322c7Brian Paul p->Instructions[ic].TexSrcUnit = 0; 2392861e737e84e4884109b9526ac645194ba892a74Michal Krol p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX; 240a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul ic++; 2412861e737e84e4884109b9526ac645194ba892a74Michal Krol } 2420c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul 2430c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul if (write_stencil) { 2442861e737e84e4884109b9526ac645194ba892a74Michal Krol /* TEX result.stencil, fragment.texcoord[0], texture[0], 2D; */ 2452861e737e84e4884109b9526ac645194ba892a74Michal Krol p->Instructions[ic].Opcode = OPCODE_TEX; 2462861e737e84e4884109b9526ac645194ba892a74Michal Krol p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT; 2472861e737e84e4884109b9526ac645194ba892a74Michal Krol p->Instructions[ic].DstReg.Index = FRAG_RESULT_STENCIL; 248308b85f29f191409e42935a3ccd5c502bdf70608Brian Paul p->Instructions[ic].DstReg.WriteMask = WRITEMASK_Y; 2490c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT; 2500c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0; 2510c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul p->Instructions[ic].TexSrcUnit = 1; 2520c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX; 2532861e737e84e4884109b9526ac645194ba892a74Michal Krol ic++; 2542861e737e84e4884109b9526ac645194ba892a74Michal Krol } 2552861e737e84e4884109b9526ac645194ba892a74Michal Krol 2562861e737e84e4884109b9526ac645194ba892a74Michal Krol /* END; */ 2572861e737e84e4884109b9526ac645194ba892a74Michal Krol p->Instructions[ic++].Opcode = OPCODE_END; 258765f1a12c6256282fe175ec92a0d01b45e4322c7Brian Paul 259765f1a12c6256282fe175ec92a0d01b45e4322c7Brian Paul assert(ic == p->NumInstructions); 260765f1a12c6256282fe175ec92a0d01b45e4322c7Brian Paul 261765f1a12c6256282fe175ec92a0d01b45e4322c7Brian Paul p->InputsRead = FRAG_BIT_TEX0 | FRAG_BIT_COL0; 262122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul p->OutputsWritten = 0; 263122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul if (write_depth) 264765f1a12c6256282fe175ec92a0d01b45e4322c7Brian Paul p->OutputsWritten |= BITFIELD64_BIT(FRAG_RESULT_DEPTH); 2652861e737e84e4884109b9526ac645194ba892a74Michal Krol if (write_stencil) 266d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle p->OutputsWritten |= BITFIELD64_BIT(FRAG_RESULT_STENCIL); 2672861e737e84e4884109b9526ac645194ba892a74Michal Krol 2682861e737e84e4884109b9526ac645194ba892a74Michal Krol p->SamplersUsed = 0x1; /* sampler 0 (bit 0) is used */ 2692861e737e84e4884109b9526ac645194ba892a74Michal Krol if (write_stencil) 2702861e737e84e4884109b9526ac645194ba892a74Michal Krol p->SamplersUsed |= 1 << 1; 2712861e737e84e4884109b9526ac645194ba892a74Michal Krol 272765f1a12c6256282fe175ec92a0d01b45e4322c7Brian Paul fp = (struct gl_fragment_program *) p; 273765f1a12c6256282fe175ec92a0d01b45e4322c7Brian Paul 274765f1a12c6256282fe175ec92a0d01b45e4322c7Brian Paul /* save the new shader */ 275765f1a12c6256282fe175ec92a0d01b45e4322c7Brian Paul st->drawpix.shaders[shaderIndex] = fp; 276122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul 277122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul return fp; 278765f1a12c6256282fe175ec92a0d01b45e4322c7Brian Paul} 2792861e737e84e4884109b9526ac645194ba892a74Michal Krol 280d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle 2812861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 2822861e737e84e4884109b9526ac645194ba892a74Michal Krol * Create a simple vertex shader that just passes through the 2832861e737e84e4884109b9526ac645194ba892a74Michal Krol * vertex position and texcoord (and optionally, color). 2842861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 2852861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void * 2862861e737e84e4884109b9526ac645194ba892a74Michal Krolmake_passthrough_vertex_shader(struct st_context *st, 2872861e737e84e4884109b9526ac645194ba892a74Michal Krol GLboolean passColor) 2882861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 2892861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!st->drawpix.vert_shaders[passColor]) { 2902861e737e84e4884109b9526ac645194ba892a74Michal Krol struct ureg_program *ureg = ureg_create( TGSI_PROCESSOR_VERTEX ); 2912861e737e84e4884109b9526ac645194ba892a74Michal Krol 2922861e737e84e4884109b9526ac645194ba892a74Michal Krol if (ureg == NULL) 293d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle return NULL; 2942861e737e84e4884109b9526ac645194ba892a74Michal Krol 2952861e737e84e4884109b9526ac645194ba892a74Michal Krol /* MOV result.pos, vertex.pos; */ 2962861e737e84e4884109b9526ac645194ba892a74Michal Krol ureg_MOV(ureg, 2972861e737e84e4884109b9526ac645194ba892a74Michal Krol ureg_DECL_output( ureg, TGSI_SEMANTIC_POSITION, 0 ), 2982861e737e84e4884109b9526ac645194ba892a74Michal Krol ureg_DECL_vs_input( ureg, 0 )); 299122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul 3002861e737e84e4884109b9526ac645194ba892a74Michal Krol /* MOV result.texcoord0, vertex.attr[1]; */ 3012861e737e84e4884109b9526ac645194ba892a74Michal Krol ureg_MOV(ureg, 302a3e86d43e6c99af97c2931c883d552c9714006e8Brian Paul ureg_DECL_output( ureg, TGSI_SEMANTIC_GENERIC, 0 ), 3032861e737e84e4884109b9526ac645194ba892a74Michal Krol ureg_DECL_vs_input( ureg, 1 )); 3042861e737e84e4884109b9526ac645194ba892a74Michal Krol 305c5af2ed60fa4fe3f33b53a8e252e24cfa490a156Brian Paul if (passColor) { 306a3e86d43e6c99af97c2931c883d552c9714006e8Brian Paul /* MOV result.color0, vertex.attr[2]; */ 307122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul ureg_MOV(ureg, 308a3e86d43e6c99af97c2931c883d552c9714006e8Brian Paul ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 ), 3092861e737e84e4884109b9526ac645194ba892a74Michal Krol ureg_DECL_vs_input( ureg, 2 )); 3102861e737e84e4884109b9526ac645194ba892a74Michal Krol } 311a3e86d43e6c99af97c2931c883d552c9714006e8Brian Paul 312122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul ureg_END( ureg ); 313122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul 314a3e86d43e6c99af97c2931c883d552c9714006e8Brian Paul st->drawpix.vert_shaders[passColor] = 3152861e737e84e4884109b9526ac645194ba892a74Michal Krol ureg_create_shader_and_destroy( ureg, st->pipe ); 3162861e737e84e4884109b9526ac645194ba892a74Michal Krol } 317a3e86d43e6c99af97c2931c883d552c9714006e8Brian Paul 3182861e737e84e4884109b9526ac645194ba892a74Michal Krol return st->drawpix.vert_shaders[passColor]; 319a3e86d43e6c99af97c2931c883d552c9714006e8Brian Paul} 3202861e737e84e4884109b9526ac645194ba892a74Michal Krol 3212861e737e84e4884109b9526ac645194ba892a74Michal Krol 3222861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 3232861e737e84e4884109b9526ac645194ba892a74Michal Krol * Return a texture internalFormat for drawing/copying an image 3242861e737e84e4884109b9526ac645194ba892a74Michal Krol * of the given format and type. 3252861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 3262861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLenum 3272861e737e84e4884109b9526ac645194ba892a74Michal Krolinternal_format(struct gl_context *ctx, GLenum format, GLenum type) 3282861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 3292861e737e84e4884109b9526ac645194ba892a74Michal Krol switch (format) { 330122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul case GL_DEPTH_COMPONENT: 3312861e737e84e4884109b9526ac645194ba892a74Michal Krol switch (type) { 332a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul case GL_UNSIGNED_SHORT: 33357e222d6e5ef5744491d093475e1136aedf81810Brian Paul return GL_DEPTH_COMPONENT16; 33457e222d6e5ef5744491d093475e1136aedf81810Brian Paul 3352861e737e84e4884109b9526ac645194ba892a74Michal Krol case GL_UNSIGNED_INT: 336308b85f29f191409e42935a3ccd5c502bdf70608Brian Paul return GL_DEPTH_COMPONENT32; 337308b85f29f191409e42935a3ccd5c502bdf70608Brian Paul 338d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle case GL_FLOAT: 3392861e737e84e4884109b9526ac645194ba892a74Michal Krol if (ctx->Extensions.ARB_depth_buffer_float) 3402861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_DEPTH_COMPONENT32F; 341de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul else 34219ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul return GL_DEPTH_COMPONENT; 343de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul 34465a51c0d6243f07491578e95b85bc483f923b817Brian Paul default: 345de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul return GL_DEPTH_COMPONENT; 34665a51c0d6243f07491578e95b85bc483f923b817Brian Paul } 347fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian 348fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian case GL_DEPTH_STENCIL: 349fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian switch (type) { 3503493e867e9f2421425627a15eb5d2a2c554fbe8aBrian case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 3513493e867e9f2421425627a15eb5d2a2c554fbe8aBrian return GL_DEPTH32F_STENCIL8; 3523493e867e9f2421425627a15eb5d2a2c554fbe8aBrian 353fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian case GL_UNSIGNED_INT_24_8: 3542861e737e84e4884109b9526ac645194ba892a74Michal Krol default: 3552861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_DEPTH24_STENCIL8; 3562861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3572861e737e84e4884109b9526ac645194ba892a74Michal Krol 3584d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul case GL_STENCIL_INDEX: 3594d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul return GL_STENCIL_INDEX; 3604d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul 3614d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul default: 3624d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul if (_mesa_is_integer_format(format)) { 3634d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul switch (type) { 3644d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul case GL_BYTE: 3654d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul return GL_RGBA8I; 3664d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul case GL_UNSIGNED_BYTE: 3674d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul return GL_RGBA8UI; 3684d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul case GL_SHORT: 3694d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul return GL_RGBA16I; 3704d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul case GL_UNSIGNED_SHORT: 3714d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul return GL_RGBA16UI; 3722861e737e84e4884109b9526ac645194ba892a74Michal Krol case GL_INT: 3733b9b8de9b0bf2f1e69a450360a812090520b2b29Brian Paul return GL_RGBA32I; 374df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian case GL_UNSIGNED_INT: 375df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian return GL_RGBA32UI; 376df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian default: 377df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian assert(0 && "Unexpected type in internal_format()"); 378df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian return GL_RGBA_INTEGER; 379df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian } 380df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian } 381df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian else { 382df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian switch (type) { 383df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian case GL_UNSIGNED_BYTE: 3844bc39c58eb7fdf3a0be62bed666998a0d1789dcfBrian Paul case GL_UNSIGNED_INT_8_8_8_8: 3854bc39c58eb7fdf3a0be62bed666998a0d1789dcfBrian Paul case GL_UNSIGNED_INT_8_8_8_8_REV: 3864bc39c58eb7fdf3a0be62bed666998a0d1789dcfBrian Paul default: 3874bc39c58eb7fdf3a0be62bed666998a0d1789dcfBrian Paul return GL_RGBA8; 3884bc39c58eb7fdf3a0be62bed666998a0d1789dcfBrian Paul 389df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian case GL_UNSIGNED_BYTE_3_3_2: 390df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian case GL_UNSIGNED_BYTE_2_3_3_REV: 391df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian case GL_UNSIGNED_SHORT_4_4_4_4: 392df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian case GL_UNSIGNED_SHORT_4_4_4_4_REV: 393df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian return GL_RGBA4; 394df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian 395df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian case GL_UNSIGNED_SHORT_5_6_5: 396df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian case GL_UNSIGNED_SHORT_5_6_5_REV: 397b4e75d6c41b2561ca86321fb775ca774c8af44ebBrian Paul case GL_UNSIGNED_SHORT_5_5_5_1: 398a3e86d43e6c99af97c2931c883d552c9714006e8Brian Paul case GL_UNSIGNED_SHORT_1_5_5_5_REV: 399a3e86d43e6c99af97c2931c883d552c9714006e8Brian Paul return GL_RGB5_A1; 400a3e86d43e6c99af97c2931c883d552c9714006e8Brian Paul 401a3e86d43e6c99af97c2931c883d552c9714006e8Brian Paul case GL_UNSIGNED_INT_10_10_10_2: 402df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian case GL_UNSIGNED_INT_2_10_10_10_REV: 403df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian return GL_RGB10_A2; 404df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian 405df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian case GL_UNSIGNED_SHORT: 406df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian case GL_UNSIGNED_INT: 407df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian return GL_RGBA16; 408d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle 409df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian case GL_BYTE: 410df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian return 411df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian ctx->Extensions.EXT_texture_snorm ? GL_RGBA8_SNORM : GL_RGBA8; 412df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian 413df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian case GL_SHORT: 414df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian case GL_INT: 415df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian return 416df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16; 417df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian 418df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian case GL_HALF_FLOAT_ARB: 419df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian return 420df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian ctx->Extensions.ARB_texture_float ? GL_RGBA16F : 421b4e75d6c41b2561ca86321fb775ca774c8af44ebBrian Paul ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16; 422a3e86d43e6c99af97c2931c883d552c9714006e8Brian Paul 423a3e86d43e6c99af97c2931c883d552c9714006e8Brian Paul case GL_FLOAT: 424a3e86d43e6c99af97c2931c883d552c9714006e8Brian Paul case GL_DOUBLE: 425a3e86d43e6c99af97c2931c883d552c9714006e8Brian Paul return 426df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian ctx->Extensions.ARB_texture_float ? GL_RGBA32F : 427df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16; 428df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian 429df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian case GL_UNSIGNED_INT_5_9_9_9_REV: 430df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian assert(ctx->Extensions.EXT_texture_shared_exponent); 431df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian return GL_RGB9_E5; 432df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian 433df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian case GL_UNSIGNED_INT_10F_11F_11F_REV: 434df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian assert(ctx->Extensions.EXT_packed_float); 435b2a3a8554a114d93691d5350c234d2022c2c2916Brian return GL_R11F_G11F_B10F; 436b2a3a8554a114d93691d5350c234d2022c2c2916Brian } 437b2a3a8554a114d93691d5350c234d2022c2c2916Brian } 438b2a3a8554a114d93691d5350c234d2022c2c2916Brian } 439b2a3a8554a114d93691d5350c234d2022c2c2916Brian} 440b2a3a8554a114d93691d5350c234d2022c2c2916Brian 441b2a3a8554a114d93691d5350c234d2022c2c2916Brian 442b2a3a8554a114d93691d5350c234d2022c2c2916Brian/** 443b2a3a8554a114d93691d5350c234d2022c2c2916Brian * Create a temporary texture to hold an image of the given size. 4445b6858c023fca9d8eefce78121aabd9aad108e09Brian * If width, height are not POT and the driver only handles POT textures, 445b2a3a8554a114d93691d5350c234d2022c2c2916Brian * allocate the next larger size of texture that is POT. 446b2a3a8554a114d93691d5350c234d2022c2c2916Brian */ 447b2a3a8554a114d93691d5350c234d2022c2c2916Brianstatic struct pipe_resource * 448b2a3a8554a114d93691d5350c234d2022c2c2916Brianalloc_texture(struct st_context *st, GLsizei width, GLsizei height, 449df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian enum pipe_format texFormat) 450df43fb661b2030d9b833a42dd47b8d7bf58d73aaBrian{ 451b2a3a8554a114d93691d5350c234d2022c2c2916Brian struct pipe_resource *pt; 452b2a3a8554a114d93691d5350c234d2022c2c2916Brian 453b2a3a8554a114d93691d5350c234d2022c2c2916Brian pt = st_texture_create(st, st->internal_target, texFormat, 0, 454b2a3a8554a114d93691d5350c234d2022c2c2916Brian width, height, 1, 1, PIPE_BIND_SAMPLER_VIEW); 45557e222d6e5ef5744491d093475e1136aedf81810Brian Paul 456b2a3a8554a114d93691d5350c234d2022c2c2916Brian return pt; 457b2a3a8554a114d93691d5350c234d2022c2c2916Brian} 45812229f119d754715e0315846fdd8d6e9213e8edfBrian 45912229f119d754715e0315846fdd8d6e9213e8edfBrian 460b2a3a8554a114d93691d5350c234d2022c2c2916Brian/** 461b2a3a8554a114d93691d5350c234d2022c2c2916Brian * Make texture containing an image for glDrawPixels image. 4620c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul * If 'pixels' is NULL, leave the texture image data undefined. 46382635aad4203d44648dd6e345ec2b5e21ff06510Nicolai Haehnle */ 464c9db223f902ce9d7e9f3038e6baac6da7f231b34Brianstatic struct pipe_resource * 465c9db223f902ce9d7e9f3038e6baac6da7f231b34Brianmake_texture(struct st_context *st, 4662e76f0a846b8273843dca701543f1cba70284751Brian GLsizei width, GLsizei height, GLenum format, GLenum type, 4672e76f0a846b8273843dca701543f1cba70284751Brian const struct gl_pixelstore_attrib *unpack, 468b2a3a8554a114d93691d5350c234d2022c2c2916Brian const GLvoid *pixels) 4692e76f0a846b8273843dca701543f1cba70284751Brian{ 4702e76f0a846b8273843dca701543f1cba70284751Brian struct gl_context *ctx = st->ctx; 4713209c3ed0d82c158eed1020759aacf51ba1c1ad5Brian struct pipe_context *pipe = st->pipe; 4723209c3ed0d82c158eed1020759aacf51ba1c1ad5Brian gl_format mformat; 473b2a3a8554a114d93691d5350c234d2022c2c2916Brian struct pipe_resource *pt; 474b2a3a8554a114d93691d5350c234d2022c2c2916Brian enum pipe_format pipeFormat; 475b2a3a8554a114d93691d5350c234d2022c2c2916Brian GLenum baseInternalFormat, intFormat; 476b2a3a8554a114d93691d5350c234d2022c2c2916Brian 477b2a3a8554a114d93691d5350c234d2022c2c2916Brian intFormat = internal_format(ctx, format, type); 478b2a3a8554a114d93691d5350c234d2022c2c2916Brian baseInternalFormat = _mesa_base_tex_format(ctx, intFormat); 479b2a3a8554a114d93691d5350c234d2022c2c2916Brian 480b2a3a8554a114d93691d5350c234d2022c2c2916Brian mformat = st_ChooseTextureFormat_renderable(ctx, intFormat, 481b2a3a8554a114d93691d5350c234d2022c2c2916Brian format, type, GL_FALSE); 482b2a3a8554a114d93691d5350c234d2022c2c2916Brian assert(mformat); 483b2a3a8554a114d93691d5350c234d2022c2c2916Brian 48421f99792a916a62fcfae7c208f50f192d4ce5926Brian pipeFormat = st_mesa_format_to_pipe_format(mformat); 48521f99792a916a62fcfae7c208f50f192d4ce5926Brian assert(pipeFormat); 48621f99792a916a62fcfae7c208f50f192d4ce5926Brian 48721f99792a916a62fcfae7c208f50f192d4ce5926Brian pixels = _mesa_map_pbo_source(ctx, unpack, pixels); 48821f99792a916a62fcfae7c208f50f192d4ce5926Brian if (!pixels) 48921f99792a916a62fcfae7c208f50f192d4ce5926Brian return NULL; 490b2a3a8554a114d93691d5350c234d2022c2c2916Brian 491b2a3a8554a114d93691d5350c234d2022c2c2916Brian /* alloc temporary texture */ 492b2a3a8554a114d93691d5350c234d2022c2c2916Brian pt = alloc_texture(st, width, height, pipeFormat); 493b2a3a8554a114d93691d5350c234d2022c2c2916Brian if (!pt) { 494b2a3a8554a114d93691d5350c234d2022c2c2916Brian _mesa_unmap_pbo_source(ctx, unpack); 495b2a3a8554a114d93691d5350c234d2022c2c2916Brian return NULL; 496b2a3a8554a114d93691d5350c234d2022c2c2916Brian } 497b2a3a8554a114d93691d5350c234d2022c2c2916Brian 498736e1ae42fd61f2b9f982b0491ca7daea7e615edNicolai Hähnle { 499b2a3a8554a114d93691d5350c234d2022c2c2916Brian struct pipe_transfer *transfer; 500b2a3a8554a114d93691d5350c234d2022c2c2916Brian GLboolean success; 501b2a3a8554a114d93691d5350c234d2022c2c2916Brian GLubyte *dest; 502b2a3a8554a114d93691d5350c234d2022c2c2916Brian const GLbitfield imageTransferStateSave = ctx->_ImageTransferState; 503b2a3a8554a114d93691d5350c234d2022c2c2916Brian 504b2a3a8554a114d93691d5350c234d2022c2c2916Brian /* we'll do pixel transfer in a fragment shader */ 505b2a3a8554a114d93691d5350c234d2022c2c2916Brian ctx->_ImageTransferState = 0x0; 506b2a3a8554a114d93691d5350c234d2022c2c2916Brian 507b2a3a8554a114d93691d5350c234d2022c2c2916Brian transfer = pipe_get_transfer(st->pipe, pt, 0, 0, 508b2a3a8554a114d93691d5350c234d2022c2c2916Brian PIPE_TRANSFER_WRITE, 0, 0, 509b2a3a8554a114d93691d5350c234d2022c2c2916Brian width, height); 510b2a3a8554a114d93691d5350c234d2022c2c2916Brian 511b2a3a8554a114d93691d5350c234d2022c2c2916Brian /* map texture transfer */ 512b2a3a8554a114d93691d5350c234d2022c2c2916Brian dest = pipe_transfer_map(pipe, transfer); 513b2a3a8554a114d93691d5350c234d2022c2c2916Brian 514b2a3a8554a114d93691d5350c234d2022c2c2916Brian 515b2a3a8554a114d93691d5350c234d2022c2c2916Brian /* Put image into texture transfer. 516b2a3a8554a114d93691d5350c234d2022c2c2916Brian * Note that the image is actually going to be upside down in 517b2a3a8554a114d93691d5350c234d2022c2c2916Brian * the texture. We deal with that with texcoords. 51819ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul */ 51919ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul success = _mesa_texstore(ctx, 2, /* dims */ 52019ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul baseInternalFormat, /* baseInternalFormat */ 52119ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul mformat, /* gl_format */ 52219ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul transfer->stride, /* dstRowStride, bytes */ 52319ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul &dest, /* destSlices */ 52419ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul width, height, 1, /* size */ 52519ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul format, type, /* src format/type */ 52619ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul pixels, /* data source */ 52719ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul unpack); 52819ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul 52919ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul /* unmap */ 53019ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul pipe_transfer_unmap(pipe, transfer); 53119ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul pipe->transfer_destroy(pipe, transfer); 53219ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul 53319ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul assert(success); 534457d7218b8e0f0c21ae31564d25b7031b423b0f8José Fonseca 53519ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul /* restore */ 53619ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul ctx->_ImageTransferState = imageTransferStateSave; 53719ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul } 53819ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul 53919ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul _mesa_unmap_pbo_source(ctx, unpack); 54019ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul 54119ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul return pt; 54219ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul} 54319ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul 54419ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul 54519ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul/** 54619ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul * Draw quad with texcoords and optional color. 54719ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul * Coords are gallium window coords with y=0=top. 54819ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul * \param color may be null 54919ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul * \param invertTex if true, flip texcoords vertically 55019ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul */ 55119ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paulstatic void 55219ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Pauldraw_quad(struct gl_context *ctx, GLfloat x0, GLfloat y0, GLfloat z, 55319ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul GLfloat x1, GLfloat y1, const GLfloat *color, 55419ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul GLboolean invertTex, GLfloat maxXcoord, GLfloat maxYcoord) 55519ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul{ 55619ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul struct st_context *st = st_context(ctx); 55719ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul struct pipe_context *pipe = st->pipe; 55819ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul GLfloat verts[4][3][4]; /* four verts, three attribs, XYZW */ 55919ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul 56019ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul /* setup vertex data */ 56119ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul { 56219ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul const struct gl_framebuffer *fb = st->ctx->DrawBuffer; 56319ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul const GLfloat fb_width = (GLfloat) fb->Width; 56419ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul const GLfloat fb_height = (GLfloat) fb->Height; 56519ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul const GLfloat clip_x0 = x0 / fb_width * 2.0f - 1.0f; 56619ad9cf7741c641bd83d20485b32d11fe27ca8dfBrian Paul const GLfloat clip_y0 = y0 / fb_height * 2.0f - 1.0f; 567b2a3a8554a114d93691d5350c234d2022c2c2916Brian const GLfloat clip_x1 = x1 / fb_width * 2.0f - 1.0f; 568d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle const GLfloat clip_y1 = y1 / fb_height * 2.0f - 1.0f; 569d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle const GLfloat sLeft = 0.0f, sRight = maxXcoord; 570d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle const GLfloat tTop = invertTex ? maxYcoord : 0.0f; 571d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle const GLfloat tBot = invertTex ? 0.0f : maxYcoord; 572d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle GLuint i; 573d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle 574d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle /* upper-left */ 575d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[0][0][0] = clip_x0; /* v[0].attr[0].x */ 576d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[0][0][1] = clip_y0; /* v[0].attr[0].y */ 577d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle 578d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle /* upper-right */ 579d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[1][0][0] = clip_x1; 580d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[1][0][1] = clip_y0; 581d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle 582d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle /* lower-right */ 58320fbb24b67dda0679774756e4b6d98c2c66c2c42Brian Paul verts[2][0][0] = clip_x1; 584d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[2][0][1] = clip_y1; 585d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle 586d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle /* lower-left */ 587d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[3][0][0] = clip_x0; 588d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[3][0][1] = clip_y1; 589d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle 590d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[0][1][0] = sLeft; /* v[0].attr[1].S */ 591d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[0][1][1] = tTop; /* v[0].attr[1].T */ 592d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[1][1][0] = sRight; 593d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[1][1][1] = tTop; 594d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[2][1][0] = sRight; 595d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[2][1][1] = tBot; 596d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[3][1][0] = sLeft; 597d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[3][1][1] = tBot; 598d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle 599d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle /* same for all verts: */ 600d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle if (color) { 601d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle for (i = 0; i < 4; i++) { 602d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[i][0][2] = z; /* v[i].attr[0].z */ 603d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[i][0][3] = 1.0f; /* v[i].attr[0].w */ 604d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[i][2][0] = color[0]; /* v[i].attr[2].r */ 605d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[i][2][1] = color[1]; /* v[i].attr[2].g */ 606d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[i][2][2] = color[2]; /* v[i].attr[2].b */ 607d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[i][2][3] = color[3]; /* v[i].attr[2].a */ 608d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[i][1][2] = 0.0f; /* v[i].attr[1].R */ 609d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[i][1][3] = 1.0f; /* v[i].attr[1].Q */ 610d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle } 611d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle } 612d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle else { 613d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle for (i = 0; i < 4; i++) { 614d8d086c20b5a43353c4980cf234d8329900585f5Nicolai Haehnle verts[i][0][2] = z; /*Z*/ 6156ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul verts[i][0][3] = 1.0f; /*W*/ 6166ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul verts[i][1][2] = 0.0f; /*R*/ 6176ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul verts[i][1][3] = 1.0f; /*Q*/ 6186ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul } 6196ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul } 6206ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul } 6216ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul 6226ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul { 6236ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul struct pipe_resource *buf = NULL; 6246ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul unsigned offset; 6250c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul 6266ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul u_upload_data(st->uploader, 0, sizeof(verts), verts, &offset, &buf); 6276ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul if (!buf) { 6286ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul return; 6296ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul } 6306ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul 6316ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul u_upload_unmap(st->uploader); 6326ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul util_draw_vertex_buffer(pipe, st->cso_context, buf, offset, 6330c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul PIPE_PRIM_QUADS, 6340c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul 4, /* verts */ 6350c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul 3); /* attribs/vert */ 6360c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul pipe_resource_reference(&buf, NULL); 6370c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul } 6386ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul} 6396ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul 6406ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul 6416ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul 6426ca948a303e1af7ae66ea7082af741f6880887f2Brian Paulstatic void 6436ca948a303e1af7ae66ea7082af741f6880887f2Brian Pauldraw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, 6446ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul GLsizei width, GLsizei height, 6456ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul GLfloat zoomX, GLfloat zoomY, 6466ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul struct pipe_sampler_view **sv, 6476ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul int num_sampler_view, 6486ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul void *driver_vp, 6496ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul void *driver_fp, 6506ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul const GLfloat *color, 6516ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul GLboolean invertTex, 6526ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul GLboolean write_depth, GLboolean write_stencil) 6536ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul{ 6546ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul struct st_context *st = st_context(ctx); 6556ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul struct pipe_context *pipe = st->pipe; 6566ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul struct cso_context *cso = st->cso_context; 6576ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul GLfloat x0, y0, x1, y1; 6586ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul GLsizei maxSize; 6596ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul boolean normalized = sv[0]->texture->target != PIPE_TEXTURE_RECT; 6606ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul 6616ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul /* limit checks */ 6626ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul /* XXX if DrawPixels image is larger than max texture size, break 6636ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul * it up into chunks. 6646ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul */ 6656ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul maxSize = 1 << (pipe->screen->get_param(pipe->screen, 6666ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1); 6676ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul assert(width <= maxSize); 6686ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul assert(height <= maxSize); 6696ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul 6706ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul cso_save_rasterizer(cso); 6710c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul cso_save_viewport(cso); 6720c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul cso_save_samplers(cso); 6736ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul cso_save_fragment_sampler_views(cso); 6746ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul cso_save_fragment_shader(cso); 6756ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul cso_save_stream_outputs(cso); 6766ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul cso_save_vertex_shader(cso); 6776ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul cso_save_geometry_shader(cso); 6786ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul cso_save_vertex_elements(cso); 6796ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul cso_save_vertex_buffers(cso); 680a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul if (write_stencil) { 681a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul cso_save_depth_stencil_alpha(cso); 6820c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul cso_save_blend(cso); 6836ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul } 6846ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul 6856ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul /* rasterizer state: just scissor */ 6866ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul { 6876ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul struct pipe_rasterizer_state rasterizer; 6886ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul memset(&rasterizer, 0, sizeof(rasterizer)); 6896ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul rasterizer.clamp_fragment_color = !st->clamp_frag_color_in_shader && 6906ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul ctx->Color._ClampFragmentColor; 6916ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul rasterizer.gl_rasterization_rules = 1; 6926ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul rasterizer.depth_clip = !ctx->Transform.DepthClamp; 6936ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul rasterizer.scissor = ctx->Scissor.Enabled; 6946ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul cso_set_rasterizer(cso, &rasterizer); 6956ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul } 6966ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul 6976ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul if (write_stencil) { 6986ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul /* Stencil writing bypasses the normal fragment pipeline to 6996ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul * disable color writing and set stencil test to always pass. 7006ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul */ 7016ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul struct pipe_depth_stencil_alpha_state dsa; 7026ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul struct pipe_blend_state blend; 703a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul 704a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul /* depth/stencil */ 705a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul memset(&dsa, 0, sizeof(dsa)); 706a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul dsa.stencil[0].enabled = 1; 7076ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul dsa.stencil[0].func = PIPE_FUNC_ALWAYS; 7080c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul dsa.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff; 7095c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; 7105c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul if (write_depth) { 7115c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul /* writing depth+stencil: depth test always passes */ 7120c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul dsa.depth.enabled = 1; 7130c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul dsa.depth.writemask = ctx->Depth.Mask; 7140c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul dsa.depth.func = PIPE_FUNC_ALWAYS; 7150c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul } 7160c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul cso_set_depth_stencil_alpha(cso, &dsa); 7170c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul 7185c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul /* blend (colormask) */ 7195c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul memset(&blend, 0, sizeof(blend)); 7205c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul cso_set_blend(cso, &blend); 7215c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul } 7225c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul 7235c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul /* fragment shader state: TEX lookup program */ 7245c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul cso_set_fragment_shader_handle(cso, driver_fp); 7255c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul 7265c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul /* vertex shader state: position + texcoord pass-through */ 7275c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul cso_set_vertex_shader_handle(cso, driver_vp); 7285c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul 7295c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul /* geometry shader state: disabled */ 7305c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul cso_set_geometry_shader_handle(cso, NULL); 7315c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul 7325c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul /* texture sampling state: */ 7335c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul { 7345c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul struct pipe_sampler_state sampler; 7355c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul memset(&sampler, 0, sizeof(sampler)); 7365c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul sampler.wrap_s = PIPE_TEX_WRAP_CLAMP; 7375c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul sampler.wrap_t = PIPE_TEX_WRAP_CLAMP; 7385c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul sampler.wrap_r = PIPE_TEX_WRAP_CLAMP; 7395c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; 7405c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 7415c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 7425c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul sampler.normalized_coords = normalized; 7435c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul 7445c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul cso_single_sampler(cso, 0, &sampler); 7450c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul if (num_sampler_view > 1) { 7460c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul cso_single_sampler(cso, 1, &sampler); 7470c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul } 7488d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul cso_single_sampler_done(cso); 7495c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul } 750a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul 751a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul /* viewport state: viewport matching window dims */ 752e469d78d33feff45f16235871ca1a3d483cdc950Brian Paul { 7530c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul const float w = (float) ctx->DrawBuffer->Width; 7540c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul const float h = (float) ctx->DrawBuffer->Height; 7550c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul struct pipe_viewport_state vp; 7560c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul vp.scale[0] = 0.5f * w; 757a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul vp.scale[1] = -0.5f * h; 758a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul vp.scale[2] = 0.5f; 7590c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul vp.scale[3] = 1.0f; 7600c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul vp.translate[0] = 0.5f * w; 7618d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul vp.translate[1] = 0.5f * h; 7620c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul vp.translate[2] = 0.5f; 7635c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul vp.translate[3] = 0.0f; 7646ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul cso_set_viewport(cso, &vp); 7655c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul } 7665c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul 7676ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul cso_set_vertex_elements(cso, 3, st->velems_util_draw); 7686ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul cso_set_stream_outputs(st->cso_context, 0, NULL, 0); 7695c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul 7705c4bd76cb65245467d4ba04e893157055d738b2dBrian Paul /* texture state: */ 7718d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul cso_set_fragment_sampler_views(cso, num_sampler_view, sv); 7720c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul 7730c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul /* Compute Gallium window coords (y=0=top) with pixel zoom. 7740c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul * Recall that these coords are transformed by the current 7756ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul * vertex shader and viewport transformation. 7760c78c766e4cb8ffcda44cabfadb8de8e09121034Brian Paul */ 7776ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul if (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM) { 7786ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul y = ctx->DrawBuffer->Height - (int) (y + height * ctx->Pixel.ZoomY); 7796ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul invertTex = !invertTex; 7806ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul } 7816ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul 7826ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul x0 = (GLfloat) x; 7836ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul x1 = x + width * ctx->Pixel.ZoomX; 7846ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul y0 = (GLfloat) y; 7856ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul y1 = y + height * ctx->Pixel.ZoomY; 7866ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul 7876ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */ 7886ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul z = z * 2.0 - 1.0; 7896ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul 7906ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex, 7916ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul normalized ? ((GLfloat) width / sv[0]->texture->width0) : (GLfloat)width, 7926ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul normalized ? ((GLfloat) height / sv[0]->texture->height0) : (GLfloat)height); 7936ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul 7946ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul /* restore state */ 7956ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul cso_restore_rasterizer(cso); 7966ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul cso_restore_viewport(cso); 797a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul cso_restore_samplers(cso); 798a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul cso_restore_fragment_sampler_views(cso); 799a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul cso_restore_fragment_shader(cso); 800a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul cso_restore_vertex_shader(cso); 801a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul cso_restore_geometry_shader(cso); 8026ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul cso_restore_vertex_elements(cso); 803a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul cso_restore_vertex_buffers(cso); 804a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul cso_restore_stream_outputs(cso); 805a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul if (write_stencil) { 806a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul cso_restore_depth_stencil_alpha(cso); 8076ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul cso_restore_blend(cso); 808a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul } 8096ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul} 810a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul 8116ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul 8126ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul/** 8136ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul * Software fallback to do glDrawPixels(GL_STENCIL_INDEX) when we 8146ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul * can't use a fragment shader to write stencil values. 8156ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul */ 816a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paulstatic void 8175076a4f53a2f34cc9116b45951037f639885c7a1Brian Pauldraw_stencil_pixels(struct gl_context *ctx, GLint x, GLint y, 8185076a4f53a2f34cc9116b45951037f639885c7a1Brian Paul GLsizei width, GLsizei height, GLenum format, GLenum type, 819a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul const struct gl_pixelstore_attrib *unpack, 820a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul const GLvoid *pixels) 821a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul{ 822a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul struct st_context *st = st_context(ctx); 8236ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul struct pipe_context *pipe = st->pipe; 8246ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul struct st_renderbuffer *strb; 8256ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul enum pipe_transfer_usage usage; 826a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul struct pipe_transfer *pt; 8276ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; 828a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul ubyte *stmap; 829a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul struct gl_pixelstore_attrib clippedUnpack = *unpack; 830a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul GLubyte *sValues; 831a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul GLuint *zValues; 832a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul 833a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul if (!zoom) { 834a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height, 835a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul &clippedUnpack)) { 836a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul /* totally clipped */ 837a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul return; 838a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul } 839a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul } 840a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul 841a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul strb = st_renderbuffer(ctx->DrawBuffer-> 842a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul Attachment[BUFFER_STENCIL].Renderbuffer); 843a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul 844a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 845a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul y = ctx->DrawBuffer->Height - y - height; 846a2ddb3d20964e562e3dcb0e973f300362a9d5d69Brian Paul } 8476ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul 8486ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul if (format == GL_STENCIL_INDEX && 8496ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul _mesa_is_format_packed_depth_stencil(strb->Base.Format)) { 8506ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul /* writing stencil to a combined depth+stencil buffer */ 8516ca948a303e1af7ae66ea7082af741f6880887f2Brian Paul usage = PIPE_TRANSFER_READ_WRITE; 852ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul } 853ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul else { 854ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul usage = PIPE_TRANSFER_WRITE; 855ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul } 856ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul 857ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul pt = pipe_get_transfer(pipe, strb->texture, 858ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul strb->rtt_level, strb->rtt_face + strb->rtt_slice, 859ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul usage, x, y, 860ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul width, height); 861ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul 862ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul stmap = pipe_transfer_map(pipe, pt); 863ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul 864ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul pixels = _mesa_map_pbo_source(ctx, &clippedUnpack, pixels); 865ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul assert(pixels); 866ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul 867ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul sValues = (GLubyte *) malloc(width * sizeof(GLubyte)); 868516d20fd2688fce833b764ca21f1f1772bed0a03Brian Paul zValues = (GLuint *) malloc(width * sizeof(GLuint)); 869516d20fd2688fce833b764ca21f1f1772bed0a03Brian Paul 870ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul if (sValues && zValues) { 871ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul GLint row; 872ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul for (row = 0; row < height; row++) { 873ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul GLfloat *zValuesFloat = (GLfloat*)zValues; 874ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul GLenum destType = GL_UNSIGNED_BYTE; 875ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul const GLvoid *source = _mesa_image_address2d(&clippedUnpack, pixels, 876ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul width, height, 877ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul format, type, 878ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul row, 0); 879ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul _mesa_unpack_stencil_span(ctx, width, destType, sValues, 880ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul type, source, &clippedUnpack, 881ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul ctx->_ImageTransferState); 882ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul 883ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul if (format == GL_DEPTH_STENCIL) { 884ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul GLenum ztype = 885ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul pt->resource->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ? 886ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul GL_FLOAT : GL_UNSIGNED_INT; 887ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul 888ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul _mesa_unpack_depth_span(ctx, width, ztype, zValues, 889ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul (1 << 24) - 1, type, source, 890ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul &clippedUnpack); 891ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul } 892ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul 893ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul if (zoom) { 894ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul _mesa_problem(ctx, "Gallium glDrawPixels(GL_STENCIL) with " 895ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul "zoom not complete"); 896ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul } 897ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul 898ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul { 899ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul GLint spanY; 900ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul 901ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 902ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul spanY = height - row - 1; 903ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul } 904ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul else { 905ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul spanY = row; 906ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul } 907ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul 908ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul /* now pack the stencil (and Z) values in the dest format */ 909ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul switch (pt->resource->format) { 910ec6ad7ba3ce4fa71620642ddde06cf843d1c8d54Brian Paul case PIPE_FORMAT_S8_UINT: 911 { 912 ubyte *dest = stmap + spanY * pt->stride; 913 assert(usage == PIPE_TRANSFER_WRITE); 914 memcpy(dest, sValues, width); 915 } 916 break; 917 case PIPE_FORMAT_Z24_UNORM_S8_UINT: 918 if (format == GL_DEPTH_STENCIL) { 919 uint *dest = (uint *) (stmap + spanY * pt->stride); 920 GLint k; 921 assert(usage == PIPE_TRANSFER_WRITE); 922 for (k = 0; k < width; k++) { 923 dest[k] = zValues[k] | (sValues[k] << 24); 924 } 925 } 926 else { 927 uint *dest = (uint *) (stmap + spanY * pt->stride); 928 GLint k; 929 assert(usage == PIPE_TRANSFER_READ_WRITE); 930 for (k = 0; k < width; k++) { 931 dest[k] = (dest[k] & 0xffffff) | (sValues[k] << 24); 932 } 933 } 934 break; 935 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 936 if (format == GL_DEPTH_STENCIL) { 937 uint *dest = (uint *) (stmap + spanY * pt->stride); 938 GLint k; 939 assert(usage == PIPE_TRANSFER_WRITE); 940 for (k = 0; k < width; k++) { 941 dest[k] = (zValues[k] << 8) | (sValues[k] & 0xff); 942 } 943 } 944 else { 945 uint *dest = (uint *) (stmap + spanY * pt->stride); 946 GLint k; 947 assert(usage == PIPE_TRANSFER_READ_WRITE); 948 for (k = 0; k < width; k++) { 949 dest[k] = (dest[k] & 0xffffff00) | (sValues[k] & 0xff); 950 } 951 } 952 break; 953 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 954 if (format == GL_DEPTH_STENCIL) { 955 uint *dest = (uint *) (stmap + spanY * pt->stride); 956 GLfloat *destf = (GLfloat*)dest; 957 GLint k; 958 assert(usage == PIPE_TRANSFER_WRITE); 959 for (k = 0; k < width; k++) { 960 destf[k*2] = zValuesFloat[k]; 961 dest[k*2+1] = sValues[k] & 0xff; 962 } 963 } 964 else { 965 uint *dest = (uint *) (stmap + spanY * pt->stride); 966 GLint k; 967 assert(usage == PIPE_TRANSFER_READ_WRITE); 968 for (k = 0; k < width; k++) { 969 dest[k*2+1] = sValues[k] & 0xff; 970 } 971 } 972 break; 973 default: 974 assert(0); 975 } 976 } 977 } 978 } 979 else { 980 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels()"); 981 } 982 983 free(sValues); 984 free(zValues); 985 986 _mesa_unmap_pbo_source(ctx, &clippedUnpack); 987 988 /* unmap the stencil buffer */ 989 pipe_transfer_unmap(pipe, pt); 990 pipe->transfer_destroy(pipe, pt); 991} 992 993 994/** 995 * Get fragment program variant for a glDrawPixels or glCopyPixels 996 * command for RGBA data. 997 */ 998static struct st_fp_variant * 999get_color_fp_variant(struct st_context *st) 1000{ 1001 struct gl_context *ctx = st->ctx; 1002 struct st_fp_variant_key key; 1003 struct st_fp_variant *fpv; 1004 1005 memset(&key, 0, sizeof(key)); 1006 1007 key.st = st; 1008 key.drawpixels = 1; 1009 key.scaleAndBias = (ctx->Pixel.RedBias != 0.0 || 1010 ctx->Pixel.RedScale != 1.0 || 1011 ctx->Pixel.GreenBias != 0.0 || 1012 ctx->Pixel.GreenScale != 1.0 || 1013 ctx->Pixel.BlueBias != 0.0 || 1014 ctx->Pixel.BlueScale != 1.0 || 1015 ctx->Pixel.AlphaBias != 0.0 || 1016 ctx->Pixel.AlphaScale != 1.0); 1017 key.pixelMaps = ctx->Pixel.MapColorFlag; 1018 key.clamp_color = st->clamp_frag_color_in_shader && 1019 st->ctx->Color._ClampFragmentColor; 1020 1021 fpv = st_get_fp_variant(st, st->fp, &key); 1022 1023 return fpv; 1024} 1025 1026 1027/** 1028 * Get fragment program variant for a glDrawPixels or glCopyPixels 1029 * command for depth/stencil data. 1030 */ 1031static struct st_fp_variant * 1032get_depth_stencil_fp_variant(struct st_context *st, GLboolean write_depth, 1033 GLboolean write_stencil) 1034{ 1035 struct st_fp_variant_key key; 1036 struct st_fp_variant *fpv; 1037 1038 memset(&key, 0, sizeof(key)); 1039 1040 key.st = st; 1041 key.drawpixels = 1; 1042 key.drawpixels_z = write_depth; 1043 key.drawpixels_stencil = write_stencil; 1044 1045 fpv = st_get_fp_variant(st, st->fp, &key); 1046 1047 return fpv; 1048} 1049 1050 1051/** 1052 * Called via ctx->Driver.DrawPixels() 1053 */ 1054static void 1055st_DrawPixels(struct gl_context *ctx, GLint x, GLint y, 1056 GLsizei width, GLsizei height, 1057 GLenum format, GLenum type, 1058 const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels) 1059{ 1060 void *driver_vp, *driver_fp; 1061 struct st_context *st = st_context(ctx); 1062 const GLfloat *color; 1063 struct pipe_context *pipe = st->pipe; 1064 GLboolean write_stencil = GL_FALSE, write_depth = GL_FALSE; 1065 struct pipe_sampler_view *sv[2]; 1066 int num_sampler_view = 1; 1067 struct st_fp_variant *fpv; 1068 1069 if (format == GL_DEPTH_STENCIL) 1070 write_stencil = write_depth = GL_TRUE; 1071 else if (format == GL_STENCIL_INDEX) 1072 write_stencil = GL_TRUE; 1073 else if (format == GL_DEPTH_COMPONENT) 1074 write_depth = GL_TRUE; 1075 1076 if (write_stencil && 1077 !pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT)) { 1078 /* software fallback */ 1079 draw_stencil_pixels(ctx, x, y, width, height, format, type, 1080 unpack, pixels); 1081 return; 1082 } 1083 1084 /* Mesa state should be up to date by now */ 1085 assert(ctx->NewState == 0x0); 1086 1087 st_validate_state(st); 1088 1089 /* 1090 * Get vertex/fragment shaders 1091 */ 1092 if (write_depth || write_stencil) { 1093 fpv = get_depth_stencil_fp_variant(st, write_depth, write_stencil); 1094 1095 driver_fp = fpv->driver_shader; 1096 1097 driver_vp = make_passthrough_vertex_shader(st, GL_TRUE); 1098 1099 color = ctx->Current.RasterColor; 1100 } 1101 else { 1102 fpv = get_color_fp_variant(st); 1103 1104 driver_fp = fpv->driver_shader; 1105 1106 driver_vp = make_passthrough_vertex_shader(st, GL_FALSE); 1107 1108 color = NULL; 1109 if (st->pixel_xfer.pixelmap_enabled) { 1110 sv[1] = st->pixel_xfer.pixelmap_sampler_view; 1111 num_sampler_view++; 1112 } 1113 } 1114 1115 /* update fragment program constants */ 1116 st_upload_constants(st, fpv->parameters, PIPE_SHADER_FRAGMENT); 1117 1118 /* draw with textured quad */ 1119 { 1120 struct pipe_resource *pt 1121 = make_texture(st, width, height, format, type, unpack, pixels); 1122 if (pt) { 1123 sv[0] = st_create_texture_sampler_view(st->pipe, pt); 1124 1125 if (sv[0]) { 1126 /* Create a second sampler view to read stencil. 1127 * The stencil is written using the shader stencil export 1128 * functionality. */ 1129 if (write_stencil) { 1130 enum pipe_format stencil_format = PIPE_FORMAT_NONE; 1131 1132 switch (pt->format) { 1133 case PIPE_FORMAT_Z24_UNORM_S8_UINT: 1134 case PIPE_FORMAT_X24S8_UINT: 1135 stencil_format = PIPE_FORMAT_X24S8_UINT; 1136 break; 1137 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 1138 case PIPE_FORMAT_S8X24_UINT: 1139 stencil_format = PIPE_FORMAT_S8X24_UINT; 1140 break; 1141 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 1142 case PIPE_FORMAT_X32_S8X24_UINT: 1143 stencil_format = PIPE_FORMAT_X32_S8X24_UINT; 1144 break; 1145 case PIPE_FORMAT_S8_UINT: 1146 stencil_format = PIPE_FORMAT_S8_UINT; 1147 break; 1148 default: 1149 assert(0); 1150 } 1151 1152 sv[1] = st_create_texture_sampler_view_format(st->pipe, pt, 1153 stencil_format); 1154 num_sampler_view++; 1155 } 1156 1157 draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2], 1158 width, height, 1159 ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, 1160 sv, 1161 num_sampler_view, 1162 driver_vp, 1163 driver_fp, 1164 color, GL_FALSE, write_depth, write_stencil); 1165 pipe_sampler_view_reference(&sv[0], NULL); 1166 if (num_sampler_view > 1) 1167 pipe_sampler_view_reference(&sv[1], NULL); 1168 } 1169 pipe_resource_reference(&pt, NULL); 1170 } 1171 } 1172} 1173 1174 1175 1176/** 1177 * Software fallback for glCopyPixels(GL_STENCIL). 1178 */ 1179static void 1180copy_stencil_pixels(struct gl_context *ctx, GLint srcx, GLint srcy, 1181 GLsizei width, GLsizei height, 1182 GLint dstx, GLint dsty) 1183{ 1184 struct st_renderbuffer *rbDraw; 1185 struct pipe_context *pipe = st_context(ctx)->pipe; 1186 enum pipe_transfer_usage usage; 1187 struct pipe_transfer *ptDraw; 1188 ubyte *drawMap; 1189 ubyte *buffer; 1190 int i; 1191 1192 buffer = malloc(width * height * sizeof(ubyte)); 1193 if (!buffer) { 1194 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels(stencil)"); 1195 return; 1196 } 1197 1198 /* Get the dest renderbuffer */ 1199 rbDraw = st_renderbuffer(ctx->DrawBuffer-> 1200 Attachment[BUFFER_STENCIL].Renderbuffer); 1201 1202 /* this will do stencil pixel transfer ops */ 1203 _mesa_readpixels(ctx, srcx, srcy, width, height, 1204 GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, 1205 &ctx->DefaultPacking, buffer); 1206 1207 if (0) { 1208 /* debug code: dump stencil values */ 1209 GLint row, col; 1210 for (row = 0; row < height; row++) { 1211 printf("%3d: ", row); 1212 for (col = 0; col < width; col++) { 1213 printf("%02x ", buffer[col + row * width]); 1214 } 1215 printf("\n"); 1216 } 1217 } 1218 1219 if (_mesa_is_format_packed_depth_stencil(rbDraw->Base.Format)) 1220 usage = PIPE_TRANSFER_READ_WRITE; 1221 else 1222 usage = PIPE_TRANSFER_WRITE; 1223 1224 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 1225 dsty = rbDraw->Base.Height - dsty - height; 1226 } 1227 1228 ptDraw = pipe_get_transfer(pipe, 1229 rbDraw->texture, 1230 rbDraw->rtt_level, 1231 rbDraw->rtt_face + rbDraw->rtt_slice, 1232 usage, dstx, dsty, 1233 width, height); 1234 1235 assert(util_format_get_blockwidth(ptDraw->resource->format) == 1); 1236 assert(util_format_get_blockheight(ptDraw->resource->format) == 1); 1237 1238 /* map the stencil buffer */ 1239 drawMap = pipe_transfer_map(pipe, ptDraw); 1240 1241 /* draw */ 1242 /* XXX PixelZoom not handled yet */ 1243 for (i = 0; i < height; i++) { 1244 ubyte *dst; 1245 const ubyte *src; 1246 int y; 1247 1248 y = i; 1249 1250 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 1251 y = height - y - 1; 1252 } 1253 1254 dst = drawMap + y * ptDraw->stride; 1255 src = buffer + i * width; 1256 1257 _mesa_pack_ubyte_stencil_row(rbDraw->Base.Format, width, src, dst); 1258 } 1259 1260 free(buffer); 1261 1262 /* unmap the stencil buffer */ 1263 pipe_transfer_unmap(pipe, ptDraw); 1264 pipe->transfer_destroy(pipe, ptDraw); 1265} 1266 1267 1268/** 1269 * Return renderbuffer to use for reading color pixels for glCopyPixels 1270 */ 1271static struct st_renderbuffer * 1272st_get_color_read_renderbuffer(struct gl_context *ctx) 1273{ 1274 struct gl_framebuffer *fb = ctx->ReadBuffer; 1275 struct st_renderbuffer *strb = 1276 st_renderbuffer(fb->_ColorReadBuffer); 1277 1278 return strb; 1279} 1280 1281 1282/** Do the src/dest regions overlap? */ 1283static GLboolean 1284regions_overlap(GLint srcX, GLint srcY, GLint dstX, GLint dstY, 1285 GLsizei width, GLsizei height) 1286{ 1287 if (srcX + width <= dstX || 1288 dstX + width <= srcX || 1289 srcY + height <= dstY || 1290 dstY + height <= srcY) 1291 return GL_FALSE; 1292 else 1293 return GL_TRUE; 1294} 1295 1296 1297/** 1298 * Try to do a glCopyPixels for simple cases with a blit by calling 1299 * pipe->resource_copy_region(). 1300 * 1301 * We can do this when we're copying color pixels (depth/stencil 1302 * eventually) with no pixel zoom, no pixel transfer ops, no 1303 * per-fragment ops, the src/dest regions don't overlap and the 1304 * src/dest pixel formats are the same. 1305 */ 1306static GLboolean 1307blit_copy_pixels(struct gl_context *ctx, GLint srcx, GLint srcy, 1308 GLsizei width, GLsizei height, 1309 GLint dstx, GLint dsty, GLenum type) 1310{ 1311 struct st_context *st = st_context(ctx); 1312 struct pipe_context *pipe = st->pipe; 1313 struct gl_pixelstore_attrib pack, unpack; 1314 GLint readX, readY, readW, readH; 1315 1316 if (type == GL_COLOR && 1317 ctx->Pixel.ZoomX == 1.0 && 1318 ctx->Pixel.ZoomY == 1.0 && 1319 ctx->_ImageTransferState == 0x0 && 1320 !ctx->Color.BlendEnabled && 1321 !ctx->Color.AlphaEnabled && 1322 !ctx->Depth.Test && 1323 !ctx->Fog.Enabled && 1324 !ctx->Stencil.Enabled && 1325 !ctx->FragmentProgram.Enabled && 1326 !ctx->VertexProgram.Enabled && 1327 !ctx->Shader.CurrentFragmentProgram && 1328 st_fb_orientation(ctx->ReadBuffer) == st_fb_orientation(ctx->DrawBuffer) && 1329 ctx->DrawBuffer->_NumColorDrawBuffers == 1 && 1330 !ctx->Query.CondRenderQuery) { 1331 struct st_renderbuffer *rbRead, *rbDraw; 1332 GLint drawX, drawY; 1333 1334 /* 1335 * Clip the read region against the src buffer bounds. 1336 * We'll still allocate a temporary buffer/texture for the original 1337 * src region size but we'll only read the region which is on-screen. 1338 * This may mean that we draw garbage pixels into the dest region, but 1339 * that's expected. 1340 */ 1341 readX = srcx; 1342 readY = srcy; 1343 readW = width; 1344 readH = height; 1345 pack = ctx->DefaultPacking; 1346 if (!_mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack)) 1347 return GL_TRUE; /* all done */ 1348 1349 /* clip against dest buffer bounds and scissor box */ 1350 drawX = dstx + pack.SkipPixels; 1351 drawY = dsty + pack.SkipRows; 1352 unpack = pack; 1353 if (!_mesa_clip_drawpixels(ctx, &drawX, &drawY, &readW, &readH, &unpack)) 1354 return GL_TRUE; /* all done */ 1355 1356 readX = readX - pack.SkipPixels + unpack.SkipPixels; 1357 readY = readY - pack.SkipRows + unpack.SkipRows; 1358 1359 rbRead = st_get_color_read_renderbuffer(ctx); 1360 rbDraw = st_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]); 1361 1362 if ((rbRead != rbDraw || 1363 !regions_overlap(readX, readY, drawX, drawY, readW, readH)) && 1364 rbRead->Base.Format == rbDraw->Base.Format) { 1365 struct pipe_box srcBox; 1366 1367 /* flip src/dst position if needed */ 1368 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1369 /* both buffers will have the same orientation */ 1370 readY = ctx->ReadBuffer->Height - readY - readH; 1371 drawY = ctx->DrawBuffer->Height - drawY - readH; 1372 } 1373 1374 u_box_2d(readX, readY, readW, readH, &srcBox); 1375 1376 pipe->resource_copy_region(pipe, 1377 rbDraw->texture, 1378 rbDraw->rtt_level, drawX, drawY, 0, 1379 rbRead->texture, 1380 rbRead->rtt_level, &srcBox); 1381 return GL_TRUE; 1382 } 1383 } 1384 1385 return GL_FALSE; 1386} 1387 1388 1389static void 1390st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy, 1391 GLsizei width, GLsizei height, 1392 GLint dstx, GLint dsty, GLenum type) 1393{ 1394 struct st_context *st = st_context(ctx); 1395 struct pipe_context *pipe = st->pipe; 1396 struct pipe_screen *screen = pipe->screen; 1397 struct st_renderbuffer *rbRead; 1398 void *driver_vp, *driver_fp; 1399 struct pipe_resource *pt; 1400 struct pipe_sampler_view *sv[2]; 1401 int num_sampler_view = 1; 1402 GLfloat *color; 1403 enum pipe_format srcFormat, texFormat; 1404 GLboolean invertTex = GL_FALSE; 1405 GLint readX, readY, readW, readH; 1406 GLuint sample_count; 1407 struct gl_pixelstore_attrib pack = ctx->DefaultPacking; 1408 struct st_fp_variant *fpv; 1409 1410 st_validate_state(st); 1411 1412 if (type == GL_DEPTH_STENCIL) { 1413 /* XXX make this more efficient */ 1414 st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_STENCIL); 1415 st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_DEPTH); 1416 return; 1417 } 1418 1419 if (type == GL_STENCIL) { 1420 /* can't use texturing to do stencil */ 1421 copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty); 1422 return; 1423 } 1424 1425 if (blit_copy_pixels(ctx, srcx, srcy, width, height, dstx, dsty, type)) 1426 return; 1427 1428 /* 1429 * The subsequent code implements glCopyPixels by copying the source 1430 * pixels into a temporary texture that's then applied to a textured quad. 1431 * When we draw the textured quad, all the usual per-fragment operations 1432 * are handled. 1433 */ 1434 1435 1436 /* 1437 * Get vertex/fragment shaders 1438 */ 1439 if (type == GL_COLOR) { 1440 rbRead = st_get_color_read_renderbuffer(ctx); 1441 color = NULL; 1442 1443 fpv = get_color_fp_variant(st); 1444 driver_fp = fpv->driver_shader; 1445 1446 driver_vp = make_passthrough_vertex_shader(st, GL_FALSE); 1447 1448 if (st->pixel_xfer.pixelmap_enabled) { 1449 sv[1] = st->pixel_xfer.pixelmap_sampler_view; 1450 num_sampler_view++; 1451 } 1452 } 1453 else { 1454 assert(type == GL_DEPTH); 1455 rbRead = st_renderbuffer(ctx->ReadBuffer-> 1456 Attachment[BUFFER_DEPTH].Renderbuffer); 1457 color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; 1458 1459 fpv = get_depth_stencil_fp_variant(st, GL_TRUE, GL_FALSE); 1460 driver_fp = fpv->driver_shader; 1461 1462 driver_vp = make_passthrough_vertex_shader(st, GL_TRUE); 1463 } 1464 1465 /* update fragment program constants */ 1466 st_upload_constants(st, fpv->parameters, PIPE_SHADER_FRAGMENT); 1467 1468 sample_count = rbRead->texture->nr_samples; 1469 /* I believe this would be legal, presumably would need to do a resolve 1470 for color, and for depth/stencil spec says to just use one of the 1471 depth/stencil samples per pixel? Need some transfer clarifications. */ 1472 assert(sample_count < 2); 1473 1474 srcFormat = rbRead->texture->format; 1475 1476 if (screen->is_format_supported(screen, srcFormat, st->internal_target, 1477 sample_count, 1478 PIPE_BIND_SAMPLER_VIEW)) { 1479 texFormat = srcFormat; 1480 } 1481 else { 1482 /* srcFormat can't be used as a texture format */ 1483 if (type == GL_DEPTH) { 1484 texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT, 1485 GL_NONE, GL_NONE, st->internal_target, 1486 sample_count, PIPE_BIND_DEPTH_STENCIL); 1487 assert(texFormat != PIPE_FORMAT_NONE); 1488 } 1489 else { 1490 /* default color format */ 1491 texFormat = st_choose_format(screen, GL_RGBA, 1492 GL_NONE, GL_NONE, st->internal_target, 1493 sample_count, PIPE_BIND_SAMPLER_VIEW); 1494 assert(texFormat != PIPE_FORMAT_NONE); 1495 } 1496 } 1497 1498 /* Invert src region if needed */ 1499 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1500 srcy = ctx->ReadBuffer->Height - srcy - height; 1501 invertTex = !invertTex; 1502 } 1503 1504 /* Clip the read region against the src buffer bounds. 1505 * We'll still allocate a temporary buffer/texture for the original 1506 * src region size but we'll only read the region which is on-screen. 1507 * This may mean that we draw garbage pixels into the dest region, but 1508 * that's expected. 1509 */ 1510 readX = srcx; 1511 readY = srcy; 1512 readW = width; 1513 readH = height; 1514 _mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack); 1515 readW = MAX2(0, readW); 1516 readH = MAX2(0, readH); 1517 1518 /* alloc temporary texture */ 1519 pt = alloc_texture(st, width, height, texFormat); 1520 if (!pt) 1521 return; 1522 1523 sv[0] = st_create_texture_sampler_view(st->pipe, pt); 1524 if (!sv[0]) { 1525 pipe_resource_reference(&pt, NULL); 1526 return; 1527 } 1528 1529 /* Make temporary texture which is a copy of the src region. 1530 */ 1531 if (srcFormat == texFormat) { 1532 struct pipe_box src_box; 1533 u_box_2d(readX, readY, readW, readH, &src_box); 1534 /* copy source framebuffer surface into mipmap/texture */ 1535 pipe->resource_copy_region(pipe, 1536 pt, /* dest tex */ 1537 0, /* dest lvl */ 1538 pack.SkipPixels, pack.SkipRows, 0, /* dest pos */ 1539 rbRead->texture, /* src tex */ 1540 rbRead->rtt_level, /* src lvl */ 1541 &src_box); 1542 1543 } 1544 else { 1545 /* CPU-based fallback/conversion */ 1546 struct pipe_transfer *ptRead = 1547 pipe_get_transfer(st->pipe, rbRead->texture, 1548 rbRead->rtt_level, 1549 rbRead->rtt_face + rbRead->rtt_slice, 1550 PIPE_TRANSFER_READ, 1551 readX, readY, readW, readH); 1552 struct pipe_transfer *ptTex; 1553 enum pipe_transfer_usage transfer_usage; 1554 1555 if (ST_DEBUG & DEBUG_FALLBACK) 1556 debug_printf("%s: fallback processing\n", __FUNCTION__); 1557 1558 if (type == GL_DEPTH && util_format_is_depth_and_stencil(pt->format)) 1559 transfer_usage = PIPE_TRANSFER_READ_WRITE; 1560 else 1561 transfer_usage = PIPE_TRANSFER_WRITE; 1562 1563 ptTex = pipe_get_transfer(st->pipe, pt, 0, 0, transfer_usage, 1564 0, 0, width, height); 1565 1566 /* copy image from ptRead surface to ptTex surface */ 1567 if (type == GL_COLOR) { 1568 /* alternate path using get/put_tile() */ 1569 GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); 1570 enum pipe_format readFormat, drawFormat; 1571 readFormat = util_format_linear(rbRead->texture->format); 1572 drawFormat = util_format_linear(pt->format); 1573 pipe_get_tile_rgba_format(pipe, ptRead, 0, 0, readW, readH, 1574 readFormat, buf); 1575 pipe_put_tile_rgba_format(pipe, ptTex, pack.SkipPixels, pack.SkipRows, 1576 readW, readH, drawFormat, buf); 1577 free(buf); 1578 } 1579 else { 1580 /* GL_DEPTH */ 1581 GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint)); 1582 pipe_get_tile_z(pipe, ptRead, 0, 0, readW, readH, buf); 1583 pipe_put_tile_z(pipe, ptTex, pack.SkipPixels, pack.SkipRows, 1584 readW, readH, buf); 1585 free(buf); 1586 } 1587 1588 pipe->transfer_destroy(pipe, ptRead); 1589 pipe->transfer_destroy(pipe, ptTex); 1590 } 1591 1592 /* OK, the texture 'pt' contains the src image/pixels. Now draw a 1593 * textured quad with that texture. 1594 */ 1595 draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2], 1596 width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, 1597 sv, 1598 num_sampler_view, 1599 driver_vp, 1600 driver_fp, 1601 color, invertTex, GL_FALSE, GL_FALSE); 1602 1603 pipe_resource_reference(&pt, NULL); 1604 pipe_sampler_view_reference(&sv[0], NULL); 1605} 1606 1607 1608 1609void st_init_drawpixels_functions(struct dd_function_table *functions) 1610{ 1611 functions->DrawPixels = st_DrawPixels; 1612 functions->CopyPixels = st_CopyPixels; 1613} 1614 1615 1616void 1617st_destroy_drawpix(struct st_context *st) 1618{ 1619 GLuint i; 1620 1621 for (i = 0; i < Elements(st->drawpix.shaders); i++) { 1622 if (st->drawpix.shaders[i]) 1623 _mesa_reference_fragprog(st->ctx, &st->drawpix.shaders[i], NULL); 1624 } 1625 1626 st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL); 1627 if (st->drawpix.vert_shaders[0]) 1628 cso_delete_vertex_shader(st->cso_context, st->drawpix.vert_shaders[0]); 1629 if (st->drawpix.vert_shaders[1]) 1630 cso_delete_vertex_shader(st->cso_context, st->drawpix.vert_shaders[1]); 1631} 1632 1633#endif /* FEATURE_drawpix */ 1634