diff --git a/src/compiler/glsl/ast.h b/src/compiler/glsl/ast.h
index 6450fed9ff6..2c3de32a715 100644
--- a/src/compiler/glsl/ast.h
+++ b/src/compiler/glsl/ast.h
@@ -607,6 +607,12 @@ struct ast_type_qualifier {
unsigned explicit_xfb_stride:1; /**< xfb_stride value assigned explicitly by shader code */
/** \} */
+ /**
+ * Flag set if GL_OVR_multiview num_views_relative layout
+ * qualifier is used.
+ */
+ unsigned explicit_numviews:1;
+
/** \name Layout qualifiers for GL_ARB_tessellation_shader */
/** \{ */
/* tess eval input layout */
@@ -745,6 +751,14 @@ struct ast_type_qualifier {
*/
ast_expression *binding;
+ /**
+ * Binding specified via GL_OVR_multiview's "num_views" keyword.
+ *
+ * \note
+ * This field is only valid if \c explicit_numviews is set.
+ */
+ ast_expression *num_views;
+
/**
* Offset specified via GL_ARB_shader_atomic_counter's or
* GL_ARB_enhanced_layouts "offset" keyword, or by GL_ARB_enhanced_layouts
diff --git a/src/compiler/glsl/ast_type.cpp b/src/compiler/glsl/ast_type.cpp
index 4aa3d657d87..194aa3e55ce 100644
--- a/src/compiler/glsl/ast_type.cpp
+++ b/src/compiler/glsl/ast_type.cpp
@@ -84,7 +84,8 @@ ast_type_qualifier::has_layout() const
|| this->flags.q.explicit_stream
|| this->flags.q.explicit_xfb_buffer
|| this->flags.q.explicit_xfb_offset
- || this->flags.q.explicit_xfb_stride;
+ || this->flags.q.explicit_xfb_stride
+ || this->flags.q.explicit_numviews;
}
bool
@@ -186,6 +187,26 @@ validate_point_mode(ASSERTED const ast_type_qualifier &qualifier,
return true;
}
+static bool
+validate_view_qualifier(YYLTYPE *loc, struct _mesa_glsl_parse_state *state,
+ unsigned view)
+{
+ if (view > MAX_VIEWS_OVR) {
+ _mesa_glsl_error(loc, state,
+ "invalid view specified %d is larger than "
+ "MAX_VIEWS_OVR (%d).",
+ view, MAX_VIEWS_OVR);
+ return false;
+ }
+ else if (view <= 0) {
+ _mesa_glsl_error(loc, state,
+ "invalid view specified %d is less than 0", view);
+ return false;
+ }
+
+ return true;
+}
+
static void
merge_bindless_qualifier(_mesa_glsl_parse_state *state)
{
@@ -272,6 +293,7 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
input_layout_mask.flags.q.sample = 1;
input_layout_mask.flags.q.smooth = 1;
input_layout_mask.flags.q.non_coherent = 1;
+ input_layout_mask.flags.q.explicit_numviews = 1;
if (state->has_bindless()) {
/* Allow to use image qualifiers with shader inputs/outputs. */
@@ -497,6 +519,18 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
this->flags.q.out = 1;
}
+ if (q.flags.q.explicit_numviews) {
+ this->num_views = q.num_views;
+ unsigned num_views;
+ if (process_qualifier_constant(state, loc, "num_views",
+ this->num_views, &num_views)){
+ if (!validate_view_qualifier(loc, state, num_views)){
+ _mesa_glsl_error(loc, state,
+ "Invalid num_views specified");
+ }
+ }
+ }
+
return r;
}
@@ -603,6 +637,12 @@ ast_type_qualifier::validate_in_qualifier(YYLTYPE *loc,
valid_in_mask.flags.i = 0;
switch (state->stage) {
+ case MESA_SHADER_VERTEX:
+ if (this->flags.q.explicit_numviews){
+ valid_in_mask.flags.q.explicit_numviews = 1;
+ break;
+ }
+
case MESA_SHADER_TESS_EVAL:
if (this->flags.q.prim_type) {
/* Make sure this is a valid input primitive type. */
@@ -709,6 +749,8 @@ ast_type_qualifier::merge_into_in_qualifier(YYLTYPE *loc,
state->in_qualifier->flags.q.early_fragment_tests = false;
}
+ state->in_qualifier->flags.q.explicit_numviews = false;
+
if (state->in_qualifier->flags.q.inner_coverage) {
state->fs_inner_coverage = true;
state->in_qualifier->flags.q.inner_coverage = false;
@@ -890,6 +932,7 @@ ast_type_qualifier::validate_flags(YYLTYPE *loc,
Q2(explicit_xfb_buffer, xfb_buffer);
Q2(xfb_stride, xfb_stride);
Q2(explicit_xfb_stride, xfb_stride);
+ Q2(explicit_numviews, num_views);
Q(vertex_spacing);
Q(ordering);
Q(point_mode);
diff --git a/src/compiler/glsl/builtin_variables.cpp b/src/compiler/glsl/builtin_variables.cpp
index dd17c2e5587..6496a6d24e5 100644
--- a/src/compiler/glsl/builtin_variables.cpp
+++ b/src/compiler/glsl/builtin_variables.cpp
@@ -1144,6 +1144,10 @@ builtin_variable_generator::generate_vs_special_vars()
add_system_value(SYSTEM_VALUE_VERTEX_ID, int_t, GLSL_PRECISION_HIGH,
"gl_VertexID");
}
+ if (state->is_version(300, 300) && state->OVR_multiview_enable){
+ add_system_value(SYSTEM_VALUE_VIEW_INDEX, int_t, GLSL_PRECISION_MEDIUM,
+ "gl_ViewID_OVR");
+ }
if (state->is_version(460, 0)) {
add_system_value(SYSTEM_VALUE_BASE_VERTEX, int_t, "gl_BaseVertex");
add_system_value(SYSTEM_VALUE_BASE_INSTANCE, int_t, "gl_BaseInstance");
diff --git a/src/compiler/glsl/glsl_parser.yy b/src/compiler/glsl/glsl_parser.yy
index aae60ef50bd..945846e92fe 100644
--- a/src/compiler/glsl/glsl_parser.yy
+++ b/src/compiler/glsl/glsl_parser.yy
@@ -1765,6 +1765,11 @@ layout_qualifier_id:
$$.location = $3;
}
+ if (match_layout_qualifier("num_views", $1, state) == 0) {
+ $$.flags.q.explicit_numviews = 1;
+ $$.num_views = $3;
+ }
+
if (match_layout_qualifier("component", $1, state) == 0) {
if (!state->has_enhanced_layouts()) {
_mesa_glsl_error(& @1, state,
diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp
index 8019e3b30f9..257869a322a 100644
--- a/src/compiler/glsl/glsl_parser_extras.cpp
+++ b/src/compiler/glsl/glsl_parser_extras.cpp
@@ -846,6 +846,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
EXT(NV_shader_atomic_int64),
EXT(NV_shader_noperspective_interpolation),
EXT(NV_viewport_array2),
+ EXT(OVR_multiview),
};
#undef EXT
diff --git a/src/compiler/glsl/glsl_parser_extras.h b/src/compiler/glsl/glsl_parser_extras.h
index 6638e826f8b..ef8de32418c 100644
--- a/src/compiler/glsl/glsl_parser_extras.h
+++ b/src/compiler/glsl/glsl_parser_extras.h
@@ -934,6 +934,8 @@ struct _mesa_glsl_parse_state {
bool NV_shader_noperspective_interpolation_warn;
bool NV_viewport_array2_enable;
bool NV_viewport_array2_warn;
+ bool OVR_multiview_enable;
+ bool OVR_multiview_warn;
/*@}*/
/** Extensions supported by the OpenGL implementation. */
diff --git a/src/gallium/auxiliary/util/u_framebuffer.c b/src/gallium/auxiliary/util/u_framebuffer.c
index 90bc37a63fe..937c0ca3519 100644
--- a/src/gallium/auxiliary/util/u_framebuffer.c
+++ b/src/gallium/auxiliary/util/u_framebuffer.c
@@ -106,6 +106,7 @@ util_copy_framebuffer_state(struct pipe_framebuffer_state *dst,
dst->nr_cbufs = src->nr_cbufs;
+ dst->viewmask = src->viewmask;
pipe_surface_reference(&dst->zsbuf, src->zsbuf);
pipe_resource_reference(&dst->resolve, src->resolve);
} else {
@@ -120,6 +121,8 @@ util_copy_framebuffer_state(struct pipe_framebuffer_state *dst,
dst->nr_cbufs = 0;
+ dst->viewmask = 0;
+
pipe_surface_reference(&dst->zsbuf, NULL);
pipe_resource_reference(&dst->resolve, NULL);
}
@@ -141,6 +144,8 @@ util_unreference_framebuffer_state(struct pipe_framebuffer_state *fb)
fb->samples = fb->layers = 0;
fb->width = fb->height = 0;
fb->nr_cbufs = 0;
+
+ fb->viewmask = 0;
}
diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c
index 9c11604b462..fb314adc396 100644
--- a/src/gallium/auxiliary/util/u_threaded_context.c
+++ b/src/gallium/auxiliary/util/u_threaded_context.c
@@ -1524,6 +1524,7 @@ tc_set_framebuffer_state(struct pipe_context *_pipe,
p->state.samples = fb->samples;
p->state.layers = fb->layers;
p->state.nr_cbufs = nr_cbufs;
+ p->state.viewmask = fb->viewmask;
/* when unbinding, mark attachments as used for the current batch */
for (unsigned i = 0; i < tc->nr_cbufs; i++) {
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index a86025678c2..3372c915bc7 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -403,6 +403,8 @@ struct pipe_framebuffer_state
/** multiple color buffers for multiple render targets */
uint8_t nr_cbufs;
+ /** used for multiview */
+ uint8_t viewmask;
struct pipe_surface *cbufs[PIPE_MAX_COLOR_BUFS];
struct pipe_surface *zsbuf; /**< Z/stencil buffer */
diff --git a/src/gallium/targets/osmesa/osmesa-symbols.txt b/src/gallium/targets/osmesa/osmesa-symbols.txt
index 4ed263e2c16..daf58d227b1 100644
--- a/src/gallium/targets/osmesa/osmesa-symbols.txt
+++ b/src/gallium/targets/osmesa/osmesa-symbols.txt
@@ -332,6 +332,7 @@ glFramebufferTexture3D
glFramebufferTexture3DEXT
glFramebufferTextureLayer
glFramebufferTextureLayerEXT
+glFramebufferTextureMultiviewOVR
glFrontFace
glFrustum
glFrustumf
diff --git a/src/mapi/glapi/gen/OVR_multiview.xml b/src/mapi/glapi/gen/OVR_multiview.xml
new file mode 100755
index 00000000000..f66056b27d1
--- /dev/null
+++ b/src/mapi/glapi/gen/OVR_multiview.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index 7e9d184b47a..305c1fa558d 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -8062,6 +8062,8 @@
+
+
diff --git a/src/mapi/glapi/gen/meson.build b/src/mapi/glapi/gen/meson.build
index db5ac894d4a..c0609b1565e 100644
--- a/src/mapi/glapi/gen/meson.build
+++ b/src/mapi/glapi/gen/meson.build
@@ -131,6 +131,7 @@ api_xml_files = files(
'OES_fixed_point.xml',
'OES_single_precision.xml',
'OES_texture_compression_astc.xml',
+ 'OVR_multiview.xml',
'GL3x.xml',
'GL4x.xml',
)
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
index 19304fed62b..97b64d9157d 100644
--- a/src/mapi/glapi/gen/static_data.py
+++ b/src/mapi/glapi/gen/static_data.py
@@ -1708,6 +1708,8 @@ offsets = {
"DrawElementsUserBufPacked": 1672,
"TexStorageAttribs2DEXT": 1673,
"TexStorageAttribs3DEXT": 1674,
+ "FramebufferTextureMultiviewOVR": 1675,
+ "NamedFramebufferTextureMultiviewOVR": 1676,
}
functions = [
@@ -2035,6 +2037,7 @@ functions = [
"FramebufferTextureLayer",
"FramebufferTextureLayerARB",
"FramebufferTextureLayerEXT",
+ "FramebufferTextureMultiviewOVR",
"FrontFace",
"Frustum",
"Frustumf",
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
index 753d847efb1..74c41fd1d95 100644
--- a/src/mesa/main/config.h
+++ b/src/mesa/main/config.h
@@ -145,6 +145,9 @@
/** For GL_EXT_texture_lod_bias (typically MAX_TEXTURE_LEVELS - 1) */
#define MAX_TEXTURE_LOD_BIAS 14.0
+/** For GL_OVR_multiview, value is recommended in extension spec. */
+#define MAX_VIEWS_OVR 6
+
/** For any program target/extension */
/*@{*/
#define MAX_PROGRAM_INSTRUCTIONS (16 * 1024)
diff --git a/src/mesa/main/consts_exts.h b/src/mesa/main/consts_exts.h
index 05d13717c5e..dc48e27c0c7 100644
--- a/src/mesa/main/consts_exts.h
+++ b/src/mesa/main/consts_exts.h
@@ -223,6 +223,7 @@ struct gl_extensions
GLboolean OES_texture_cube_map_array;
GLboolean OES_texture_view;
GLboolean OES_viewport_array;
+ GLboolean OVR_multiview;
/* vendor extensions */
GLboolean AMD_compressed_ATC_texture;
GLboolean AMD_framebuffer_multisample_advanced;
diff --git a/src/mesa/main/extensions_table.h b/src/mesa/main/extensions_table.h
index 433ced540a5..00ff007d2a1 100644
--- a/src/mesa/main/extensions_table.h
+++ b/src/mesa/main/extensions_table.h
@@ -505,7 +505,7 @@ EXT(OES_texture_view , OES_texture_view
EXT(OES_vertex_array_object , dummy_true , x , x , ES1, ES2, 2010)
EXT(OES_vertex_half_float , ARB_half_float_vertex , x , x , x , ES2, 2005)
EXT(OES_viewport_array , OES_viewport_array , x , x , x , 31, 2010)
-
+EXT(OVR_multiview , OVR_multiview , GLL, GLC, x , 30, 2018)
EXT(S3_s3tc , ANGLE_texture_compression_dxt , GLL, GLC, x , x , 1999)
EXT(SGIS_generate_mipmap , dummy_true , GLL, x , x , x , 1997)
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 8a7d9d876a4..fef538a8c14 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -57,6 +57,7 @@
#include "state_tracker/st_context.h"
#include "state_tracker/st_format.h"
#include "state_tracker/st_util.h"
+#include "util/u_debug.h"
/**
* Notes:
@@ -447,6 +448,7 @@ render_texture(struct gl_context *ctx,
rb->rtt_slice = att->Zoffset;
rb->rtt_layered = att->Layered;
rb->rtt_nr_samples = att->NumSamples;
+ rb->rtt_numviews = att->NumViews;
pipe_resource_reference(&rb->texture, pt);
_mesa_update_renderbuffer_surface(ctx, rb);
@@ -602,7 +604,7 @@ set_texture_attachment(struct gl_context *ctx,
struct gl_renderbuffer_attachment *att,
struct gl_texture_object *texObj,
GLenum texTarget, GLuint level, GLsizei samples,
- GLuint layer, GLboolean layered)
+ GLuint layer, GLboolean layered, GLint numviews)
{
struct gl_renderbuffer *rb = att->Renderbuffer;
@@ -629,6 +631,7 @@ set_texture_attachment(struct gl_context *ctx,
att->Zoffset = layer;
att->Layered = layered;
att->Complete = GL_FALSE;
+ att->NumViews = numviews;
_mesa_update_texture_renderbuffer(ctx, fb, att);
}
@@ -3720,6 +3723,47 @@ check_layered_texture_target(struct gl_context *ctx, GLenum target,
}
+/**
+ * Common code called by gl*FramebufferTextureMultiviewOVR() to verify the texture target
+ *
+ * \return true if no errors, false if errors
+ */
+static bool
+check_multiview_texture_target(struct gl_context *ctx, GLuint texture, GLenum target, GLint level,
+ GLint baseViewIndex, GLsizei numViews, const char *caller)
+{
+ bool ret = true;
+ if (target != GL_TEXTURE_2D_ARRAY)
+ {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(invalid texture target %s), only 2D_ARRAY is supported", caller,
+ _mesa_enum_to_string(target));
+ ret = false;
+ }
+ else if (level > 0)
+ {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(invalid texture target %s), multisample is supported by OVR_multiview2", caller,
+ _mesa_enum_to_string(target));
+ ret = false;
+ }
+ else if ((numViews > MAX_VIEWS_OVR) || (numViews <= 0))
+ {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s numViews is less than 1 or greater than MAX_VIEWS_OVR)", caller);
+ ret = false;
+ }
+ else if ((texture > 0) && (baseViewIndex < 0))
+ {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s baseViewIndex is less than 0)", caller);
+ ret = false;
+ }
+
+ return ret;
+}
+
+
/**
* Common code called by gl*FramebufferTextureLayer() to verify the texture
* target.
@@ -3962,7 +4006,7 @@ _mesa_framebuffer_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
struct gl_renderbuffer_attachment *att,
struct gl_texture_object *texObj, GLenum textarget,
GLint level, GLsizei samples,
- GLuint layer, GLboolean layered)
+ GLuint layer, GLboolean layered, GLsizei numviews)
{
FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0);
@@ -3994,7 +4038,7 @@ _mesa_framebuffer_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
BUFFER_DEPTH);
} else {
set_texture_attachment(ctx, fb, att, texObj, textarget,
- level, samples, layer, layered);
+ level, samples, layer, layered, numviews);
if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
/* Above we created a new renderbuffer and attached it to the
@@ -4049,7 +4093,7 @@ framebuffer_texture_with_dims_no_error(GLenum target, GLenum attachment,
get_attachment(ctx, fb, attachment, NULL);
_mesa_framebuffer_texture(ctx, fb, attachment, att, texObj, textarget,
- level, 0, layer, GL_FALSE);
+ level, 0, layer, GL_FALSE, 0);
}
@@ -4096,7 +4140,7 @@ framebuffer_texture_with_dims(int dims, GLenum target, GLuint framebuffer,
return;
_mesa_framebuffer_texture(ctx, fb, attachment, att, texObj, textarget,
- level, samples, layer, GL_FALSE);
+ level, samples, layer, GL_FALSE, 0);
}
@@ -4174,7 +4218,7 @@ static ALWAYS_INLINE void
frame_buffer_texture(GLuint framebuffer, GLenum target,
GLenum attachment, GLuint texture,
GLint level, GLint layer, const char *func,
- bool dsa, bool no_error, bool check_layered)
+ bool dsa, bool no_error, bool check_layered, GLsizei numviews)
{
GET_CURRENT_CONTEXT(ctx);
GLboolean layered = GL_FALSE;
@@ -4235,6 +4279,16 @@ frame_buffer_texture(GLuint framebuffer, GLenum target,
return;
}
+ if (numviews > 1) {
+ /* We do this regardless of no_error because this sets multiviews */
+ if (!check_multiview_texture_target(ctx, texture, texObj->Target, level, layer, numviews, func))
+ {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)",
+ func, _mesa_enum_to_string(target));
+ return;
+ }
+ }
+
if (!no_error) {
if (!check_layered) {
if (!check_texture_target(ctx, texObj->Target, func))
@@ -4256,16 +4310,17 @@ frame_buffer_texture(GLuint framebuffer, GLenum target,
}
_mesa_framebuffer_texture(ctx, fb, attachment, att, texObj, textarget,
- level, 0, layer, layered);
+ level, 0, layer, layered, numviews);
}
+
void GLAPIENTRY
_mesa_FramebufferTextureLayer_no_error(GLenum target, GLenum attachment,
GLuint texture, GLint level,
GLint layer)
{
frame_buffer_texture(0, target, attachment, texture, level, layer,
- "glFramebufferTextureLayer", false, true, false);
+ "glFramebufferTextureLayer", false, true, false, 0);
}
@@ -4274,7 +4329,7 @@ _mesa_FramebufferTextureLayer(GLenum target, GLenum attachment,
GLuint texture, GLint level, GLint layer)
{
frame_buffer_texture(0, target, attachment, texture, level, layer,
- "glFramebufferTextureLayer", false, false, false);
+ "glFramebufferTextureLayer", false, false, false, 0);
}
@@ -4285,7 +4340,7 @@ _mesa_NamedFramebufferTextureLayer_no_error(GLuint framebuffer,
GLint layer)
{
frame_buffer_texture(framebuffer, 0, attachment, texture, level, layer,
- "glNamedFramebufferTextureLayer", true, true, false);
+ "glNamedFramebufferTextureLayer", true, true, false, 0);
}
@@ -4294,7 +4349,47 @@ _mesa_NamedFramebufferTextureLayer(GLuint framebuffer, GLenum attachment,
GLuint texture, GLint level, GLint layer)
{
frame_buffer_texture(framebuffer, 0, attachment, texture, level, layer,
- "glNamedFramebufferTextureLayer", true, false, false);
+ "glNamedFramebufferTextureLayer", true, false, false, 0);
+}
+
+
+void GLAPIENTRY
+_mesa_FramebufferTextureMultiviewOVR_no_error(GLenum target, GLenum attachment,
+ GLuint texture, GLint level,
+ GLint baseViewIndex, GLsizei numViews)
+{
+ frame_buffer_texture(0, target, attachment, texture, level, baseViewIndex,
+ "glFramebufferTexture", false, true, false, numViews);
+}
+
+
+void GLAPIENTRY
+_mesa_FramebufferTextureMultiviewOVR(GLenum target, GLenum attachment,
+ GLuint texture, GLint level,
+ GLint baseViewIndex, GLsizei numViews)
+{
+ frame_buffer_texture(0, target, attachment, texture, level, baseViewIndex,
+ "glFramebufferTexture", false, false, false, numViews);
+}
+
+
+void GLAPIENTRY
+_mesa_NamedFramebufferTextureMultiviewOVR_no_error(GLuint framebuffer, GLenum attachment,
+ GLuint texture, GLint level,
+ GLint baseViewIndex, GLsizei numViews)
+{
+ frame_buffer_texture(framebuffer, 0, attachment, texture, level, baseViewIndex,
+ "glFramebufferTexture", true, true, false, numViews);
+}
+
+
+void GLAPIENTRY
+_mesa_NamedFramebufferTextureMultiviewOVR(GLuint framebuffer, GLenum attachment,
+ GLuint texture, GLint level,
+ GLint baseViewIndex, GLsizei numViews)
+{
+ frame_buffer_texture(framebuffer, 0, attachment, texture, level, baseViewIndex,
+ "glFramebufferTexture", true, false, false, numViews);
}
@@ -4303,7 +4398,7 @@ _mesa_FramebufferTexture_no_error(GLenum target, GLenum attachment,
GLuint texture, GLint level)
{
frame_buffer_texture(0, target, attachment, texture, level, 0,
- "glFramebufferTexture", false, true, true);
+ "glFramebufferTexture", false, true, true, 0);
}
@@ -4312,7 +4407,7 @@ _mesa_FramebufferTexture(GLenum target, GLenum attachment,
GLuint texture, GLint level)
{
frame_buffer_texture(0, target, attachment, texture, level, 0,
- "glFramebufferTexture", false, false, true);
+ "glFramebufferTexture", false, false, true, 0);
}
void GLAPIENTRY
@@ -4320,7 +4415,7 @@ _mesa_NamedFramebufferTexture_no_error(GLuint framebuffer, GLenum attachment,
GLuint texture, GLint level)
{
frame_buffer_texture(framebuffer, 0, attachment, texture, level, 0,
- "glNamedFramebufferTexture", true, true, true);
+ "glNamedFramebufferTexture", true, true, true, 0);
}
@@ -4329,7 +4424,7 @@ _mesa_NamedFramebufferTexture(GLuint framebuffer, GLenum attachment,
GLuint texture, GLint level)
{
frame_buffer_texture(framebuffer, 0, attachment, texture, level, 0,
- "glNamedFramebufferTexture", true, false, true);
+ "glNamedFramebufferTexture", true, false, true, 0);
}
diff --git a/src/mesa/main/fbobject.h b/src/mesa/main/fbobject.h
index 7dedf1006ea..b36445f0446 100644
--- a/src/mesa/main/fbobject.h
+++ b/src/mesa/main/fbobject.h
@@ -122,7 +122,7 @@ _mesa_framebuffer_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
struct gl_renderbuffer_attachment *att,
struct gl_texture_object *texObj, GLenum textarget,
GLint level, GLsizei samples,
- GLuint layer, GLboolean layered);
+ GLuint layer, GLboolean layered, GLsizei numviews);
extern GLenum
_mesa_check_framebuffer_status(struct gl_context *ctx,
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index cd6788da78f..9924eeee613 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2556,6 +2556,7 @@ struct gl_renderbuffer
unsigned rtt_face, rtt_slice;
bool rtt_layered; /**< whether glFramebufferTexture was called */
unsigned rtt_nr_samples; /**< from FramebufferTexture2DMultisampleEXT */
+ unsigned rtt_numviews;
};
@@ -2585,6 +2586,7 @@ struct gl_renderbuffer_attachment
GLuint Zoffset; /**< Slice for 3D textures, or layer for both 1D
* and 2D array textures */
GLboolean Layered;
+ GLsizei NumViews;
};
diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c
index dd3d7da4af6..af15081fe1c 100644
--- a/src/mesa/main/renderbuffer.c
+++ b/src/mesa/main/renderbuffer.c
@@ -606,7 +606,10 @@ _mesa_update_renderbuffer_surface(struct gl_context *ctx,
/* determine the layer bounds */
unsigned first_layer, last_layer;
- if (rb->rtt_layered) {
+ if (rb->rtt_numviews) {
+ first_layer = rb->rtt_slice;
+ last_layer = first_layer + rb->rtt_numviews - 1;
+ } else if (rb->rtt_layered) {
first_layer = 0;
last_layer = util_max_layer(rb->texture, level);
}
diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c
index 16542bbb2a8..4f831a30cfb 100644
--- a/src/mesa/state_tracker/st_atom_framebuffer.c
+++ b/src/mesa/state_tracker/st_atom_framebuffer.c
@@ -111,7 +111,7 @@ void
st_update_framebuffer_state( struct st_context *st )
{
struct gl_context *ctx = st->ctx;
- struct pipe_framebuffer_state framebuffer;
+ struct pipe_framebuffer_state framebuffer = {0};
struct gl_framebuffer *fb = st->ctx->DrawBuffer;
struct gl_renderbuffer *rb;
GLuint i;
@@ -146,6 +146,8 @@ st_update_framebuffer_state( struct st_context *st )
*/
framebuffer.nr_cbufs = fb->_NumColorDrawBuffers;
+ unsigned num_multiview_layer = 0;
+ unsigned first_multiview_layer = 0;
for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
framebuffer.cbufs[i] = NULL;
rb = fb->_ColorDrawBuffers[i];
@@ -156,6 +158,11 @@ st_update_framebuffer_state( struct st_context *st )
/* rendering to a GL texture, may have to update surface */
_mesa_update_renderbuffer_surface(ctx, rb);
+
+ if (rb->rtt_numviews) {
+ first_multiview_layer = rb->rtt_slice;
+ num_multiview_layer = MAX2(num_multiview_layer, rb->rtt_numviews);
+ }
}
if (rb->surface) {
@@ -168,6 +175,8 @@ st_update_framebuffer_state( struct st_context *st )
rb->defined = GL_TRUE; /* we'll be drawing something */
}
}
+ if (num_multiview_layer)
+ framebuffer.viewmask = BITFIELD_RANGE(first_multiview_layer, num_multiview_layer);
for (i = framebuffer.nr_cbufs; i < PIPE_MAX_COLOR_BUFS; i++) {
framebuffer.cbufs[i] = NULL;