nouveau_context.c revision c25fcf5aa5beccd7731706b8f85682170a2eca56
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright (C) 2009-2010 Francisco Jerez.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * All Rights Reserved.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Permission is hereby granted, free of charge, to any person obtaining
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * a copy of this software and associated documentation files (the
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * "Software"), to deal in the Software without restriction, including
8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * without limitation the rights to use, copy, modify, merge, publish,
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * distribute, sublicense, and/or sell copies of the Software, and to
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * permit persons to whom the Software is furnished to do so, subject to
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * the following conditions:
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *
13948639b823dc76dbaa8cc68f32c1f7defcb8fb07mike@reedtribe.org * The above copyright notice and this permission notice (including the
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * next paragraph) shall be included in all copies or substantial
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * portions of the Software.
16c07d23a6e220c0aff36e3e4e06c1b685a440108ereed@android.com *
17045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *
2599219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org */
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "nouveau_driver.h"
2899219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org#include "nouveau_context.h"
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "nouveau_bufferobj.h"
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "nouveau_fbo.h"
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "main/dd.h"
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "main/framebuffer.h"
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "main/light.h"
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "main/state.h"
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "drivers/common/meta.h"
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "drivers/common/driverfuncs.h"
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "swrast/swrast.h"
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "swrast/s_context.h"
4099219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org#include "vbo/vbo.h"
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "tnl/tnl.h"
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "tnl/t_context.h"
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define need_GL_EXT_framebuffer_object
4599219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org#define need_GL_EXT_fog_coord
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define need_GL_EXT_secondary_color
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "main/remap_helper.h"
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const struct dri_extension nouveau_extensions[] = {
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	{ "GL_ARB_multitexture",	NULL },
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	{ "GL_ARB_texture_env_add",	NULL },
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	{ "GL_ARB_texture_mirrored_repeat", NULL },
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	{ "GL_EXT_fog_coord",		GL_EXT_fog_coord_functions },
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	{ "GL_EXT_framebuffer_blit",	NULL },
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	{ "GL_EXT_framebuffer_object",	GL_EXT_framebuffer_object_functions },
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	{ "GL_EXT_packed_depth_stencil", NULL},
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	{ "GL_EXT_secondary_color",	GL_EXT_secondary_color_functions },
5999219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org	{ "GL_EXT_stencil_wrap",	NULL },
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	{ "GL_EXT_texture_env_combine",	NULL },
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	{ "GL_EXT_texture_filter_anisotropic", NULL },
6299219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org	{ "GL_EXT_texture_lod_bias",	NULL },
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	{ "GL_NV_blend_square",         NULL },
6455b6b58d8f6e7529c9b9cea606a6e3637c8e2e39reed@google.com	{ "GL_NV_texture_env_combine4",	NULL },
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	{ NULL,				NULL }
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void
6999219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.orgnouveau_channel_flush_notify(struct nouveau_channel *chan)
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
7199219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org	struct nouveau_context *nctx = chan->user_private;
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	GLcontext *ctx = &nctx->base;
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	if (nctx->fallback < SWRAST)
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		nouveau_bo_state_emit(ctx);
7699219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org}
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comGLboolean
7999219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.orgnouveau_context_create(gl_api api,
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		       const __GLcontextModes *visual, __DRIcontext *dri_ctx,
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		       void *share_ctx)
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	__DRIscreen *dri_screen = dri_ctx->driScreenPriv;
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	struct nouveau_screen *screen = dri_screen->private;
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	struct nouveau_context *nctx;
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	GLcontext *ctx;
8799219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org
8899219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org	ctx = screen->driver->context_create(screen, visual, share_ctx);
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	if (!ctx)
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		return GL_FALSE;
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	nctx = to_nouveau_context(ctx);
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	nctx->dri_context = dri_ctx;
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	dri_ctx->driverPrivate = ctx;
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	return GL_TRUE;
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comGLboolean
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comnouveau_context_init(GLcontext *ctx, struct nouveau_screen *screen,
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		     const GLvisual *visual, GLcontext *share_ctx)
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	struct nouveau_context *nctx = to_nouveau_context(ctx);
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	struct dd_function_table functions;
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	int ret;
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	nctx->screen = screen;
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	nctx->fallback = HWTNL;
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	/* Initialize the function pointers. */
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	_mesa_init_driver_functions(&functions);
112dca6a56b71b922aab32098d6a55bbb041f3a2b48reed@android.com	nouveau_driver_functions_init(&functions);
11399219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org	nouveau_bufferobj_functions_init(&functions);
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	nouveau_texture_functions_init(&functions);
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	nouveau_fbo_functions_init(&functions);
116dca6a56b71b922aab32098d6a55bbb041f3a2b48reed@android.com
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	/* Initialize the mesa context. */
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	_mesa_initialize_context(ctx, visual, share_ctx, &functions, NULL);
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
12099219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org	nouveau_state_init(ctx);
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	nouveau_bo_state_init(ctx);
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	_mesa_meta_init(ctx);
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	_swrast_CreateContext(ctx);
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	_vbo_CreateContext(ctx);
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	_tnl_CreateContext(ctx);
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	nouveau_span_functions_init(ctx);
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	_mesa_allow_light_in_model(ctx, GL_FALSE);
12855b6b58d8f6e7529c9b9cea606a6e3637c8e2e39reed@google.com
1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	/* Allocate a hardware channel. */
1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	ret = nouveau_channel_alloc(context_dev(ctx), 0xbeef0201, 0xbeef0202,
1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com				    512*1024, &nctx->hw.chan);
13255b6b58d8f6e7529c9b9cea606a6e3637c8e2e39reed@google.com	if (ret) {
13399219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org		nouveau_error("Error initializing the FIFO.\n");
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		return GL_FALSE;
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	}
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	nctx->hw.chan->flush_notify = nouveau_channel_flush_notify;
13899219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org	nctx->hw.chan->user_private = nctx;
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	/* Enable any supported extensions. */
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	driInitExtensions(ctx, nouveau_extensions, GL_TRUE);
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	return GL_TRUE;
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
14599219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org
1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comnouveau_context_deinit(GLcontext *ctx)
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	struct nouveau_context *nctx = to_nouveau_context(ctx);
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	if (TNL_CONTEXT(ctx))
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		_tnl_DestroyContext(ctx);
15399219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org
15499219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org	if (vbo_context(ctx))
15599219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org		_vbo_DestroyContext(ctx);
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
15755b6b58d8f6e7529c9b9cea606a6e3637c8e2e39reed@google.com	if (SWRAST_CONTEXT(ctx))
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		_swrast_DestroyContext(ctx);
1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	if (ctx->Meta)
16199219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org		_mesa_meta_free(ctx);
16299219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	if (nctx->hw.chan)
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		nouveau_channel_free(&nctx->hw.chan);
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	nouveau_bo_state_destroy(ctx);
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	_mesa_free_context_data(ctx);
16899219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org}
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid
1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comnouveau_context_destroy(__DRIcontext *dri_ctx)
1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
17399219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org	struct nouveau_context *nctx = dri_ctx->driverPrivate;
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	GLcontext *ctx = &nctx->base;
17599219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org
1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	context_drv(ctx)->context_destroy(ctx);
17799219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org}
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comnouveau_update_renderbuffers(__DRIcontext *dri_ctx, __DRIdrawable *draw)
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
18255b6b58d8f6e7529c9b9cea606a6e3637c8e2e39reed@google.com	GLcontext *ctx = dri_ctx->driverPrivate;
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	__DRIscreen *screen = dri_ctx->driScreenPriv;
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	struct gl_framebuffer *fb = draw->driverPrivate;
1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	struct nouveau_framebuffer *nfb = to_nouveau_framebuffer(fb);
1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	unsigned int attachments[10];
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	__DRIbuffer *buffers = NULL;
18899219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org	int i = 0, count, ret;
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
19099219d337f66cb6a8e566e1c6407bfb4b1b6cb8bmike@reedtribe.org	if (draw->lastStamp == *draw->pStamp)
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		return;
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	draw->lastStamp = *draw->pStamp;
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	if (nfb->need_front)
1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
196e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	if (fb->Visual.doubleBufferMode)
197e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		attachments[i++] = __DRI_BUFFER_BACK_LEFT;
198e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	if (fb->Visual.haveDepthBuffer && fb->Visual.haveStencilBuffer)
199e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
200e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	else if (fb->Visual.haveDepthBuffer)
201e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		attachments[i++] = __DRI_BUFFER_DEPTH;
202e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	else if (fb->Visual.haveStencilBuffer)
203e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		attachments[i++] = __DRI_BUFFER_STENCIL;
204e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com
205e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	buffers = (*screen->dri2.loader->getBuffers)(draw, &draw->w, &draw->h,
206e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com						     attachments, i, &count,
207e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com						     draw->loaderPrivate);
208e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	if (buffers == NULL)
209e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		return;
210e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com
211e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	for (i = 0; i < count; i++) {
212e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		struct gl_renderbuffer *rb;
213e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		struct nouveau_surface *s;
214e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		int index;
215e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com
216e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		switch (buffers[i].attachment) {
217e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		case __DRI_BUFFER_FRONT_LEFT:
218e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		case __DRI_BUFFER_FAKE_FRONT_LEFT:
219e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com			index = BUFFER_FRONT_LEFT;
220e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com			break;
221e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		case __DRI_BUFFER_BACK_LEFT:
222e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com			index = BUFFER_BACK_LEFT;
223e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com			break;
224e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		case __DRI_BUFFER_DEPTH:
225e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		case __DRI_BUFFER_DEPTH_STENCIL:
226e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com			index = BUFFER_DEPTH;
227e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com			break;
228e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		case __DRI_BUFFER_STENCIL:
229e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com			index = BUFFER_STENCIL;
230e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com			break;
231e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		default:
232e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com			assert(0);
233e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		}
234e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com
235e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		rb = fb->Attachment[index].Renderbuffer;
236e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		s = &to_nouveau_renderbuffer(rb)->surface;
237e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com
238e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		s->width = draw->w;
239e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		s->height = draw->h;
240e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		s->pitch = buffers[i].pitch;
241e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		s->cpp = buffers[i].cpp;
242e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com
243e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		nouveau_bo_ref(NULL, &s->bo);
244e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		ret = nouveau_bo_handle_ref(context_dev(ctx),
245e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com					    buffers[i].name, &s->bo);
246e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		assert(!ret);
247e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	}
248e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com
249e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	_mesa_resize_framebuffer(NULL, fb, draw->w, draw->h);
250e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com}
251e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com
252e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.comstatic void
253e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.comupdate_framebuffer(__DRIcontext *dri_ctx, __DRIdrawable *draw,
254e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		   int *stamp)
255e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com{
256e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	GLcontext *ctx = dri_ctx->driverPrivate;
257e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	struct gl_framebuffer *fb = draw->driverPrivate;
258e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com
259e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	*stamp = *draw->pStamp;
260e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com
261e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	nouveau_update_renderbuffers(dri_ctx, draw);
262e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	_mesa_resize_framebuffer(ctx, fb, draw->w, draw->h);
263e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com
264e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	/* Clean up references to the old framebuffer objects. */
265e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	context_dirty(ctx, FRAMEBUFFER);
266e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	context_bctx(ctx, FRAMEBUFFER);
267e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	FIRE_RING(context_chan(ctx));
268e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com}
269e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com
270e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.comGLboolean
271e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.comnouveau_context_make_current(__DRIcontext *dri_ctx, __DRIdrawable *dri_draw,
272e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com			     __DRIdrawable *dri_read)
273e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com{
274e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	if (dri_ctx) {
275e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		struct nouveau_context *nctx = dri_ctx->driverPrivate;
276e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		GLcontext *ctx = &nctx->base;
277e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com
278e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		/* Ask the X server for new renderbuffers. */
279e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		if (dri_draw->driverPrivate != ctx->WinSysDrawBuffer)
280e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com			update_framebuffer(dri_ctx, dri_draw,
281e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com					   &dri_ctx->dri2.draw_stamp);
282e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com
283e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		if (dri_draw != dri_read &&
284e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		    dri_read->driverPrivate != ctx->WinSysReadBuffer)
285e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com			update_framebuffer(dri_ctx, dri_read,
286e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com					   &dri_ctx->dri2.read_stamp);
287e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com
288e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		/* Pass it down to mesa. */
289e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		_mesa_make_current(ctx, dri_draw->driverPrivate,
290e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com				   dri_read->driverPrivate);
291e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		_mesa_update_state(ctx);
292e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com
293e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	} else {
294e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com		_mesa_make_current(NULL, NULL, NULL);
295e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	}
296e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com
297e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	return GL_TRUE;
298e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com}
299e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com
300e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.comGLboolean
301e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.comnouveau_context_unbind(__DRIcontext *dri_ctx)
302e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com{
303e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	/* Unset current context and dispath table */
304e3a83ec4e5c0abd2f5b756d7a6e7d58515969f18reed@google.com	_mesa_make_current(NULL, NULL, NULL);
3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	return GL_TRUE;
3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid
3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comnouveau_fallback(GLcontext *ctx, enum nouveau_fallback mode)
3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	struct nouveau_context *nctx = to_nouveau_context(ctx);
3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	nctx->fallback = MAX2(HWTNL, mode);
3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	if (mode < SWRAST)
3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		nouveau_state_emit(ctx);
3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	else
3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		FIRE_RING(context_chan(ctx));
3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void
3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvalidate_framebuffer(__DRIcontext *dri_ctx, __DRIdrawable *draw,
3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		     int *stamp)
3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	struct gl_framebuffer *fb = draw->driverPrivate;
3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	struct nouveau_framebuffer *nfb = to_nouveau_framebuffer(fb);
3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	GLboolean need_front =
3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		(fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT ||
3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		 fb->_ColorReadBufferIndex == BUFFER_FRONT_LEFT);
3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	if (nfb->need_front != need_front) {
3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		nfb->need_front = need_front;
3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		dri2InvalidateDrawable(draw);
3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	}
3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	if (*draw->pStamp != *stamp)
33855b6b58d8f6e7529c9b9cea606a6e3637c8e2e39reed@google.com		update_framebuffer(dri_ctx, draw, stamp);
3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid
3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comnouveau_validate_framebuffer(GLcontext *ctx)
3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	__DRIcontext *dri_ctx = to_nouveau_context(ctx)->dri_context;
3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	__DRIdrawable *dri_draw = dri_ctx->driDrawablePriv;
3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	__DRIdrawable *dri_read = dri_ctx->driReadablePriv;
3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	if (ctx->DrawBuffer->Name == 0)
3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		validate_framebuffer(dri_ctx, dri_draw,
3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com				     &dri_ctx->dri2.draw_stamp);
3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com	if (ctx->ReadBuffer->Name == 0)
3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com		validate_framebuffer(dri_ctx, dri_read,
3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com				     &dri_ctx->dri2.read_stamp);
3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
35655b6b58d8f6e7529c9b9cea606a6e3637c8e2e39reed@google.com	nouveau_state_emit(ctx);
3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com