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 */
/** \} */
/**
* 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

View File

@@ -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);

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,
"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");

View File

@@ -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,

View File

@@ -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

View File

@@ -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. */

View File

@@ -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;
}

View File

@@ -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++) {

View File

@@ -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 */

View File

@@ -332,6 +332,7 @@ glFramebufferTexture3D
glFramebufferTexture3DEXT
glFramebufferTextureLayer
glFramebufferTextureLayerEXT
glFramebufferTextureMultiviewOVR
glFrontFace
glFrustum
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="OVR_multiview.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<!-- 46. GL_ARB_framebuffer_sRGB -->
<!-- 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_single_precision.xml',
'OES_texture_compression_astc.xml',
'OVR_multiview.xml',
'GL3x.xml',
'GL4x.xml',
)

View File

@@ -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",

View File

@@ -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)

View File

@@ -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;

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_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)

View File

@@ -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);
}

View File

@@ -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,

View File

@@ -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;
};

View File

@@ -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);
}

View File

@@ -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;