summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorRhys Perry <[email protected]>2018-06-14 19:56:28 -0600
committerBrian Paul <[email protected]>2018-06-14 20:09:45 -0600
commit67f40dadaa6666dacd90d1540eaadef20b9d48ba (patch)
treea070a32006510b483b9710ef6acb7356f6c94b01 /src/mesa
parentcd2e673abc436d71e304fd5ad577054197041c7f (diff)
mesa: add support for ARB_sample_locations
Signed-off-by: Rhys Perry <[email protected]> Reviewed-by: Brian Paul <[email protected]> (v2) Reviewed-by: Marek Olšák <[email protected]> (v2)
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/main/config.h9
-rw-r--r--src/mesa/main/dd.h8
-rw-r--r--src/mesa/main/extensions_table.h2
-rw-r--r--src/mesa/main/fbobject.c256
-rw-r--r--src/mesa/main/fbobject.h20
-rw-r--r--src/mesa/main/framebuffer.c10
-rw-r--r--src/mesa/main/get.c31
-rw-r--r--src/mesa/main/get_hash_params.py6
-rw-r--r--src/mesa/main/mtypes.h9
-rw-r--r--src/mesa/main/multisample.c18
-rw-r--r--src/mesa/main/tests/dispatch_sanity.cpp10
11 files changed, 351 insertions, 28 deletions
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
index 81573bfbf2c..6a2f766222a 100644
--- a/src/mesa/main/config.h
+++ b/src/mesa/main/config.h
@@ -315,4 +315,13 @@
#define MAX_CLIPPED_VERTICES ((2 * (6 + MAX_CLIP_PLANES))+1)
+/** For GL_ARB_sample_locations - maximum of SAMPLE_LOCATION_PIXEL_GRID_*_ARB */
+#define MAX_SAMPLE_LOCATION_GRID_SIZE 4
+
+/* It is theoretically possible for Consts.MaxSamples to be >32 but
+ * other code seems to assume that is not the case.
+ */
+#define MAX_SAMPLE_LOCATION_TABLE_SIZE \
+ (MAX_SAMPLE_LOCATION_GRID_SIZE * MAX_SAMPLE_LOCATION_GRID_SIZE * 32)
+
#endif /* MESA_CONFIG_H_INCLUDED */
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 9f9606ac6b5..1b048d3ff8e 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -788,6 +788,14 @@ struct dd_function_table {
const GLenum *attachments);
/**
+ * \name Functions for GL_ARB_sample_locations
+ */
+ void (*GetProgrammableSampleCaps)(struct gl_context *ctx,
+ const struct gl_framebuffer *fb,
+ GLuint *bits, GLuint *width, GLuint *height);
+ void (*EvaluateDepthValues)(struct gl_context *ctx);
+
+ /**
* \name Query objects
*/
/*@{*/
diff --git a/src/mesa/main/extensions_table.h b/src/mesa/main/extensions_table.h
index 79ef228b693..1c55df8a228 100644
--- a/src/mesa/main/extensions_table.h
+++ b/src/mesa/main/extensions_table.h
@@ -104,6 +104,7 @@ EXT(ARB_provoking_vertex , EXT_provoking_vertex
EXT(ARB_query_buffer_object , ARB_query_buffer_object , GLL, GLC, x , x , 2013)
EXT(ARB_robust_buffer_access_behavior , ARB_robust_buffer_access_behavior , GLL, GLC, x , x , 2012)
EXT(ARB_robustness , dummy_true , GLL, GLC, x , x , 2010)
+EXT(ARB_sample_locations , ARB_sample_locations , GLL, GLC, x , x , 2015)
EXT(ARB_sample_shading , ARB_sample_shading , GLL, GLC, x , x , 2009)
EXT(ARB_sampler_objects , dummy_true , GLL, GLC, x , x , 2009)
EXT(ARB_seamless_cube_map , ARB_seamless_cube_map , GLL, GLC, x , x , 2009)
@@ -351,6 +352,7 @@ EXT(NV_read_buffer , dummy_true
EXT(NV_read_depth , dummy_true , x , x , x , ES2, 2011)
EXT(NV_read_depth_stencil , dummy_true , x , x , x , ES2, 2011)
EXT(NV_read_stencil , dummy_true , x , x , x , ES2, 2011)
+EXT(NV_sample_locations , ARB_sample_locations , GLL, GLC, x , ES2, 2015)
EXT(NV_texgen_reflection , dummy_true , GLL, x , x , x , 1999)
EXT(NV_texture_barrier , NV_texture_barrier , GLL, GLC, x , x , 2009)
EXT(NV_texture_env_combine4 , NV_texture_env_combine4 , GLL, x , x , x , 1999)
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index a63e8b8de52..5d7e5d29847 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -35,6 +35,7 @@
#include "buffers.h"
#include "context.h"
+#include "debug_output.h"
#include "enums.h"
#include "fbobject.h"
#include "formats.h"
@@ -1404,14 +1405,41 @@ _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
}
/**
- * ARB_framebuffer_no_attachment - Application passes requested param's
- * here. NOTE: NumSamples requested need not be _NumSamples which is
- * what the hw supports.
+ * ARB_framebuffer_no_attachment and ARB_sample_locations - Application passes
+ * requested param's here. NOTE: NumSamples requested need not be _NumSamples
+ * which is what the hw supports.
*/
static void
framebuffer_parameteri(struct gl_context *ctx, struct gl_framebuffer *fb,
GLenum pname, GLint param, const char *func)
{
+ bool cannot_be_winsys_fbo = false;
+
+ switch (pname) {
+ case GL_FRAMEBUFFER_DEFAULT_WIDTH:
+ case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
+ case GL_FRAMEBUFFER_DEFAULT_LAYERS:
+ case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
+ case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
+ if (!ctx->Extensions.ARB_framebuffer_no_attachments)
+ goto invalid_pname_enum;
+ cannot_be_winsys_fbo = true;
+ break;
+ case GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB:
+ case GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB:
+ if (!ctx->Extensions.ARB_sample_locations)
+ goto invalid_pname_enum;
+ break;
+ default:
+ goto invalid_pname_enum;
+ }
+
+ if (cannot_be_winsys_fbo && _mesa_is_winsys_fbo(fb)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(invalid pname=0x%x for default framebuffer)", func, pname);
+ return;
+ }
+
switch (pname) {
case GL_FRAMEBUFFER_DEFAULT_WIDTH:
if (param < 0 || param > ctx->Const.MaxFramebufferWidth)
@@ -1448,13 +1476,30 @@ framebuffer_parameteri(struct gl_context *ctx, struct gl_framebuffer *fb,
case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
fb->DefaultGeometry.FixedSampleLocations = param;
break;
+ case GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB:
+ fb->ProgrammableSampleLocations = !!param;
+ break;
+ case GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB:
+ fb->SampleLocationPixelGrid = !!param;
+ break;
+ }
+
+ switch (pname) {
+ case GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB:
+ case GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB:
+ if (fb == ctx->DrawBuffer)
+ ctx->NewDriverState |= ctx->DriverFlags.NewSampleLocations;
+ break;
default:
- _mesa_error(ctx, GL_INVALID_ENUM,
- "%s(pname=0x%x)", func, pname);
+ invalidate_framebuffer(fb);
+ ctx->NewState |= _NEW_BUFFERS;
+ break;
}
- invalidate_framebuffer(fb);
- ctx->NewState |= _NEW_BUFFERS;
+ return;
+
+invalid_pname_enum:
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
}
void GLAPIENTRY
@@ -1463,10 +1508,12 @@ _mesa_FramebufferParameteri(GLenum target, GLenum pname, GLint param)
GET_CURRENT_CONTEXT(ctx);
struct gl_framebuffer *fb;
- if (!ctx->Extensions.ARB_framebuffer_no_attachments) {
+ if (!ctx->Extensions.ARB_framebuffer_no_attachments &&
+ !ctx->Extensions.ARB_sample_locations) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glFramebufferParameteriv not supported "
- "(ARB_framebuffer_no_attachments not implemented)");
+ "(neither ARB_framebuffer_no_attachments nor ARB_sample_locations"
+ " is available)");
return;
}
@@ -1477,13 +1524,6 @@ _mesa_FramebufferParameteri(GLenum target, GLenum pname, GLint param)
return;
}
- /* check framebuffer binding */
- if (_mesa_is_winsys_fbo(fb)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferParameteri");
- return;
- }
-
framebuffer_parameteri(ctx, fb, pname, param, "glFramebufferParameteri");
}
@@ -1528,9 +1568,14 @@ validate_get_framebuffer_parameteriv_pname(struct gl_context *ctx,
*/
cannot_be_winsys_fbo = !_mesa_is_desktop_gl(ctx);
break;
+ case GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB:
+ case GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB:
+ if (!ctx->Extensions.ARB_sample_locations)
+ goto invalid_pname_enum;
+ cannot_be_winsys_fbo = false;
+ break;
default:
- _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
- return false;
+ goto invalid_pname_enum;
}
if (cannot_be_winsys_fbo && _mesa_is_winsys_fbo(fb)) {
@@ -1540,6 +1585,10 @@ validate_get_framebuffer_parameteriv_pname(struct gl_context *ctx,
}
return true;
+
+invalid_pname_enum:
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
+ return false;
}
static void
@@ -1583,6 +1632,12 @@ get_framebuffer_parameteriv(struct gl_context *ctx, struct gl_framebuffer *fb,
case GL_STEREO:
*params = fb->Visual.stereoMode;
break;
+ case GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB:
+ *params = fb->ProgrammableSampleLocations;
+ break;
+ case GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB:
+ *params = fb->SampleLocationPixelGrid;
+ break;
}
}
@@ -1592,10 +1647,12 @@ _mesa_GetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
GET_CURRENT_CONTEXT(ctx);
struct gl_framebuffer *fb;
- if (!ctx->Extensions.ARB_framebuffer_no_attachments) {
+ if (!ctx->Extensions.ARB_framebuffer_no_attachments &&
+ !ctx->Extensions.ARB_sample_locations) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetFramebufferParameteriv not supported "
- "(ARB_framebuffer_no_attachments not implemented)");
+ "(neither ARB_framebuffer_no_attachments nor ARB_sample_locations"
+ " is available)");
return;
}
@@ -2694,6 +2751,7 @@ _mesa_bind_framebuffers(struct gl_context *ctx,
if (bindDrawBuf) {
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+ ctx->NewDriverState |= ctx->DriverFlags.NewSampleLocations;
/* check if old framebuffer had any texture attachments */
if (oldDrawFb)
@@ -4234,15 +4292,21 @@ _mesa_NamedFramebufferParameteri(GLuint framebuffer, GLenum pname,
GET_CURRENT_CONTEXT(ctx);
struct gl_framebuffer *fb = NULL;
- if (!ctx->Extensions.ARB_framebuffer_no_attachments) {
+ if (!ctx->Extensions.ARB_framebuffer_no_attachments &&
+ !ctx->Extensions.ARB_sample_locations) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glNamedFramebufferParameteri("
- "ARB_framebuffer_no_attachments not implemented)");
+ "neither ARB_framebuffer_no_attachments nor "
+ "ARB_sample_locations is available)");
return;
}
- fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
- "glNamedFramebufferParameteri");
+ if (framebuffer) {
+ fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+ "glNamedFramebufferParameteri");
+ } else {
+ fb = ctx->WinSysDrawBuffer;
+ }
if (fb) {
framebuffer_parameteri(ctx, fb, pname, param,
@@ -4261,16 +4325,16 @@ _mesa_GetNamedFramebufferParameteriv(GLuint framebuffer, GLenum pname,
if (!ctx->Extensions.ARB_framebuffer_no_attachments) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glNamedFramebufferParameteriv("
- "ARB_framebuffer_no_attachments not implemented)");
+ "neither ARB_framebuffer_no_attachments nor ARB_sample_locations"
+ " is available)");
return;
}
- if (framebuffer) {
+ if (framebuffer)
fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
"glGetNamedFramebufferParameteriv");
- } else {
+ else
fb = ctx->WinSysDrawBuffer;
- }
if (fb) {
get_framebuffer_parameteriv(ctx, fb, pname, param,
@@ -4605,3 +4669,139 @@ invalid_enum:
"glDiscardFramebufferEXT(attachment %s)",
_mesa_enum_to_string(attachments[i]));
}
+
+static void
+sample_locations(struct gl_context *ctx, struct gl_framebuffer *fb,
+ GLuint start, GLsizei count, const GLfloat *v, bool no_error,
+ const char *name)
+{
+ GLsizei i;
+
+ if (!no_error) {
+ if (!ctx->Extensions.ARB_sample_locations) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s not supported "
+ "(ARB_sample_locations not available)", name);
+ return;
+ }
+
+ if (start + count > MAX_SAMPLE_LOCATION_TABLE_SIZE) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(start+size > sample location table size)", name);
+ return;
+ }
+ }
+
+ if (!fb->SampleLocationTable) {
+ size_t size = MAX_SAMPLE_LOCATION_TABLE_SIZE * 2 * sizeof(GLfloat);
+ fb->SampleLocationTable = malloc(size);
+ if (!fb->SampleLocationTable)
+ _mesa_error(ctx, GL_OUT_OF_MEMORY,
+ "Cannot allocate sample location table");
+ for (i = 0; i < MAX_SAMPLE_LOCATION_TABLE_SIZE * 2; i++)
+ fb->SampleLocationTable[i] = 0.5f;
+ }
+
+ for (i = 0; i < count * 2; i++) {
+ /* The ARB_sample_locations spec says:
+ *
+ * Sample locations outside of [0,1] result in undefined
+ * behavior.
+ *
+ * To simplify driver implementations, we choose to clamp to
+ * [0,1] and change NaN into 0.5.
+ */
+ if (isnan(v[i]) || v[i] < 0.0f || v[i] > 1.0f) {
+ static GLuint msg_id = 0;
+ static const char* msg = "Invalid sample location specified";
+ _mesa_debug_get_id(&msg_id);
+
+ _mesa_log_msg(ctx, MESA_DEBUG_SOURCE_API, MESA_DEBUG_TYPE_UNDEFINED,
+ msg_id, MESA_DEBUG_SEVERITY_HIGH, strlen(msg), msg);
+ }
+
+ if (isnan(v[i]))
+ fb->SampleLocationTable[start * 2 + i] = 0.5f;
+ else
+ fb->SampleLocationTable[start * 2 + i] = CLAMP(v[i], 0.0f, 1.0f);
+ }
+
+ if (fb == ctx->DrawBuffer)
+ ctx->NewDriverState |= ctx->DriverFlags.NewSampleLocations;
+}
+
+void GLAPIENTRY
+_mesa_FramebufferSampleLocationsfvARB(GLenum target, GLuint start,
+ GLsizei count, const GLfloat *v)
+{
+ struct gl_framebuffer *fb;
+
+ GET_CURRENT_CONTEXT(ctx);
+
+ fb = get_framebuffer_target(ctx, target);
+ if (!fb) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferSampleLocationsfvARB(target %s)",
+ _mesa_enum_to_string(target));
+ return;
+ }
+
+ sample_locations(ctx, fb, start, count, v, false,
+ "glFramebufferSampleLocationsfvARB");
+}
+
+void GLAPIENTRY
+_mesa_NamedFramebufferSampleLocationsfvARB(GLuint framebuffer, GLuint start,
+ GLsizei count, const GLfloat *v)
+{
+ struct gl_framebuffer *fb;
+
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (framebuffer) {
+ fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
+ "glNamedFramebufferSampleLocationsfvARB");
+ if (!fb)
+ return;
+ }
+ else
+ fb = ctx->WinSysDrawBuffer;
+
+ sample_locations(ctx, fb, start, count, v, false,
+ "glNamedFramebufferSampleLocationsfvARB");
+}
+
+void GLAPIENTRY
+_mesa_FramebufferSampleLocationsfvARB_no_error(GLenum target, GLuint start,
+ GLsizei count, const GLfloat *v)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ sample_locations(ctx, get_framebuffer_target(ctx, target), start,
+ count, v, true, "glFramebufferSampleLocationsfvARB");
+}
+
+void GLAPIENTRY
+_mesa_NamedFramebufferSampleLocationsfvARB_no_error(GLuint framebuffer,
+ GLuint start, GLsizei count,
+ const GLfloat *v)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ sample_locations(ctx, _mesa_lookup_framebuffer(ctx, framebuffer), start,
+ count, v, true, "glNamedFramebufferSampleLocationsfvARB");
+}
+
+void GLAPIENTRY
+_mesa_EvaluateDepthValuesARB(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->Extensions.ARB_sample_locations) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "EvaluateDepthValuesARB not supported (neither "
+ "ARB_sample_locations nor NV_sample_locations is available)");
+ return;
+ }
+
+ if (ctx->Driver.EvaluateDepthValues)
+ ctx->Driver.EvaluateDepthValues(ctx);
+}
diff --git a/src/mesa/main/fbobject.h b/src/mesa/main/fbobject.h
index 31d743d3fb5..5ba62d6cb1a 100644
--- a/src/mesa/main/fbobject.h
+++ b/src/mesa/main/fbobject.h
@@ -355,4 +355,24 @@ _mesa_FramebufferParameteri(GLenum target, GLenum pname, GLint param);
extern void GLAPIENTRY
_mesa_GetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params);
+extern void GLAPIENTRY
+_mesa_FramebufferSampleLocationsfvARB(GLenum target, GLuint start,
+ GLsizei count, const GLfloat *v);
+
+extern void GLAPIENTRY
+_mesa_NamedFramebufferSampleLocationsfvARB(GLuint framebuffer, GLuint start,
+ GLsizei count, const GLfloat *v);
+
+extern void GLAPIENTRY
+_mesa_FramebufferSampleLocationsfvARB_no_error(GLenum target, GLuint start,
+ GLsizei count, const GLfloat *v);
+
+extern void GLAPIENTRY
+_mesa_NamedFramebufferSampleLocationsfvARB_no_error(GLuint framebuffer,
+ GLuint start, GLsizei count,
+ const GLfloat *v);
+
+extern void GLAPIENTRY
+_mesa_EvaluateDepthValuesARB(void);
+
#endif /* FBOBJECT_H */
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index 8e751b453b7..3ec8b91eaa2 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -160,6 +160,10 @@ _mesa_initialize_window_framebuffer(struct gl_framebuffer *fb,
fb->_HasSNormOrFloatColorBuffer = visual->floatMode;
fb->_HasAttachments = true;
+ fb->SampleLocationTable = NULL;
+ fb->ProgrammableSampleLocations = 0;
+ fb->SampleLocationPixelGrid = 0;
+
compute_depth_max(fb);
}
@@ -183,6 +187,9 @@ _mesa_initialize_user_framebuffer(struct gl_framebuffer *fb, GLuint name)
fb->_ColorDrawBufferIndexes[0] = BUFFER_COLOR0;
fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT;
fb->_ColorReadBufferIndex = BUFFER_COLOR0;
+ fb->SampleLocationTable = NULL;
+ fb->ProgrammableSampleLocations = 0;
+ fb->SampleLocationPixelGrid = 0;
fb->Delete = _mesa_destroy_framebuffer;
simple_mtx_init(&fb->Mutex, mtx_plain);
}
@@ -227,6 +234,9 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
assert(!att->Texture);
att->Type = GL_NONE;
}
+
+ free(fb->SampleLocationTable);
+ fb->SampleLocationTable = NULL;
}
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 0bf5c1ff0c4..772ca00da1f 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -192,6 +192,7 @@ union value {
GLenum value_enum;
GLubyte value_ubyte;
GLshort value_short;
+ GLuint value_uint;
/* Sigh, see GL_COMPRESSED_TEXTURE_FORMATS_ARB handling */
struct {
@@ -516,6 +517,7 @@ EXTRA_EXT(ARB_sparse_buffer);
EXTRA_EXT(NV_conservative_raster);
EXTRA_EXT(NV_conservative_raster_dilate);
EXTRA_EXT(NV_conservative_raster_pre_snap_triangles);
+EXTRA_EXT(ARB_sample_locations);
static const int
extra_ARB_color_buffer_float_or_glcore[] = {
@@ -1197,6 +1199,35 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
simple_mtx_unlock(&ctx->Shared->Mutex);
}
break;
+ /* GL_ARB_sample_locations */
+ case GL_SAMPLE_LOCATION_SUBPIXEL_BITS_ARB:
+ case GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_ARB:
+ case GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_ARB:
+ {
+ GLuint bits, width, height;
+
+ if (ctx->NewState & _NEW_BUFFERS)
+ _mesa_update_state(ctx);
+
+ if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE) {
+ v->value_uint = 0;
+ break;
+ }
+
+ ctx->Driver.GetProgrammableSampleCaps(ctx, ctx->DrawBuffer,
+ &bits, &width, &height);
+
+ if (d->pname == GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_ARB)
+ v->value_uint = width;
+ else if (d->pname == GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_ARB)
+ v->value_uint = height;
+ else
+ v->value_uint = bits;
+ }
+ break;
+ case GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_ARB:
+ v->value_uint = MAX_SAMPLE_LOCATION_TABLE_SIZE;
+ break;
}
}
diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py
index 7e14cf51f55..83136108e95 100644
--- a/src/mesa/main/get_hash_params.py
+++ b/src/mesa/main/get_hash_params.py
@@ -564,6 +564,12 @@ descriptor=[
# GL_NUM_SHADING_LANGUAGE_VERSIONS
[ "NUM_SHADING_LANGUAGE_VERSIONS", "LOC_CUSTOM, TYPE_INT, 0, extra_version_43" ],
+ # GL_ARB_sample_locations
+ [ "SAMPLE_LOCATION_SUBPIXEL_BITS_ARB", "LOC_CUSTOM, TYPE_UINT, 0, extra_ARB_sample_locations" ],
+ [ "SAMPLE_LOCATION_PIXEL_GRID_WIDTH_ARB", "LOC_CUSTOM, TYPE_UINT, 0, extra_ARB_sample_locations" ],
+ [ "SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_ARB", "LOC_CUSTOM, TYPE_UINT, 0, extra_ARB_sample_locations" ],
+ [ "PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_ARB", "LOC_CUSTOM, TYPE_UINT, 0, extra_ARB_sample_locations" ],
+
# GL_ARB_draw_indirect / GLES 3.1
[ "DRAW_INDIRECT_BUFFER_BINDING", "LOC_CUSTOM, TYPE_INT, 0, extra_ARB_draw_indirect" ],
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 482c42a4b2d..ef9fce24d91 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -3489,6 +3489,11 @@ struct gl_framebuffer
GLenum16 ColorDrawBuffer[MAX_DRAW_BUFFERS];
GLenum16 ColorReadBuffer;
+ /* GL_ARB_sample_locations */
+ GLfloat *SampleLocationTable; /**< If NULL, no table has been specified */
+ GLboolean ProgrammableSampleLocations;
+ GLboolean SampleLocationPixelGrid;
+
/** Computed from ColorDraw/ReadBuffer above */
GLuint _NumColorDrawBuffers;
gl_buffer_index _ColorDrawBufferIndexes[MAX_DRAW_BUFFERS];
@@ -4100,6 +4105,7 @@ struct gl_extensions
GLboolean ARB_post_depth_coverage;
GLboolean ARB_query_buffer_object;
GLboolean ARB_robust_buffer_access_behavior;
+ GLboolean ARB_sample_locations;
GLboolean ARB_sample_shading;
GLboolean ARB_seamless_cube_map;
GLboolean ARB_shader_atomic_counter_ops;
@@ -4564,6 +4570,9 @@ struct gl_driver_flags
/** Shader constants (uniforms, program parameters, state constants) */
uint64_t NewShaderConstants[MESA_SHADER_STAGES];
+
+ /** Programmable sample location state for gl_context::DrawBuffer */
+ uint64_t NewSampleLocations;
};
struct gl_buffer_binding
diff --git a/src/mesa/main/multisample.c b/src/mesa/main/multisample.c
index dfe6a371427..f93a18832da 100644
--- a/src/mesa/main/multisample.c
+++ b/src/mesa/main/multisample.c
@@ -101,6 +101,24 @@ _mesa_GetMultisamplefv(GLenum pname, GLuint index, GLfloat * val)
return;
}
+ case GL_PROGRAMMABLE_SAMPLE_LOCATION_ARB:
+ if (!ctx->Extensions.ARB_sample_locations) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetMultisamplefv(pname)" );
+ return;
+ }
+
+ if (index >= MAX_SAMPLE_LOCATION_TABLE_SIZE * 2) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glGetMultisamplefv(index)" );
+ return;
+ }
+
+ if (ctx->DrawBuffer->SampleLocationTable)
+ *val = ctx->DrawBuffer->SampleLocationTable[index];
+ else
+ *val = 0.5f;
+
+ return;
+
default:
_mesa_error( ctx, GL_INVALID_ENUM, "glGetMultisamplefv(pname)" );
return;
diff --git a/src/mesa/main/tests/dispatch_sanity.cpp b/src/mesa/main/tests/dispatch_sanity.cpp
index 096d16a6092..96ace539204 100644
--- a/src/mesa/main/tests/dispatch_sanity.cpp
+++ b/src/mesa/main/tests/dispatch_sanity.cpp
@@ -1035,6 +1035,11 @@ const struct function common_desktop_functions_possible[] = {
/* GL_NV_conservative_raster_pre_snap_triangles */
{ "glConservativeRasterParameteriNV", 10, -1 },
+ /* GL_ARB_sample_locations */
+ { "glFramebufferSampleLocationsfvARB", 30, -1 },
+ { "glNamedFramebufferSampleLocationsfvARB", 30, -1 },
+ { "glEvaluateDepthValuesARB", 30, -1 },
+
{ NULL, 0, -1 }
};
@@ -2781,5 +2786,10 @@ const struct function gles31_functions_possible[] = {
{ "glDepthRangeIndexedfOES", 31, -1 },
{ "glGetFloati_vOES", 31, -1 },
+ /* GL_ARB_sample_locations */
+ { "glFramebufferSampleLocationsfvARB", 31, -1 },
+ { "glNamedFramebufferSampleLocationsfvARB", 31, -1 },
+ { "glEvaluateDepthValuesARB", 31, -1 },
+
{ NULL, 0, -1 },
};