1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Mesa 3-D graphics library
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker *
6*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
7*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
8*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
9*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
11*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
12*61046927SAndroid Build Coastguard Worker *
13*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included
14*61046927SAndroid Build Coastguard Worker * in all copies or substantial portions of the Software.
15*61046927SAndroid Build Coastguard Worker *
16*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17*61046927SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20*61046927SAndroid Build Coastguard Worker * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21*61046927SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22*61046927SAndroid Build Coastguard Worker * OTHER DEALINGS IN THE SOFTWARE.
23*61046927SAndroid Build Coastguard Worker */
24*61046927SAndroid Build Coastguard Worker
25*61046927SAndroid Build Coastguard Worker
26*61046927SAndroid Build Coastguard Worker #include "util/glheader.h"
27*61046927SAndroid Build Coastguard Worker #include "main/context.h"
28*61046927SAndroid Build Coastguard Worker #include "main/macros.h"
29*61046927SAndroid Build Coastguard Worker #include "main/multisample.h"
30*61046927SAndroid Build Coastguard Worker #include "main/mtypes.h"
31*61046927SAndroid Build Coastguard Worker #include "main/fbobject.h"
32*61046927SAndroid Build Coastguard Worker #include "main/glformats.h"
33*61046927SAndroid Build Coastguard Worker #include "main/state.h"
34*61046927SAndroid Build Coastguard Worker #include "api_exec_decl.h"
35*61046927SAndroid Build Coastguard Worker #include "main/framebuffer.h"
36*61046927SAndroid Build Coastguard Worker
37*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_context.h"
38*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_format.h"
39*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_util.h"
40*61046927SAndroid Build Coastguard Worker
41*61046927SAndroid Build Coastguard Worker /**
42*61046927SAndroid Build Coastguard Worker * Called via glSampleCoverageARB
43*61046927SAndroid Build Coastguard Worker */
44*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_SampleCoverage(GLclampf value,GLboolean invert)45*61046927SAndroid Build Coastguard Worker _mesa_SampleCoverage(GLclampf value, GLboolean invert)
46*61046927SAndroid Build Coastguard Worker {
47*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
48*61046927SAndroid Build Coastguard Worker
49*61046927SAndroid Build Coastguard Worker value = SATURATE(value);
50*61046927SAndroid Build Coastguard Worker
51*61046927SAndroid Build Coastguard Worker if (ctx->Multisample.SampleCoverageInvert == invert &&
52*61046927SAndroid Build Coastguard Worker ctx->Multisample.SampleCoverageValue == value)
53*61046927SAndroid Build Coastguard Worker return;
54*61046927SAndroid Build Coastguard Worker
55*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, GL_MULTISAMPLE_BIT);
56*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_SAMPLE_STATE;
57*61046927SAndroid Build Coastguard Worker ctx->Multisample.SampleCoverageValue = value;
58*61046927SAndroid Build Coastguard Worker ctx->Multisample.SampleCoverageInvert = invert;
59*61046927SAndroid Build Coastguard Worker }
60*61046927SAndroid Build Coastguard Worker
61*61046927SAndroid Build Coastguard Worker
62*61046927SAndroid Build Coastguard Worker /**
63*61046927SAndroid Build Coastguard Worker * Initialize the context's multisample state.
64*61046927SAndroid Build Coastguard Worker * \param ctx the GL context.
65*61046927SAndroid Build Coastguard Worker */
66*61046927SAndroid Build Coastguard Worker void
_mesa_init_multisample(struct gl_context * ctx)67*61046927SAndroid Build Coastguard Worker _mesa_init_multisample(struct gl_context *ctx)
68*61046927SAndroid Build Coastguard Worker {
69*61046927SAndroid Build Coastguard Worker ctx->Multisample.Enabled = GL_TRUE;
70*61046927SAndroid Build Coastguard Worker ctx->Multisample.SampleAlphaToCoverage = GL_FALSE;
71*61046927SAndroid Build Coastguard Worker ctx->Multisample.SampleAlphaToCoverageDitherControl = GL_ALPHA_TO_COVERAGE_DITHER_DEFAULT_NV;
72*61046927SAndroid Build Coastguard Worker ctx->Multisample.SampleAlphaToOne = GL_FALSE;
73*61046927SAndroid Build Coastguard Worker ctx->Multisample.SampleCoverage = GL_FALSE;
74*61046927SAndroid Build Coastguard Worker ctx->Multisample.SampleCoverageValue = 1.0;
75*61046927SAndroid Build Coastguard Worker ctx->Multisample.SampleCoverageInvert = GL_FALSE;
76*61046927SAndroid Build Coastguard Worker ctx->Multisample.SampleShading = GL_FALSE;
77*61046927SAndroid Build Coastguard Worker ctx->Multisample.MinSampleShadingValue = 0.0f;
78*61046927SAndroid Build Coastguard Worker
79*61046927SAndroid Build Coastguard Worker /* ARB_texture_multisample / GL3.2 additions */
80*61046927SAndroid Build Coastguard Worker ctx->Multisample.SampleMask = GL_FALSE;
81*61046927SAndroid Build Coastguard Worker ctx->Multisample.SampleMaskValue = ~(GLbitfield)0;
82*61046927SAndroid Build Coastguard Worker }
83*61046927SAndroid Build Coastguard Worker
84*61046927SAndroid Build Coastguard Worker static void
get_sample_position(struct gl_context * ctx,struct gl_framebuffer * fb,GLuint index,GLfloat * outPos)85*61046927SAndroid Build Coastguard Worker get_sample_position(struct gl_context *ctx,
86*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb,
87*61046927SAndroid Build Coastguard Worker GLuint index,
88*61046927SAndroid Build Coastguard Worker GLfloat *outPos)
89*61046927SAndroid Build Coastguard Worker {
90*61046927SAndroid Build Coastguard Worker struct st_context *st = st_context(ctx);
91*61046927SAndroid Build Coastguard Worker
92*61046927SAndroid Build Coastguard Worker st_validate_state(st, ST_PIPELINE_UPDATE_FB_STATE_MASK);
93*61046927SAndroid Build Coastguard Worker
94*61046927SAndroid Build Coastguard Worker if (ctx->pipe->get_sample_position)
95*61046927SAndroid Build Coastguard Worker ctx->pipe->get_sample_position(ctx->pipe,
96*61046927SAndroid Build Coastguard Worker _mesa_geometric_samples(fb),
97*61046927SAndroid Build Coastguard Worker index, outPos);
98*61046927SAndroid Build Coastguard Worker else
99*61046927SAndroid Build Coastguard Worker outPos[0] = outPos[1] = 0.5f;
100*61046927SAndroid Build Coastguard Worker }
101*61046927SAndroid Build Coastguard Worker
102*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetMultisamplefv(GLenum pname,GLuint index,GLfloat * val)103*61046927SAndroid Build Coastguard Worker _mesa_GetMultisamplefv(GLenum pname, GLuint index, GLfloat * val)
104*61046927SAndroid Build Coastguard Worker {
105*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
106*61046927SAndroid Build Coastguard Worker
107*61046927SAndroid Build Coastguard Worker if (ctx->NewState & _NEW_BUFFERS) {
108*61046927SAndroid Build Coastguard Worker _mesa_update_state(ctx);
109*61046927SAndroid Build Coastguard Worker }
110*61046927SAndroid Build Coastguard Worker
111*61046927SAndroid Build Coastguard Worker switch (pname) {
112*61046927SAndroid Build Coastguard Worker case GL_SAMPLE_POSITION: {
113*61046927SAndroid Build Coastguard Worker if (index >= ctx->DrawBuffer->Visual.samples) {
114*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_INVALID_VALUE, "glGetMultisamplefv(index)" );
115*61046927SAndroid Build Coastguard Worker return;
116*61046927SAndroid Build Coastguard Worker }
117*61046927SAndroid Build Coastguard Worker
118*61046927SAndroid Build Coastguard Worker get_sample_position(ctx, ctx->DrawBuffer, index, val);
119*61046927SAndroid Build Coastguard Worker
120*61046927SAndroid Build Coastguard Worker /* FBOs can be upside down (winsys always are)*/
121*61046927SAndroid Build Coastguard Worker if (ctx->DrawBuffer->FlipY)
122*61046927SAndroid Build Coastguard Worker val[1] = 1.0f - val[1];
123*61046927SAndroid Build Coastguard Worker
124*61046927SAndroid Build Coastguard Worker return;
125*61046927SAndroid Build Coastguard Worker }
126*61046927SAndroid Build Coastguard Worker
127*61046927SAndroid Build Coastguard Worker case GL_PROGRAMMABLE_SAMPLE_LOCATION_ARB:
128*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_sample_locations) {
129*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_INVALID_ENUM, "glGetMultisamplefv(pname)" );
130*61046927SAndroid Build Coastguard Worker return;
131*61046927SAndroid Build Coastguard Worker }
132*61046927SAndroid Build Coastguard Worker
133*61046927SAndroid Build Coastguard Worker if (index >= MAX_SAMPLE_LOCATION_TABLE_SIZE * 2) {
134*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_INVALID_VALUE, "glGetMultisamplefv(index)" );
135*61046927SAndroid Build Coastguard Worker return;
136*61046927SAndroid Build Coastguard Worker }
137*61046927SAndroid Build Coastguard Worker
138*61046927SAndroid Build Coastguard Worker if (ctx->DrawBuffer->SampleLocationTable)
139*61046927SAndroid Build Coastguard Worker *val = ctx->DrawBuffer->SampleLocationTable[index];
140*61046927SAndroid Build Coastguard Worker else
141*61046927SAndroid Build Coastguard Worker *val = 0.5f;
142*61046927SAndroid Build Coastguard Worker
143*61046927SAndroid Build Coastguard Worker return;
144*61046927SAndroid Build Coastguard Worker
145*61046927SAndroid Build Coastguard Worker default:
146*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_INVALID_ENUM, "glGetMultisamplefv(pname)" );
147*61046927SAndroid Build Coastguard Worker return;
148*61046927SAndroid Build Coastguard Worker }
149*61046927SAndroid Build Coastguard Worker }
150*61046927SAndroid Build Coastguard Worker
151*61046927SAndroid Build Coastguard Worker static void
sample_maski(struct gl_context * ctx,GLuint index,GLbitfield mask)152*61046927SAndroid Build Coastguard Worker sample_maski(struct gl_context *ctx, GLuint index, GLbitfield mask)
153*61046927SAndroid Build Coastguard Worker {
154*61046927SAndroid Build Coastguard Worker if (ctx->Multisample.SampleMaskValue == mask)
155*61046927SAndroid Build Coastguard Worker return;
156*61046927SAndroid Build Coastguard Worker
157*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
158*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_SAMPLE_STATE;
159*61046927SAndroid Build Coastguard Worker ctx->Multisample.SampleMaskValue = mask;
160*61046927SAndroid Build Coastguard Worker }
161*61046927SAndroid Build Coastguard Worker
162*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_SampleMaski_no_error(GLuint index,GLbitfield mask)163*61046927SAndroid Build Coastguard Worker _mesa_SampleMaski_no_error(GLuint index, GLbitfield mask)
164*61046927SAndroid Build Coastguard Worker {
165*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
166*61046927SAndroid Build Coastguard Worker sample_maski(ctx, index, mask);
167*61046927SAndroid Build Coastguard Worker }
168*61046927SAndroid Build Coastguard Worker
169*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_SampleMaski(GLuint index,GLbitfield mask)170*61046927SAndroid Build Coastguard Worker _mesa_SampleMaski(GLuint index, GLbitfield mask)
171*61046927SAndroid Build Coastguard Worker {
172*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
173*61046927SAndroid Build Coastguard Worker
174*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_texture_multisample) {
175*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMaski");
176*61046927SAndroid Build Coastguard Worker return;
177*61046927SAndroid Build Coastguard Worker }
178*61046927SAndroid Build Coastguard Worker
179*61046927SAndroid Build Coastguard Worker if (index != 0) {
180*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glSampleMaski(index)");
181*61046927SAndroid Build Coastguard Worker return;
182*61046927SAndroid Build Coastguard Worker }
183*61046927SAndroid Build Coastguard Worker
184*61046927SAndroid Build Coastguard Worker sample_maski(ctx, index, mask);
185*61046927SAndroid Build Coastguard Worker }
186*61046927SAndroid Build Coastguard Worker
187*61046927SAndroid Build Coastguard Worker static void
min_sample_shading(struct gl_context * ctx,GLclampf value)188*61046927SAndroid Build Coastguard Worker min_sample_shading(struct gl_context *ctx, GLclampf value)
189*61046927SAndroid Build Coastguard Worker {
190*61046927SAndroid Build Coastguard Worker value = SATURATE(value);
191*61046927SAndroid Build Coastguard Worker
192*61046927SAndroid Build Coastguard Worker if (ctx->Multisample.MinSampleShadingValue == value)
193*61046927SAndroid Build Coastguard Worker return;
194*61046927SAndroid Build Coastguard Worker
195*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, GL_MULTISAMPLE_BIT);
196*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ctx->DriverFlags.NewSampleShading;
197*61046927SAndroid Build Coastguard Worker ctx->Multisample.MinSampleShadingValue = value;
198*61046927SAndroid Build Coastguard Worker }
199*61046927SAndroid Build Coastguard Worker
200*61046927SAndroid Build Coastguard Worker /**
201*61046927SAndroid Build Coastguard Worker * Called via glMinSampleShadingARB
202*61046927SAndroid Build Coastguard Worker */
203*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_MinSampleShading_no_error(GLclampf value)204*61046927SAndroid Build Coastguard Worker _mesa_MinSampleShading_no_error(GLclampf value)
205*61046927SAndroid Build Coastguard Worker {
206*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
207*61046927SAndroid Build Coastguard Worker min_sample_shading(ctx, value);
208*61046927SAndroid Build Coastguard Worker }
209*61046927SAndroid Build Coastguard Worker
210*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_MinSampleShading(GLclampf value)211*61046927SAndroid Build Coastguard Worker _mesa_MinSampleShading(GLclampf value)
212*61046927SAndroid Build Coastguard Worker {
213*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
214*61046927SAndroid Build Coastguard Worker
215*61046927SAndroid Build Coastguard Worker if (!_mesa_has_ARB_sample_shading(ctx) &&
216*61046927SAndroid Build Coastguard Worker !_mesa_has_OES_sample_shading(ctx)) {
217*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "glMinSampleShading");
218*61046927SAndroid Build Coastguard Worker return;
219*61046927SAndroid Build Coastguard Worker }
220*61046927SAndroid Build Coastguard Worker
221*61046927SAndroid Build Coastguard Worker min_sample_shading(ctx, value);
222*61046927SAndroid Build Coastguard Worker }
223*61046927SAndroid Build Coastguard Worker
224*61046927SAndroid Build Coastguard Worker /**
225*61046927SAndroid Build Coastguard Worker * Helper for checking a requested sample count against the limit
226*61046927SAndroid Build Coastguard Worker * for a particular (target, internalFormat) pair. The limit imposed,
227*61046927SAndroid Build Coastguard Worker * and the error generated, both depend on which extensions are supported.
228*61046927SAndroid Build Coastguard Worker *
229*61046927SAndroid Build Coastguard Worker * Returns a GL error enum, or GL_NO_ERROR if the requested sample count is
230*61046927SAndroid Build Coastguard Worker * acceptable.
231*61046927SAndroid Build Coastguard Worker */
232*61046927SAndroid Build Coastguard Worker GLenum
_mesa_check_sample_count(struct gl_context * ctx,GLenum target,GLenum internalFormat,GLsizei samples,GLsizei storageSamples)233*61046927SAndroid Build Coastguard Worker _mesa_check_sample_count(struct gl_context *ctx, GLenum target,
234*61046927SAndroid Build Coastguard Worker GLenum internalFormat, GLsizei samples,
235*61046927SAndroid Build Coastguard Worker GLsizei storageSamples)
236*61046927SAndroid Build Coastguard Worker {
237*61046927SAndroid Build Coastguard Worker /* Section 4.4 (Framebuffer objects), page 198 of the OpenGL ES 3.0.0
238*61046927SAndroid Build Coastguard Worker * specification says:
239*61046927SAndroid Build Coastguard Worker *
240*61046927SAndroid Build Coastguard Worker * "If internalformat is a signed or unsigned integer format and samples
241*61046927SAndroid Build Coastguard Worker * is greater than zero, then the error INVALID_OPERATION is generated."
242*61046927SAndroid Build Coastguard Worker *
243*61046927SAndroid Build Coastguard Worker * This restriction is relaxed for OpenGL ES 3.1.
244*61046927SAndroid Build Coastguard Worker */
245*61046927SAndroid Build Coastguard Worker if ((_mesa_is_gles2(ctx) && ctx->Version == 30) &&
246*61046927SAndroid Build Coastguard Worker _mesa_is_enum_format_integer(internalFormat)
247*61046927SAndroid Build Coastguard Worker && samples > 0) {
248*61046927SAndroid Build Coastguard Worker return GL_INVALID_OPERATION;
249*61046927SAndroid Build Coastguard Worker }
250*61046927SAndroid Build Coastguard Worker
251*61046927SAndroid Build Coastguard Worker if (ctx->Extensions.AMD_framebuffer_multisample_advanced &&
252*61046927SAndroid Build Coastguard Worker target == GL_RENDERBUFFER) {
253*61046927SAndroid Build Coastguard Worker if (!_mesa_is_depth_or_stencil_format(internalFormat)) {
254*61046927SAndroid Build Coastguard Worker /* From the AMD_framebuffer_multisample_advanced spec:
255*61046927SAndroid Build Coastguard Worker *
256*61046927SAndroid Build Coastguard Worker * "An INVALID_OPERATION error is generated if <internalformat>
257*61046927SAndroid Build Coastguard Worker * is a color format and <storageSamples> is greater than
258*61046927SAndroid Build Coastguard Worker * the implementation-dependent limit MAX_COLOR_FRAMEBUFFER_-
259*61046927SAndroid Build Coastguard Worker * STORAGE_SAMPLES_AMD."
260*61046927SAndroid Build Coastguard Worker */
261*61046927SAndroid Build Coastguard Worker if (samples > ctx->Const.MaxColorFramebufferSamples)
262*61046927SAndroid Build Coastguard Worker return GL_INVALID_OPERATION;
263*61046927SAndroid Build Coastguard Worker
264*61046927SAndroid Build Coastguard Worker /* From the AMD_framebuffer_multisample_advanced spec:
265*61046927SAndroid Build Coastguard Worker *
266*61046927SAndroid Build Coastguard Worker * "An INVALID_OPERATION error is generated if <internalformat>
267*61046927SAndroid Build Coastguard Worker * is a color format and <storageSamples> is greater than
268*61046927SAndroid Build Coastguard Worker * the implementation-dependent limit MAX_COLOR_FRAMEBUFFER_-
269*61046927SAndroid Build Coastguard Worker * STORAGE_SAMPLES_AMD."
270*61046927SAndroid Build Coastguard Worker */
271*61046927SAndroid Build Coastguard Worker if (storageSamples > ctx->Const.MaxColorFramebufferStorageSamples)
272*61046927SAndroid Build Coastguard Worker return GL_INVALID_OPERATION;
273*61046927SAndroid Build Coastguard Worker
274*61046927SAndroid Build Coastguard Worker /* From the AMD_framebuffer_multisample_advanced spec:
275*61046927SAndroid Build Coastguard Worker *
276*61046927SAndroid Build Coastguard Worker * "An INVALID_OPERATION error is generated if <storageSamples> is
277*61046927SAndroid Build Coastguard Worker * greater than <samples>."
278*61046927SAndroid Build Coastguard Worker */
279*61046927SAndroid Build Coastguard Worker if (storageSamples > samples)
280*61046927SAndroid Build Coastguard Worker return GL_INVALID_OPERATION;
281*61046927SAndroid Build Coastguard Worker
282*61046927SAndroid Build Coastguard Worker /* Color renderbuffer sample counts are now fully validated
283*61046927SAndroid Build Coastguard Worker * according to AMD_framebuffer_multisample_advanced.
284*61046927SAndroid Build Coastguard Worker */
285*61046927SAndroid Build Coastguard Worker return GL_NO_ERROR;
286*61046927SAndroid Build Coastguard Worker } else {
287*61046927SAndroid Build Coastguard Worker /* From the AMD_framebuffer_multisample_advanced spec:
288*61046927SAndroid Build Coastguard Worker *
289*61046927SAndroid Build Coastguard Worker * "An INVALID_OPERATION error is generated if <internalformat> is
290*61046927SAndroid Build Coastguard Worker * a depth or stencil format and <storageSamples> is not equal to
291*61046927SAndroid Build Coastguard Worker * <samples>."
292*61046927SAndroid Build Coastguard Worker */
293*61046927SAndroid Build Coastguard Worker if (storageSamples != samples)
294*61046927SAndroid Build Coastguard Worker return GL_INVALID_OPERATION;
295*61046927SAndroid Build Coastguard Worker }
296*61046927SAndroid Build Coastguard Worker } else {
297*61046927SAndroid Build Coastguard Worker /* If the extension is unsupported, it's not possible to set
298*61046927SAndroid Build Coastguard Worker * storageSamples differently.
299*61046927SAndroid Build Coastguard Worker */
300*61046927SAndroid Build Coastguard Worker assert(samples == storageSamples);
301*61046927SAndroid Build Coastguard Worker }
302*61046927SAndroid Build Coastguard Worker
303*61046927SAndroid Build Coastguard Worker /* If ARB_internalformat_query is supported, then treat its highest
304*61046927SAndroid Build Coastguard Worker * returned sample count as the absolute maximum for this format; it is
305*61046927SAndroid Build Coastguard Worker * allowed to exceed MAX_SAMPLES.
306*61046927SAndroid Build Coastguard Worker *
307*61046927SAndroid Build Coastguard Worker * From the ARB_internalformat_query spec:
308*61046927SAndroid Build Coastguard Worker *
309*61046927SAndroid Build Coastguard Worker * "If <samples is greater than the maximum number of samples supported
310*61046927SAndroid Build Coastguard Worker * for <internalformat> then the error INVALID_OPERATION is generated."
311*61046927SAndroid Build Coastguard Worker */
312*61046927SAndroid Build Coastguard Worker if (ctx->Extensions.ARB_internalformat_query) {
313*61046927SAndroid Build Coastguard Worker GLint buffer[16] = {-1};
314*61046927SAndroid Build Coastguard Worker GLint limit;
315*61046927SAndroid Build Coastguard Worker
316*61046927SAndroid Build Coastguard Worker st_QueryInternalFormat(ctx, target, internalFormat,
317*61046927SAndroid Build Coastguard Worker GL_SAMPLES, buffer);
318*61046927SAndroid Build Coastguard Worker /* since the query returns samples sorted in descending order,
319*61046927SAndroid Build Coastguard Worker * the first element is the greatest supported sample value.
320*61046927SAndroid Build Coastguard Worker */
321*61046927SAndroid Build Coastguard Worker limit = buffer[0];
322*61046927SAndroid Build Coastguard Worker
323*61046927SAndroid Build Coastguard Worker return samples > limit ? GL_INVALID_OPERATION : GL_NO_ERROR;
324*61046927SAndroid Build Coastguard Worker }
325*61046927SAndroid Build Coastguard Worker
326*61046927SAndroid Build Coastguard Worker /* If ARB_texture_multisample is supported, we have separate limits,
327*61046927SAndroid Build Coastguard Worker * which may be lower than MAX_SAMPLES:
328*61046927SAndroid Build Coastguard Worker *
329*61046927SAndroid Build Coastguard Worker * From the ARB_texture_multisample spec, when describing the operation
330*61046927SAndroid Build Coastguard Worker * of RenderbufferStorageMultisample:
331*61046927SAndroid Build Coastguard Worker *
332*61046927SAndroid Build Coastguard Worker * "If <internalformat> is a signed or unsigned integer format and
333*61046927SAndroid Build Coastguard Worker * <samples> is greater than the value of MAX_INTEGER_SAMPLES, then the
334*61046927SAndroid Build Coastguard Worker * error INVALID_OPERATION is generated"
335*61046927SAndroid Build Coastguard Worker *
336*61046927SAndroid Build Coastguard Worker * And when describing the operation of TexImage*Multisample:
337*61046927SAndroid Build Coastguard Worker *
338*61046927SAndroid Build Coastguard Worker * "The error INVALID_OPERATION may be generated if any of the following
339*61046927SAndroid Build Coastguard Worker * are true:
340*61046927SAndroid Build Coastguard Worker *
341*61046927SAndroid Build Coastguard Worker * * <internalformat> is a depth/stencil-renderable format and <samples>
342*61046927SAndroid Build Coastguard Worker * is greater than the value of MAX_DEPTH_TEXTURE_SAMPLES
343*61046927SAndroid Build Coastguard Worker * * <internalformat> is a color-renderable format and <samples> is
344*61046927SAndroid Build Coastguard Worker * grater than the value of MAX_COLOR_TEXTURE_SAMPLES
345*61046927SAndroid Build Coastguard Worker * * <internalformat> is a signed or unsigned integer format and
346*61046927SAndroid Build Coastguard Worker * <samples> is greater than the value of MAX_INTEGER_SAMPLES
347*61046927SAndroid Build Coastguard Worker */
348*61046927SAndroid Build Coastguard Worker
349*61046927SAndroid Build Coastguard Worker if (ctx->Extensions.ARB_texture_multisample) {
350*61046927SAndroid Build Coastguard Worker if (_mesa_is_enum_format_integer(internalFormat))
351*61046927SAndroid Build Coastguard Worker return samples > ctx->Const.MaxIntegerSamples
352*61046927SAndroid Build Coastguard Worker ? GL_INVALID_OPERATION : GL_NO_ERROR;
353*61046927SAndroid Build Coastguard Worker
354*61046927SAndroid Build Coastguard Worker if (target == GL_TEXTURE_2D_MULTISAMPLE ||
355*61046927SAndroid Build Coastguard Worker target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
356*61046927SAndroid Build Coastguard Worker
357*61046927SAndroid Build Coastguard Worker if (_mesa_is_depth_or_stencil_format(internalFormat))
358*61046927SAndroid Build Coastguard Worker return samples > ctx->Const.MaxDepthTextureSamples
359*61046927SAndroid Build Coastguard Worker ? GL_INVALID_OPERATION : GL_NO_ERROR;
360*61046927SAndroid Build Coastguard Worker else
361*61046927SAndroid Build Coastguard Worker return samples > ctx->Const.MaxColorTextureSamples
362*61046927SAndroid Build Coastguard Worker ? GL_INVALID_OPERATION : GL_NO_ERROR;
363*61046927SAndroid Build Coastguard Worker }
364*61046927SAndroid Build Coastguard Worker }
365*61046927SAndroid Build Coastguard Worker
366*61046927SAndroid Build Coastguard Worker /* No more specific limit is available, so just use MAX_SAMPLES:
367*61046927SAndroid Build Coastguard Worker *
368*61046927SAndroid Build Coastguard Worker * On p205 of the GL3.1 spec:
369*61046927SAndroid Build Coastguard Worker *
370*61046927SAndroid Build Coastguard Worker * "... or if samples is greater than MAX_SAMPLES, then the error
371*61046927SAndroid Build Coastguard Worker * INVALID_VALUE is generated"
372*61046927SAndroid Build Coastguard Worker */
373*61046927SAndroid Build Coastguard Worker return (GLuint) samples > ctx->Const.MaxSamples
374*61046927SAndroid Build Coastguard Worker ? GL_INVALID_VALUE : GL_NO_ERROR;
375*61046927SAndroid Build Coastguard Worker }
376*61046927SAndroid Build Coastguard Worker
377*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_AlphaToCoverageDitherControlNV_no_error(GLenum mode)378*61046927SAndroid Build Coastguard Worker _mesa_AlphaToCoverageDitherControlNV_no_error(GLenum mode)
379*61046927SAndroid Build Coastguard Worker {
380*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
381*61046927SAndroid Build Coastguard Worker
382*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, GL_MULTISAMPLE_BIT);
383*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_BLEND;
384*61046927SAndroid Build Coastguard Worker ctx->Multisample.SampleAlphaToCoverageDitherControl = mode;
385*61046927SAndroid Build Coastguard Worker }
386*61046927SAndroid Build Coastguard Worker
387*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_AlphaToCoverageDitherControlNV(GLenum mode)388*61046927SAndroid Build Coastguard Worker _mesa_AlphaToCoverageDitherControlNV(GLenum mode)
389*61046927SAndroid Build Coastguard Worker {
390*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
391*61046927SAndroid Build Coastguard Worker
392*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, GL_MULTISAMPLE_BIT);
393*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_BLEND;
394*61046927SAndroid Build Coastguard Worker switch (mode) {
395*61046927SAndroid Build Coastguard Worker case GL_ALPHA_TO_COVERAGE_DITHER_DEFAULT_NV:
396*61046927SAndroid Build Coastguard Worker case GL_ALPHA_TO_COVERAGE_DITHER_ENABLE_NV:
397*61046927SAndroid Build Coastguard Worker case GL_ALPHA_TO_COVERAGE_DITHER_DISABLE_NV:
398*61046927SAndroid Build Coastguard Worker ctx->Multisample.SampleAlphaToCoverageDitherControl = mode;
399*61046927SAndroid Build Coastguard Worker break;
400*61046927SAndroid Build Coastguard Worker default:
401*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glAlphaToCoverageDitherControlNV(invalid parameter)");
402*61046927SAndroid Build Coastguard Worker }
403*61046927SAndroid Build Coastguard Worker }
404*61046927SAndroid Build Coastguard Worker
405*61046927SAndroid Build Coastguard Worker void
_mesa_GetProgrammableSampleCaps(struct gl_context * ctx,const struct gl_framebuffer * fb,GLuint * outBits,GLuint * outWidth,GLuint * outHeight)406*61046927SAndroid Build Coastguard Worker _mesa_GetProgrammableSampleCaps(struct gl_context *ctx, const struct gl_framebuffer *fb,
407*61046927SAndroid Build Coastguard Worker GLuint *outBits, GLuint *outWidth, GLuint *outHeight)
408*61046927SAndroid Build Coastguard Worker {
409*61046927SAndroid Build Coastguard Worker struct st_context *st = st_context(ctx);
410*61046927SAndroid Build Coastguard Worker struct pipe_screen *screen = ctx->pipe->screen;
411*61046927SAndroid Build Coastguard Worker
412*61046927SAndroid Build Coastguard Worker st_validate_state(st, ST_PIPELINE_UPDATE_FB_STATE_MASK);
413*61046927SAndroid Build Coastguard Worker
414*61046927SAndroid Build Coastguard Worker *outBits = 4;
415*61046927SAndroid Build Coastguard Worker *outWidth = 1;
416*61046927SAndroid Build Coastguard Worker *outHeight = 1;
417*61046927SAndroid Build Coastguard Worker
418*61046927SAndroid Build Coastguard Worker if (ctx->Extensions.ARB_sample_locations)
419*61046927SAndroid Build Coastguard Worker screen->get_sample_pixel_grid(screen, st->state.fb_num_samples,
420*61046927SAndroid Build Coastguard Worker outWidth, outHeight);
421*61046927SAndroid Build Coastguard Worker
422*61046927SAndroid Build Coastguard Worker /* We could handle this better in some circumstances,
423*61046927SAndroid Build Coastguard Worker * but it's not really an issue */
424*61046927SAndroid Build Coastguard Worker if (*outWidth > MAX_SAMPLE_LOCATION_GRID_SIZE ||
425*61046927SAndroid Build Coastguard Worker *outHeight > MAX_SAMPLE_LOCATION_GRID_SIZE) {
426*61046927SAndroid Build Coastguard Worker *outWidth = 1;
427*61046927SAndroid Build Coastguard Worker *outHeight = 1;
428*61046927SAndroid Build Coastguard Worker }
429*61046927SAndroid Build Coastguard Worker }
430