diff options
Diffstat (limited to 'mesalib/src/mesa')
22 files changed, 637 insertions, 66 deletions
diff --git a/mesalib/src/mesa/drivers/common/driverfuncs.c b/mesalib/src/mesa/drivers/common/driverfuncs.c index 43c9de97f..731d46658 100644 --- a/mesalib/src/mesa/drivers/common/driverfuncs.c +++ b/mesalib/src/mesa/drivers/common/driverfuncs.c @@ -209,6 +209,9 @@ _mesa_init_driver_functions(struct dd_function_table *driver) /* GL_ARB_texture_storage */ driver->AllocTextureStorage = _swrast_AllocTextureStorage; + + /* GL_ARB_texture_multisample */ + driver->GetSamplePosition = NULL; } 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 3fdb75323..3de736828 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 281d652a5..c5b44b7c1 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 */ diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index ce409eca9..486cf4639 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -1478,6 +1478,13 @@ ir_to_mesa_visitor::visit(ir_expression *ir) assert(!"not supported"); break; + case ir_triop_lrp: + /* ir_triop_lrp operands are (x, y, a) while + * OPCODE_LRP operands are (a, y, x) to match ARB_fragment_program. + */ + emit(ir, OPCODE_LRP, result_dst, op[2], op[1], op[0]); + break; + case ir_quadop_vector: /* This operation should have already been handled. */ @@ -2038,6 +2045,9 @@ ir_to_mesa_visitor::visit(ir_texture *ir) ir->lod_info.grad.dPdy->accept(this); dy = this->result; break; + case ir_txf_ms: + assert(!"Unexpected ir_txf_ms opcode"); + break; } const glsl_type *sampler_type = ir->sampler->type; diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 63b74285a..c41b5833e 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -1942,6 +1942,10 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) } break; } + case ir_triop_lrp: + /* note: we have to reorder the three args here */ + emit(ir, TGSI_OPCODE_LRP, result_dst, op[2], op[1], op[0]); + break; case ir_unop_pack_snorm_2x16: case ir_unop_pack_unorm_2x16: case ir_unop_pack_half_2x16: @@ -2742,6 +2746,9 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) offset = this->result; } break; + case ir_txf_ms: + assert(!"Unexpected ir_txf_ms opcode"); + break; } if (ir->projector) { |