st_cb_drawpixels.c revision edbc302ad678e1a4a8803ba0e827a13dd27105d2
1cf5933a716e7eb6bd5ff49aa62f3e76379ebaf51Chris Lattner/************************************************************************** 2fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman * 3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell * All Rights Reserved. 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner * 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner * Permission is hereby granted, free of charge, to any person obtaining a 7fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman * copy of this software and associated documentation files (the 8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell * "Software"), to deal in the Software without restriction, including 9237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner * without limitation the rights to use, copy, modify, merge, publish, 10befa499d45ffcc32bd9902518aec18589464e47cChris Lattner * distribute, sub license, and/or sell copies of the Software, and to 11befa499d45ffcc32bd9902518aec18589464e47cChris Lattner * permit persons to whom the Software is furnished to do so, subject to 12befa499d45ffcc32bd9902518aec18589464e47cChris Lattner * the following conditions: 13237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner * 14237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner * The above copyright notice and this permission notice (including the 15237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner * next paragraph) shall be included in all copies or substantial portions 1686453c52ba02e743d29c08456e51006500041456Chris Lattner * of the Software. 17237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner * 1847b14a4a6a455c7be169cfd312fcbe796f0ad426Misha Brukman * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 191f67ce4aa3f65619f54c8a3072539da5b0022841Dale Johannesen * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21e4aeec003f82a5263ffb168e175e6fca8b6f681dDan Gohman * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 236f7426ec2e46bb19cc9f9e75f1c355b35cf12d7dTanya Lattner * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 254ff4141a9ee9ce705f2a709f3372acaf58d86ea3Chris Lattner * 264ff4141a9ee9ce705f2a709f3372acaf58d86ea3Chris Lattner **************************************************************************/ 27551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer 28551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer /* 29ce63ffb52f249b62cdf2d250c128007b13f27e71Daniel Dunbar * Authors: 3012f0babca4459c253675700e1d707652d5b6ba17Chris Lattner * Brian Paul 31551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer */ 32befa499d45ffcc32bd9902518aec18589464e47cChris Lattner 33a51bcb50b0c74adc741361824ef81dbefb715c53Chris Lattner#include "main/imports.h" 34d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke#include "main/image.h" 3586453c52ba02e743d29c08456e51006500041456Chris Lattner#include "main/bufferobj.h" 36dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner#include "main/macros.h" 3786453c52ba02e743d29c08456e51006500041456Chris Lattner#include "main/texformat.h" 38199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner#include "main/texstore.h" 3986453c52ba02e743d29c08456e51006500041456Chris Lattner#include "shader/program.h" 40844731a7f1909f55935e3514c9e713a62d67662eDan Gohman#include "shader/prog_print.h" 41f9c3b228e5579e0d2a9cd05a2191fe17b4c58b23Jakob Stoklund Olesen 42f9c3b228e5579e0d2a9cd05a2191fe17b4c58b23Jakob Stoklund Olesen#include "st_debug.h" 43237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner#include "st_context.h" 44f0907fe59093753fe5a9e8fe5adc399dbdc94627Jakob Stoklund Olesen#include "st_atom.h" 45f0907fe59093753fe5a9e8fe5adc399dbdc94627Jakob Stoklund Olesen#include "st_atom_constbuf.h" 46f0907fe59093753fe5a9e8fe5adc399dbdc94627Jakob Stoklund Olesen#include "st_program.h" 47570a4a5d9ca31f276a67502d1e0533d59d331feaJakob Stoklund Olesen#include "st_cb_drawpixels.h" 48570a4a5d9ca31f276a67502d1e0533d59d331feaJakob Stoklund Olesen#include "st_cb_readpixels.h" 49570a4a5d9ca31f276a67502d1e0533d59d331feaJakob Stoklund Olesen#include "st_cb_fbo.h" 50570a4a5d9ca31f276a67502d1e0533d59d331feaJakob Stoklund Olesen#include "st_format.h" 51ae73dc1448d25b02cabc7c64c86c64371453dda8Dan Gohman#include "st_texture.h" 52ae73dc1448d25b02cabc7c64c86c64371453dda8Dan Gohman 53237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner#include "pipe/p_context.h" 54ae73dc1448d25b02cabc7c64c86c64371453dda8Dan Gohman#include "pipe/p_defines.h" 55ae73dc1448d25b02cabc7c64c86c64371453dda8Dan Gohman#include "util/u_inlines.h" 56120d053e3ba810b44047fbcb719824bed5673ca9Chris Lattner#include "tgsi/tgsi_ureg.h" 57ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner#include "util/u_tile.h" 58ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner#include "util/u_draw_quad.h" 59ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner#include "util/u_format.h" 60ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner#include "util/u_math.h" 61ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner#include "shader/prog_instruction.h" 62ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner#include "cso_cache/cso_context.h" 63ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner 64199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner 65199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner/** 66199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner * Check if the given program is: 67199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner * 0: MOVE result.color, fragment.color; 68199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner * 1: END; 69199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner */ 70199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattnerstatic GLboolean 71199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattneris_passthrough_program(const struct gl_fragment_program *prog) 72cc0a0299d96676e0a51e9b8f5bf617d8025f09a7Chris Lattner{ 73cc0a0299d96676e0a51e9b8f5bf617d8025f09a7Chris Lattner if (prog->Base.NumInstructions == 2) { 74cc0a0299d96676e0a51e9b8f5bf617d8025f09a7Chris Lattner const struct prog_instruction *inst = prog->Base.Instructions; 75cc0a0299d96676e0a51e9b8f5bf617d8025f09a7Chris Lattner if (inst[0].Opcode == OPCODE_MOV && 76199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner inst[1].Opcode == OPCODE_END && 77199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner inst[0].DstReg.File == PROGRAM_OUTPUT && 78199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner inst[0].DstReg.Index == FRAG_RESULT_COLOR && 79befa499d45ffcc32bd9902518aec18589464e47cChris Lattner inst[0].DstReg.WriteMask == WRITEMASK_XYZW && 8066c75aaa028683c389c55b377ee2411b61081677Bill Wendling inst[0].SrcReg[0].File == PROGRAM_INPUT && 8166c75aaa028683c389c55b377ee2411b61081677Bill Wendling inst[0].SrcReg[0].Index == FRAG_ATTRIB_COL0 && 82199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner inst[0].SrcReg[0].Swizzle == SWIZZLE_XYZW) { 83199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner return GL_TRUE; 84199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner } 85199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner } 8612f0babca4459c253675700e1d707652d5b6ba17Chris Lattner return GL_FALSE; 87fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman} 888c1604e7d617622cb391f1c679ddf70ea03baedcBill Wendling 898c1604e7d617622cb391f1c679ddf70ea03baedcBill Wendling 908c1604e7d617622cb391f1c679ddf70ea03baedcBill Wendling 918c1604e7d617622cb391f1c679ddf70ea03baedcBill Wendling/** 928c1604e7d617622cb391f1c679ddf70ea03baedcBill Wendling * Make fragment shader for glDraw/CopyPixels. This shader is made 938c1604e7d617622cb391f1c679ddf70ea03baedcBill Wendling * by combining the pixel transfer shader with the user-defined shader. 948c1604e7d617622cb391f1c679ddf70ea03baedcBill Wendling * \return pointer to Gallium driver fragment shader 958c1604e7d617622cb391f1c679ddf70ea03baedcBill Wendling */ 96199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattnerstatic void * 97199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattnercombined_drawpix_fragment_program(GLcontext *ctx) 98199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner{ 99199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner struct st_context *st = st_context(ctx); 100199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner struct st_fragment_program *stfp; 101199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner 102199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner if (st->pixel_xfer.program->serialNo == st->pixel_xfer.xfer_prog_sn 103199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner && st->fp->serialNo == st->pixel_xfer.user_prog_sn) { 104199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner /* the pixel tranfer program has not changed and the user-defined 105199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner * program has not changed, so re-use the combined program. 106199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner */ 107199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner stfp = st->pixel_xfer.combined_prog; 108199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner } 109199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner else { 110199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner /* Concatenate the pixel transfer program with the current user- 111199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner * defined program. 112199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner */ 113199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner if (is_passthrough_program(&st->fp->Base)) { 114199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner stfp = (struct st_fragment_program *) 115199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner _mesa_clone_fragment_program(ctx, &st->pixel_xfer.program->Base); 116199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner } 117199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner else { 118199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner#if 0 119199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner printf("Base program:\n"); 120199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner _mesa_print_program(&st->fp->Base.Base); 121199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner printf("DrawPix program:\n"); 122199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner _mesa_print_program(&st->pixel_xfer.program->Base.Base); 123199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner#endif 124199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner stfp = (struct st_fragment_program *) 125199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner _mesa_combine_programs(ctx, 126199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner &st->pixel_xfer.program->Base.Base, 127199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner &st->fp->Base.Base); 128199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner } 129199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner 130199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner#if 0 131199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner { 132199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner struct gl_program *p = &stfp->Base.Base; 133199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner printf("Combined DrawPixels program:\n"); 134199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner _mesa_print_program(p); 135199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner printf("InputsRead: 0x%x\n", p->InputsRead); 136199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner printf("OutputsWritten: 0x%x\n", p->OutputsWritten); 137199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner _mesa_print_parameter_list(p->Parameters); 138199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner } 139199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner#endif 140199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner 141199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner /* translate to TGSI tokens */ 142199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner st_translate_fragment_program(st, stfp); 143199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner 144199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner /* save new program, update serial numbers */ 145199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner st->pixel_xfer.xfer_prog_sn = st->pixel_xfer.program->serialNo; 146199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner st->pixel_xfer.user_prog_sn = st->fp->serialNo; 147199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner st->pixel_xfer.combined_prog_sn = stfp->serialNo; 148199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner /* can't reference new program directly, already have a reference on it */ 149199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL); 150199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner st->pixel_xfer.combined_prog = stfp; 151199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner } 152199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner 153199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner /* Ideally we'd have updated the pipe constants during the normal 154199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner * st/atom mechanism. But we can't since this is specific to glDrawPixels. 155199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner */ 156199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner st_upload_constants(st, stfp->Base.Base.Parameters, PIPE_SHADER_FRAGMENT); 157c0aa67950ae0f6e9611240d8f0e3ac49dc8195c0David Greene 158199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner return stfp->driver_shader; 159199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner} 160199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner 161199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner 162199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner/** 163199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner * Create fragment shader that does a TEX() instruction to get a Z 164199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner * value, then writes to FRAG_RESULT_DEPTH. 165fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman * Pass fragment color through as-is. 166199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner * \return pointer to the Gallium driver fragment shader 167199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner */ 168199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattnerstatic void * 1691f67ce4aa3f65619f54c8a3072539da5b0022841Dale Johannesenmake_fragment_shader_z(struct st_context *st) 170199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner{ 171199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner GLcontext *ctx = st->ctx; 172199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner struct gl_program *p; 173199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner GLuint ic = 0; 174199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner 175199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner if (st->drawpix.z_shader) { 176199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner return st->drawpix.z_shader->driver_shader; 177befa499d45ffcc32bd9902518aec18589464e47cChris Lattner } 178199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner 179befa499d45ffcc32bd9902518aec18589464e47cChris Lattner /* 180237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner * Create shader now 181f8526cb711ec96cd2d5aff30da57f65ae8e5b7b8Jakob Stoklund Olesen */ 182570a4a5d9ca31f276a67502d1e0533d59d331feaJakob Stoklund Olesen p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); 183f0907fe59093753fe5a9e8fe5adc399dbdc94627Jakob Stoklund Olesen if (!p) 184570a4a5d9ca31f276a67502d1e0533d59d331feaJakob Stoklund Olesen return NULL; 185570a4a5d9ca31f276a67502d1e0533d59d331feaJakob Stoklund Olesen 186570a4a5d9ca31f276a67502d1e0533d59d331feaJakob Stoklund Olesen p->NumInstructions = 3; 187f8526cb711ec96cd2d5aff30da57f65ae8e5b7b8Jakob Stoklund Olesen 188f8526cb711ec96cd2d5aff30da57f65ae8e5b7b8Jakob Stoklund Olesen p->Instructions = _mesa_alloc_instructions(p->NumInstructions); 189f8526cb711ec96cd2d5aff30da57f65ae8e5b7b8Jakob Stoklund Olesen if (!p->Instructions) { 190f0907fe59093753fe5a9e8fe5adc399dbdc94627Jakob Stoklund Olesen ctx->Driver.DeleteProgram(ctx, p); 191f0907fe59093753fe5a9e8fe5adc399dbdc94627Jakob Stoklund Olesen return NULL; 192f0907fe59093753fe5a9e8fe5adc399dbdc94627Jakob Stoklund Olesen } 193f0907fe59093753fe5a9e8fe5adc399dbdc94627Jakob Stoklund Olesen _mesa_init_instructions(p->Instructions, p->NumInstructions); 194f0907fe59093753fe5a9e8fe5adc399dbdc94627Jakob Stoklund Olesen 195f0907fe59093753fe5a9e8fe5adc399dbdc94627Jakob Stoklund Olesen /* TEX result.depth, fragment.texcoord[0], texture[0], 2D; */ 196f0907fe59093753fe5a9e8fe5adc399dbdc94627Jakob Stoklund Olesen p->Instructions[ic].Opcode = OPCODE_TEX; 197570a4a5d9ca31f276a67502d1e0533d59d331feaJakob Stoklund Olesen p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT; 198f0907fe59093753fe5a9e8fe5adc399dbdc94627Jakob Stoklund Olesen p->Instructions[ic].DstReg.Index = FRAG_RESULT_DEPTH; 199f8526cb711ec96cd2d5aff30da57f65ae8e5b7b8Jakob Stoklund Olesen p->Instructions[ic].DstReg.WriteMask = WRITEMASK_Z; 200f8526cb711ec96cd2d5aff30da57f65ae8e5b7b8Jakob Stoklund Olesen p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT; 2011a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0; 2021a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar p->Instructions[ic].TexSrcUnit = 0; 2031a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX; 204c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar ic++; 2051a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar 206c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar /* MOV result.color, fragment.color */ 207c0aa67950ae0f6e9611240d8f0e3ac49dc8195c0David Greene p->Instructions[ic].Opcode = OPCODE_MOV; 20884a832f9272ed7f1a47c3e019c770b62e373cc6cBill Wendling p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT; 209c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar p->Instructions[ic].DstReg.Index = FRAG_RESULT_COLOR; 210c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT; 211c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_COL0; 212c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar ic++; 213c0aa67950ae0f6e9611240d8f0e3ac49dc8195c0David Greene 21484a832f9272ed7f1a47c3e019c770b62e373cc6cBill Wendling /* END; */ 215c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar p->Instructions[ic++].Opcode = OPCODE_END; 216c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar 217c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar assert(ic == p->NumInstructions); 218c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar 219e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen p->InputsRead = FRAG_BIT_TEX0 | FRAG_BIT_COL0; 220570a4a5d9ca31f276a67502d1e0533d59d331feaJakob Stoklund Olesen p->OutputsWritten = (1 << FRAG_RESULT_COLOR) | (1 << FRAG_RESULT_DEPTH); 221135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner p->SamplersUsed = 0x1; /* sampler 0 (bit 0) is used */ 2222ddbf8208e0ee50cb1aeb24d509b52549a85c211Jakob Stoklund Olesen 2232ddbf8208e0ee50cb1aeb24d509b52549a85c211Jakob Stoklund Olesen st->drawpix.z_shader = (struct st_fragment_program *) p; 224c0aa67950ae0f6e9611240d8f0e3ac49dc8195c0David Greene st_translate_fragment_program(st, st->drawpix.z_shader); 2252ddbf8208e0ee50cb1aeb24d509b52549a85c211Jakob Stoklund Olesen 22684a832f9272ed7f1a47c3e019c770b62e373cc6cBill Wendling return st->drawpix.z_shader->driver_shader; 2271a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar} 2281a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar 229135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner 230e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen 231e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen/** 232e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen * Create a simple vertex shader that just passes through the 233e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen * vertex position and texcoord (and optionally, color). 234e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen */ 235e91b9a3b59688023e20cee8441179300b87c844eDale Johannesenstatic void * 236e91b9a3b59688023e20cee8441179300b87c844eDale Johannesenmake_passthrough_vertex_shader(struct st_context *st, 237e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen GLboolean passColor) 238e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen{ 239e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen if (!st->drawpix.vert_shaders[passColor]) { 240e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen struct ureg_program *ureg = 241e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen ureg_create( TGSI_PROCESSOR_VERTEX ); 242e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen 243e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen if (ureg == NULL) 244e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen return NULL; 245e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen 246e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen /* MOV result.pos, vertex.pos; */ 247e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen ureg_MOV(ureg, 248e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen ureg_DECL_output( ureg, TGSI_SEMANTIC_POSITION, 0 ), 249e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen ureg_DECL_vs_input( ureg, 0 )); 250e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen 251e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen /* MOV result.texcoord0, vertex.attr[1]; */ 252e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen ureg_MOV(ureg, 253e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen ureg_DECL_output( ureg, TGSI_SEMANTIC_GENERIC, 0 ), 254e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen ureg_DECL_vs_input( ureg, 1 )); 255e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen 256e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen if (passColor) { 257e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen /* MOV result.color0, vertex.attr[2]; */ 258570a4a5d9ca31f276a67502d1e0533d59d331feaJakob Stoklund Olesen ureg_MOV(ureg, 259e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 ), 260e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen ureg_DECL_vs_input( ureg, 2 )); 261e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen } 262e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen 263e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen ureg_END( ureg ); 264bdb984bc2757114bc706026603ed40d7f508c4c1Dale Johannesen 265e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen st->drawpix.vert_shaders[passColor] = 266e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen ureg_create_shader_and_destroy( ureg, st->pipe ); 267bdb984bc2757114bc706026603ed40d7f508c4c1Dale Johannesen } 268bdb984bc2757114bc706026603ed40d7f508c4c1Dale Johannesen 269e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen return st->drawpix.vert_shaders[passColor]; 270e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen} 271e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen 272e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen 273e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen/** 274e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen * Return a texture internalFormat for drawing/copying an image 275e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen * of the given type. 276e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen */ 277e91b9a3b59688023e20cee8441179300b87c844eDale Johannesenstatic GLenum 278bdb984bc2757114bc706026603ed40d7f508c4c1Dale Johannesenbase_format(GLenum format) 279e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen{ 280e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen switch (format) { 281e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen case GL_DEPTH_COMPONENT: 282c0aa67950ae0f6e9611240d8f0e3ac49dc8195c0David Greene return GL_DEPTH_COMPONENT; 283e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen case GL_DEPTH_STENCIL: 284e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen return GL_DEPTH_STENCIL; 285e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen case GL_STENCIL_INDEX: 286e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen return GL_STENCIL_INDEX; 287e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen default: 288e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen return GL_RGBA; 289c0aa67950ae0f6e9611240d8f0e3ac49dc8195c0David Greene } 2902ddbf8208e0ee50cb1aeb24d509b52549a85c211Jakob Stoklund Olesen} 291e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen 292135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner 2931a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar/** 294237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner * Create a temporary texture to hold an image of the given size. 2955095e3d1d1caef8d573534d369e37277c623064cChris Lattner * If width, height are not POT and the driver only handles POT textures, 296237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner * allocate the next larger size of texture that is POT. 29702a436c48ecff9e34d50ce0a2f861e5acdd9bf3fDan Gohman */ 298237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattnerstatic struct pipe_resource * 29916581bf931c0ccf2f8993397acfa4e1d509a68dcDale Johannesenalloc_texture(struct st_context *st, GLsizei width, GLsizei height, 300c0aa67950ae0f6e9611240d8f0e3ac49dc8195c0David Greene enum pipe_format texFormat) 301237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner{ 302befa499d45ffcc32bd9902518aec18589464e47cChris Lattner struct pipe_context *pipe = st->pipe; 303befa499d45ffcc32bd9902518aec18589464e47cChris Lattner struct pipe_screen *screen = pipe->screen; 304c0aa67950ae0f6e9611240d8f0e3ac49dc8195c0David Greene struct pipe_resource *pt; 305237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner int ptw, pth; 306237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner 307befa499d45ffcc32bd9902518aec18589464e47cChris Lattner ptw = width; 308befa499d45ffcc32bd9902518aec18589464e47cChris Lattner pth = height; 309befa499d45ffcc32bd9902518aec18589464e47cChris Lattner 310199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner /* Need to use POT texture? */ 311befa499d45ffcc32bd9902518aec18589464e47cChris Lattner if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) { 312135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner int l2pt, maxSize; 313135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner 314135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner l2pt = util_logbase2(width); 315135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner if (1 << l2pt != width) { 316135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner ptw = 1 << (l2pt + 1); 317135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner } 318135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner 319e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen l2pt = util_logbase2(height); 320d43d5e832f756c9d2c0c8ff4d2f51807a27cab8dChris Lattner if (1 << l2pt != height) { 321d43d5e832f756c9d2c0c8ff4d2f51807a27cab8dChris Lattner pth = 1 << (l2pt + 1); 322135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner } 323135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner 324d43d5e832f756c9d2c0c8ff4d2f51807a27cab8dChris Lattner /* Check against maximum texture size */ 325d43d5e832f756c9d2c0c8ff4d2f51807a27cab8dChris Lattner maxSize = 1 << (pipe->screen->get_param(pipe->screen, 326d43d5e832f756c9d2c0c8ff4d2f51807a27cab8dChris Lattner PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1); 327d43d5e832f756c9d2c0c8ff4d2f51807a27cab8dChris Lattner assert(ptw <= maxSize); 328d43d5e832f756c9d2c0c8ff4d2f51807a27cab8dChris Lattner assert(pth <= maxSize); 329d43d5e832f756c9d2c0c8ff4d2f51807a27cab8dChris Lattner } 330d43d5e832f756c9d2c0c8ff4d2f51807a27cab8dChris Lattner 331135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner pt = st_texture_create(st, PIPE_TEXTURE_2D, texFormat, 0, 332135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner ptw, pth, 1, PIPE_BIND_SAMPLER_VIEW); 333237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner 334c0aa67950ae0f6e9611240d8f0e3ac49dc8195c0David Greene return pt; 335fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman} 336befa499d45ffcc32bd9902518aec18589464e47cChris Lattner 337befa499d45ffcc32bd9902518aec18589464e47cChris Lattner 338befa499d45ffcc32bd9902518aec18589464e47cChris Lattner/** 339befa499d45ffcc32bd9902518aec18589464e47cChris Lattner * Make texture containing an image for glDrawPixels image. 340befa499d45ffcc32bd9902518aec18589464e47cChris Lattner * If 'pixels' is NULL, leave the texture image data undefined. 341befa499d45ffcc32bd9902518aec18589464e47cChris Lattner */ 342befa499d45ffcc32bd9902518aec18589464e47cChris Lattnerstatic struct pipe_resource * 343fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukmanmake_texture(struct st_context *st, 344199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner GLsizei width, GLsizei height, GLenum format, GLenum type, 345199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner const struct gl_pixelstore_attrib *unpack, 346199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner const GLvoid *pixels) 347befa499d45ffcc32bd9902518aec18589464e47cChris Lattner{ 348befa499d45ffcc32bd9902518aec18589464e47cChris Lattner GLcontext *ctx = st->ctx; 349befa499d45ffcc32bd9902518aec18589464e47cChris Lattner struct pipe_context *pipe = st->pipe; 350befa499d45ffcc32bd9902518aec18589464e47cChris Lattner gl_format mformat; 351befa499d45ffcc32bd9902518aec18589464e47cChris Lattner struct pipe_resource *pt; 352befa499d45ffcc32bd9902518aec18589464e47cChris Lattner enum pipe_format pipeFormat; 353befa499d45ffcc32bd9902518aec18589464e47cChris Lattner GLuint cpp; 354befa499d45ffcc32bd9902518aec18589464e47cChris Lattner GLenum baseFormat; 355135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner 356199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner baseFormat = base_format(format); 357199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner 358dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner mformat = st_ChooseTextureFormat(ctx, baseFormat, format, type); 359199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner assert(mformat); 360dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner 361dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner pipeFormat = st_mesa_format_to_pipe_format(mformat); 362dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner assert(pipeFormat); 363dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner cpp = util_format_get_blocksize(pipeFormat); 364dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner 3654ff4141a9ee9ce705f2a709f3372acaf58d86ea3Chris Lattner pixels = _mesa_map_pbo_source(ctx, unpack, pixels); 366c0aa67950ae0f6e9611240d8f0e3ac49dc8195c0David Greene if (!pixels) 367dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner return NULL; 368dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner 369dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner /* alloc temporary texture */ 370dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner pt = alloc_texture(st, width, height, pipeFormat); 371dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner if (!pt) { 372f7477470d37ee2ab9075eaee4745fa084d424ab8Jakob Stoklund Olesen _mesa_unmap_pbo_source(ctx, unpack); 373f7477470d37ee2ab9075eaee4745fa084d424ab8Jakob Stoklund Olesen return NULL; 374dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner } 375dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner 376dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner { 377135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner struct pipe_transfer *transfer; 378dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner static const GLuint dstImageOffsets = 0; 379dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner GLboolean success; 380dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner GLubyte *dest; 381dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner const GLbitfield imageTransferStateSave = ctx->_ImageTransferState; 382e91b9a3b59688023e20cee8441179300b87c844eDale Johannesen 383dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner /* we'll do pixel transfer in a fragment shader */ 384dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner ctx->_ImageTransferState = 0x0; 385dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner 386dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner transfer = pipe_get_transfer(st->pipe, pt, 0, 0, 0, 387f7477470d37ee2ab9075eaee4745fa084d424ab8Jakob Stoklund Olesen PIPE_TRANSFER_WRITE, 0, 0, 388f7477470d37ee2ab9075eaee4745fa084d424ab8Jakob Stoklund Olesen width, height); 389f7477470d37ee2ab9075eaee4745fa084d424ab8Jakob Stoklund Olesen 390dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner /* map texture transfer */ 391135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner dest = pipe_transfer_map(pipe, transfer); 392dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner 393dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner 394dbab4dc942e0c3286415908762de71a9447f9dfaChris Lattner /* Put image into texture transfer. 395d43d5e832f756c9d2c0c8ff4d2f51807a27cab8dChris Lattner * Note that the image is actually going to be upside down in 396b374b90e81d0ce6b5d02041ba4f7b15a945b38d8Chris Lattner * the texture. We deal with that with texcoords. 397d43d5e832f756c9d2c0c8ff4d2f51807a27cab8dChris Lattner */ 398b374b90e81d0ce6b5d02041ba4f7b15a945b38d8Chris Lattner success = _mesa_texstore(ctx, 2, /* dims */ 399b374b90e81d0ce6b5d02041ba4f7b15a945b38d8Chris Lattner baseFormat, /* baseInternalFormat */ 400b374b90e81d0ce6b5d02041ba4f7b15a945b38d8Chris Lattner mformat, /* gl_format */ 401b374b90e81d0ce6b5d02041ba4f7b15a945b38d8Chris Lattner dest, /* dest */ 402c0aa67950ae0f6e9611240d8f0e3ac49dc8195c0David Greene 0, 0, 0, /* dstX/Y/Zoffset */ 403199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner transfer->stride, /* dstRowStride, bytes */ 404199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner &dstImageOffsets, /* dstImageOffsets */ 405199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner width, height, 1, /* size */ 406199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner format, type, /* src format/type */ 407199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner pixels, /* data source */ 408199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner unpack); 409199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner 410199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner /* unmap */ 411199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner pipe_transfer_unmap(pipe, transfer); 412199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner pipe->transfer_destroy(pipe, transfer); 413199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner 414199ba42cbf56b2fc9c708edb4f08f97dd99ddd49Chris Lattner assert(success); 415135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner 416135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner /* restore */ 417135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner ctx->_ImageTransferState = imageTransferStateSave; 418135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner } 419135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner 420135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner _mesa_unmap_pbo_source(ctx, unpack); 421135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner 422135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner return pt; 423135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner} 424135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner 425237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner 426135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner/** 427135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner * Draw quad with texcoords and optional color. 428135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner * Coords are gallium window coords with y=0=top. 429135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner * \param color may be null 430135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner * \param invertTex if true, flip texcoords vertically 431befa499d45ffcc32bd9902518aec18589464e47cChris Lattner */ 432237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattnerstatic void 433775cbdd51a3b33dd5eb343689f65ab5cc8ac7118Chris Lattnerdraw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z, 434237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner GLfloat x1, GLfloat y1, const GLfloat *color, 435d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke GLboolean invertTex, GLfloat maxXcoord, GLfloat maxYcoord) 43668d57e7ae80044401efd889270a12c71b3efb9abChris Lattner{ 43768d57e7ae80044401efd889270a12c71b3efb9abChris Lattner struct st_context *st = st_context(ctx); 43868d57e7ae80044401efd889270a12c71b3efb9abChris Lattner struct pipe_context *pipe = st->pipe; 439b7c6bf1e073088635951435acedff793add1cefdDevang Patel GLfloat verts[4][3][4]; /* four verts, three attribs, XYZW */ 440b7c6bf1e073088635951435acedff793add1cefdDevang Patel 441b7c6bf1e073088635951435acedff793add1cefdDevang Patel /* setup vertex data */ 442135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner { 443135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner const struct gl_framebuffer *fb = st->ctx->DrawBuffer; 444b7c6bf1e073088635951435acedff793add1cefdDevang Patel const GLfloat fb_width = (GLfloat) fb->Width; 445135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner const GLfloat fb_height = (GLfloat) fb->Height; 446135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner const GLfloat clip_x0 = x0 / fb_width * 2.0f - 1.0f; 4473e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner const GLfloat clip_y0 = y0 / fb_height * 2.0f - 1.0f; 4483e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner const GLfloat clip_x1 = x1 / fb_width * 2.0f - 1.0f; 4493e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner const GLfloat clip_y1 = y1 / fb_height * 2.0f - 1.0f; 4503e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner const GLfloat sLeft = 0.0f, sRight = maxXcoord; 4513e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner const GLfloat tTop = invertTex ? maxYcoord : 0.0f; 452b374b90e81d0ce6b5d02041ba4f7b15a945b38d8Chris Lattner const GLfloat tBot = invertTex ? 0.0f : maxYcoord; 453135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner GLuint i; 454135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner 455135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner /* upper-left */ 456135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[0][0][0] = clip_x0; /* v[0].attr[0].x */ 457135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[0][0][1] = clip_y0; /* v[0].attr[0].y */ 458135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner 459135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner /* upper-right */ 460135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[1][0][0] = clip_x1; 461135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[1][0][1] = clip_y0; 462135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner 463b374b90e81d0ce6b5d02041ba4f7b15a945b38d8Chris Lattner /* lower-right */ 464b374b90e81d0ce6b5d02041ba4f7b15a945b38d8Chris Lattner verts[2][0][0] = clip_x1; 465135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[2][0][1] = clip_y1; 466135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner 467135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner /* lower-left */ 468135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[3][0][0] = clip_x0; 469135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[3][0][1] = clip_y1; 470135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner 471135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[0][1][0] = sLeft; /* v[0].attr[1].S */ 472135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[0][1][1] = tTop; /* v[0].attr[1].T */ 473135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[1][1][0] = sRight; 474135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[1][1][1] = tTop; 475135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[2][1][0] = sRight; 476fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman verts[2][1][1] = tBot; 477135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[3][1][0] = sLeft; 478135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[3][1][1] = tBot; 47968d57e7ae80044401efd889270a12c71b3efb9abChris Lattner 4803e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner /* same for all verts: */ 4813e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner if (color) { 4823e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner for (i = 0; i < 4; i++) { 4833e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner verts[i][0][2] = z; /* v[i].attr[0].z */ 484135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[i][0][3] = 1.0f; /* v[i].attr[0].w */ 485135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[i][2][0] = color[0]; /* v[i].attr[2].r */ 486135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[i][2][1] = color[1]; /* v[i].attr[2].g */ 487135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[i][2][2] = color[2]; /* v[i].attr[2].b */ 4883e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner verts[i][2][3] = color[3]; /* v[i].attr[2].a */ 489135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[i][1][2] = 0.0f; /* v[i].attr[1].R */ 490135755dae4c3fa8003b76150689d5064aa4612eeChris Lattner verts[i][1][3] = 1.0f; /* v[i].attr[1].Q */ 4911f67ce4aa3f65619f54c8a3072539da5b0022841Dale Johannesen } 4923e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner } 4933e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner else { 4943e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner for (i = 0; i < 4; i++) { 4953e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner verts[i][0][2] = z; /*Z*/ 4963e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner verts[i][0][3] = 1.0f; /*W*/ 49768d57e7ae80044401efd889270a12c71b3efb9abChris Lattner verts[i][1][2] = 0.0f; /*R*/ 49868d57e7ae80044401efd889270a12c71b3efb9abChris Lattner verts[i][1][3] = 1.0f; /*Q*/ 499 } 500 } 501 } 502 503 { 504 struct pipe_resource *buf; 505 506 /* allocate/load buffer object with vertex data */ 507 buf = pipe_buffer_create(pipe->screen, 508 PIPE_BIND_VERTEX_BUFFER, 509 sizeof(verts)); 510 pipe_buffer_write(st->pipe, buf, 0, sizeof(verts), verts); 511 512 util_draw_vertex_buffer(pipe, buf, 0, 513 PIPE_PRIM_QUADS, 514 4, /* verts */ 515 3); /* attribs/vert */ 516 pipe_resource_reference(&buf, NULL); 517 } 518} 519 520 521 522static void 523draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, 524 GLsizei width, GLsizei height, 525 GLfloat zoomX, GLfloat zoomY, 526 struct pipe_sampler_view *sv, 527 void *driver_vp, 528 void *driver_fp, 529 const GLfloat *color, 530 GLboolean invertTex) 531{ 532 struct st_context *st = st_context(ctx); 533 struct pipe_context *pipe = st->pipe; 534 struct cso_context *cso = st->cso_context; 535 GLfloat x0, y0, x1, y1; 536 GLsizei maxSize; 537 538 /* limit checks */ 539 /* XXX if DrawPixels image is larger than max texture size, break 540 * it up into chunks. 541 */ 542 maxSize = 1 << (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1); 543 assert(width <= maxSize); 544 assert(height <= maxSize); 545 546 cso_save_rasterizer(cso); 547 cso_save_viewport(cso); 548 cso_save_samplers(cso); 549 cso_save_fragment_sampler_views(cso); 550 cso_save_fragment_shader(cso); 551 cso_save_vertex_shader(cso); 552 cso_save_vertex_elements(cso); 553 554 /* rasterizer state: just scissor */ 555 { 556 struct pipe_rasterizer_state rasterizer; 557 memset(&rasterizer, 0, sizeof(rasterizer)); 558 rasterizer.gl_rasterization_rules = 1; 559 rasterizer.scissor = ctx->Scissor.Enabled; 560 cso_set_rasterizer(cso, &rasterizer); 561 } 562 563 /* fragment shader state: TEX lookup program */ 564 cso_set_fragment_shader_handle(cso, driver_fp); 565 566 /* vertex shader state: position + texcoord pass-through */ 567 cso_set_vertex_shader_handle(cso, driver_vp); 568 569 570 /* texture sampling state: */ 571 { 572 struct pipe_sampler_state sampler; 573 memset(&sampler, 0, sizeof(sampler)); 574 sampler.wrap_s = PIPE_TEX_WRAP_CLAMP; 575 sampler.wrap_t = PIPE_TEX_WRAP_CLAMP; 576 sampler.wrap_r = PIPE_TEX_WRAP_CLAMP; 577 sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; 578 sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 579 sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 580 sampler.normalized_coords = 1; 581 582 cso_single_sampler(cso, 0, &sampler); 583 if (st->pixel_xfer.pixelmap_enabled) { 584 cso_single_sampler(cso, 1, &sampler); 585 } 586 cso_single_sampler_done(cso); 587 } 588 589 /* viewport state: viewport matching window dims */ 590 { 591 const float w = (float) ctx->DrawBuffer->Width; 592 const float h = (float) ctx->DrawBuffer->Height; 593 struct pipe_viewport_state vp; 594 vp.scale[0] = 0.5f * w; 595 vp.scale[1] = -0.5f * h; 596 vp.scale[2] = 0.5f; 597 vp.scale[3] = 1.0f; 598 vp.translate[0] = 0.5f * w; 599 vp.translate[1] = 0.5f * h; 600 vp.translate[2] = 0.5f; 601 vp.translate[3] = 0.0f; 602 cso_set_viewport(cso, &vp); 603 } 604 605 cso_set_vertex_elements(cso, 3, st->velems_util_draw); 606 607 /* texture state: */ 608 if (st->pixel_xfer.pixelmap_enabled) { 609 struct pipe_sampler_view *sampler_views[2]; 610 sampler_views[0] = sv; 611 sampler_views[1] = st->pixel_xfer.pixelmap_sampler_view; 612 cso_set_fragment_sampler_views(cso, 2, sampler_views); 613 } 614 else { 615 cso_set_fragment_sampler_views(cso, 1, &sv); 616 } 617 618 /* Compute Gallium window coords (y=0=top) with pixel zoom. 619 * Recall that these coords are transformed by the current 620 * vertex shader and viewport transformation. 621 */ 622 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM) { 623 y = ctx->DrawBuffer->Height - (int) (y + height * ctx->Pixel.ZoomY); 624 invertTex = !invertTex; 625 } 626 627 x0 = (GLfloat) x; 628 x1 = x + width * ctx->Pixel.ZoomX; 629 y0 = (GLfloat) y; 630 y1 = y + height * ctx->Pixel.ZoomY; 631 632 /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */ 633 z = z * 2.0 - 1.0; 634 635 draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex, 636 (GLfloat) width / sv->texture->width0, 637 (GLfloat) height / sv->texture->height0); 638 639 /* restore state */ 640 cso_restore_rasterizer(cso); 641 cso_restore_viewport(cso); 642 cso_restore_samplers(cso); 643 cso_restore_fragment_sampler_views(cso); 644 cso_restore_fragment_shader(cso); 645 cso_restore_vertex_shader(cso); 646 cso_restore_vertex_elements(cso); 647} 648 649 650static void 651draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, 652 GLsizei width, GLsizei height, GLenum format, GLenum type, 653 const struct gl_pixelstore_attrib *unpack, 654 const GLvoid *pixels) 655{ 656 struct st_context *st = st_context(ctx); 657 struct pipe_context *pipe = st->pipe; 658 struct st_renderbuffer *strb; 659 enum pipe_transfer_usage usage; 660 struct pipe_transfer *pt; 661 const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; 662 GLint skipPixels; 663 ubyte *stmap; 664 struct gl_pixelstore_attrib clippedUnpack = *unpack; 665 666 if (!zoom) { 667 if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height, 668 &clippedUnpack)) { 669 /* totally clipped */ 670 return; 671 } 672 } 673 674 strb = st_renderbuffer(ctx->DrawBuffer-> 675 Attachment[BUFFER_STENCIL].Renderbuffer); 676 677 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 678 y = ctx->DrawBuffer->Height - y - height; 679 } 680 681 if(format != GL_DEPTH_STENCIL && 682 util_format_get_component_bits(strb->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0) 683 usage = PIPE_TRANSFER_READ_WRITE; 684 else 685 usage = PIPE_TRANSFER_WRITE; 686 687 pt = pipe_get_transfer(st_context(ctx)->pipe, strb->texture, 0, 0, 0, 688 usage, x, y, 689 width, height); 690 691 stmap = pipe_transfer_map(pipe, pt); 692 693 pixels = _mesa_map_pbo_source(ctx, &clippedUnpack, pixels); 694 assert(pixels); 695 696 /* if width > MAX_WIDTH, have to process image in chunks */ 697 skipPixels = 0; 698 while (skipPixels < width) { 699 const GLint spanX = skipPixels; 700 const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH); 701 GLint row; 702 for (row = 0; row < height; row++) { 703 GLubyte sValues[MAX_WIDTH]; 704 GLuint zValues[MAX_WIDTH]; 705 GLenum destType = GL_UNSIGNED_BYTE; 706 const GLvoid *source = _mesa_image_address2d(&clippedUnpack, pixels, 707 width, height, 708 format, type, 709 row, skipPixels); 710 _mesa_unpack_stencil_span(ctx, spanWidth, destType, sValues, 711 type, source, &clippedUnpack, 712 ctx->_ImageTransferState); 713 714 if (format == GL_DEPTH_STENCIL) { 715 _mesa_unpack_depth_span(ctx, spanWidth, GL_UNSIGNED_INT, zValues, 716 (1 << 24) - 1, type, source, 717 &clippedUnpack); 718 } 719 720 if (zoom) { 721 _mesa_problem(ctx, "Gallium glDrawPixels(GL_STENCIL) with " 722 "zoom not complete"); 723 } 724 725 { 726 GLint spanY; 727 728 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 729 spanY = height - row - 1; 730 } 731 else { 732 spanY = row; 733 } 734 735 /* now pack the stencil (and Z) values in the dest format */ 736 switch (pt->resource->format) { 737 case PIPE_FORMAT_S8_USCALED: 738 { 739 ubyte *dest = stmap + spanY * pt->stride + spanX; 740 assert(usage == PIPE_TRANSFER_WRITE); 741 memcpy(dest, sValues, spanWidth); 742 } 743 break; 744 case PIPE_FORMAT_Z24_UNORM_S8_USCALED: 745 if (format == GL_DEPTH_STENCIL) { 746 uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); 747 GLint k; 748 assert(usage == PIPE_TRANSFER_WRITE); 749 for (k = 0; k < spanWidth; k++) { 750 dest[k] = zValues[k] | (sValues[k] << 24); 751 } 752 } 753 else { 754 uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); 755 GLint k; 756 assert(usage == PIPE_TRANSFER_READ_WRITE); 757 for (k = 0; k < spanWidth; k++) { 758 dest[k] = (dest[k] & 0xffffff) | (sValues[k] << 24); 759 } 760 } 761 break; 762 case PIPE_FORMAT_S8_USCALED_Z24_UNORM: 763 if (format == GL_DEPTH_STENCIL) { 764 uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); 765 GLint k; 766 assert(usage == PIPE_TRANSFER_WRITE); 767 for (k = 0; k < spanWidth; k++) { 768 dest[k] = (zValues[k] << 8) | (sValues[k] & 0xff); 769 } 770 } 771 else { 772 uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); 773 GLint k; 774 assert(usage == PIPE_TRANSFER_READ_WRITE); 775 for (k = 0; k < spanWidth; k++) { 776 dest[k] = (dest[k] & 0xffffff00) | (sValues[k] & 0xff); 777 } 778 } 779 break; 780 default: 781 assert(0); 782 } 783 } 784 } 785 skipPixels += spanWidth; 786 } 787 788 _mesa_unmap_pbo_source(ctx, &clippedUnpack); 789 790 /* unmap the stencil buffer */ 791 pipe_transfer_unmap(pipe, pt); 792 pipe->transfer_destroy(pipe, pt); 793} 794 795 796/** 797 * Called via ctx->Driver.DrawPixels() 798 */ 799static void 800st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, 801 GLenum format, GLenum type, 802 const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels) 803{ 804 void *driver_vp, *driver_fp; 805 struct st_context *st = st_context(ctx); 806 const GLfloat *color; 807 808 if (format == GL_STENCIL_INDEX || 809 format == GL_DEPTH_STENCIL) { 810 draw_stencil_pixels(ctx, x, y, width, height, format, type, 811 unpack, pixels); 812 return; 813 } 814 815 /* Mesa state should be up to date by now */ 816 assert(ctx->NewState == 0x0); 817 818 st_validate_state(st); 819 820 if (format == GL_DEPTH_COMPONENT) { 821 driver_fp = make_fragment_shader_z(st); 822 driver_vp = make_passthrough_vertex_shader(st, GL_TRUE); 823 color = ctx->Current.RasterColor; 824 } 825 else { 826 driver_fp = combined_drawpix_fragment_program(ctx); 827 driver_vp = make_passthrough_vertex_shader(st, GL_FALSE); 828 color = NULL; 829 } 830 831 /* draw with textured quad */ 832 { 833 struct pipe_resource *pt 834 = make_texture(st, width, height, format, type, unpack, pixels); 835 if (pt) { 836 struct pipe_sampler_view *sv = st_create_texture_sampler_view(st->pipe, pt); 837 838 if (sv) { 839 draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2], 840 width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, 841 sv, 842 driver_vp, 843 driver_fp, 844 color, GL_FALSE); 845 pipe_sampler_view_reference(&sv, NULL); 846 } 847 pipe_resource_reference(&pt, NULL); 848 } 849 } 850} 851 852 853 854static void 855copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, 856 GLsizei width, GLsizei height, 857 GLint dstx, GLint dsty) 858{ 859 struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer); 860 struct pipe_context *pipe = st_context(ctx)->pipe; 861 enum pipe_transfer_usage usage; 862 struct pipe_transfer *ptDraw; 863 ubyte *drawMap; 864 ubyte *buffer; 865 int i; 866 867 buffer = malloc(width * height * sizeof(ubyte)); 868 if (!buffer) { 869 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels(stencil)"); 870 return; 871 } 872 873 /* this will do stencil pixel transfer ops */ 874 st_read_stencil_pixels(ctx, srcx, srcy, width, height, 875 GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, 876 &ctx->DefaultPacking, buffer); 877 878 if(util_format_get_component_bits(rbDraw->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0) 879 usage = PIPE_TRANSFER_READ_WRITE; 880 else 881 usage = PIPE_TRANSFER_WRITE; 882 883 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 884 dsty = rbDraw->Base.Height - dsty - height; 885 } 886 887 ptDraw = pipe_get_transfer(st_context(ctx)->pipe, 888 rbDraw->texture, 0, 0, 0, 889 usage, dstx, dsty, 890 width, height); 891 892 assert(util_format_get_blockwidth(ptDraw->resource->format) == 1); 893 assert(util_format_get_blockheight(ptDraw->resource->format) == 1); 894 895 /* map the stencil buffer */ 896 drawMap = pipe_transfer_map(pipe, ptDraw); 897 898 /* draw */ 899 /* XXX PixelZoom not handled yet */ 900 for (i = 0; i < height; i++) { 901 ubyte *dst; 902 const ubyte *src; 903 int y; 904 905 y = i; 906 907 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 908 y = height - y - 1; 909 } 910 911 dst = drawMap + y * ptDraw->stride; 912 src = buffer + i * width; 913 914 switch (ptDraw->resource->format) { 915 case PIPE_FORMAT_Z24_UNORM_S8_USCALED: 916 { 917 uint *dst4 = (uint *) dst; 918 int j; 919 assert(usage == PIPE_TRANSFER_READ_WRITE); 920 for (j = 0; j < width; j++) { 921 *dst4 = (*dst4 & 0xffffff) | (src[j] << 24); 922 dst4++; 923 } 924 } 925 break; 926 case PIPE_FORMAT_S8_USCALED_Z24_UNORM: 927 { 928 uint *dst4 = (uint *) dst; 929 int j; 930 assert(usage == PIPE_TRANSFER_READ_WRITE); 931 for (j = 0; j < width; j++) { 932 *dst4 = (*dst4 & 0xffffff00) | (src[j] & 0xff); 933 dst4++; 934 } 935 } 936 break; 937 case PIPE_FORMAT_S8_USCALED: 938 assert(usage == PIPE_TRANSFER_WRITE); 939 memcpy(dst, src, width); 940 break; 941 default: 942 assert(0); 943 } 944 } 945 946 free(buffer); 947 948 /* unmap the stencil buffer */ 949 pipe_transfer_unmap(pipe, ptDraw); 950 pipe->transfer_destroy(pipe, ptDraw); 951} 952 953 954static void 955st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, 956 GLsizei width, GLsizei height, 957 GLint dstx, GLint dsty, GLenum type) 958{ 959 struct st_context *st = st_context(ctx); 960 struct pipe_context *pipe = st->pipe; 961 struct pipe_screen *screen = pipe->screen; 962 struct st_renderbuffer *rbRead; 963 void *driver_vp, *driver_fp; 964 struct pipe_resource *pt; 965 struct pipe_sampler_view *sv; 966 GLfloat *color; 967 enum pipe_format srcFormat, texFormat; 968 GLboolean invertTex = GL_FALSE; 969 GLint readX, readY, readW, readH; 970 struct gl_pixelstore_attrib pack = ctx->DefaultPacking; 971 972 st_validate_state(st); 973 974 if (type == GL_STENCIL) { 975 /* can't use texturing to do stencil */ 976 copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty); 977 return; 978 } 979 980 if (type == GL_COLOR) { 981 rbRead = st_get_color_read_renderbuffer(ctx); 982 color = NULL; 983 driver_fp = combined_drawpix_fragment_program(ctx); 984 driver_vp = make_passthrough_vertex_shader(st, GL_FALSE); 985 } 986 else { 987 assert(type == GL_DEPTH); 988 rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer); 989 color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; 990 driver_fp = make_fragment_shader_z(st); 991 driver_vp = make_passthrough_vertex_shader(st, GL_TRUE); 992 } 993 994 srcFormat = rbRead->texture->format; 995 996 if (screen->is_format_supported(screen, srcFormat, PIPE_TEXTURE_2D, 997 PIPE_BIND_SAMPLER_VIEW, 0)) { 998 texFormat = srcFormat; 999 } 1000 else { 1001 /* srcFormat can't be used as a texture format */ 1002 if (type == GL_DEPTH) { 1003 texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT, 1004 PIPE_TEXTURE_2D, 1005 PIPE_BIND_DEPTH_STENCIL); 1006 assert(texFormat != PIPE_FORMAT_NONE); 1007 } 1008 else { 1009 /* default color format */ 1010 texFormat = st_choose_format(screen, GL_RGBA, PIPE_TEXTURE_2D, 1011 PIPE_BIND_SAMPLER_VIEW); 1012 assert(texFormat != PIPE_FORMAT_NONE); 1013 } 1014 } 1015 1016 /* Invert src region if needed */ 1017 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1018 srcy = ctx->ReadBuffer->Height - srcy - height; 1019 invertTex = !invertTex; 1020 } 1021 1022 /* Clip the read region against the src buffer bounds. 1023 * We'll still allocate a temporary buffer/texture for the original 1024 * src region size but we'll only read the region which is on-screen. 1025 * This may mean that we draw garbage pixels into the dest region, but 1026 * that's expected. 1027 */ 1028 readX = srcx; 1029 readY = srcy; 1030 readW = width; 1031 readH = height; 1032 _mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack); 1033 readW = MAX2(0, readW); 1034 readH = MAX2(0, readH); 1035 1036 /* alloc temporary texture */ 1037 pt = alloc_texture(st, width, height, texFormat); 1038 if (!pt) 1039 return; 1040 1041 sv = st_create_texture_sampler_view(st->pipe, pt); 1042 if (!sv) { 1043 pipe_resource_reference(&pt, NULL); 1044 return; 1045 } 1046 1047 /* Make temporary texture which is a copy of the src region. 1048 */ 1049 if (srcFormat == texFormat) { 1050 /* copy source framebuffer surface into mipmap/texture */ 1051 struct pipe_surface *psRead = screen->get_tex_surface(screen, 1052 rbRead->texture, 0, 0, 0, 1053 PIPE_BIND_BLIT_SOURCE); 1054 struct pipe_surface *psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, 1055 PIPE_BIND_RENDER_TARGET | 1056 PIPE_BIND_BLIT_DESTINATION); 1057 pipe->surface_copy(pipe, 1058 psTex, /* dest surf */ 1059 pack.SkipPixels, pack.SkipRows, /* dest pos */ 1060 psRead, /* src surf */ 1061 readX, readY, readW, readH); /* src region */ 1062 1063 if (0) { 1064 /* debug */ 1065 debug_dump_surface(pipe, "copypixsrcsurf", psRead); 1066 debug_dump_surface(pipe, "copypixtemptex", psTex); 1067 } 1068 1069 pipe_surface_reference(&psRead, NULL); 1070 pipe_surface_reference(&psTex, NULL); 1071 } 1072 else { 1073 /* CPU-based fallback/conversion */ 1074 struct pipe_transfer *ptRead = 1075 pipe_get_transfer(st->pipe, rbRead->texture, 0, 0, 0, 1076 PIPE_TRANSFER_READ, 1077 readX, readY, readW, readH); 1078 struct pipe_transfer *ptTex; 1079 enum pipe_transfer_usage transfer_usage; 1080 1081 if (ST_DEBUG & DEBUG_FALLBACK) 1082 debug_printf("%s: fallback processing\n", __FUNCTION__); 1083 1084 if (type == GL_DEPTH && util_format_is_depth_and_stencil(pt->format)) 1085 transfer_usage = PIPE_TRANSFER_READ_WRITE; 1086 else 1087 transfer_usage = PIPE_TRANSFER_WRITE; 1088 1089 ptTex = pipe_get_transfer(st->pipe, pt, 0, 0, 0, transfer_usage, 1090 0, 0, width, height); 1091 1092 /* copy image from ptRead surface to ptTex surface */ 1093 if (type == GL_COLOR) { 1094 /* alternate path using get/put_tile() */ 1095 GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); 1096 pipe_get_tile_rgba(pipe, ptRead, readX, readY, readW, readH, buf); 1097 pipe_put_tile_rgba(pipe, ptTex, pack.SkipPixels, pack.SkipRows, 1098 readW, readH, buf); 1099 free(buf); 1100 } 1101 else { 1102 /* GL_DEPTH */ 1103 GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint)); 1104 pipe_get_tile_z(pipe, ptRead, readX, readY, readW, readH, buf); 1105 pipe_put_tile_z(pipe, ptTex, pack.SkipPixels, pack.SkipRows, 1106 readW, readH, buf); 1107 free(buf); 1108 } 1109 1110 pipe->transfer_destroy(pipe, ptRead); 1111 pipe->transfer_destroy(pipe, ptTex); 1112 } 1113 1114 /* OK, the texture 'pt' contains the src image/pixels. Now draw a 1115 * textured quad with that texture. 1116 */ 1117 draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2], 1118 width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, 1119 sv, 1120 driver_vp, 1121 driver_fp, 1122 color, invertTex); 1123 1124 pipe_resource_reference(&pt, NULL); 1125 pipe_sampler_view_reference(&sv, NULL); 1126} 1127 1128 1129 1130void st_init_drawpixels_functions(struct dd_function_table *functions) 1131{ 1132 functions->DrawPixels = st_DrawPixels; 1133 functions->CopyPixels = st_CopyPixels; 1134} 1135 1136 1137void 1138st_destroy_drawpix(struct st_context *st) 1139{ 1140 st_reference_fragprog(st, &st->drawpix.z_shader, NULL); 1141 st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL); 1142 if (st->drawpix.vert_shaders[0]) 1143 ureg_free_tokens(st->drawpix.vert_shaders[0]); 1144 if (st->drawpix.vert_shaders[1]) 1145 ureg_free_tokens(st->drawpix.vert_shaders[1]); 1146} 1147