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;
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 */
}
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,
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;
}
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[] = {
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;
[ "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" ],
+
+
# GL_ARB_sampler_objects / GL 3.3
[ "SAMPLER_BINDING", "LOC_CUSTOM, TYPE_INT, GL_SAMPLER_BINDING, NO_EXTRA" ],
*/
typedef enum
{
+ TEXTURE_2D_MULTISAMPLE_INDEX,
+ TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX,
TEXTURE_CUBE_ARRAY_INDEX,
TEXTURE_BUFFER_INDEX,
TEXTURE_2D_ARRAY_INDEX,
* 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)
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? */
};
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,
* 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 ||
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);
}
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;
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;
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;
}
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:
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:
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 */
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);
img->HeightLog2 = 0;
img->DepthLog2 = 0;
img->TexFormat = MESA_FORMAT_NONE;
+ img->NumSamples = 0;
+ img->FixedSampleLocations = GL_TRUE;
}
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:
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)
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 */
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)
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)
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 */
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;
}
}
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");
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:
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) {
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;
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;
? 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;
}
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;
* "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;
}
*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;
}
* 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,