<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, May 4, 2018 at 8:09 AM, Rhys Perry <span dir="ltr"><<a href="mailto:pendingchaos02@gmail.com" target="_blank">pendingchaos02@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Signed-off-by: Rhys Perry <<a href="mailto:pendingchaos02@gmail.com">pendingchaos02@gmail.com</a>><br>
---<br>
src/mapi/glapi/gen/gl_API.xml | 52 +++++++<br>
src/mesa/main/config.h | 7 +<br>
src/mesa/main/dd.h | 7 +<br>
src/mesa/main/extensions_<wbr>table.h | 1 +<br>
src/mesa/main/fbobject.c | 247 ++++++++++++++++++++++++++++--<wbr>--<br>
src/mesa/main/fbobject.h | 20 +++<br>
src/mesa/main/framebuffer.c | 10 ++<br>
src/mesa/main/get.c | 32 +++++<br>
src/mesa/main/get_hash_params.<wbr>py | 6 +<br>
src/mesa/main/mtypes.h | 6 +<br>
src/mesa/main/multisample.c | 18 +++<br>
src/mesa/main/tests/dispatch_<wbr>sanity.cpp | 10 ++<br>
12 files changed, 386 insertions(+), 30 deletions(-)<br>
<br>
diff --git a/src/mapi/glapi/gen/gl_API.<wbr>xml b/src/mapi/glapi/gen/gl_API.<wbr>xml<br>
index 38c1921047..a23094a548 100644<br>
--- a/src/mapi/glapi/gen/gl_API.<wbr>xml<br>
+++ b/src/mapi/glapi/gen/gl_API.<wbr>xml<br>
@@ -10891,6 +10891,58 @@<br>
<br>
<!-- Extension number 180 is not listed in the extension registry. --><br>
<br>
+<category name="GL_ARB_sample_locations" number="181"><br>
+ <enum name="SAMPLE_LOCATION_<wbr>SUBPIXEL_BITS_ARB" value="0x933D"><br>
+ <size name="Get" mode="get"/><br>
+ </enum><br>
+<br>
+ <enum name="SAMPLE_LOCATION_PIXEL_<wbr>GRID_WIDTH_ARB" value="0x933E"><br>
+ <size name="Get" mode="get"/><br>
+ </enum><br>
+<br>
+ <enum name="SAMPLE_LOCATION_PIXEL_<wbr>GRID_HEIGHT_ARB" value="0x933F"><br>
+ <size name="Get" mode="get"/><br>
+ </enum><br>
+<br>
+ <enum name="PROGRAMMABLE_SAMPLE_<wbr>LOCATION_TABLE_SIZE_ARB" value="0x9340"><br>
+ <size name="Get" mode="get"/><br>
+ </enum><br>
+<br>
+ <enum name="SAMPLE_LOCATION_ARB" value="0x8E50"><br>
+ <size name="GetMultisamplefv" mode="get"/><br>
+ </enum><br>
+<br>
+ <enum name="PROGRAMMABLE_SAMPLE_<wbr>LOCATION_ARB" value="0x9341"><br>
+ <size name="GetMultisamplefv" mode="get"/><br>
+ </enum><br>
+<br>
+ <enum name="FRAMEBUFFER_<wbr>PROGRAMMABLE_SAMPLE_LOCATIONS_<wbr>ARB" value="0x9342"><br>
+ <size name="FramebufferParameteri"/><br>
+ <size name="<wbr>GetFramebufferParameteri"/><br>
+ </enum><br>
+<br>
+ <enum name="FRAMEBUFFER_SAMPLE_<wbr>LOCATION_PIXEL_GRID_ARB" value="0x9343"><br>
+ <size name="FramebufferParameteri"/><br>
+ <size name="<wbr>GetFramebufferParameteri"/><br>
+ </enum><br>
+<br>
+ <function name="<wbr>FramebufferSampleLocationsfvAR<wbr>B" no_error="true" es2="3.1"><br>
+ <param name="target" type="GLenum"/><br>
+ <param name="start" type="GLuint"/><br>
+ <param name="count" type="GLsizei"/><br>
+ <param name="v" type="const GLfloat *"/><br>
+ </function><br>
+<br>
+ <function name="<wbr>NamedFramebufferSampleLocation<wbr>sfvARB" no_error="true" es2="3.1"><br>
+ <param name="framebuffer" type="GLuint"/><br>
+ <param name="start" type="GLuint"/><br>
+ <param name="count" type="GLsizei"/><br>
+ <param name="v" type="const GLfloat *"/><br>
+ </function><br>
+<br>
+ <function name="EvaluateDepthValuesARB" es2="3.1"/><br>
+</category><br>
+<br>
<category name="GL_SUN_convolution_<wbr>border_modes" number="182"><br>
<enum name="WRAP_BORDER_SUN" value="0x81D4"/><br>
</category><br>
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h<br>
index 81573bfbf2..444e4dedad 100644<br>
--- a/src/mesa/main/config.h<br>
+++ b/src/mesa/main/config.h<br>
@@ -315,4 +315,11 @@<br>
#define MAX_CLIPPED_VERTICES ((2 * (6 + MAX_CLIP_PLANES))+1)<br>
<br>
<br>
+/** For GL_ARB_sample_locations - maximum of SAMPLE_LOCATION_PIXEL_GRID_*_<wbr>ARB */<br>
+#define MAX_SAMPLE_LOCATION_GRID_SIZE 4<br>
+/* It is theoretically possible for Consts.MaxSamples to be >32 but<br>
+ * other code seems to assume that is not the case */<br>
+#define MAX_SAMPLE_LOCATION_TABLE_SIZE \<br>
+ (MAX_SAMPLE_LOCATION_GRID_<wbr>SIZE*MAX_SAMPLE_LOCATION_GRID_<wbr>SIZE*32)<br>
+<br>
#endif /* MESA_CONFIG_H_INCLUDED */<br>
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h<br>
index d85d89ef50..8929a2e267 100644<br>
--- a/src/mesa/main/dd.h<br>
+++ b/src/mesa/main/dd.h<br>
@@ -785,6 +785,13 @@ struct dd_function_table {<br>
GLenum target, GLsizei numAttachments,<br>
const GLenum *attachments);<br>
<br>
+ /**<br>
+ * \name Functions for GL_ARB_sample_locations<br>
+ */<br>
+ void (*GetProgrammableSampleCaps)(<wbr>struct gl_context *ctx, struct gl_framebuffer *fb,<br>
+ GLuint *bits, GLuint *width, GLuint *height);<br>
+ void (*EvaluateDepthValues)(struct gl_context *ctx, struct gl_framebuffer *fb);<br>
+<br>
/**<br>
* \name Query objects<br>
*/<br>
diff --git a/src/mesa/main/extensions_<wbr>table.h b/src/mesa/main/extensions_<wbr>table.h<br>
index 492f7c3d20..3497cbea0e 100644<br>
--- a/src/mesa/main/extensions_<wbr>table.h<br>
+++ b/src/mesa/main/extensions_<wbr>table.h<br>
@@ -103,6 +103,7 @@ EXT(ARB_provoking_vertex , EXT_provoking_vertex<br>
EXT(ARB_query_buffer_object , ARB_query_buffer_object , GLL, GLC, x , x , 2013)<br>
EXT(ARB_robust_buffer_access_<wbr>behavior , ARB_robust_buffer_access_<wbr>behavior , GLL, GLC, x , x , 2012)<br>
EXT(ARB_robustness , dummy_true , GLL, GLC, x , x , 2010)<br>
+EXT(ARB_sample_locations , ARB_sample_locations , GLL, GLC, x , ES2, 2015)<br>
EXT(ARB_sample_shading , ARB_sample_shading , GLL, GLC, x , x , 2009)<br>
EXT(ARB_sampler_objects , dummy_true , GLL, GLC, x , x , 2009)<br>
EXT(ARB_seamless_cube_map , ARB_seamless_cube_map , GLL, GLC, x , x , 2009)<br>
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c<br>
index c72204e11a..33d7f0307d 100644<br>
--- a/src/mesa/main/fbobject.c<br>
+++ b/src/mesa/main/fbobject.c<br>
@@ -35,6 +35,7 @@<br>
<br>
#include "buffers.h"<br>
#include "context.h"<br>
+#include "debug_output.h"<br>
#include "enums.h"<br>
#include "fbobject.h"<br>
#include "formats.h"<br>
@@ -1403,15 +1404,57 @@ _mesa_BindRenderbufferEXT(<wbr>GLenum target, GLuint renderbuffer)<br>
bind_renderbuffer(target, renderbuffer, true);<br>
}<br>
<br>
+static bool<br>
+_pname_writable_for_default_<wbr>framebuffer(struct gl_context *ctx,<br>
+ GLenum pname)<br>
+{<br>
+ switch (pname) {<br>
+ case GL_FRAMEBUFFER_PROGRAMMABLE_<wbr>SAMPLE_LOCATIONS_ARB:<br>
+ case GL_FRAMEBUFFER_SAMPLE_<wbr>LOCATION_PIXEL_GRID_ARB:<br>
+ return true;<br>
+ default:<br>
+ return false;<br>
+ }<br>
+}<br>
+<br>
/**<br>
- * ARB_framebuffer_no_attachment - Application passes requested param's<br>
- * here. NOTE: NumSamples requested need not be _NumSamples which is<br>
- * what the hw supports.<br>
+ * ARB_framebuffer_no_attachment and ARB_sample_locations - Application passes<br>
+ * requested param's here. NOTE: NumSamples requested need not be _NumSamples<br>
+ * which is what the hw supports.<br>
*/<br>
static void<br>
framebuffer_parameteri(struct gl_context *ctx, struct gl_framebuffer *fb,<br>
GLenum pname, GLint param, const char *func)<br>
{<br>
+ switch (pname) {<br>
+ case GL_FRAMEBUFFER_DEFAULT_WIDTH:<br>
+ case GL_FRAMEBUFFER_DEFAULT_HEIGHT:<br>
+ case GL_FRAMEBUFFER_DEFAULT_LAYERS:<br>
+ case GL_FRAMEBUFFER_DEFAULT_<wbr>SAMPLES:<br>
+ case GL_FRAMEBUFFER_DEFAULT_FIXED_<wbr>SAMPLE_LOCATIONS:<br>
+ if (!ctx->Extensions.ARB_<wbr>framebuffer_no_attachments)<br>
+ goto invalid_pname_enum;<br>
+ break;<br>
+ case GL_FRAMEBUFFER_PROGRAMMABLE_<wbr>SAMPLE_LOCATIONS_ARB:<br>
+ case GL_FRAMEBUFFER_SAMPLE_<wbr>LOCATION_PIXEL_GRID_ARB:<br>
+ if (!ctx->Extensions.ARB_sample_<wbr>locations)<br>
+ goto invalid_pname_enum;<br>
+ break;<br>
+ default:<br>
+ goto invalid_pname_enum;<br>
+ }<br>
+<br>
+ if (_mesa_is_winsys_fbo(fb) &&<br>
+ !_pname_writable_for_default_<wbr>framebuffer(ctx, pname)) {<br>
+ if (ctx->Extensions.ARB_sample_<wbr>locations)<br>
+ _mesa_error(ctx, GL_INVALID_OPERATION,<br>
+ "%s(invalid pname=0x%x for default framebuffer)", func, pname);<br>
+ else<br>
+ _mesa_error(ctx, GL_INVALID_OPERATION,<br>
+ "%s(default framebuffer used)", func);<br>
+ return;<br>
+ }<br>
+<br>
switch (pname) {<br>
case GL_FRAMEBUFFER_DEFAULT_WIDTH:<br>
if (param < 0 || param > ctx->Const.<wbr>MaxFramebufferWidth)<br>
@@ -1448,13 +1491,29 @@ framebuffer_parameteri(struct gl_context *ctx, struct gl_framebuffer *fb,<br>
case GL_FRAMEBUFFER_DEFAULT_FIXED_<wbr>SAMPLE_LOCATIONS:<br>
fb->DefaultGeometry.<wbr>FixedSampleLocations = param;<br>
break;<br>
- default:<br>
- _mesa_error(ctx, GL_INVALID_ENUM,<br>
- "%s(pname=0x%x)", func, pname);<br>
+ case GL_FRAMEBUFFER_PROGRAMMABLE_<wbr>SAMPLE_LOCATIONS_ARB:<br>
+ fb-><wbr>ProgrammableSampleLocations = param;<br>
+ break;<br>
+ case GL_FRAMEBUFFER_SAMPLE_<wbr>LOCATION_PIXEL_GRID_ARB:<br>
+ fb->SampleLocationPixelGrid = param;<br>
+ break;<br>
}<br>
<br>
- invalidate_framebuffer(fb);<br>
+ switch (pname) {<br>
+ case GL_FRAMEBUFFER_PROGRAMMABLE_<wbr>SAMPLE_LOCATIONS_ARB:<br>
+ case GL_FRAMEBUFFER_SAMPLE_<wbr>LOCATION_PIXEL_GRID_ARB:<br>
+ break;<br>
+ default:<br>
+ invalidate_framebuffer(fb);<br>
+ break;<br>
+ }<br>
ctx->NewState |= _NEW_BUFFERS;<br>
+<br>
+ return;<br>
+<br>
+invalid_pname_enum:<br>
+ _mesa_error(ctx, GL_INVALID_ENUM,<br>
+ "%s(pname=0x%x)", func, pname);<br>
}<br>
<br>
void GLAPIENTRY<br>
@@ -1463,10 +1522,10 @@ _mesa_FramebufferParameteri(<wbr>GLenum target, GLenum pname, GLint param)<br>
GET_CURRENT_CONTEXT(ctx);<br>
struct gl_framebuffer *fb;<br>
<br>
- if (!ctx->Extensions.ARB_<wbr>framebuffer_no_attachments) {<br>
+ if (!ctx->Extensions.ARB_<wbr>framebuffer_no_attachments && !ctx->Extensions.ARB_sample_<wbr>locations) {<br>
_mesa_error(ctx, GL_INVALID_OPERATION,<br>
"glFramebufferParameteriv not supported "<br>
- "(ARB_framebuffer_no_<wbr>attachments not implemented)");<br>
+ "(ARB_framebuffer_no_<wbr>attachments or ARB_sample_locations not implemented)");<br>
return;<br>
}<br>
<br>
@@ -1477,23 +1536,13 @@ _mesa_FramebufferParameteri(<wbr>GLenum target, GLenum pname, GLint param)<br>
return;<br>
}<br>
<br>
- /* check framebuffer binding */<br>
- if (_mesa_is_winsys_fbo(fb)) {<br>
- _mesa_error(ctx, GL_INVALID_OPERATION,<br>
- "glFramebufferParameteri");<br>
- return;<br>
- }<br>
-<br>
framebuffer_parameteri(ctx, fb, pname, param, "glFramebufferParameteri");<br>
}<br>
<br>
static bool<br>
-_pname_valid_for_default_<wbr>framebuffer(struct gl_context *ctx,<br>
- GLenum pname)<br>
+_pname_readable_for_default_<wbr>framebuffer(struct gl_context *ctx,<br>
+ GLenum pname)<br>
{<br>
- if (!_mesa_is_desktop_gl(ctx))<br>
- return false;<br>
-<br>
switch (pname) {<br>
case GL_DOUBLEBUFFER:<br>
case GL_IMPLEMENTATION_COLOR_READ_<wbr>FORMAT:<br>
@@ -1501,6 +1550,9 @@ _pname_valid_for_default_<wbr>framebuffer(struct gl_context *ctx,<br>
case GL_SAMPLES:<br>
case GL_SAMPLE_BUFFERS:<br>
case GL_STEREO:<br>
+ return _mesa_is_desktop_gl(ctx);<br>
+ case GL_FRAMEBUFFER_PROGRAMMABLE_<wbr>SAMPLE_LOCATIONS_ARB:<br>
+ case GL_FRAMEBUFFER_SAMPLE_<wbr>LOCATION_PIXEL_GRID_ARB:<br>
return true;<br>
default:<br>
return false;<br>
@@ -1519,10 +1571,10 @@ get_framebuffer_parameteriv(<wbr>struct gl_context *ctx, struct gl_framebuffer *fb,<br>
* SAMPLE_POSITION."<br>
*<br>
* For OpenGL ES, using default framebuffer still raises INVALID_OPERATION<br>
- * for any pname.<br>
+ * for any pname other than the ARB_sample_location names.<br>
*/<br>
if (_mesa_is_winsys_fbo(fb) &&<br>
- !_pname_valid_for_default_<wbr>framebuffer(ctx, pname)) {<br>
+ !_pname_readable_for_default_<wbr>framebuffer(ctx, pname)) {<br>
_mesa_error(ctx, GL_INVALID_OPERATION,<br>
"%s(invalid pname=0x%x for default framebuffer)", func, pname);<br>
return;<br>
@@ -1570,6 +1622,20 @@ get_framebuffer_parameteriv(<wbr>struct gl_context *ctx, struct gl_framebuffer *fb,<br>
case GL_STEREO:<br>
*params = fb->Visual.stereoMode;<br>
break;<br>
+ case GL_FRAMEBUFFER_PROGRAMMABLE_<wbr>SAMPLE_LOCATIONS_ARB:<br>
+ if (!ctx->Extensions.ARB_sample_<wbr>locations) {<br>
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);<br>
+ break;<br>
+ }<br>
+ *params = fb-><wbr>ProgrammableSampleLocations;<br>
+ break;<br>
+ case GL_FRAMEBUFFER_SAMPLE_<wbr>LOCATION_PIXEL_GRID_ARB:<br>
+ if (!ctx->Extensions.ARB_sample_<wbr>locations) {<br>
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);<br>
+ break;<br>
+ }<br>
+ *params = fb->SampleLocationPixelGrid;<br>
+ break;<br>
default:<br>
_mesa_error(ctx, GL_INVALID_ENUM,<br>
"%s(pname=0x%x)", func, pname);<br>
@@ -1582,10 +1648,12 @@ _mesa_<wbr>GetFramebufferParameteriv(<wbr>GLenum target, GLenum pname, GLint *params)<br>
GET_CURRENT_CONTEXT(ctx);<br>
struct gl_framebuffer *fb;<br>
<br>
- if (!ctx->Extensions.ARB_<wbr>framebuffer_no_attachments) {<br>
+ if (!ctx->Extensions.ARB_<wbr>framebuffer_no_attachments &&<br>
+ !ctx->Extensions.ARB_sample_<wbr>locations) {<br>
_mesa_error(ctx, GL_INVALID_OPERATION,<br>
"glGetFramebufferParameteriv not supported "<br>
- "(ARB_framebuffer_no_<wbr>attachments not implemented)");<br>
+ "(both ARB_framebuffer_no_attachments and ARB_sample_locations"<br>
+ " not implemented)");<br>
return;<br>
}<br>
<br>
@@ -4224,15 +4292,21 @@ _mesa_<wbr>NamedFramebufferParameteri(<wbr>GLuint framebuffer, GLenum pname,<br>
GET_CURRENT_CONTEXT(ctx);<br>
struct gl_framebuffer *fb = NULL;<br>
<br>
- if (!ctx->Extensions.ARB_<wbr>framebuffer_no_attachments) {<br>
+ if (!ctx->Extensions.ARB_<wbr>framebuffer_no_attachments &&<br>
+ !ctx->Extensions.ARB_sample_<wbr>locations) {<br>
_mesa_error(ctx, GL_INVALID_OPERATION,<br>
"glNamedFramebufferParameteri(<wbr>"<br>
- "ARB_framebuffer_no_<wbr>attachments not implemented)");<br>
+ "both ARB_framebuffer_no_attachments and "<br>
+ "ARB_sample_locations not implemented)");<br>
return;<br>
}<br>
<br>
- fb = _mesa_lookup_framebuffer_err(<wbr>ctx, framebuffer,<br>
- "glNamedFramebufferParameteri"<wbr>);<br>
+ if (framebuffer) {<br>
+ fb = _mesa_lookup_framebuffer_err(<wbr>ctx, framebuffer,<br>
+ "glNamedFramebufferParameteri"<wbr>);<br>
+ } else {<br>
+ fb = ctx->WinSysDrawBuffer;<br>
+ }<br>
<br>
if (fb) {<br>
framebuffer_parameteri(ctx, fb, pname, param,<br>
@@ -4251,7 +4325,8 @@ _mesa_<wbr>GetNamedFramebufferParameteriv<wbr>(GLuint framebuffer, GLenum pname,<br>
if (!ctx->Extensions.ARB_<wbr>framebuffer_no_attachments) {<br>
_mesa_error(ctx, GL_INVALID_OPERATION,<br>
"<wbr>glNamedFramebufferParameteriv(<wbr>"<br>
- "ARB_framebuffer_no_<wbr>attachments not implemented)");<br>
+ "both ARB_framebuffer_no_attachments and ARB_sample_locations"<br>
+ " not implemented)");<br>
return;<br>
}<br>
<br>
@@ -4595,3 +4670,115 @@ invalid_enum:<br>
"glDiscardFramebufferEXT(<wbr>attachment %s)",<br>
_mesa_enum_to_string(<wbr>attachments[i]));<br>
}<br>
+<br>
+static void<br>
+sample_locations(struct gl_context *ctx, struct gl_framebuffer *fb,<br>
+ GLuint start, GLsizei count, const GLfloat *v, bool no_error,<br>
+ const char *name)<br>
+{<br>
+ GLsizei i;<br>
+<br>
+ if (!no_error && !ctx->Extensions.ARB_sample_<wbr>locations) {<br>
+ _mesa_error(ctx, GL_INVALID_OPERATION,<br>
+ "%s not supported "<br>
+ "(ARB_sample_locations not implemented)", name);<br>
+ return;<br>
+ }<br>
+<br>
+ if (!no_error && start+count>MAX_SAMPLE_<wbr>LOCATION_TABLE_SIZE) {<br>
+ _mesa_error(ctx, GL_INVALID_VALUE,<br>
+ "%s(start+size > sample location table size)", name);<br>
+ return;<br>
+ }<br>
+<br>
+ if (!fb->SampleLocationTable) {<br>
+ size_t size = MAX_SAMPLE_LOCATION_TABLE_SIZE * 2 * sizeof(GLfloat);<br>
+ fb->SampleLocationTable = malloc(size);<br>
+ for (i = 0; i < MAX_SAMPLE_LOCATION_TABLE_SIZE * 2; i++)<br>
+ fb->SampleLocationTable[i] = 0.5f;<br>
+ }<br>
+<br>
+ for (i = 0; i < count * 2; i++) {<br>
+ if (v[i] != v[i] || v[i] < 0.0 || v[i] > 1.0) {<br>
+ static GLuint msg_id = 0;<br>
+ static const char* msg = "Invalid sample location specified";<br>
+ _mesa_debug_get_id(&msg_id);<br>
+<br>
+ fb->SampleLocationTable[start * 2 + i] = CLAMP(v[i], 0.0, 1.0);<br>
+ _mesa_log_msg(ctx, MESA_DEBUG_SOURCE_API, MESA_DEBUG_TYPE_UNDEFINED,<br>
+ msg_id, MESA_DEBUG_SEVERITY_HIGH, strlen(msg), msg);<br>
+ } else<br>
+ fb->SampleLocationTable[start * 2 + i] = v[i];<br>
+ }<br>
+<br>
+ ctx->NewState |= _NEW_BUFFERS;<br></blockquote><div><br></div><div>I wouldn't like to see _NEW_* being used for anything new. _NEW_BUFFERS implies a memory and execution barrier in gallium, so it decreases performance.<br><br></div><div>gl_driver_flags provides a more efficient mechanism for communicating state changes to drivers. A new flag in that structure is highly preferred.<br><br></div><div>Marek<br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+}<br>
+<br>
+void GLAPIENTRY<br>
+_mesa_<wbr>FramebufferSampleLocationsfvAR<wbr>B(GLenum target, GLuint start,<br>
+ GLsizei count, const GLfloat *v)<br>
+{<br>
+ struct gl_framebuffer *fb;<br>
+<br>
+ GET_CURRENT_CONTEXT(ctx);<br>
+<br>
+ fb = get_framebuffer_target(ctx, target);<br>
+ if (!fb) {<br>
+ _mesa_error(ctx, GL_INVALID_ENUM,<br>
+ "<wbr>glFramebufferSampleLocationsfv<wbr>ARB(target %s)",<br>
+ _mesa_enum_to_string(target));<br>
+ return;<br>
+ }<br>
+<br>
+ sample_locations(ctx, fb, start, count, v, false,<br>
+ "<wbr>glFramebufferSampleLocationsfv<wbr>ARB");<br>
+}<br>
+<br>
+void GLAPIENTRY<br>
+_mesa_<wbr>NamedFramebufferSampleLocation<wbr>sfvARB(GLuint framebuffer, GLuint start,<br>
+ GLsizei count, const GLfloat *v)<br>
+{<br>
+ struct gl_framebuffer *fb;<br>
+<br>
+ GET_CURRENT_CONTEXT(ctx);<br>
+<br>
+ if (framebuffer) {<br>
+ fb = _mesa_lookup_framebuffer_err(<wbr>ctx, framebuffer,<br>
+ "<wbr>glNamedFramebufferSampleLocati<wbr>onsfvARB");<br>
+ if (!fb)<br>
+ return;<br>
+ }<br>
+ else<br>
+ fb = ctx->WinSysDrawBuffer;<br>
+<br>
+ sample_locations(ctx, fb, start, count, v, false,<br>
+ "<wbr>glNamedFramebufferSampleLocati<wbr>onsfvARB");<br>
+}<br>
+<br>
+void GLAPIENTRY<br>
+_mesa_<wbr>FramebufferSampleLocationsfvAR<wbr>B_no_error(GLenum target, GLuint start,<br>
+ GLsizei count, const GLfloat *v)<br>
+{<br>
+ GET_CURRENT_CONTEXT(ctx);<br>
+<br>
+ sample_locations(ctx, get_framebuffer_target(ctx, target), start,<br>
+ count, v, true, "<wbr>glFramebufferSampleLocationsfv<wbr>ARB");<br>
+}<br>
+<br>
+void GLAPIENTRY<br>
+_mesa_<wbr>NamedFramebufferSampleLocation<wbr>sfvARB_no_error(GLuint framebuffer,<br>
+ GLuint start, GLsizei count,<br>
+ const GLfloat *v)<br>
+{<br>
+ GET_CURRENT_CONTEXT(ctx);<br>
+ sample_locations(ctx, _mesa_lookup_framebuffer(ctx, framebuffer), start,<br>
+ count, v, true, "<wbr>glNamedFramebufferSampleLocati<wbr>onsfvARB");<br>
+}<br>
+<br>
+void GLAPIENTRY<br>
+_mesa_EvaluateDepthValuesARB(<wbr>void)<br>
+{<br>
+ GET_CURRENT_CONTEXT(ctx);<br>
+ if (ctx->Driver.<wbr>EvaluateDepthValues)<br>
+ ctx->Driver.<wbr>EvaluateDepthValues(ctx, ctx->DrawBuffer);<br>
+}<br>
diff --git a/src/mesa/main/fbobject.h b/src/mesa/main/fbobject.h<br>
index 31d743d3fb..5ba62d6cb1 100644<br>
--- a/src/mesa/main/fbobject.h<br>
+++ b/src/mesa/main/fbobject.h<br>
@@ -355,4 +355,24 @@ _mesa_FramebufferParameteri(<wbr>GLenum target, GLenum pname, GLint param);<br>
extern void GLAPIENTRY<br>
_mesa_<wbr>GetFramebufferParameteriv(<wbr>GLenum target, GLenum pname, GLint *params);<br>
<br>
+extern void GLAPIENTRY<br>
+_mesa_<wbr>FramebufferSampleLocationsfvAR<wbr>B(GLenum target, GLuint start,<br>
+ GLsizei count, const GLfloat *v);<br>
+<br>
+extern void GLAPIENTRY<br>
+_mesa_<wbr>NamedFramebufferSampleLocation<wbr>sfvARB(GLuint framebuffer, GLuint start,<br>
+ GLsizei count, const GLfloat *v);<br>
+<br>
+extern void GLAPIENTRY<br>
+_mesa_<wbr>FramebufferSampleLocationsfvAR<wbr>B_no_error(GLenum target, GLuint start,<br>
+ GLsizei count, const GLfloat *v);<br>
+<br>
+extern void GLAPIENTRY<br>
+_mesa_<wbr>NamedFramebufferSampleLocation<wbr>sfvARB_no_error(GLuint framebuffer,<br>
+ GLuint start, GLsizei count,<br>
+ const GLfloat *v);<br>
+<br>
+extern void GLAPIENTRY<br>
+_mesa_EvaluateDepthValuesARB(<wbr>void);<br>
+<br>
#endif /* FBOBJECT_H */<br>
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c<br>
index 249e775f8c..02f84dca75 100644<br>
--- a/src/mesa/main/framebuffer.c<br>
+++ b/src/mesa/main/framebuffer.c<br>
@@ -160,6 +160,10 @@ _mesa_initialize_window_<wbr>framebuffer(struct gl_framebuffer *fb,<br>
fb->_<wbr>HasSNormOrFloatColorBuffer = visual->floatMode;<br>
fb->_HasAttachments = true;<br>
<br>
+ fb->SampleLocationTable = NULL;<br>
+ fb-><wbr>ProgrammableSampleLocations = 0;<br>
+ fb->SampleLocationPixelGrid = 0;<br>
+<br>
compute_depth_max(fb);<br>
}<br>
<br>
@@ -183,6 +187,9 @@ _mesa_initialize_user_<wbr>framebuffer(struct gl_framebuffer *fb, GLuint name)<br>
fb->_ColorDrawBufferIndexes[0] = BUFFER_COLOR0;<br>
fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT;<br>
fb->_ColorReadBufferIndex = BUFFER_COLOR0;<br>
+ fb->SampleLocationTable = NULL;<br>
+ fb-><wbr>ProgrammableSampleLocations = 0;<br>
+ fb->SampleLocationPixelGrid = 0;<br>
fb->Delete = _mesa_destroy_framebuffer;<br>
simple_mtx_init(&fb->Mutex, mtx_plain);<br>
}<br>
@@ -229,6 +236,9 @@ _mesa_free_framebuffer_data(<wbr>struct gl_framebuffer *fb)<br>
assert(!att->Texture);<br>
att->Type = GL_NONE;<br>
}<br>
+<br>
+ free(fb->SampleLocationTable);<br>
+ fb->SampleLocationTable = NULL;<br>
}<br>
<br>
<br>
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c<br>
index 90ab7ca60f..2a43937ec3 100644<br>
--- a/src/mesa/main/get.c<br>
+++ b/src/mesa/main/get.c<br>
@@ -188,6 +188,7 @@ union value {<br>
GLint value_int_4[4];<br>
GLint64 value_int64;<br>
GLenum value_enum;<br>
+ GLuint value_uint;<br>
<br>
/* Sigh, see GL_COMPRESSED_TEXTURE_FORMATS_<wbr>ARB handling */<br>
struct {<br>
@@ -506,6 +507,7 @@ EXTRA_EXT(OES_primitive_<wbr>bounding_box);<br>
EXTRA_EXT(ARB_compute_<wbr>variable_group_size);<br>
EXTRA_EXT(KHR_robustness);<br>
EXTRA_EXT(ARB_sparse_buffer);<br>
+EXTRA_EXT(ARB_sample_<wbr>locations);<br>
<br>
static const int<br>
extra_ARB_color_buffer_float_<wbr>or_glcore[] = {<br>
@@ -1187,6 +1189,36 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu<br>
simple_mtx_unlock(&ctx-><wbr>Shared->Mutex);<br>
}<br>
break;<br>
+ /* GL_ARB_sample_locations */<br>
+ case GL_SAMPLE_LOCATION_SUBPIXEL_<wbr>BITS_ARB:<br>
+ case GL_SAMPLE_LOCATION_PIXEL_GRID_<wbr>WIDTH_ARB:<br>
+ case GL_SAMPLE_LOCATION_PIXEL_GRID_<wbr>HEIGHT_ARB:<br>
+ {<br>
+ GLuint bits=0, width=1, height=1;<br>
+<br>
+ if (ctx->NewState & _NEW_BUFFERS)<br>
+ _mesa_update_state(ctx);<br>
+<br>
+ if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE) {<br>
+ v->value_uint = 0;<br>
+ break;<br>
+ }<br>
+<br>
+ if (ctx->Driver.<wbr>GetProgrammableSampleCaps)<br>
+ ctx->Driver.<wbr>GetProgrammableSampleCaps(ctx, ctx->DrawBuffer,<br>
+ &bits, &width, &height);<br>
+<br>
+ if (d->pname == GL_SAMPLE_LOCATION_PIXEL_GRID_<wbr>WIDTH_ARB)<br>
+ v->value_uint = width;<br>
+ else if (d->pname == GL_SAMPLE_LOCATION_PIXEL_GRID_<wbr>HEIGHT_ARB)<br>
+ v->value_uint = height;<br>
+ else<br>
+ v->value_uint = bits;<br>
+ }<br>
+ break;<br>
+ case GL_PROGRAMMABLE_SAMPLE_<wbr>LOCATION_TABLE_SIZE_ARB:<br>
+ v->value_uint = MAX_SAMPLE_LOCATION_TABLE_<wbr>SIZE;<br>
+ break;<br>
}<br>
}<br>
<br>
diff --git a/src/mesa/main/get_hash_<wbr>params.py b/src/mesa/main/get_hash_<wbr>params.py<br>
index f38a87df88..eba68a6321 100644<br>
--- a/src/mesa/main/get_hash_<wbr>params.py<br>
+++ b/src/mesa/main/get_hash_<wbr>params.py<br>
@@ -545,6 +545,12 @@ descriptor=[<br>
<br>
# GL_NUM_SHADING_LANGUAGE_<wbr>VERSIONS<br>
[ "NUM_SHADING_LANGUAGE_<wbr>VERSIONS", "LOC_CUSTOM, TYPE_INT, 0, extra_version_43" ],<br>
+<br>
+ # GL_ARB_sample_locations<br>
+ [ "SAMPLE_LOCATION_SUBPIXEL_<wbr>BITS_ARB", "LOC_CUSTOM, TYPE_UINT, 0, extra_ARB_sample_locations" ],<br>
+ [ "SAMPLE_LOCATION_PIXEL_GRID_<wbr>WIDTH_ARB", "LOC_CUSTOM, TYPE_UINT, 0, extra_ARB_sample_locations" ],<br>
+ [ "SAMPLE_LOCATION_PIXEL_GRID_<wbr>HEIGHT_ARB", "LOC_CUSTOM, TYPE_UINT, 0, extra_ARB_sample_locations" ],<br>
+ [ "PROGRAMMABLE_SAMPLE_LOCATION_<wbr>TABLE_SIZE_ARB", "LOC_CUSTOM, TYPE_UINT, 0, extra_ARB_sample_locations" ],<br>
]},<br>
<br>
# Enums in OpenGL Core profile and ES 3.0<br>
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h<br>
index b65e7b2c3c..1feb3a658a 100644<br>
--- a/src/mesa/main/mtypes.h<br>
+++ b/src/mesa/main/mtypes.h<br>
@@ -3441,6 +3441,11 @@ struct gl_framebuffer<br>
GLenum16 ColorDrawBuffer[MAX_DRAW_<wbr>BUFFERS];<br>
GLenum16 ColorReadBuffer;<br>
<br>
+ /* GL_ARB_sample_locations */<br>
+ GLfloat* SampleLocationTable; /**< If NULL, no table has been specified */<br>
+ GLint ProgrammableSampleLocations;<br>
+ GLint SampleLocationPixelGrid;<br>
+<br>
/** Computed from ColorDraw/ReadBuffer above */<br>
GLuint _NumColorDrawBuffers;<br>
gl_buffer_index _ColorDrawBufferIndexes[MAX_<wbr>DRAW_BUFFERS];<br>
@@ -4043,6 +4048,7 @@ struct gl_extensions<br>
GLboolean ARB_post_depth_coverage;<br>
GLboolean ARB_query_buffer_object;<br>
GLboolean ARB_robust_buffer_access_<wbr>behavior;<br>
+ GLboolean ARB_sample_locations;<br>
GLboolean ARB_sample_shading;<br>
GLboolean ARB_seamless_cube_map;<br>
GLboolean ARB_shader_atomic_counter_ops;<br>
diff --git a/src/mesa/main/multisample.c b/src/mesa/main/multisample.c<br>
index dfe6a37142..08f6acb7e1 100644<br>
--- a/src/mesa/main/multisample.c<br>
+++ b/src/mesa/main/multisample.c<br>
@@ -101,6 +101,24 @@ _mesa_GetMultisamplefv(GLenum pname, GLuint index, GLfloat * val)<br>
return;<br>
}<br>
<br>
+ case GL_PROGRAMMABLE_SAMPLE_<wbr>LOCATION_ARB:<br>
+ if (!ctx->Extensions.ARB_sample_<wbr>locations) {<br>
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetMultisamplefv(pname)" );<br>
+ return;<br>
+ }<br>
+<br>
+ if (index >= MAX_SAMPLE_LOCATION_TABLE_<wbr>SIZE*2) {<br>
+ _mesa_error( ctx, GL_INVALID_VALUE, "glGetMultisamplefv(index)" );<br>
+ return;<br>
+ }<br>
+<br>
+ if (ctx->DrawBuffer-><wbr>SampleLocationTable)<br>
+ *val = ctx->DrawBuffer-><wbr>SampleLocationTable[index];<br>
+ else<br>
+ *val = 0.5f;<br>
+<br>
+ return;<br>
+<br>
default:<br>
_mesa_error( ctx, GL_INVALID_ENUM, "glGetMultisamplefv(pname)" );<br>
return;<br>
diff --git a/src/mesa/main/tests/<wbr>dispatch_sanity.cpp b/src/mesa/main/tests/<wbr>dispatch_sanity.cpp<br>
index 83a4b04654..884f0c2e8c 100644<br>
--- a/src/mesa/main/tests/<wbr>dispatch_sanity.cpp<br>
+++ b/src/mesa/main/tests/<wbr>dispatch_sanity.cpp<br>
@@ -1026,6 +1026,11 @@ const struct function common_desktop_functions_<wbr>possible[] = {<br>
/* GL_EXT_shader_framebuffer_<wbr>fetch_non_coherent */<br>
{ "glFramebufferFetchBarrierEXT"<wbr>, 20, -1 },<br>
<br>
+ /* GL_ARB_sample_locations */<br>
+ { "<wbr>glFramebufferSampleLocationsfv<wbr>ARB", 30, -1 },<br>
+ { "<wbr>glNamedFramebufferSampleLocati<wbr>onsfvARB", 30, -1 },<br>
+ { "glEvaluateDepthValuesARB", 30, -1 },<br>
+<br>
{ NULL, 0, -1 }<br>
};<br>
<br>
@@ -2752,5 +2757,10 @@ const struct function gles31_functions_possible[] = {<br>
{ "glDepthRangeIndexedfOES", 31, -1 },<br>
{ "glGetFloati_vOES", 31, -1 },<br>
<br>
+ /* GL_ARB_sample_locations */<br>
+ { "<wbr>glFramebufferSampleLocationsfv<wbr>ARB", 31, -1 },<br>
+ { "<wbr>glNamedFramebufferSampleLocati<wbr>onsfvARB", 31, -1 },<br>
+ { "glEvaluateDepthValuesARB", 31, -1 },<br>
+<br>
{ NULL, 0, -1 },<br>
};<br>
<span class="HOEnZb"><font color="#888888">-- <br>
2.14.3<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>