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;