multisample.c revision af69d88d
1c1f859d4Smrg/* 2c1f859d4Smrg * Mesa 3-D graphics library 3c1f859d4Smrg * 4c1f859d4Smrg * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 5c1f859d4Smrg * 6c1f859d4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7c1f859d4Smrg * copy of this software and associated documentation files (the "Software"), 8c1f859d4Smrg * to deal in the Software without restriction, including without limitation 9c1f859d4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10c1f859d4Smrg * and/or sell copies of the Software, and to permit persons to whom the 11c1f859d4Smrg * Software is furnished to do so, subject to the following conditions: 12c1f859d4Smrg * 13c1f859d4Smrg * The above copyright notice and this permission notice shall be included 14c1f859d4Smrg * in all copies or substantial portions of the Software. 15c1f859d4Smrg * 16c1f859d4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17c1f859d4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18c1f859d4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE. 23c1f859d4Smrg */ 24c1f859d4Smrg 25c1f859d4Smrg 26c1f859d4Smrg#include "main/glheader.h" 27c1f859d4Smrg#include "main/context.h" 28c1f859d4Smrg#include "main/macros.h" 29c1f859d4Smrg#include "main/multisample.h" 303464ebd5Sriastradh#include "main/mtypes.h" 31af69d88dSmrg#include "main/fbobject.h" 32af69d88dSmrg#include "main/glformats.h" 33af69d88dSmrg#include "main/state.h" 34c1f859d4Smrg 35c1f859d4Smrg 36c1f859d4Smrg/** 37c1f859d4Smrg * Called via glSampleCoverageARB 38c1f859d4Smrg */ 39c1f859d4Smrgvoid GLAPIENTRY 40af69d88dSmrg_mesa_SampleCoverage(GLclampf value, GLboolean invert) 41c1f859d4Smrg{ 42c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 43c1f859d4Smrg 44af69d88dSmrg FLUSH_VERTICES(ctx, 0); 45c1f859d4Smrg 46c1f859d4Smrg ctx->Multisample.SampleCoverageValue = (GLfloat) CLAMP(value, 0.0, 1.0); 47c1f859d4Smrg ctx->Multisample.SampleCoverageInvert = invert; 48c1f859d4Smrg ctx->NewState |= _NEW_MULTISAMPLE; 49c1f859d4Smrg} 50c1f859d4Smrg 51c1f859d4Smrg 52c1f859d4Smrg/** 53c1f859d4Smrg * Initialize the context's multisample state. 54c1f859d4Smrg * \param ctx the GL context. 55c1f859d4Smrg */ 56c1f859d4Smrgvoid 573464ebd5Sriastradh_mesa_init_multisample(struct gl_context *ctx) 58c1f859d4Smrg{ 59c1f859d4Smrg ctx->Multisample.Enabled = GL_TRUE; 60c1f859d4Smrg ctx->Multisample.SampleAlphaToCoverage = GL_FALSE; 61c1f859d4Smrg ctx->Multisample.SampleAlphaToOne = GL_FALSE; 62c1f859d4Smrg ctx->Multisample.SampleCoverage = GL_FALSE; 63c1f859d4Smrg ctx->Multisample.SampleCoverageValue = 1.0; 64c1f859d4Smrg ctx->Multisample.SampleCoverageInvert = GL_FALSE; 65af69d88dSmrg 66af69d88dSmrg /* ARB_texture_multisample / GL3.2 additions */ 67af69d88dSmrg ctx->Multisample.SampleMask = GL_FALSE; 68af69d88dSmrg ctx->Multisample.SampleMaskValue = ~(GLbitfield)0; 69af69d88dSmrg} 70af69d88dSmrg 71af69d88dSmrg 72af69d88dSmrgvoid GLAPIENTRY 73af69d88dSmrg_mesa_GetMultisamplefv(GLenum pname, GLuint index, GLfloat * val) 74af69d88dSmrg{ 75af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 76af69d88dSmrg 77af69d88dSmrg if (ctx->NewState & _NEW_BUFFERS) { 78af69d88dSmrg _mesa_update_state(ctx); 79af69d88dSmrg } 80af69d88dSmrg 81af69d88dSmrg switch (pname) { 82af69d88dSmrg case GL_SAMPLE_POSITION: { 83af69d88dSmrg if ((int) index >= ctx->DrawBuffer->Visual.samples) { 84af69d88dSmrg _mesa_error( ctx, GL_INVALID_VALUE, "glGetMultisamplefv(index)" ); 85af69d88dSmrg return; 86af69d88dSmrg } 87af69d88dSmrg 88af69d88dSmrg ctx->Driver.GetSamplePosition(ctx, ctx->DrawBuffer, index, val); 89af69d88dSmrg 90af69d88dSmrg /* winsys FBOs are upside down */ 91af69d88dSmrg if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) 92af69d88dSmrg val[1] = 1.0f - val[1]; 93af69d88dSmrg 94af69d88dSmrg return; 95af69d88dSmrg } 96af69d88dSmrg 97af69d88dSmrg default: 98af69d88dSmrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetMultisamplefv(pname)" ); 99af69d88dSmrg return; 100af69d88dSmrg } 101af69d88dSmrg} 102af69d88dSmrg 103af69d88dSmrgvoid GLAPIENTRY 104af69d88dSmrg_mesa_SampleMaski(GLuint index, GLbitfield mask) 105af69d88dSmrg{ 106af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 107af69d88dSmrg 108af69d88dSmrg if (!ctx->Extensions.ARB_texture_multisample) { 109af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMaski"); 110af69d88dSmrg return; 111af69d88dSmrg } 112af69d88dSmrg 113af69d88dSmrg if (index != 0) { 114af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glSampleMaski(index)"); 115af69d88dSmrg return; 116af69d88dSmrg } 117af69d88dSmrg 118af69d88dSmrg FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE); 119af69d88dSmrg ctx->Multisample.SampleMaskValue = mask; 120af69d88dSmrg} 121af69d88dSmrg 122af69d88dSmrg/** 123af69d88dSmrg * Called via glMinSampleShadingARB 124af69d88dSmrg */ 125af69d88dSmrgvoid GLAPIENTRY 126af69d88dSmrg_mesa_MinSampleShading(GLclampf value) 127af69d88dSmrg{ 128af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 129af69d88dSmrg 130af69d88dSmrg if (!ctx->Extensions.ARB_sample_shading || !_mesa_is_desktop_gl(ctx)) { 131af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, "glMinSampleShading"); 132af69d88dSmrg return; 133af69d88dSmrg } 134af69d88dSmrg 135af69d88dSmrg FLUSH_VERTICES(ctx, 0); 136af69d88dSmrg 137af69d88dSmrg ctx->Multisample.MinSampleShadingValue = CLAMP(value, 0.0, 1.0); 138af69d88dSmrg ctx->NewState |= _NEW_MULTISAMPLE; 139af69d88dSmrg} 140af69d88dSmrg 141af69d88dSmrg/** 142af69d88dSmrg * Helper for checking a requested sample count against the limit 143af69d88dSmrg * for a particular (target, internalFormat) pair. The limit imposed, 144af69d88dSmrg * and the error generated, both depend on which extensions are supported. 145af69d88dSmrg * 146af69d88dSmrg * Returns a GL error enum, or GL_NO_ERROR if the requested sample count is 147af69d88dSmrg * acceptable. 148af69d88dSmrg */ 149af69d88dSmrgGLenum 150af69d88dSmrg_mesa_check_sample_count(struct gl_context *ctx, GLenum target, 151af69d88dSmrg GLenum internalFormat, GLsizei samples) 152af69d88dSmrg{ 153af69d88dSmrg /* If ARB_internalformat_query is supported, then treat its highest 154af69d88dSmrg * returned sample count as the absolute maximum for this format; it is 155af69d88dSmrg * allowed to exceed MAX_SAMPLES. 156af69d88dSmrg * 157af69d88dSmrg * From the ARB_internalformat_query spec: 158af69d88dSmrg * 159af69d88dSmrg * "If <samples is greater than the maximum number of samples supported 160af69d88dSmrg * for <internalformat> then the error INVALID_OPERATION is generated." 161af69d88dSmrg */ 162af69d88dSmrg if (ctx->Extensions.ARB_internalformat_query) { 163af69d88dSmrg GLint buffer[16]; 164af69d88dSmrg int count = ctx->Driver.QuerySamplesForFormat(ctx, target, 165af69d88dSmrg internalFormat, buffer); 166af69d88dSmrg int limit = count ? buffer[0] : -1; 167af69d88dSmrg 168af69d88dSmrg return samples > limit ? GL_INVALID_OPERATION : GL_NO_ERROR; 169af69d88dSmrg } 170af69d88dSmrg 171af69d88dSmrg /* If ARB_texture_multisample is supported, we have separate limits, 172af69d88dSmrg * which may be lower than MAX_SAMPLES: 173af69d88dSmrg * 174af69d88dSmrg * From the ARB_texture_multisample spec, when describing the operation 175af69d88dSmrg * of RenderbufferStorageMultisample: 176af69d88dSmrg * 177af69d88dSmrg * "If <internalformat> is a signed or unsigned integer format and 178af69d88dSmrg * <samples> is greater than the value of MAX_INTEGER_SAMPLES, then the 179af69d88dSmrg * error INVALID_OPERATION is generated" 180af69d88dSmrg * 181af69d88dSmrg * And when describing the operation of TexImage*Multisample: 182af69d88dSmrg * 183af69d88dSmrg * "The error INVALID_OPERATION may be generated if any of the following 184af69d88dSmrg * are true: 185af69d88dSmrg * 186af69d88dSmrg * * <internalformat> is a depth/stencil-renderable format and <samples> 187af69d88dSmrg * is greater than the value of MAX_DEPTH_TEXTURE_SAMPLES 188af69d88dSmrg * * <internalformat> is a color-renderable format and <samples> is 189af69d88dSmrg * grater than the value of MAX_COLOR_TEXTURE_SAMPLES 190af69d88dSmrg * * <internalformat> is a signed or unsigned integer format and 191af69d88dSmrg * <samples> is greater than the value of MAX_INTEGER_SAMPLES 192af69d88dSmrg */ 193af69d88dSmrg 194af69d88dSmrg if (ctx->Extensions.ARB_texture_multisample) { 195af69d88dSmrg if (_mesa_is_enum_format_integer(internalFormat)) 196af69d88dSmrg return samples > ctx->Const.MaxIntegerSamples 197af69d88dSmrg ? GL_INVALID_OPERATION : GL_NO_ERROR; 198af69d88dSmrg 199af69d88dSmrg if (target == GL_TEXTURE_2D_MULTISAMPLE || 200af69d88dSmrg target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) { 201af69d88dSmrg 202af69d88dSmrg if (_mesa_is_depth_or_stencil_format(internalFormat)) 203af69d88dSmrg return samples > ctx->Const.MaxDepthTextureSamples 204af69d88dSmrg ? GL_INVALID_OPERATION : GL_NO_ERROR; 205af69d88dSmrg else 206af69d88dSmrg return samples > ctx->Const.MaxColorTextureSamples 207af69d88dSmrg ? GL_INVALID_OPERATION : GL_NO_ERROR; 208af69d88dSmrg } 209af69d88dSmrg } 210af69d88dSmrg 211af69d88dSmrg /* No more specific limit is available, so just use MAX_SAMPLES: 212af69d88dSmrg * 213af69d88dSmrg * On p205 of the GL3.1 spec: 214af69d88dSmrg * 215af69d88dSmrg * "... or if samples is greater than MAX_SAMPLES, then the error 216af69d88dSmrg * INVALID_VALUE is generated" 217af69d88dSmrg */ 218af69d88dSmrg return (GLuint) samples > ctx->Const.MaxSamples 219af69d88dSmrg ? GL_INVALID_VALUE : GL_NO_ERROR; 220c1f859d4Smrg} 221