1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version: 7.1 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"), 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions: 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software. 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \file buffers.c 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * glReadBuffer, DrawBuffer functions. 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glheader.h" 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "buffers.h" 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "colormac.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "context.h" 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "enums.h" 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "fbobject.h" 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "mtypes.h" 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define BAD_MASK ~0u 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return bitmask of BUFFER_BIT_* flags indicating which color buffers are 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * available to the rendering context (for drawing or reading). 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This depends on the type of framebuffer. For window system framebuffers 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * we look at the framebuffer's visual. But for user-create framebuffers we 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * look at the number of supported color attachments. 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param fb the framebuffer to draw to, or read from 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return bitmask of BUFFER_BIT_* flags 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLbitfield 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsupported_buffer_bitmask(const struct gl_context *ctx, 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct gl_framebuffer *fb) 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLbitfield mask = 0x0; 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_mesa_is_user_fbo(fb)) { 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* A user-created renderbuffer */ 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint i; 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(ctx->Extensions.EXT_framebuffer_object); 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < ctx->Const.MaxColorAttachments; i++) { 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mask |= (BUFFER_BIT_COLOR0 << i); 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* A window system framebuffer */ 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint i; 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mask = BUFFER_BIT_FRONT_LEFT; /* always have this */ 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (fb->Visual.stereoMode) { 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mask |= BUFFER_BIT_FRONT_RIGHT; 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (fb->Visual.doubleBufferMode) { 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mask |= BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT; 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (fb->Visual.doubleBufferMode) { 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mask |= BUFFER_BIT_BACK_LEFT; 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < fb->Visual.numAuxBuffers; i++) { 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mask |= (BUFFER_BIT_AUX0 << i); 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return mask; 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Helper routine used by glDrawBuffer and glDrawBuffersARB. 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Given a GLenum naming one or more color buffers (such as 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GL_FRONT_AND_BACK), return the corresponding bitmask of BUFFER_BIT_* flags. 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLbitfield 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdraw_buffer_enum_to_bitmask(GLenum buffer) 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (buffer) { 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_NONE: 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_FRONT: 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT; 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_BACK: 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT; 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_RIGHT: 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT; 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_FRONT_RIGHT: 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BIT_FRONT_RIGHT; 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_BACK_RIGHT: 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BIT_BACK_RIGHT; 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_BACK_LEFT: 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BIT_BACK_LEFT; 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_FRONT_AND_BACK: 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org | BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT; 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_LEFT: 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT; 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_FRONT_LEFT: 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BIT_FRONT_LEFT; 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_AUX0: 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BIT_AUX0; 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_AUX1: 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_AUX2: 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_AUX3: 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1 << BUFFER_COUNT; /* invalid, but not BAD_MASK */ 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_COLOR_ATTACHMENT0_EXT: 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BIT_COLOR0; 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_COLOR_ATTACHMENT1_EXT: 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BIT_COLOR1; 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_COLOR_ATTACHMENT2_EXT: 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BIT_COLOR2; 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_COLOR_ATTACHMENT3_EXT: 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BIT_COLOR3; 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_COLOR_ATTACHMENT4_EXT: 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BIT_COLOR4; 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_COLOR_ATTACHMENT5_EXT: 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BIT_COLOR5; 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_COLOR_ATTACHMENT6_EXT: 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BIT_COLOR6; 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_COLOR_ATTACHMENT7_EXT: 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BIT_COLOR7; 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* error */ 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BAD_MASK; 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Helper routine used by glReadBuffer. 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Given a GLenum naming a color buffer, return the index of the corresponding 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * renderbuffer (a BUFFER_* value). 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * return -1 for an invalid buffer. 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLint 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgread_buffer_enum_to_index(GLenum buffer) 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (buffer) { 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_FRONT: 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_FRONT_LEFT; 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_BACK: 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BACK_LEFT; 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_RIGHT: 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_FRONT_RIGHT; 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_FRONT_RIGHT: 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_FRONT_RIGHT; 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_BACK_RIGHT: 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BACK_RIGHT; 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_BACK_LEFT: 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_BACK_LEFT; 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_LEFT: 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_FRONT_LEFT; 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_FRONT_LEFT: 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_FRONT_LEFT; 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_AUX0: 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_AUX0; 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_AUX1: 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_AUX2: 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_AUX3: 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_COUNT; /* invalid, but not -1 */ 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_COLOR_ATTACHMENT0_EXT: 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_COLOR0; 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_COLOR_ATTACHMENT1_EXT: 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_COLOR1; 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_COLOR_ATTACHMENT2_EXT: 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_COLOR2; 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_COLOR_ATTACHMENT3_EXT: 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_COLOR3; 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_COLOR_ATTACHMENT4_EXT: 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_COLOR4; 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_COLOR_ATTACHMENT5_EXT: 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_COLOR5; 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_COLOR_ATTACHMENT6_EXT: 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_COLOR6; 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_COLOR_ATTACHMENT7_EXT: 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return BUFFER_COLOR7; 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* error */ 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return -1; 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called by glDrawBuffer(). 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Specify which renderbuffer(s) to draw into for the first color output. 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * <buffer> can name zero, one, two or four renderbuffers! 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \sa _mesa_DrawBuffersARB 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param buffer buffer token such as GL_LEFT or GL_FRONT_AND_BACK, etc. 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note that the behaviour of this function depends on whether the 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * current ctx->DrawBuffer is a window-system framebuffer (Name=0) or 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a user-created framebuffer object (Name!=0). 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In the former case, we update the per-context ctx->Color.DrawBuffer 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * state var _and_ the FB's ColorDrawBuffer state. 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In the later case, we update the FB's ColorDrawBuffer state only. 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Furthermore, upon a MakeCurrent() or BindFramebuffer() call, if the 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * new FB is a window system FB, we need to re-update the FB's 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ColorDrawBuffer state to match the context. This is handled in 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * _mesa_update_framebuffer(). 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * See the GL_EXT_framebuffer_object spec for more info. 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid GLAPIENTRY 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_DrawBuffer(GLenum buffer) 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLbitfield destMask; 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GET_CURRENT_CONTEXT(ctx); 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex... */ 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (MESA_VERBOSE & VERBOSE_API) { 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (buffer == GL_NONE) { 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org destMask = 0x0; 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLbitfield supportedMask 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org = supported_buffer_bitmask(ctx, ctx->DrawBuffer); 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org destMask = draw_buffer_enum_to_bitmask(buffer); 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (destMask == BAD_MASK) { 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* totally bogus buffer */ 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_ENUM, 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "glDrawBuffer(buffer=0x%x)", buffer); 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org destMask &= supportedMask; 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (destMask == 0x0) { 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* none of the named color buffers exist! */ 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_OPERATION, 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "glDrawBuffer(buffer=0x%x)", buffer); 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* if we get here, there's no error so set new state */ 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_drawbuffers(ctx, 1, &buffer, &destMask); 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Call device driver function. 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->Driver.DrawBuffers) 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.DrawBuffers(ctx, 1, &buffer); 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (ctx->Driver.DrawBuffer) 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.DrawBuffer(ctx, buffer); 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called by glDrawBuffersARB; specifies the destination color renderbuffers 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * for N fragment program color outputs. 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \sa _mesa_DrawBuffer 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param n number of outputs 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param buffers array [n] of renderbuffer names. Unlike glDrawBuffer, the 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * names cannot specify more than one buffer. For example, 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GL_FRONT_AND_BACK is illegal. 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid GLAPIENTRY 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers) 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint output; 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLbitfield usedBufferMask, supportedMask; 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLbitfield destMask[MAX_DRAW_BUFFERS]; 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GET_CURRENT_CONTEXT(ctx); 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Turns out n==0 is a valid input that should not produce an error. 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The remaining code below correctly handles the n==0 case. 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (n < 0 || n > (GLsizei) ctx->Const.MaxDrawBuffers) { 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_VALUE, "glDrawBuffersARB(n)"); 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org supportedMask = supported_buffer_bitmask(ctx, ctx->DrawBuffer); 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org usedBufferMask = 0x0; 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* complicated error checking... */ 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (output = 0; output < n; output++) { 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (buffers[output] == GL_NONE) { 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org destMask[output] = 0x0; 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org destMask[output] = draw_buffer_enum_to_bitmask(buffers[output]); 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (destMask[output] == BAD_MASK 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || _mesa_bitcount(destMask[output]) > 1) { 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)"); 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org destMask[output] &= supportedMask; 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (destMask[output] == 0) { 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_OPERATION, 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "glDrawBuffersARB(unsupported buffer)"); 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (destMask[output] & usedBufferMask) { 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* can't specify a dest buffer more than once! */ 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_OPERATION, 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "glDrawBuffersARB(duplicated buffer)"); 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* update bitmask */ 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org usedBufferMask |= destMask[output]; 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* OK, if we get here, there were no errors so set the new state */ 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_drawbuffers(ctx, n, buffers, destMask); 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Call device driver function. Note that n can be equal to 0, 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in which case we don't want to reference buffers[0], which 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * may not be valid. 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->Driver.DrawBuffers) 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.DrawBuffers(ctx, n, buffers); 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (ctx->Driver.DrawBuffer) 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.DrawBuffer(ctx, n > 0 ? buffers[0] : GL_NONE); 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Performs necessary state updates when _mesa_drawbuffers makes an 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * actual change. 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgupdated_drawbuffers(struct gl_context *ctx) 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FLUSH_VERTICES(ctx, _NEW_BUFFERS); 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if FEATURE_GL 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->API == API_OPENGL && !ctx->Extensions.ARB_ES2_compatibility) { 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_framebuffer *fb = ctx->DrawBuffer; 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Flag the FBO as requiring validation. */ 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_mesa_is_user_fbo(fb)) { 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fb->_Status = 0; 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Helper function to set the GL_DRAW_BUFFER state in the context and 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * current FBO. Called via glDrawBuffer(), glDrawBuffersARB() 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All error checking will have been done prior to calling this function 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * so nothing should go wrong at this point. 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param ctx current context 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param n number of color outputs to set 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param buffers array[n] of colorbuffer names, like GL_LEFT. 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param destMask array[n] of BUFFER_BIT_* bitmasks which correspond to the 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * colorbuffer names. (i.e. GL_FRONT_AND_BACK => 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT). 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers, 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLbitfield *destMask) 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_framebuffer *fb = ctx->DrawBuffer; 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLbitfield mask[MAX_DRAW_BUFFERS]; 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint buf; 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!destMask) { 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* compute destMask values now */ 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLbitfield supportedMask = supported_buffer_bitmask(ctx, fb); 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint output; 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (output = 0; output < n; output++) { 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mask[output] = draw_buffer_enum_to_bitmask(buffers[output]); 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(mask[output] != BAD_MASK); 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mask[output] &= supportedMask; 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org destMask = mask; 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If n==1, destMask[0] may have up to four bits set. 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Otherwise, destMask[x] can only have one bit set. 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (n == 1) { 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint count = 0, destMask0 = destMask[0]; 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (destMask0) { 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint bufIndex = ffs(destMask0) - 1; 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (fb->_ColorDrawBufferIndexes[count] != bufIndex) { 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org updated_drawbuffers(ctx); 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fb->_ColorDrawBufferIndexes[count] = bufIndex; 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org count++; 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org destMask0 &= ~(1 << bufIndex); 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fb->ColorDrawBuffer[0] = buffers[0]; 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fb->_NumColorDrawBuffers = count; 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint count = 0; 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (buf = 0; buf < n; buf++ ) { 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (destMask[buf]) { 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint bufIndex = ffs(destMask[buf]) - 1; 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* only one bit should be set in the destMask[buf] field */ 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(_mesa_bitcount(destMask[buf]) == 1); 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (fb->_ColorDrawBufferIndexes[buf] != bufIndex) { 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org updated_drawbuffers(ctx); 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fb->_ColorDrawBufferIndexes[buf] = bufIndex; 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org count = buf + 1; 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (fb->_ColorDrawBufferIndexes[buf] != -1) { 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org updated_drawbuffers(ctx); 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fb->_ColorDrawBufferIndexes[buf] = -1; 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fb->ColorDrawBuffer[buf] = buffers[buf]; 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fb->_NumColorDrawBuffers = count; 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* set remaining outputs to -1 (GL_NONE) */ 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (buf = fb->_NumColorDrawBuffers; buf < ctx->Const.MaxDrawBuffers; buf++) { 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (fb->_ColorDrawBufferIndexes[buf] != -1) { 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org updated_drawbuffers(ctx); 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fb->_ColorDrawBufferIndexes[buf] = -1; 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (buf = n; buf < ctx->Const.MaxDrawBuffers; buf++) { 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fb->ColorDrawBuffer[buf] = GL_NONE; 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_mesa_is_winsys_fbo(fb)) { 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* also set context drawbuffer state */ 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) { 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->Color.DrawBuffer[buf] != fb->ColorDrawBuffer[buf]) { 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org updated_drawbuffers(ctx); 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Color.DrawBuffer[buf] = fb->ColorDrawBuffer[buf]; 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Update the current drawbuffer's _ColorDrawBufferIndex[] list, etc. 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * from the context's Color.DrawBuffer[] state. 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Use when changing contexts. 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_update_draw_buffers(struct gl_context *ctx) 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum buffers[MAX_DRAW_BUFFERS]; 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint i; 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* should be a window system FBO */ 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(_mesa_is_winsys_fbo(ctx->DrawBuffer)); 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffers[i] = ctx->Color.DrawBuffer[i]; 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers, buffers, NULL); 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Like \sa _mesa_drawbuffers(), this is a helper function for setting 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GL_READ_BUFFER state in the context and current FBO. 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param ctx the rendering context 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param buffer GL_FRONT, GL_BACK, GL_COLOR_ATTACHMENT0, etc. 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param bufferIndex the numerical index corresponding to 'buffer' 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_readbuffer(struct gl_context *ctx, GLenum buffer, GLint bufferIndex) 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_framebuffer *fb = ctx->ReadBuffer; 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_mesa_is_winsys_fbo(fb)) { 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Only update the per-context READ_BUFFER state if we're bound to 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a window-system framebuffer. 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Pixel.ReadBuffer = buffer; 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fb->ColorReadBuffer = buffer; 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fb->_ColorReadBufferIndex = bufferIndex; 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->NewState |= _NEW_BUFFERS; 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called by glReadBuffer to set the source renderbuffer for reading pixels. 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param mode color buffer such as GL_FRONT, GL_BACK, etc. 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid GLAPIENTRY 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_ReadBuffer(GLenum buffer) 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_framebuffer *fb; 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLbitfield supportedMask; 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint srcBuffer; 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GET_CURRENT_CONTEXT(ctx); 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (MESA_VERBOSE & VERBOSE_API) 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fb = ctx->ReadBuffer; 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (MESA_VERBOSE & VERBOSE_API) 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (buffer == GL_NONE) { 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* This is legal--it means that no buffer should be bound for reading. */ 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcBuffer = -1; 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* general case / window-system framebuffer */ 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcBuffer = read_buffer_enum_to_index(buffer); 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcBuffer == -1) { 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_ENUM, 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "glReadBuffer(buffer=0x%x)", buffer); 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org supportedMask = supported_buffer_bitmask(ctx, fb); 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (((1 << srcBuffer) & supportedMask) == 0) { 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_INVALID_OPERATION, 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "glReadBuffer(buffer=0x%x)", buffer); 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* OK, all error checking has been completed now */ 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_readbuffer(ctx, buffer, srcBuffer); 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->NewState |= _NEW_BUFFERS; 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Call device driver function. 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->Driver.ReadBuffer) 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (*ctx->Driver.ReadBuffer)(ctx, buffer); 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 568