aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/main')
-rw-r--r--mesalib/src/mesa/main/attrib.c15
-rw-r--r--mesalib/src/mesa/main/context.c5
-rw-r--r--mesalib/src/mesa/main/dd.h9
-rw-r--r--mesalib/src/mesa/main/enable.c18
-rw-r--r--mesalib/src/mesa/main/fbobject.c62
-rw-r--r--mesalib/src/mesa/main/get.c12
-rw-r--r--mesalib/src/mesa/main/get_hash_params.py10
-rw-r--r--mesalib/src/mesa/main/mtypes.h19
-rw-r--r--mesalib/src/mesa/main/multisample.c52
-rw-r--r--mesalib/src/mesa/main/multisample.h6
-rw-r--r--mesalib/src/mesa/main/queryobj.c11
-rw-r--r--mesalib/src/mesa/main/shared.c2
-rw-r--r--mesalib/src/mesa/main/teximage.c240
-rw-r--r--mesalib/src/mesa/main/teximage.h11
-rw-r--r--mesalib/src/mesa/main/texobj.c96
-rw-r--r--mesalib/src/mesa/main/texparam.c16
-rw-r--r--mesalib/src/mesa/main/texstate.c2
-rw-r--r--mesalib/src/mesa/main/version.c94
-rw-r--r--mesalib/src/mesa/main/version.h3
19 files changed, 617 insertions, 66 deletions
diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c
index a95128328..3b991bcac 100644
--- a/mesalib/src/mesa/main/attrib.c
+++ b/mesalib/src/mesa/main/attrib.c
@@ -130,6 +130,9 @@ struct gl_enable_attrib
GLboolean VertexProgramPointSize;
GLboolean VertexProgramTwoSide;
+ /* GL_ARB_fragment_program */
+ GLboolean FragmentProgram;
+
/* GL_ARB_point_sprite / GL_NV_point_sprite */
GLboolean PointSprite;
GLboolean FragmentShaderATI;
@@ -316,6 +319,10 @@ _mesa_PushAttrib(GLbitfield mask)
attr->VertexProgram = ctx->VertexProgram.Enabled;
attr->VertexProgramPointSize = ctx->VertexProgram.PointSizeEnabled;
attr->VertexProgramTwoSide = ctx->VertexProgram.TwoSideEnabled;
+
+ /* GL_ARB_fragment_program */
+ attr->FragmentProgram = ctx->FragmentProgram.Enabled;
+
save_attrib_data(&head, GL_ENABLE_BIT, attr);
/* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
@@ -607,6 +614,11 @@ pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib *enable)
enable->VertexProgramTwoSide,
GL_VERTEX_PROGRAM_TWO_SIDE_ARB);
+ /* GL_ARB_fragment_program */
+ TEST_AND_UPDATE(ctx->FragmentProgram.Enabled,
+ enable->FragmentProgram,
+ GL_FRAGMENT_PROGRAM_ARB);
+
/* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
TEST_AND_UPDATE(ctx->Color.sRGBEnabled, enable->sRGBEnabled,
GL_FRAMEBUFFER_SRGB);
@@ -767,6 +779,9 @@ pop_texture_group(struct gl_context *ctx, struct texture_state *texstate)
continue;
else if (obj->Target == GL_TEXTURE_EXTERNAL_OES)
continue;
+ else if (obj->Target == GL_TEXTURE_2D_MULTISAMPLE ||
+ obj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
+ continue;
target = obj->Target;
diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c
index 02acfc2aa..cdcf7adfa 100644
--- a/mesalib/src/mesa/main/context.c
+++ b/mesalib/src/mesa/main/context.c
@@ -661,6 +661,11 @@ _mesa_init_constants(struct gl_context *ctx)
/* ES 3.0 or ARB_ES3_compatibility */
ctx->Const.MaxElementIndex = 0xffffffffu;
+
+ /* GL_ARB_texture_multisample */
+ ctx->Const.MaxColorTextureSamples = 1;
+ ctx->Const.MaxDepthTextureSamples = 1;
+ ctx->Const.MaxIntegerSamples = 1;
}
diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h
index 9c818ccd8..4860d4d12 100644
--- a/mesalib/src/mesa/main/dd.h
+++ b/mesalib/src/mesa/main/dd.h
@@ -638,6 +638,7 @@ struct dd_function_table {
struct gl_query_object * (*NewQueryObject)(struct gl_context *ctx, GLuint id);
void (*DeleteQuery)(struct gl_context *ctx, struct gl_query_object *q);
void (*BeginQuery)(struct gl_context *ctx, struct gl_query_object *q);
+ void (*QueryCounter)(struct gl_context *ctx, struct gl_query_object *q);
void (*EndQuery)(struct gl_context *ctx, struct gl_query_object *q);
void (*CheckQuery)(struct gl_context *ctx, struct gl_query_object *q);
void (*WaitQuery)(struct gl_context *ctx, struct gl_query_object *q);
@@ -833,6 +834,14 @@ struct dd_function_table {
* This should be equivalent to glGetInteger64v(GL_TIMESTAMP);
*/
uint64_t (*GetTimestamp)(struct gl_context *ctx);
+
+ /**
+ * \name GL_ARB_texture_multisample
+ */
+ void (*GetSamplePosition)(struct gl_context *ctx,
+ struct gl_framebuffer *fb,
+ GLuint index,
+ GLfloat *outValue);
};
diff --git a/mesalib/src/mesa/main/enable.c b/mesalib/src/mesa/main/enable.c
index 7e85fdfb3..b688f050b 100644
--- a/mesalib/src/mesa/main/enable.c
+++ b/mesalib/src/mesa/main/enable.c
@@ -1013,6 +1013,17 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
}
break;
+ /* ARB_texture_multisample */
+ case GL_SAMPLE_MASK:
+ if (!_mesa_is_desktop_gl(ctx))
+ goto invalid_enum_error;
+ CHECK_EXTENSION(ARB_texture_multisample, cap);
+ if (ctx->Multisample.SampleMask == state)
+ return;
+ FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
+ ctx->Multisample.SampleMask = state;
+ break;
+
default:
goto invalid_enum_error;
}
@@ -1583,6 +1594,13 @@ _mesa_IsEnabled( GLenum cap )
CHECK_EXTENSION(OES_EGL_image_external);
return is_texture_enabled(ctx, TEXTURE_EXTERNAL_BIT);
+ /* ARB_texture_multisample */
+ case GL_SAMPLE_MASK:
+ if (!_mesa_is_desktop_gl(ctx))
+ goto invalid_enum_error;
+ CHECK_EXTENSION(ARB_texture_multisample);
+ return ctx->Multisample.SampleMask;
+
default:
goto invalid_enum_error;
}
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c
index 89bc57509..d6acc5896 100644
--- a/mesalib/src/mesa/main/fbobject.c
+++ b/mesalib/src/mesa/main/fbobject.c
@@ -745,6 +745,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
GLenum intFormat = GL_NONE; /* color buffers' internal format */
GLuint minWidth = ~0, minHeight = ~0, maxWidth = 0, maxHeight = 0;
GLint numSamples = -1;
+ GLint fixedSampleLocations = -1;
GLint i;
GLuint j;
@@ -814,12 +815,29 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
f = texImg->_BaseFormat;
attFormat = texImg->TexFormat;
numImages++;
+
if (!is_format_color_renderable(ctx, attFormat, texImg->InternalFormat) &&
!is_legal_depth_format(ctx, f)) {
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
fbo_incomplete("texture attachment incomplete", -1);
return;
}
+
+ if (numSamples < 0)
+ numSamples = texImg->NumSamples;
+ else if (numSamples != texImg->NumSamples) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
+ fbo_incomplete("inconsistent sample count", -1);
+ return;
+ }
+
+ if (fixedSampleLocations < 0)
+ fixedSampleLocations = texImg->FixedSampleLocations;
+ else if (fixedSampleLocations != texImg->FixedSampleLocations) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
+ fbo_incomplete("inconsistent fixed sample locations", -1);
+ return;
+ }
}
else if (att->Type == GL_RENDERBUFFER_EXT) {
minWidth = MIN2(minWidth, att->Renderbuffer->Width);
@@ -829,24 +847,35 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
f = att->Renderbuffer->InternalFormat;
attFormat = att->Renderbuffer->Format;
numImages++;
+
+ if (numSamples < 0)
+ numSamples = att->Renderbuffer->NumSamples;
+ else if (numSamples != att->Renderbuffer->NumSamples) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
+ fbo_incomplete("inconsistent sample count", -1);
+ return;
+ }
+
+ /* RENDERBUFFER has fixedSampleLocations implicitly true */
+ if (fixedSampleLocations < 0)
+ fixedSampleLocations = GL_TRUE;
+ else if (fixedSampleLocations != GL_TRUE) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
+ fbo_incomplete("inconsistent fixed sample locations", -1);
+ return;
+ }
}
else {
assert(att->Type == GL_NONE);
continue;
}
- if (att->Renderbuffer && numSamples < 0) {
- /* first buffer */
- numSamples = att->Renderbuffer->NumSamples;
- }
-
/* check if integer color */
fb->_IntegerColor = _mesa_is_format_integer_color(attFormat);
- /* Error-check width, height, format, samples
- */
+ /* Error-check width, height, format */
if (numImages == 1) {
- /* save format, num samples */
+ /* save format */
if (i >= 0) {
intFormat = f;
}
@@ -866,12 +895,6 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
return;
}
}
- if (att->Renderbuffer &&
- att->Renderbuffer->NumSamples != numSamples) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
- fbo_incomplete("inconsistant number of samples", i);
- return;
- }
}
/* Check that the format is valid. (MESA_FORMAT_NONE means unsupported)
@@ -2069,7 +2092,8 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
err = (texObj->Target != GL_TEXTURE_3D) &&
(texObj->Target != GL_TEXTURE_1D_ARRAY_EXT) &&
(texObj->Target != GL_TEXTURE_2D_ARRAY_EXT) &&
- (texObj->Target != GL_TEXTURE_CUBE_MAP_ARRAY);
+ (texObj->Target != GL_TEXTURE_CUBE_MAP_ARRAY) &&
+ (texObj->Target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
}
else {
/* Make sure textarget is consistent with the texture's type */
@@ -2103,7 +2127,8 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
}
else if ((texObj->Target == GL_TEXTURE_1D_ARRAY_EXT) ||
(texObj->Target == GL_TEXTURE_2D_ARRAY_EXT) ||
- (texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY)) {
+ (texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY) ||
+ (texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)) {
if (zoffset < 0 ||
zoffset >= (GLint) ctx->Const.MaxArrayTextureLayers) {
_mesa_error(ctx, GL_INVALID_VALUE,
@@ -2255,6 +2280,11 @@ _mesa_FramebufferTexture2D(GLenum target, GLenum attachment,
error = (_mesa_is_gles(ctx) && ctx->Version < 30)
|| !ctx->Extensions.EXT_texture_array;
break;
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ error = _mesa_is_gles(ctx)
+ || !ctx->Extensions.ARB_texture_multisample;
+ break;
default:
error = GL_TRUE;
}
diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c
index da1e01cb5..2399f9c9d 100644
--- a/mesalib/src/mesa/main/get.c
+++ b/mesalib/src/mesa/main/get.c
@@ -354,6 +354,7 @@ EXTRA_EXT(ARB_timer_query);
EXTRA_EXT(ARB_map_buffer_alignment);
EXTRA_EXT(ARB_texture_cube_map_array);
EXTRA_EXT(ARB_texture_buffer_range);
+EXTRA_EXT(ARB_texture_multisample);
static const int
extra_NV_primitive_restart[] = {
@@ -693,6 +694,8 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
case GL_TEXTURE_BINDING_RECTANGLE_NV:
case GL_TEXTURE_BINDING_EXTERNAL_OES:
case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY:
+ case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
+ case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
unit = ctx->Texture.CurrentUnit;
v->value_int =
ctx->Texture.Unit[unit].CurrentTex[d->offset]->Name;
@@ -1632,6 +1635,15 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v)
goto invalid_enum;
v->value_int = ctx->UniformBufferBindings[index].Size;
return TYPE_INT;
+
+ /* ARB_texture_multisample / GL3.2 */
+ case GL_SAMPLE_MASK_VALUE:
+ if (index != 0)
+ goto invalid_value;
+ if (!ctx->Extensions.ARB_texture_multisample)
+ goto invalid_enum;
+ v->value_int = ctx->Multisample.SampleMaskValue;
+ return TYPE_INT;
}
invalid_enum:
diff --git a/mesalib/src/mesa/main/get_hash_params.py b/mesalib/src/mesa/main/get_hash_params.py
index 1b7d6ad8e..5022ddc40 100644
--- a/mesalib/src/mesa/main/get_hash_params.py
+++ b/mesalib/src/mesa/main/get_hash_params.py
@@ -658,6 +658,16 @@ descriptor=[
[ "TEXTURE_BUFFER_FORMAT_ARB", "LOC_CUSTOM, TYPE_INT, 0, extra_texture_buffer_object" ],
[ "TEXTURE_BUFFER_ARB", "LOC_CUSTOM, TYPE_INT, 0, extra_texture_buffer_object" ],
+# GL_ARB_texture_multisample / GL 3.2
+ [ "TEXTURE_BINDING_2D_MULTISAMPLE", "LOC_CUSTOM, TYPE_INT, TEXTURE_2D_MULTISAMPLE_INDEX, extra_ARB_texture_multisample" ],
+ [ "TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY", "LOC_CUSTOM, TYPE_INT, TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX, extra_ARB_texture_multisample" ],
+ [ "MAX_COLOR_TEXTURE_SAMPLES", "CONTEXT_INT(Const.MaxColorTextureSamples), extra_ARB_texture_multisample" ],
+ [ "MAX_DEPTH_TEXTURE_SAMPLES", "CONTEXT_INT(Const.MaxDepthTextureSamples), extra_ARB_texture_multisample" ],
+ [ "MAX_INTEGER_SAMPLES", "CONTEXT_INT(Const.MaxIntegerSamples), extra_ARB_texture_multisample" ],
+ [ "SAMPLE_MASK", "CONTEXT_BOOL(Multisample.SampleMask), extra_ARB_texture_multisample" ],
+ [ "MAX_SAMPLE_MASK_WORDS", "CONST(1), extra_ARB_texture_multisample" ],
+
+
# GL_ARB_sampler_objects / GL 3.3
[ "SAMPLER_BINDING", "LOC_CUSTOM, TYPE_INT, GL_SAMPLER_BINDING, NO_EXTRA" ],
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index b92f98e7d..a80944c81 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -993,6 +993,12 @@ struct gl_multisample_attrib
GLboolean SampleCoverage;
GLfloat SampleCoverageValue;
GLboolean SampleCoverageInvert;
+
+ /* ARB_texture_multisample / GL3.2 additions */
+ GLboolean SampleMask;
+ GLbitfield SampleMaskValue; /* GL spec defines this as an array but >32x MSAA is
+ * madness
+ */
};
@@ -1148,6 +1154,8 @@ struct gl_stencil_attrib
*/
typedef enum
{
+ TEXTURE_2D_MULTISAMPLE_INDEX,
+ TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX,
TEXTURE_CUBE_ARRAY_INDEX,
TEXTURE_BUFFER_INDEX,
TEXTURE_2D_ARRAY_INDEX,
@@ -1167,6 +1175,8 @@ typedef enum
* Used for Texture.Unit[]._ReallyEnabled flags.
*/
/*@{*/
+#define TEXTURE_2D_MULTISAMPLE_BIT (1 << TEXTURE_2D_MULTISAMPLE_INDEX)
+#define TEXTURE_2D_MULTISAMPLE_ARRAY_BIT (1 << TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX)
#define TEXTURE_CUBE_ARRAY_BIT (1 << TEXTURE_CUBE_ARRAY_INDEX)
#define TEXTURE_BUFFER_BIT (1 << TEXTURE_BUFFER_INDEX)
#define TEXTURE_2D_ARRAY_BIT (1 << TEXTURE_2D_ARRAY_INDEX)
@@ -1212,6 +1222,10 @@ struct gl_texture_image
GLuint Level; /**< Which mipmap level am I? */
/** Cube map face: index into gl_texture_object::Image[] array */
GLuint Face;
+
+ /** GL_ARB_texture_multisample */
+ GLuint NumSamples; /**< Sample count, or 0 for non-multisample */
+ GLboolean FixedSampleLocations; /**< Same sample locations for all pixels? */
};
@@ -3027,6 +3041,11 @@ struct gl_constants
* backslash character ('\') in GLSL source.
*/
GLboolean DisableGLSLLineContinuations;
+
+ /** GL_ARB_texture_multisample */
+ GLint MaxColorTextureSamples;
+ GLint MaxDepthTextureSamples;
+ GLint MaxIntegerSamples;
};
diff --git a/mesalib/src/mesa/main/multisample.c b/mesalib/src/mesa/main/multisample.c
index f792ad01e..248494615 100644
--- a/mesalib/src/mesa/main/multisample.c
+++ b/mesalib/src/mesa/main/multisample.c
@@ -28,6 +28,7 @@
#include "main/macros.h"
#include "main/multisample.h"
#include "main/mtypes.h"
+#include "main/fbobject.h"
/**
@@ -59,4 +60,55 @@ _mesa_init_multisample(struct gl_context *ctx)
ctx->Multisample.SampleCoverage = GL_FALSE;
ctx->Multisample.SampleCoverageValue = 1.0;
ctx->Multisample.SampleCoverageInvert = GL_FALSE;
+
+ /* ARB_texture_multisample / GL3.2 additions */
+ ctx->Multisample.SampleMask = GL_FALSE;
+ ctx->Multisample.SampleMaskValue = ~(GLbitfield)0;
+}
+
+
+void GLAPIENTRY
+_mesa_GetMultisamplefv(GLenum pname, GLuint index, GLfloat * val)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ switch (pname) {
+ case GL_SAMPLE_POSITION: {
+ if (index >= ctx->DrawBuffer->Visual.samples) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glGetMultisamplefv(index)" );
+ return;
+ }
+
+ ctx->Driver.GetSamplePosition(ctx, ctx->DrawBuffer, index, val);
+
+ /* winsys FBOs are upside down */
+ if (_mesa_is_winsys_fbo(ctx->DrawBuffer))
+ val[1] = 1 - val[1];
+
+ return;
+ }
+
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetMultisamplefv(pname)" );
+ return;
+ }
+}
+
+void GLAPIENTRY
+_mesa_SampleMaski(GLuint index, GLbitfield mask)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->Extensions.ARB_texture_multisample) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMaski");
+ return;
+ }
+
+ if (index != 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glSampleMaski(index)");
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
+ ctx->Multisample.SampleMaskValue = mask;
}
diff --git a/mesalib/src/mesa/main/multisample.h b/mesalib/src/mesa/main/multisample.h
index 30726c34c..9e6b8e0d3 100644
--- a/mesalib/src/mesa/main/multisample.h
+++ b/mesalib/src/mesa/main/multisample.h
@@ -38,4 +38,10 @@ extern void
_mesa_init_multisample(struct gl_context *ctx);
+extern void GLAPIENTRY
+_mesa_GetMultisamplefv(GLenum pname, GLuint index, GLfloat* val);
+
+extern void GLAPIENTRY
+_mesa_SampleMaski(GLuint index, GLbitfield mask);
+
#endif
diff --git a/mesalib/src/mesa/main/queryobj.c b/mesalib/src/mesa/main/queryobj.c
index d0c5a2543..f0db740fd 100644
--- a/mesalib/src/mesa/main/queryobj.c
+++ b/mesalib/src/mesa/main/queryobj.c
@@ -486,9 +486,14 @@ _mesa_QueryCounter(GLuint id, GLenum target)
q->Result = 0;
q->Ready = GL_FALSE;
- /* QueryCounter is implemented using EndQuery without BeginQuery
- * in drivers. This is actually Direct3D and Gallium convention. */
- ctx->Driver.EndQuery(ctx, q);
+ if (ctx->Driver.QueryCounter) {
+ ctx->Driver.QueryCounter(ctx, q);
+ } else {
+ /* QueryCounter is implemented using EndQuery without BeginQuery
+ * in drivers. This is actually Direct3D and Gallium convention.
+ */
+ ctx->Driver.EndQuery(ctx, q);
+ }
}
diff --git a/mesalib/src/mesa/main/shared.c b/mesalib/src/mesa/main/shared.c
index a98a45c75..408125998 100644
--- a/mesalib/src/mesa/main/shared.c
+++ b/mesalib/src/mesa/main/shared.c
@@ -92,6 +92,8 @@ _mesa_alloc_shared_state(struct gl_context *ctx)
for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
/* NOTE: the order of these enums matches the TEXTURE_x_INDEX values */
static const GLenum targets[] = {
+ GL_TEXTURE_2D_MULTISAMPLE,
+ GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
GL_TEXTURE_CUBE_MAP_ARRAY,
GL_TEXTURE_BUFFER,
GL_TEXTURE_2D_ARRAY_EXT,
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index f0de0fb49..0dcf88ae4 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -661,7 +661,7 @@ _mesa_is_proxy_texture(GLenum target)
* NUM_TEXTURE_TARGETS should match number of terms below, except there's no
* proxy for GL_TEXTURE_BUFFER and GL_TEXTURE_EXTERNAL_OES.
*/
- assert(NUM_TEXTURE_TARGETS == 8 + 2);
+ assert(NUM_TEXTURE_TARGETS == 10 + 2);
return (target == GL_PROXY_TEXTURE_1D ||
target == GL_PROXY_TEXTURE_2D ||
@@ -670,7 +670,9 @@ _mesa_is_proxy_texture(GLenum target)
target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
target == GL_PROXY_TEXTURE_1D_ARRAY_EXT ||
target == GL_PROXY_TEXTURE_2D_ARRAY_EXT ||
- target == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY);
+ target == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY ||
+ target == GL_PROXY_TEXTURE_2D_MULTISAMPLE ||
+ target == GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY);
}
@@ -711,6 +713,12 @@ _mesa_get_proxy_target(GLenum target)
case GL_TEXTURE_CUBE_MAP_ARRAY:
case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
return GL_PROXY_TEXTURE_CUBE_MAP_ARRAY;
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
+ return GL_PROXY_TEXTURE_2D_MULTISAMPLE;
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY;
default:
_mesa_problem(NULL, "unexpected target in _mesa_get_proxy_target()");
return 0;
@@ -788,6 +796,18 @@ _mesa_select_tex_object(struct gl_context *ctx,
case GL_TEXTURE_EXTERNAL_OES:
return ctx->Extensions.OES_EGL_image_external
? texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX] : NULL;
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ return ctx->Extensions.ARB_texture_multisample
+ ? texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_INDEX] : NULL;
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
+ return ctx->Extensions.ARB_texture_multisample
+ ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_INDEX] : NULL;
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return ctx->Extensions.ARB_texture_multisample
+ ? texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL;
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return ctx->Extensions.ARB_texture_multisample
+ ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL;
default:
_mesa_problem(NULL, "bad target in _mesa_select_tex_object()");
return NULL;
@@ -918,6 +938,16 @@ get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level)
return NULL;
texIndex = TEXTURE_CUBE_ARRAY_INDEX;
break;
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
+ if (level > 0)
+ return 0;
+ texIndex = TEXTURE_2D_MULTISAMPLE_INDEX;
+ break;
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ if (level > 0)
+ return 0;
+ texIndex = TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX;
+ break;
default:
return NULL;
}
@@ -987,6 +1017,13 @@ _mesa_max_texture_levels(struct gl_context *ctx, GLenum target)
case GL_TEXTURE_BUFFER:
return ctx->API == API_OPENGL_CORE &&
ctx->Extensions.ARB_texture_buffer_object ? 1 : 0;
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return _mesa_is_desktop_gl(ctx)
+ && ctx->Extensions.ARB_texture_multisample
+ ? 1 : 0;
case GL_TEXTURE_EXTERNAL_OES:
/* fall-through */
default:
@@ -1020,6 +1057,8 @@ _mesa_get_texture_dimensions(GLenum target)
case GL_TEXTURE_1D_ARRAY:
case GL_PROXY_TEXTURE_1D_ARRAY:
case GL_TEXTURE_EXTERNAL_OES:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
return 2;
case GL_TEXTURE_3D:
case GL_PROXY_TEXTURE_3D:
@@ -1027,6 +1066,8 @@ _mesa_get_texture_dimensions(GLenum target)
case GL_PROXY_TEXTURE_2D_ARRAY:
case GL_TEXTURE_CUBE_MAP_ARRAY:
case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
return 3;
case GL_TEXTURE_BUFFER:
/* fall-through */
@@ -1068,6 +1109,8 @@ _mesa_get_tex_max_num_levels(GLenum target, GLsizei width, GLsizei height,
break;
case GL_TEXTURE_RECTANGLE:
case GL_TEXTURE_EXTERNAL_OES:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
return 1;
default:
assert(0);
@@ -1153,6 +1196,8 @@ clear_teximage_fields(struct gl_texture_image *img)
img->HeightLog2 = 0;
img->DepthLog2 = 0;
img->TexFormat = MESA_FORMAT_NONE;
+ img->NumSamples = 0;
+ img->FixedSampleLocations = GL_TRUE;
}
@@ -1196,6 +1241,9 @@ _mesa_init_teximage_fields(struct gl_context *ctx,
img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */
img->WidthLog2 = _mesa_logbase2(img->Width2);
+ img->NumSamples = 0;
+ img->FixedSampleLocations = GL_TRUE;
+
switch(target) {
case GL_TEXTURE_1D:
case GL_TEXTURE_BUFFER:
@@ -1234,6 +1282,8 @@ _mesa_init_teximage_fields(struct gl_context *ctx,
case GL_PROXY_TEXTURE_2D:
case GL_PROXY_TEXTURE_RECTANGLE:
case GL_PROXY_TEXTURE_CUBE_MAP:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
img->HeightLog2 = _mesa_logbase2(img->Height2);
if (depth == 0)
@@ -1246,6 +1296,8 @@ _mesa_init_teximage_fields(struct gl_context *ctx,
case GL_PROXY_TEXTURE_2D_ARRAY:
case GL_TEXTURE_CUBE_MAP_ARRAY:
case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
img->HeightLog2 = _mesa_logbase2(img->Height2);
img->Depth2 = depth; /* no border */
@@ -1317,6 +1369,8 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target,
case GL_TEXTURE_2D:
case GL_PROXY_TEXTURE_2D:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
maxSize >>= level;
if (width < 2 * border || width > 2 * border + maxSize)
@@ -1399,6 +1453,8 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target,
case GL_TEXTURE_2D_ARRAY_EXT:
case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
maxSize >>= level;
if (width < 2 * border || width > 2 * border + maxSize)
@@ -4102,3 +4158,183 @@ _mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer,
texbufferrange(ctx, target, internalFormat, bufObj, offset, size);
}
+
+static GLboolean
+is_renderable_texture_format(struct gl_context *ctx, GLenum internalformat)
+{
+ /* Everything that is allowed for renderbuffers,
+ * except for a base format of GL_STENCIL_INDEX.
+ */
+ GLenum baseFormat = _mesa_base_fbo_format(ctx, internalformat);
+ return baseFormat != 0 && baseFormat != GL_STENCIL_INDEX;
+}
+
+/** GL_ARB_texture_multisample */
+static GLboolean
+check_multisample_target(GLuint dims, GLenum target)
+{
+ switch(target) {
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
+ return dims == 2;
+
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return dims == 3;
+
+ default:
+ return GL_FALSE;
+ }
+}
+
+static void
+teximagemultisample(GLuint dims, GLenum target, GLsizei samples,
+ GLint internalformat, GLsizei width, GLsizei height,
+ GLsizei depth, GLboolean fixedsamplelocations)
+{
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLboolean sizeOK, dimensionsOK;
+ gl_format texFormat;
+
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!(ctx->Extensions.ARB_texture_multisample
+ && _mesa_is_desktop_gl(ctx))) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTexImage%uDMultisample", dims);
+ return;
+ }
+
+ if (!check_multisample_target(dims, target)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%uDMultisample(target)", dims);
+ return;
+ }
+
+ /* check that the specified internalformat is color/depth/stencil-renderable;
+ * refer GL3.1 spec 4.4.4
+ */
+
+ if (!is_renderable_texture_format(ctx, internalformat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexImage%uDMultisample(internalformat=%s)",
+ dims,
+ _mesa_lookup_enum_by_nr(internalformat));
+ return;
+ }
+
+ if (_mesa_is_enum_format_integer(internalformat)) {
+ if (samples > ctx->Const.MaxIntegerSamples) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexImage%uDMultisample(samples>GL_MAX_INTEGER_SAMPLES)",
+ dims);
+ return;
+ }
+ }
+ else if (_mesa_is_depth_or_stencil_format(internalformat)) {
+ if (samples > ctx->Const.MaxDepthTextureSamples) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexImage%uDMultisample(samples>GL_MAX_DEPTH_TEXTURE_SAMPLES)",
+ dims);
+ return;
+ }
+ }
+ else {
+ if (samples > ctx->Const.MaxColorTextureSamples) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTexImage%uDMultisample(samples>GL_MAX_COLOR_TEXTURE_SAMPLES)",
+ dims);
+ return;
+ }
+ }
+
+ /* TODO: should ask the driver for the exact limit for this internalformat
+ * once IDR's internalformat_query bits land
+ */
+
+ texObj = _mesa_get_current_tex_object(ctx, target);
+ texImage = _mesa_get_tex_image(ctx, texObj, 0, 0);
+
+ if (texImage == NULL) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uDMultisample()", dims);
+ return;
+ }
+
+ texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
+ internalformat, GL_NONE, GL_NONE);
+ assert(texFormat != MESA_FORMAT_NONE);
+
+ dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0,
+ width, height, depth, 0);
+
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 0, texFormat,
+ width, height, depth, 0);
+
+ if (_mesa_is_proxy_texture(target)) {
+ if (dimensionsOK && sizeOK) {
+ _mesa_init_teximage_fields(ctx, texImage,
+ width, height, depth, 0, internalformat, texFormat);
+ texImage->NumSamples = samples;
+ texImage->FixedSampleLocations = fixedsamplelocations;
+ }
+ else {
+ /* clear all image fields */
+ _mesa_init_teximage_fields(ctx, texImage,
+ 0, 0, 0, 0, GL_NONE, MESA_FORMAT_NONE);
+ }
+ }
+ else {
+ if (!dimensionsOK) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%uDMultisample(invalid width or height)", dims);
+ return;
+ }
+
+ if (!sizeOK) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY,
+ "glTexImage%uDMultisample(texture too large)", dims);
+ return;
+ }
+
+ ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
+
+ _mesa_init_teximage_fields(ctx, texImage,
+ width, height, depth, 0, internalformat, texFormat);
+
+ texImage->NumSamples = samples;
+ texImage->FixedSampleLocations = fixedsamplelocations;
+
+ if (width > 0 && height > 0 && depth > 0) {
+
+ if (!ctx->Driver.AllocTextureStorage(ctx, texObj, 1,
+ width, height, depth)) {
+ /* tidy up the texture image state. strictly speaking,
+ * we're allowed to just leave this in whatever state we
+ * like, but being tidy is good.
+ */
+ _mesa_init_teximage_fields(ctx, texImage,
+ 0, 0, 0, 0, GL_NONE, MESA_FORMAT_NONE);
+ }
+ }
+
+ _mesa_update_fbo_texture(ctx, texObj, 0, 0);
+ }
+}
+
+void GLAPIENTRY
+_mesa_TexImage2DMultisample(GLenum target, GLsizei samples,
+ GLint internalformat, GLsizei width,
+ GLsizei height, GLboolean fixedsamplelocations)
+{
+ teximagemultisample(2, target, samples, internalformat,
+ width, height, 1, fixedsamplelocations);
+}
+
+void GLAPIENTRY
+_mesa_TexImage3DMultisample(GLenum target, GLsizei samples,
+ GLint internalformat, GLsizei width,
+ GLsizei height, GLsizei depth,
+ GLboolean fixedsamplelocations)
+{
+ teximagemultisample(3, target, samples, internalformat,
+ width, height, depth, fixedsamplelocations);
+}
diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h
index 7124cac52..744c47a8a 100644
--- a/mesalib/src/mesa/main/teximage.h
+++ b/mesalib/src/mesa/main/teximage.h
@@ -294,6 +294,17 @@ _mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer,
GLintptr offset, GLsizeiptr size);
+extern void GLAPIENTRY
+_mesa_TexImage2DMultisample(GLenum target, GLsizei samples,
+ GLint internalformat, GLsizei width,
+ GLsizei height, GLboolean fixedsamplelocations);
+
+extern void GLAPIENTRY
+_mesa_TexImage3DMultisample(GLenum target, GLsizei samples,
+ GLint internalformat, GLsizei width,
+ GLsizei height, GLsizei depth,
+ GLboolean fixedsamplelocations);
+
/*@}*/
#ifdef __cplusplus
diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c
index e99b0dc38..66377c8c0 100644
--- a/mesalib/src/mesa/main/texobj.c
+++ b/mesalib/src/mesa/main/texobj.c
@@ -109,7 +109,9 @@ _mesa_initialize_texture_object( struct gl_texture_object *obj,
target == GL_TEXTURE_2D_ARRAY_EXT ||
target == GL_TEXTURE_EXTERNAL_OES ||
target == GL_TEXTURE_CUBE_MAP_ARRAY ||
- target == GL_TEXTURE_BUFFER);
+ target == GL_TEXTURE_BUFFER ||
+ target == GL_TEXTURE_2D_MULTISAMPLE ||
+ target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
memset(obj, 0, sizeof(*obj));
/* init the non-zero fields */
@@ -166,23 +168,39 @@ static void
finish_texture_init(struct gl_context *ctx, GLenum target,
struct gl_texture_object *obj)
{
+ GLenum filter = GL_LINEAR;
assert(obj->Target == 0);
- if (target == GL_TEXTURE_RECTANGLE_NV ||
- target == GL_TEXTURE_EXTERNAL_OES) {
- /* have to init wrap and filter state here - kind of klunky */
- obj->Sampler.WrapS = GL_CLAMP_TO_EDGE;
- obj->Sampler.WrapT = GL_CLAMP_TO_EDGE;
- obj->Sampler.WrapR = GL_CLAMP_TO_EDGE;
- obj->Sampler.MinFilter = GL_LINEAR;
- if (ctx->Driver.TexParameter) {
- static const GLfloat fparam_wrap[1] = {(GLfloat) GL_CLAMP_TO_EDGE};
- static const GLfloat fparam_filter[1] = {(GLfloat) GL_LINEAR};
- ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_S, fparam_wrap);
- ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_T, fparam_wrap);
- ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_R, fparam_wrap);
- ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_MIN_FILTER, fparam_filter);
- }
+ switch (target) {
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ filter = GL_NEAREST;
+ /* fallthrough */
+
+ case GL_TEXTURE_RECTANGLE_NV:
+ case GL_TEXTURE_EXTERNAL_OES:
+ /* have to init wrap and filter state here - kind of klunky */
+ obj->Sampler.WrapS = GL_CLAMP_TO_EDGE;
+ obj->Sampler.WrapT = GL_CLAMP_TO_EDGE;
+ obj->Sampler.WrapR = GL_CLAMP_TO_EDGE;
+ obj->Sampler.MinFilter = filter;
+ obj->Sampler.MagFilter = filter;
+ if (ctx->Driver.TexParameter) {
+ static const GLfloat fparam_wrap[1] = {(GLfloat) GL_CLAMP_TO_EDGE};
+ const GLfloat fparam_filter[1] = {(GLfloat) filter};
+ ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_S, fparam_wrap);
+ ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_T, fparam_wrap);
+ ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_R, fparam_wrap);
+ ctx->Driver.TexParameter(ctx, target, obj,
+ GL_TEXTURE_MIN_FILTER, fparam_filter);
+ ctx->Driver.TexParameter(ctx, target, obj,
+ GL_TEXTURE_MAG_FILTER, fparam_filter);
+ }
+ break;
+
+ default:
+ /* nothing needs done */
+ break;
}
}
@@ -318,6 +336,8 @@ valid_texture_object(const struct gl_texture_object *tex)
case GL_TEXTURE_BUFFER:
case GL_TEXTURE_EXTERNAL_OES:
case GL_TEXTURE_CUBE_MAP_ARRAY:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
return GL_TRUE;
case 0x99:
_mesa_problem(NULL, "invalid reference to a deleted texture object");
@@ -517,6 +537,8 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
case GL_TEXTURE_RECTANGLE_NV:
case GL_TEXTURE_BUFFER:
case GL_TEXTURE_EXTERNAL_OES:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
maxLevels = 1; /* no mipmapping */
break;
default:
@@ -585,7 +607,9 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
height = baseImage->Height2;
depth = baseImage->Depth2;
- /* Note: this loop will be a no-op for RECT, BUFFER, EXTERNAL textures */
+ /* Note: this loop will be a no-op for RECT, BUFFER, EXTERNAL,
+ * MULTISAMPLE and MULTISAMPLE_ARRAY textures
+ */
for (i = baseLevel + 1; i < maxLevels; i++) {
/* Compute the expected size of image at level[i] */
if (width > 1) {
@@ -763,7 +787,7 @@ _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex)
dims = 0;
target = GL_TEXTURE_BUFFER;
break;
- case TEXTURE_CUBE_ARRAY_INDEX:
+ case TEXTURE_CUBE_ARRAY_INDEX:
dims = 3;
target = GL_TEXTURE_CUBE_MAP_ARRAY;
break;
@@ -771,6 +795,14 @@ _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex)
dims = 2;
target = GL_TEXTURE_EXTERNAL_OES;
break;
+ case TEXTURE_2D_MULTISAMPLE_INDEX:
+ dims = 2;
+ target = GL_TEXTURE_2D_MULTISAMPLE;
+ break;
+ case TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX:
+ dims = 3;
+ target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
+ break;
default:
/* no-op */
return NULL;
@@ -960,6 +992,9 @@ _mesa_GenTextures( GLsizei n, GLuint *textures )
GLuint first;
GLint i;
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glGenTextures %d\n", n);
+
if (n < 0) {
_mesa_error( ctx, GL_INVALID_VALUE, "glGenTextures" );
return;
@@ -1069,6 +1104,9 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
GET_CURRENT_CONTEXT(ctx);
GLint i;
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glDeleteTextures %d\n", n);
+
FLUSH_VERTICES(ctx, 0); /* too complex */
if (!textures)
@@ -1156,6 +1194,12 @@ target_enum_to_index(struct gl_context *ctx, GLenum target)
? TEXTURE_EXTERNAL_INDEX : -1;
case GL_TEXTURE_CUBE_MAP_ARRAY:
return TEXTURE_CUBE_ARRAY_INDEX;
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample
+ ? TEXTURE_2D_MULTISAMPLE_INDEX: -1;
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample
+ ? TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX: -1;
default:
return -1;
}
@@ -1290,6 +1334,9 @@ _mesa_PrioritizeTextures( GLsizei n, const GLuint *texName,
GET_CURRENT_CONTEXT(ctx);
GLint i;
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glPrioritizeTextures %d\n", n);
+
FLUSH_VERTICES(ctx, 0);
if (n < 0) {
@@ -1334,6 +1381,9 @@ _mesa_AreTexturesResident(GLsizei n, const GLuint *texName,
GLint i;
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glAreTexturesResident %d\n", n);
+
if (n < 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident(n)");
return GL_FALSE;
@@ -1379,6 +1429,9 @@ _mesa_IsTexture( GLuint texture )
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glIsTexture %d\n", texture);
+
if (!texture)
return GL_FALSE;
@@ -1428,6 +1481,9 @@ _mesa_InvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset,
struct gl_texture_image *image;
GET_CURRENT_CONTEXT(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glInvalidateTexSubImage %d\n", texture);
+
t = invalidate_tex_image_error_check(ctx, texture, level,
"glInvalidateTexSubImage");
@@ -1494,6 +1550,7 @@ _mesa_InvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset,
break;
case GL_TEXTURE_2D_ARRAY:
case GL_TEXTURE_CUBE_MAP_ARRAY:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
xBorder = image->Border;
yBorder = image->Border;
zBorder = 0;
@@ -1566,6 +1623,9 @@ _mesa_InvalidateTexImage(GLuint texture, GLint level)
{
GET_CURRENT_CONTEXT(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glInvalidateTexImage(%d, %d)\n", texture, level);
+
invalidate_tex_image_error_check(ctx, texture, level,
"glInvalidateTexImage");
diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c
index bc66bb36d..120845b4a 100644
--- a/mesalib/src/mesa/main/texparam.c
+++ b/mesalib/src/mesa/main/texparam.c
@@ -966,6 +966,9 @@ legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target)
* "target may also be TEXTURE_BUFFER, indicating the texture buffer."
*/
return ctx->API == API_OPENGL_CORE && ctx->Version >= 31;
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return ctx->Extensions.ARB_texture_multisample;
default:
return GL_FALSE;
}
@@ -1105,6 +1108,19 @@ get_tex_level_parameter_image(struct gl_context *ctx,
*params = GL_NONE;
break;
+ /* GL_ARB_texture_multisample */
+ case GL_TEXTURE_SAMPLES:
+ if (!ctx->Extensions.ARB_texture_multisample)
+ goto invalid_pname;
+ *params = img->NumSamples;
+ break;
+
+ case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
+ if (!ctx->Extensions.ARB_texture_multisample)
+ goto invalid_pname;
+ *params = img->FixedSampleLocations;
+ break;
+
default:
goto invalid_pname;
}
diff --git a/mesalib/src/mesa/main/texstate.c b/mesalib/src/mesa/main/texstate.c
index 9e591d3b9..1bd9f911f 100644
--- a/mesalib/src/mesa/main/texstate.c
+++ b/mesalib/src/mesa/main/texstate.c
@@ -707,6 +707,8 @@ alloc_proxy_textures( struct gl_context *ctx )
* values!
*/
static const GLenum targets[] = {
+ GL_TEXTURE_2D_MULTISAMPLE,
+ GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
GL_TEXTURE_CUBE_MAP_ARRAY,
GL_TEXTURE_BUFFER,
GL_TEXTURE_2D_ARRAY_EXT,
diff --git a/mesalib/src/mesa/main/version.c b/mesalib/src/mesa/main/version.c
index e944a5518..c90318981 100644
--- a/mesalib/src/mesa/main/version.c
+++ b/mesalib/src/mesa/main/version.c
@@ -50,6 +50,45 @@ check_for_ending(const char *string, const char *ending)
}
/**
+ * Returns the gl override data
+ *
+ * version > 0 indicates there is an override requested
+ * fwd_context is only valid if version > 0
+ */
+static void
+get_gl_override(int *version, GLboolean *fwd_context)
+{
+ const char *env_var = "MESA_GL_VERSION_OVERRIDE";
+ const char *version_str;
+ int major, minor, n;
+ static int override_version = -1;
+ static GLboolean fc_suffix = GL_FALSE;
+
+ if (override_version < 0) {
+ override_version = 0;
+
+ version_str = getenv(env_var);
+ if (version_str) {
+ fc_suffix = check_for_ending(version_str, "FC");
+
+ n = sscanf(version_str, "%u.%u", &major, &minor);
+ if (n != 2) {
+ fprintf(stderr, "error: invalid value for %s: %s\n", env_var, version_str);
+ override_version = 0;
+ } else {
+ override_version = major * 10 + minor;
+ if (override_version < 30 && fc_suffix) {
+ fprintf(stderr, "error: invalid value for %s: %s\n", env_var, version_str);
+ }
+ }
+ }
+ }
+
+ *version = override_version;
+ *fwd_context = fc_suffix;
+}
+
+/**
* Builds the MESA version string.
*/
static void
@@ -87,41 +126,42 @@ create_version_string(struct gl_context *ctx, const char *prefix)
void
_mesa_override_gl_version(struct gl_context *ctx)
{
- const char *env_var = "MESA_GL_VERSION_OVERRIDE";
- const char *version;
- int n;
- int major, minor;
- GLboolean fc_suffix;
+ int version;
+ GLboolean fwd_context;
- version = getenv(env_var);
- if (!version) {
- return;
- }
+ get_gl_override(&version, &fwd_context);
- fc_suffix = check_for_ending(version, "FC");
-
- n = sscanf(version, "%u.%u", &major, &minor);
- if (n != 2) {
- fprintf(stderr, "error: invalid value for %s: %s\n", env_var, version);
- } else {
- ctx->Version = major * 10 + minor;
- if (ctx->Version < 30 && fc_suffix) {
- fprintf(stderr, "error: invalid value for %s: %s\n", env_var, version);
+ if (version > 0) {
+ ctx->Version = version;
+ if (version >= 30 && fwd_context) {
+ ctx->API = API_OPENGL_CORE;
+ ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
+ } else if (version >= 31) {
+ ctx->API = API_OPENGL_CORE;
} else {
- if (ctx->Version >= 30 && fc_suffix) {
- ctx->API = API_OPENGL_CORE;
- ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
- } else if (ctx->Version >= 31) {
- ctx->API = API_OPENGL_CORE;
- } else {
- ctx->API = API_OPENGL_COMPAT;
- }
- create_version_string(ctx, "");
+ ctx->API = API_OPENGL_COMPAT;
}
+ create_version_string(ctx, "");
}
}
/**
+ * Returns the gl override value
+ *
+ * version > 0 indicates there is an override requested
+ */
+int
+_mesa_get_gl_version_override(void)
+{
+ int version;
+ GLboolean fwd_context;
+
+ get_gl_override(&version, &fwd_context);
+
+ return version;
+}
+
+/**
* Override the context's GLSL version if the environment variable
* MESA_GLSL_VERSION_OVERRIDE is set. Valid values for
* MESA_GLSL_VERSION_OVERRIDE are integers, such as "130".
diff --git a/mesalib/src/mesa/main/version.h b/mesalib/src/mesa/main/version.h
index 8167ed051..c1cb3177d 100644
--- a/mesalib/src/mesa/main/version.h
+++ b/mesalib/src/mesa/main/version.h
@@ -51,4 +51,7 @@ _mesa_override_gl_version(struct gl_context *ctx);
extern void
_mesa_override_glsl_version(struct gl_context *ctx);
+extern int
+_mesa_get_gl_version_override(void);
+
#endif /* VERSION_H */