formatquery.c revision 848b8605
1/* 2 * Copyright © 2012 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24#include "mtypes.h" 25#include "context.h" 26#include "glformats.h" 27#include "macros.h" 28#include "enums.h" 29#include "fbobject.h" 30#include "formatquery.h" 31 32/* default implementation of QuerySamplesForFormat driverfunc, for 33 * non-multisample-capable drivers. */ 34size_t 35_mesa_query_samples_for_format(struct gl_context *ctx, GLenum target, 36 GLenum internalFormat, int samples[16]) 37{ 38 (void) target; 39 (void) internalFormat; 40 (void) ctx; 41 42 samples[0] = 1; 43 return 1; 44} 45 46 47void GLAPIENTRY 48_mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, 49 GLsizei bufSize, GLint *params) 50{ 51 GLint buffer[16]; 52 GLsizei count = 0; 53 GET_CURRENT_CONTEXT(ctx); 54 55 ASSERT_OUTSIDE_BEGIN_END(ctx); 56 57 if (!ctx->Extensions.ARB_internalformat_query) { 58 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInternalformativ"); 59 return; 60 } 61 62 assert(ctx->Driver.QuerySamplesForFormat != NULL); 63 64 /* The ARB_internalformat_query spec says: 65 * 66 * "If the <target> parameter to GetInternalformativ is not one of 67 * TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY or RENDERBUFFER 68 * then an INVALID_ENUM error is generated." 69 */ 70 switch (target) { 71 case GL_RENDERBUFFER: 72 break; 73 74 case GL_TEXTURE_2D_MULTISAMPLE: 75 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 76 /* These enums are only valid if ARB_texture_multisample is supported */ 77 if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample) 78 break; 79 80 default: 81 _mesa_error(ctx, GL_INVALID_ENUM, 82 "glGetInternalformativ(target=%s)", 83 _mesa_lookup_enum_by_nr(target)); 84 return; 85 } 86 87 /* The ARB_internalformat_query spec says: 88 * 89 * "If the <internalformat> parameter to GetInternalformativ is not 90 * color-, depth- or stencil-renderable, then an INVALID_ENUM error is 91 * generated." 92 */ 93 if (_mesa_base_fbo_format(ctx, internalformat) == 0) { 94 _mesa_error(ctx, GL_INVALID_ENUM, 95 "glGetInternalformativ(internalformat=%s)", 96 _mesa_lookup_enum_by_nr(internalformat)); 97 return; 98 } 99 100 /* The ARB_internalformat_query spec says: 101 * 102 * "If the <bufSize> parameter to GetInternalformativ is negative, then 103 * an INVALID_VALUE error is generated." 104 */ 105 if (bufSize < 0) { 106 _mesa_error(ctx, GL_INVALID_VALUE, 107 "glGetInternalformativ(target=%s)", 108 _mesa_lookup_enum_by_nr(target)); 109 return; 110 } 111 112 switch (pname) { 113 case GL_SAMPLES: 114 count = ctx->Driver.QuerySamplesForFormat(ctx, target, 115 internalformat, buffer); 116 break; 117 case GL_NUM_SAMPLE_COUNTS: { 118 /* The driver can return 0, and we should pass that along to the 119 * application. The ARB decided that ARB_internalformat_query should 120 * behave as ARB_internalformat_query2 in this situation. 121 * 122 * The ARB_internalformat_query2 spec says: 123 * 124 * "- NUM_SAMPLE_COUNTS: The number of sample counts that would be 125 * returned by querying SAMPLES is returned in <params>. 126 * * If <internalformat> is not color-renderable, 127 * depth-renderable, or stencil-renderable (as defined in 128 * section 4.4.4), or if <target> does not support multiple 129 * samples (ie other than TEXTURE_2D_MULTISAMPLE, 130 * TEXTURE_2D_MULTISAMPLE_ARRAY, or RENDERBUFFER), 0 is 131 * returned." 132 */ 133 const size_t num_samples = 134 ctx->Driver.QuerySamplesForFormat(ctx, target, internalformat, buffer); 135 136 /* QuerySamplesForFormat writes some stuff to buffer, so we have to 137 * separately over-write it with the requested value. 138 */ 139 buffer[0] = (GLint) num_samples; 140 count = 1; 141 break; 142 } 143 default: 144 _mesa_error(ctx, GL_INVALID_ENUM, 145 "glGetInternalformativ(pname=%s)", 146 _mesa_lookup_enum_by_nr(pname)); 147 return; 148 } 149 150 if (bufSize != 0 && params == NULL) { 151 /* Emit a warning to aid application debugging, but go ahead and do the 152 * memcpy (and probably crash) anyway. 153 */ 154 _mesa_warning(ctx, 155 "glGetInternalformativ(bufSize = %d, but params = NULL)", 156 bufSize); 157 } 158 159 /* Copy the data from the temporary buffer to the buffer supplied by the 160 * application. Clamp the size of the copy to the size supplied by the 161 * application. 162 */ 163 memcpy(params, buffer, MIN2(count, bufSize) * sizeof(GLint)); 164 165 return; 166} 167