1bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/*
2bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * Copyright (C) 2009 Francisco Jerez.
3bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * All Rights Reserved.
4bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez *
5bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * Permission is hereby granted, free of charge, to any person obtaining
6bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * a copy of this software and associated documentation files (the
7bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * "Software"), to deal in the Software without restriction, including
8bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * without limitation the rights to use, copy, modify, merge, publish,
9bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * distribute, sublicense, and/or sell copies of the Software, and to
10bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * permit persons to whom the Software is furnished to do so, subject to
11bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * the following conditions:
12bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez *
13bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * The above copyright notice and this permission notice (including the
14bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * next paragraph) shall be included in all copies or substantial
15bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * portions of the Software.
16bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez *
17bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez *
25bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez */
26bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
2778ee6fdb2303a630925405bf12af2b61f20383d7Brian Paul#include <stdio.h>
28264b584294dc1c00c53f6a0622b7e6e55e8dce37Brian Paul#include "main/mtypes.h"
29264b584294dc1c00c53f6a0622b7e6e55e8dce37Brian Paul#include "main/fbobject.h"
301933e97034a1774e37268035f67ca5973220e8c6Vinson Lee
31bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_driver.h"
32bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_context.h"
33bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_fbo.h"
34bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_util.h"
35bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
36bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "drivers/common/meta.h"
37bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
38bf34748b39a8ae81f314db083eb73bb0be4e9c1dIlia Mirkinconst char * const nouveau_vendor_string = "Nouveau";
3976f07362ea411fd6ef29b34df3885def5137bcbaEmil Velikov
4076f07362ea411fd6ef29b34df3885def5137bcbaEmil Velikovconst char *
4176f07362ea411fd6ef29b34df3885def5137bcbaEmil Velikovnouveau_get_renderer_string(unsigned chipset)
42bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
43bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	char hardware_name[32];
4476f07362ea411fd6ef29b34df3885def5137bcbaEmil Velikov	static char buffer[128];
4576f07362ea411fd6ef29b34df3885def5137bcbaEmil Velikov
4676f07362ea411fd6ef29b34df3885def5137bcbaEmil Velikov	snprintf(hardware_name, sizeof(hardware_name), "nv%02X", chipset);
4776f07362ea411fd6ef29b34df3885def5137bcbaEmil Velikov	driGetRendererString(buffer, hardware_name, 0);
48bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
4976f07362ea411fd6ef29b34df3885def5137bcbaEmil Velikov	return buffer;
5076f07362ea411fd6ef29b34df3885def5137bcbaEmil Velikov}
5176f07362ea411fd6ef29b34df3885def5137bcbaEmil Velikov
5276f07362ea411fd6ef29b34df3885def5137bcbaEmil Velikovstatic const GLubyte *
5376f07362ea411fd6ef29b34df3885def5137bcbaEmil Velikovnouveau_get_string(struct gl_context *ctx, GLenum name)
5476f07362ea411fd6ef29b34df3885def5137bcbaEmil Velikov{
55bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	switch (name) {
56bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		case GL_VENDOR:
5776f07362ea411fd6ef29b34df3885def5137bcbaEmil Velikov			return (GLubyte *)nouveau_vendor_string;
58bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
59bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		case GL_RENDERER:
6076f07362ea411fd6ef29b34df3885def5137bcbaEmil Velikov			return (GLubyte *)nouveau_get_renderer_string(context_chipset(ctx));
61bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		default:
62bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			return NULL;
63bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
64bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
65bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
66bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
67f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_flush(struct gl_context *ctx)
68bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
69bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_context *nctx = to_nouveau_context(ctx);
702e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	struct nouveau_pushbuf *push = context_push(ctx);
71bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
722e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_KICK(push);
73bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
74264b584294dc1c00c53f6a0622b7e6e55e8dce37Brian Paul	if (_mesa_is_winsys_fbo(ctx->DrawBuffer) &&
75bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	    ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
76bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		__DRIscreen *screen = nctx->screen->dri_screen;
7738f20f79da4212c86d0869951f533d66a5ef907eEmil Velikov		const __DRIdri2LoaderExtension *dri2 = screen->dri2.loader;
78bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		__DRIdrawable *drawable = nctx->dri_context->driDrawablePriv;
79bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
8017f1cb1d99e66227d1e05925ef937643f5c1089aJan de Groot		if (drawable && drawable->loaderPrivate)
8117f1cb1d99e66227d1e05925ef937643f5c1089aJan de Groot			dri2->flushFrontBuffer(drawable, drawable->loaderPrivate);
82bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
83bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
84bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
85bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
86f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_finish(struct gl_context *ctx)
87bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
88666004148353fa46e818772e496f6d09bd979737Ben Skeggs	struct nouveau_context *nctx = to_nouveau_context(ctx);
89666004148353fa46e818772e496f6d09bd979737Ben Skeggs	struct nouveau_pushbuf *push = context_push(ctx);
90666004148353fa46e818772e496f6d09bd979737Ben Skeggs	struct nouveau_pushbuf_refn refn =
91666004148353fa46e818772e496f6d09bd979737Ben Skeggs		{ nctx->fence, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR };
92666004148353fa46e818772e496f6d09bd979737Ben Skeggs
93bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nouveau_flush(ctx);
94666004148353fa46e818772e496f6d09bd979737Ben Skeggs
95666004148353fa46e818772e496f6d09bd979737Ben Skeggs	if (!nouveau_pushbuf_space(push, 16, 0, 0) &&
96666004148353fa46e818772e496f6d09bd979737Ben Skeggs	    !nouveau_pushbuf_refn(push, &refn, 1)) {
97666004148353fa46e818772e496f6d09bd979737Ben Skeggs		PUSH_DATA(push, 0);
98666004148353fa46e818772e496f6d09bd979737Ben Skeggs		PUSH_KICK(push);
99666004148353fa46e818772e496f6d09bd979737Ben Skeggs	}
100666004148353fa46e818772e496f6d09bd979737Ben Skeggs
101666004148353fa46e818772e496f6d09bd979737Ben Skeggs	nouveau_bo_wait(nctx->fence, NOUVEAU_BO_RDWR, context_client(ctx));
102bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
103bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
104bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
105f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_clear(struct gl_context *ctx, GLbitfield buffers)
106bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
107bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_framebuffer *fb = ctx->DrawBuffer;
108bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int x, y, w, h;
109bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i, buf;
110bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
111bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nouveau_validate_framebuffer(ctx);
112bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	get_scissors(fb, &x, &y, &w, &h);
113bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
114bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = 0; i < BUFFER_COUNT; i++) {
115bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		struct nouveau_surface *s;
116bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		unsigned mask, value;
117bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
118bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		buf = buffers & (1 << i);
119bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (!buf)
120bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			continue;
121bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
122bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		s = &to_nouveau_renderbuffer(
12359a5b5a193d5d9c5776aa586b34657b6e315479dBrian Paul			fb->Attachment[i].Renderbuffer)->surface;
124bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
125bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (buf & BUFFER_BITS_COLOR) {
126a89353381ac3603bacb7ec56f5e4b3bf6ef6fb59Ilia Mirkin			const float *color = ctx->Color.ClearColor.f;
127a89353381ac3603bacb7ec56f5e4b3bf6ef6fb59Ilia Mirkin
128a89353381ac3603bacb7ec56f5e4b3bf6ef6fb59Ilia Mirkin			if (fb->Attachment[i].Renderbuffer->_BaseFormat ==
129a89353381ac3603bacb7ec56f5e4b3bf6ef6fb59Ilia Mirkin			    GL_LUMINANCE_ALPHA)
130a89353381ac3603bacb7ec56f5e4b3bf6ef6fb59Ilia Mirkin				value = pack_la_clamp_f(
131a89353381ac3603bacb7ec56f5e4b3bf6ef6fb59Ilia Mirkin						s->format, color[0], color[3]);
132a89353381ac3603bacb7ec56f5e4b3bf6ef6fb59Ilia Mirkin			else
133a89353381ac3603bacb7ec56f5e4b3bf6ef6fb59Ilia Mirkin				value = pack_rgba_clamp_f(s->format, color);
134a89353381ac3603bacb7ec56f5e4b3bf6ef6fb59Ilia Mirkin
135bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			mask = pack_rgba_i(s->format, ctx->Color.ColorMask[0]);
136bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
137bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			if (mask)
138bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				context_drv(ctx)->surface_fill(
139bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez					ctx, s, mask, value, x, y, w, h);
140bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
141bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			buffers &= ~buf;
142bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
143bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		} else if (buf & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) {
144bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			mask = pack_zs_i(s->format,
145bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez					 (buffers & BUFFER_BIT_DEPTH &&
146bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez					  ctx->Depth.Mask) ? ~0 : 0,
14791af398b32f0f63a1560fe023651be0861c08f8aFrancisco Jerez					 (buffers & BUFFER_BIT_STENCIL ?
14891af398b32f0f63a1560fe023651be0861c08f8aFrancisco Jerez					  ctx->Stencil.WriteMask[0] : 0));
149bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			value = pack_zs_f(s->format,
150bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez					  ctx->Depth.Clear,
151bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez					  ctx->Stencil.Clear);
152bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
153bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			if (mask)
154bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				context_drv(ctx)->surface_fill(
155bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez					ctx, s, mask, value, x, y, w, h);
156bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
157bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			buffers &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
158bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		}
159bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
160bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
161bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (buffers)
162bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		_mesa_meta_Clear(ctx, buffers);
163bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
164bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
165bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
166bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_driver_functions_init(struct dd_function_table *functions)
167bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
168bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->GetString = nouveau_get_string;
169bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->Flush = nouveau_flush;
170bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->Finish = nouveau_finish;
171bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->Clear = nouveau_clear;
172fc7890dc6c1f70a4f1c4bffb0fca7ae0cde30a2eFrancisco Jerez	functions->DrawPixels = _mesa_meta_DrawPixels;
173fc7890dc6c1f70a4f1c4bffb0fca7ae0cde30a2eFrancisco Jerez	functions->CopyPixels = _mesa_meta_CopyPixels;
174fc7890dc6c1f70a4f1c4bffb0fca7ae0cde30a2eFrancisco Jerez	functions->Bitmap = _mesa_meta_Bitmap;
17554540ea691e926b36a81a9b1e27b8f035995d07dKenneth Graunke	functions->BlitFramebuffer = _mesa_meta_and_swrast_BlitFramebuffer;
176bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
177