mesa,glsl,gallium: add GL_OVR_multiview

Co-authored-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31128>
This commit is contained in:
Marek Olšák
2024-07-09 07:13:19 -04:00
committed by Marge Bot
parent a5a2f82149
commit 328c29d600
22 changed files with 243 additions and 20 deletions

View File

@@ -607,6 +607,12 @@ struct ast_type_qualifier {
unsigned explicit_xfb_stride:1; /**< xfb_stride value assigned explicitly by shader code */ 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 */ /** \name Layout qualifiers for GL_ARB_tessellation_shader */
/** \{ */ /** \{ */
/* tess eval input layout */ /* tess eval input layout */
@@ -745,6 +751,14 @@ struct ast_type_qualifier {
*/ */
ast_expression *binding; 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 * Offset specified via GL_ARB_shader_atomic_counter's or
* GL_ARB_enhanced_layouts "offset" keyword, or by GL_ARB_enhanced_layouts * GL_ARB_enhanced_layouts "offset" keyword, or by GL_ARB_enhanced_layouts

View File

@@ -84,7 +84,8 @@ ast_type_qualifier::has_layout() const
|| this->flags.q.explicit_stream || this->flags.q.explicit_stream
|| this->flags.q.explicit_xfb_buffer || this->flags.q.explicit_xfb_buffer
|| this->flags.q.explicit_xfb_offset || this->flags.q.explicit_xfb_offset
|| this->flags.q.explicit_xfb_stride; || this->flags.q.explicit_xfb_stride
|| this->flags.q.explicit_numviews;
} }
bool bool
@@ -186,6 +187,26 @@ validate_point_mode(ASSERTED const ast_type_qualifier &qualifier,
return true; 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 static void
merge_bindless_qualifier(_mesa_glsl_parse_state *state) 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.sample = 1;
input_layout_mask.flags.q.smooth = 1; input_layout_mask.flags.q.smooth = 1;
input_layout_mask.flags.q.non_coherent = 1; input_layout_mask.flags.q.non_coherent = 1;
input_layout_mask.flags.q.explicit_numviews = 1;
if (state->has_bindless()) { if (state->has_bindless()) {
/* Allow to use image qualifiers with shader inputs/outputs. */ /* 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; 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; return r;
} }
@@ -603,6 +637,12 @@ ast_type_qualifier::validate_in_qualifier(YYLTYPE *loc,
valid_in_mask.flags.i = 0; valid_in_mask.flags.i = 0;
switch (state->stage) { 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: case MESA_SHADER_TESS_EVAL:
if (this->flags.q.prim_type) { if (this->flags.q.prim_type) {
/* Make sure this is a valid input primitive 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.early_fragment_tests = false;
} }
state->in_qualifier->flags.q.explicit_numviews = false;
if (state->in_qualifier->flags.q.inner_coverage) { if (state->in_qualifier->flags.q.inner_coverage) {
state->fs_inner_coverage = true; state->fs_inner_coverage = true;
state->in_qualifier->flags.q.inner_coverage = false; 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(explicit_xfb_buffer, xfb_buffer);
Q2(xfb_stride, xfb_stride); Q2(xfb_stride, xfb_stride);
Q2(explicit_xfb_stride, xfb_stride); Q2(explicit_xfb_stride, xfb_stride);
Q2(explicit_numviews, num_views);
Q(vertex_spacing); Q(vertex_spacing);
Q(ordering); Q(ordering);
Q(point_mode); Q(point_mode);

View File

@@ -1144,6 +1144,10 @@ builtin_variable_generator::generate_vs_special_vars()
add_system_value(SYSTEM_VALUE_VERTEX_ID, int_t, GLSL_PRECISION_HIGH, add_system_value(SYSTEM_VALUE_VERTEX_ID, int_t, GLSL_PRECISION_HIGH,
"gl_VertexID"); "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)) { if (state->is_version(460, 0)) {
add_system_value(SYSTEM_VALUE_BASE_VERTEX, int_t, "gl_BaseVertex"); add_system_value(SYSTEM_VALUE_BASE_VERTEX, int_t, "gl_BaseVertex");
add_system_value(SYSTEM_VALUE_BASE_INSTANCE, int_t, "gl_BaseInstance"); add_system_value(SYSTEM_VALUE_BASE_INSTANCE, int_t, "gl_BaseInstance");

View File

@@ -1765,6 +1765,11 @@ layout_qualifier_id:
$$.location = $3; $$.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 (match_layout_qualifier("component", $1, state) == 0) {
if (!state->has_enhanced_layouts()) { if (!state->has_enhanced_layouts()) {
_mesa_glsl_error(& @1, state, _mesa_glsl_error(& @1, state,

View File

@@ -846,6 +846,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
EXT(NV_shader_atomic_int64), EXT(NV_shader_atomic_int64),
EXT(NV_shader_noperspective_interpolation), EXT(NV_shader_noperspective_interpolation),
EXT(NV_viewport_array2), EXT(NV_viewport_array2),
EXT(OVR_multiview),
}; };
#undef EXT #undef EXT

View File

@@ -934,6 +934,8 @@ struct _mesa_glsl_parse_state {
bool NV_shader_noperspective_interpolation_warn; bool NV_shader_noperspective_interpolation_warn;
bool NV_viewport_array2_enable; bool NV_viewport_array2_enable;
bool NV_viewport_array2_warn; bool NV_viewport_array2_warn;
bool OVR_multiview_enable;
bool OVR_multiview_warn;
/*@}*/ /*@}*/
/** Extensions supported by the OpenGL implementation. */ /** Extensions supported by the OpenGL implementation. */

View File

@@ -106,6 +106,7 @@ util_copy_framebuffer_state(struct pipe_framebuffer_state *dst,
dst->nr_cbufs = src->nr_cbufs; dst->nr_cbufs = src->nr_cbufs;
dst->viewmask = src->viewmask;
pipe_surface_reference(&dst->zsbuf, src->zsbuf); pipe_surface_reference(&dst->zsbuf, src->zsbuf);
pipe_resource_reference(&dst->resolve, src->resolve); pipe_resource_reference(&dst->resolve, src->resolve);
} else { } else {
@@ -120,6 +121,8 @@ util_copy_framebuffer_state(struct pipe_framebuffer_state *dst,
dst->nr_cbufs = 0; dst->nr_cbufs = 0;
dst->viewmask = 0;
pipe_surface_reference(&dst->zsbuf, NULL); pipe_surface_reference(&dst->zsbuf, NULL);
pipe_resource_reference(&dst->resolve, 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->samples = fb->layers = 0;
fb->width = fb->height = 0; fb->width = fb->height = 0;
fb->nr_cbufs = 0; fb->nr_cbufs = 0;
fb->viewmask = 0;
} }

View File

@@ -1524,6 +1524,7 @@ tc_set_framebuffer_state(struct pipe_context *_pipe,
p->state.samples = fb->samples; p->state.samples = fb->samples;
p->state.layers = fb->layers; p->state.layers = fb->layers;
p->state.nr_cbufs = nr_cbufs; p->state.nr_cbufs = nr_cbufs;
p->state.viewmask = fb->viewmask;
/* when unbinding, mark attachments as used for the current batch */ /* when unbinding, mark attachments as used for the current batch */
for (unsigned i = 0; i < tc->nr_cbufs; i++) { for (unsigned i = 0; i < tc->nr_cbufs; i++) {

View File

@@ -403,6 +403,8 @@ struct pipe_framebuffer_state
/** multiple color buffers for multiple render targets */ /** multiple color buffers for multiple render targets */
uint8_t nr_cbufs; uint8_t nr_cbufs;
/** used for multiview */
uint8_t viewmask;
struct pipe_surface *cbufs[PIPE_MAX_COLOR_BUFS]; struct pipe_surface *cbufs[PIPE_MAX_COLOR_BUFS];
struct pipe_surface *zsbuf; /**< Z/stencil buffer */ struct pipe_surface *zsbuf; /**< Z/stencil buffer */

View File

@@ -332,6 +332,7 @@ glFramebufferTexture3D
glFramebufferTexture3DEXT glFramebufferTexture3DEXT
glFramebufferTextureLayer glFramebufferTextureLayer
glFramebufferTextureLayerEXT glFramebufferTextureLayerEXT
glFramebufferTextureMultiviewOVR
glFrontFace glFrontFace
glFrustum glFrustum
glFrustumf glFrustumf

View File

@@ -0,0 +1,26 @@
<?xml version="1.0"?>
<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
<OpenGLAPI>
<category name="GL_OVR_multiview">
<function name="FramebufferTextureMultiviewOVR" es2="3.0" desktop="true" no_error="true">
<param name="target" type="GLenum"/>
<param name="attachment" type="GLenum"/>
<param name="texture" type="GLuint"/>
<param name="level" type="GLint"/>
<param name="baseviewindex" type="GLint"/>
<param name="numviews" type="GLsizei"/>
</function>
<function name="NamedFramebufferTextureMultiviewOVR" es2="3.0" desktop="true" no_error="true">
<param name="framebuffer" type="GLuint"/>
<param name="attachment" type="GLenum"/>
<param name="texture" type="GLuint"/>
<param name="level" type="GLint"/>
<param name="baseviewindex" type="GLint"/>
<param name="numviews" type="GLsizei"/>
</function>
</category>
</OpenGLAPI>

View File

@@ -8062,6 +8062,8 @@
<xi:include href="ARB_framebuffer_object.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="ARB_framebuffer_object.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="OVR_multiview.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<!-- 46. GL_ARB_framebuffer_sRGB --> <!-- 46. GL_ARB_framebuffer_sRGB -->
<!-- 47. GL_ARB_geometry_shader4. There are no intentions to implement this extension --> <!-- 47. GL_ARB_geometry_shader4. There are no intentions to implement this extension -->

View File

@@ -131,6 +131,7 @@ api_xml_files = files(
'OES_fixed_point.xml', 'OES_fixed_point.xml',
'OES_single_precision.xml', 'OES_single_precision.xml',
'OES_texture_compression_astc.xml', 'OES_texture_compression_astc.xml',
'OVR_multiview.xml',
'GL3x.xml', 'GL3x.xml',
'GL4x.xml', 'GL4x.xml',
) )

View File

@@ -1708,6 +1708,8 @@ offsets = {
"DrawElementsUserBufPacked": 1672, "DrawElementsUserBufPacked": 1672,
"TexStorageAttribs2DEXT": 1673, "TexStorageAttribs2DEXT": 1673,
"TexStorageAttribs3DEXT": 1674, "TexStorageAttribs3DEXT": 1674,
"FramebufferTextureMultiviewOVR": 1675,
"NamedFramebufferTextureMultiviewOVR": 1676,
} }
functions = [ functions = [
@@ -2035,6 +2037,7 @@ functions = [
"FramebufferTextureLayer", "FramebufferTextureLayer",
"FramebufferTextureLayerARB", "FramebufferTextureLayerARB",
"FramebufferTextureLayerEXT", "FramebufferTextureLayerEXT",
"FramebufferTextureMultiviewOVR",
"FrontFace", "FrontFace",
"Frustum", "Frustum",
"Frustumf", "Frustumf",

View File

@@ -145,6 +145,9 @@
/** For GL_EXT_texture_lod_bias (typically MAX_TEXTURE_LEVELS - 1) */ /** For GL_EXT_texture_lod_bias (typically MAX_TEXTURE_LEVELS - 1) */
#define MAX_TEXTURE_LOD_BIAS 14.0 #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 */ /** For any program target/extension */
/*@{*/ /*@{*/
#define MAX_PROGRAM_INSTRUCTIONS (16 * 1024) #define MAX_PROGRAM_INSTRUCTIONS (16 * 1024)

View File

@@ -223,6 +223,7 @@ struct gl_extensions
GLboolean OES_texture_cube_map_array; GLboolean OES_texture_cube_map_array;
GLboolean OES_texture_view; GLboolean OES_texture_view;
GLboolean OES_viewport_array; GLboolean OES_viewport_array;
GLboolean OVR_multiview;
/* vendor extensions */ /* vendor extensions */
GLboolean AMD_compressed_ATC_texture; GLboolean AMD_compressed_ATC_texture;
GLboolean AMD_framebuffer_multisample_advanced; GLboolean AMD_framebuffer_multisample_advanced;

View File

@@ -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_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_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(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(S3_s3tc , ANGLE_texture_compression_dxt , GLL, GLC, x , x , 1999)
EXT(SGIS_generate_mipmap , dummy_true , GLL, x , x , x , 1997) EXT(SGIS_generate_mipmap , dummy_true , GLL, x , x , x , 1997)

View File

@@ -57,6 +57,7 @@
#include "state_tracker/st_context.h" #include "state_tracker/st_context.h"
#include "state_tracker/st_format.h" #include "state_tracker/st_format.h"
#include "state_tracker/st_util.h" #include "state_tracker/st_util.h"
#include "util/u_debug.h"
/** /**
* Notes: * Notes:
@@ -447,6 +448,7 @@ render_texture(struct gl_context *ctx,
rb->rtt_slice = att->Zoffset; rb->rtt_slice = att->Zoffset;
rb->rtt_layered = att->Layered; rb->rtt_layered = att->Layered;
rb->rtt_nr_samples = att->NumSamples; rb->rtt_nr_samples = att->NumSamples;
rb->rtt_numviews = att->NumViews;
pipe_resource_reference(&rb->texture, pt); pipe_resource_reference(&rb->texture, pt);
_mesa_update_renderbuffer_surface(ctx, rb); _mesa_update_renderbuffer_surface(ctx, rb);
@@ -602,7 +604,7 @@ set_texture_attachment(struct gl_context *ctx,
struct gl_renderbuffer_attachment *att, struct gl_renderbuffer_attachment *att,
struct gl_texture_object *texObj, struct gl_texture_object *texObj,
GLenum texTarget, GLuint level, GLsizei samples, GLenum texTarget, GLuint level, GLsizei samples,
GLuint layer, GLboolean layered) GLuint layer, GLboolean layered, GLint numviews)
{ {
struct gl_renderbuffer *rb = att->Renderbuffer; struct gl_renderbuffer *rb = att->Renderbuffer;
@@ -629,6 +631,7 @@ set_texture_attachment(struct gl_context *ctx,
att->Zoffset = layer; att->Zoffset = layer;
att->Layered = layered; att->Layered = layered;
att->Complete = GL_FALSE; att->Complete = GL_FALSE;
att->NumViews = numviews;
_mesa_update_texture_renderbuffer(ctx, fb, att); _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 * Common code called by gl*FramebufferTextureLayer() to verify the texture
* target. * target.
@@ -3962,7 +4006,7 @@ _mesa_framebuffer_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
struct gl_renderbuffer_attachment *att, struct gl_renderbuffer_attachment *att,
struct gl_texture_object *texObj, GLenum textarget, struct gl_texture_object *texObj, GLenum textarget,
GLint level, GLsizei samples, GLint level, GLsizei samples,
GLuint layer, GLboolean layered) GLuint layer, GLboolean layered, GLsizei numviews)
{ {
FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0); FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0);
@@ -3994,7 +4038,7 @@ _mesa_framebuffer_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
BUFFER_DEPTH); BUFFER_DEPTH);
} else { } else {
set_texture_attachment(ctx, fb, att, texObj, textarget, set_texture_attachment(ctx, fb, att, texObj, textarget,
level, samples, layer, layered); level, samples, layer, layered, numviews);
if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
/* Above we created a new renderbuffer and attached it to the /* 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); get_attachment(ctx, fb, attachment, NULL);
_mesa_framebuffer_texture(ctx, fb, attachment, att, texObj, textarget, _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; return;
_mesa_framebuffer_texture(ctx, fb, attachment, att, texObj, textarget, _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, frame_buffer_texture(GLuint framebuffer, GLenum target,
GLenum attachment, GLuint texture, GLenum attachment, GLuint texture,
GLint level, GLint layer, const char *func, 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); GET_CURRENT_CONTEXT(ctx);
GLboolean layered = GL_FALSE; GLboolean layered = GL_FALSE;
@@ -4235,6 +4279,16 @@ frame_buffer_texture(GLuint framebuffer, GLenum target,
return; 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 (!no_error) {
if (!check_layered) { if (!check_layered) {
if (!check_texture_target(ctx, texObj->Target, func)) 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, _mesa_framebuffer_texture(ctx, fb, attachment, att, texObj, textarget,
level, 0, layer, layered); level, 0, layer, layered, numviews);
} }
void GLAPIENTRY void GLAPIENTRY
_mesa_FramebufferTextureLayer_no_error(GLenum target, GLenum attachment, _mesa_FramebufferTextureLayer_no_error(GLenum target, GLenum attachment,
GLuint texture, GLint level, GLuint texture, GLint level,
GLint layer) GLint layer)
{ {
frame_buffer_texture(0, target, attachment, texture, level, 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) GLuint texture, GLint level, GLint layer)
{ {
frame_buffer_texture(0, target, attachment, texture, level, 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) GLint layer)
{ {
frame_buffer_texture(framebuffer, 0, attachment, texture, level, 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) GLuint texture, GLint level, GLint layer)
{ {
frame_buffer_texture(framebuffer, 0, attachment, texture, level, 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) GLuint texture, GLint level)
{ {
frame_buffer_texture(0, target, attachment, texture, level, 0, 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) GLuint texture, GLint level)
{ {
frame_buffer_texture(0, target, attachment, texture, level, 0, frame_buffer_texture(0, target, attachment, texture, level, 0,
"glFramebufferTexture", false, false, true); "glFramebufferTexture", false, false, true, 0);
} }
void GLAPIENTRY void GLAPIENTRY
@@ -4320,7 +4415,7 @@ _mesa_NamedFramebufferTexture_no_error(GLuint framebuffer, GLenum attachment,
GLuint texture, GLint level) GLuint texture, GLint level)
{ {
frame_buffer_texture(framebuffer, 0, attachment, texture, level, 0, 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) GLuint texture, GLint level)
{ {
frame_buffer_texture(framebuffer, 0, attachment, texture, level, 0, frame_buffer_texture(framebuffer, 0, attachment, texture, level, 0,
"glNamedFramebufferTexture", true, false, true); "glNamedFramebufferTexture", true, false, true, 0);
} }

View File

@@ -122,7 +122,7 @@ _mesa_framebuffer_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
struct gl_renderbuffer_attachment *att, struct gl_renderbuffer_attachment *att,
struct gl_texture_object *texObj, GLenum textarget, struct gl_texture_object *texObj, GLenum textarget,
GLint level, GLsizei samples, GLint level, GLsizei samples,
GLuint layer, GLboolean layered); GLuint layer, GLboolean layered, GLsizei numviews);
extern GLenum extern GLenum
_mesa_check_framebuffer_status(struct gl_context *ctx, _mesa_check_framebuffer_status(struct gl_context *ctx,

View File

@@ -2556,6 +2556,7 @@ struct gl_renderbuffer
unsigned rtt_face, rtt_slice; unsigned rtt_face, rtt_slice;
bool rtt_layered; /**< whether glFramebufferTexture was called */ bool rtt_layered; /**< whether glFramebufferTexture was called */
unsigned rtt_nr_samples; /**< from FramebufferTexture2DMultisampleEXT */ 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 GLuint Zoffset; /**< Slice for 3D textures, or layer for both 1D
* and 2D array textures */ * and 2D array textures */
GLboolean Layered; GLboolean Layered;
GLsizei NumViews;
}; };

View File

@@ -606,7 +606,10 @@ _mesa_update_renderbuffer_surface(struct gl_context *ctx,
/* determine the layer bounds */ /* determine the layer bounds */
unsigned first_layer, last_layer; 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; first_layer = 0;
last_layer = util_max_layer(rb->texture, level); last_layer = util_max_layer(rb->texture, level);
} }

View File

@@ -111,7 +111,7 @@ void
st_update_framebuffer_state( struct st_context *st ) st_update_framebuffer_state( struct st_context *st )
{ {
struct gl_context *ctx = st->ctx; 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_framebuffer *fb = st->ctx->DrawBuffer;
struct gl_renderbuffer *rb; struct gl_renderbuffer *rb;
GLuint i; GLuint i;
@@ -146,6 +146,8 @@ st_update_framebuffer_state( struct st_context *st )
*/ */
framebuffer.nr_cbufs = fb->_NumColorDrawBuffers; framebuffer.nr_cbufs = fb->_NumColorDrawBuffers;
unsigned num_multiview_layer = 0;
unsigned first_multiview_layer = 0;
for (i = 0; i < fb->_NumColorDrawBuffers; i++) { for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
framebuffer.cbufs[i] = NULL; framebuffer.cbufs[i] = NULL;
rb = fb->_ColorDrawBuffers[i]; 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 */ /* rendering to a GL texture, may have to update surface */
_mesa_update_renderbuffer_surface(ctx, rb); _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) { if (rb->surface) {
@@ -168,6 +175,8 @@ st_update_framebuffer_state( struct st_context *st )
rb->defined = GL_TRUE; /* we'll be drawing something */ 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++) { for (i = framebuffer.nr_cbufs; i < PIPE_MAX_COLOR_BUFS; i++) {
framebuffer.cbufs[i] = NULL; framebuffer.cbufs[i] = NULL;