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
271933e97034a1774e37268035f67ca5973220e8c6Vinson Lee#include "main/mfeatures.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
38bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic const GLubyte *
39f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_get_string(struct gl_context *ctx, GLenum name)
40bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
41bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	static char buffer[128];
42bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	char hardware_name[32];
43bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
44bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	switch (name) {
45bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		case GL_VENDOR:
46bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			return (GLubyte *)"Nouveau";
47bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
48bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		case GL_RENDERER:
49bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			sprintf(hardware_name, "nv%02X", context_chipset(ctx));
500fe34b7bbc9a8e089bbb4d0fe401b09095a571ebIan Romanick			driGetRendererString(buffer, hardware_name, 0);
51bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
52bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			return (GLubyte *)buffer;
53bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		default:
54bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			return NULL;
55bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
56bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
57bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
58bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
59f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_flush(struct gl_context *ctx)
60bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
61bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_context *nctx = to_nouveau_context(ctx);
622e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	struct nouveau_pushbuf *push = context_push(ctx);
63bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
642e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	PUSH_KICK(push);
65bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
66264b584294dc1c00c53f6a0622b7e6e55e8dce37Brian Paul	if (_mesa_is_winsys_fbo(ctx->DrawBuffer) &&
67bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	    ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
68bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		__DRIscreen *screen = nctx->screen->dri_screen;
69bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		__DRIdri2LoaderExtension *dri2 = screen->dri2.loader;
70bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		__DRIdrawable *drawable = nctx->dri_context->driDrawablePriv;
71bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
72bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		dri2->flushFrontBuffer(drawable, drawable->loaderPrivate);
73bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
74bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
75bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
76bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
77f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_finish(struct gl_context *ctx)
78bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
79666004148353fa46e818772e496f6d09bd979737Ben Skeggs	struct nouveau_context *nctx = to_nouveau_context(ctx);
80666004148353fa46e818772e496f6d09bd979737Ben Skeggs	struct nouveau_pushbuf *push = context_push(ctx);
81666004148353fa46e818772e496f6d09bd979737Ben Skeggs	struct nouveau_pushbuf_refn refn =
82666004148353fa46e818772e496f6d09bd979737Ben Skeggs		{ nctx->fence, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR };
83666004148353fa46e818772e496f6d09bd979737Ben Skeggs
84bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nouveau_flush(ctx);
85666004148353fa46e818772e496f6d09bd979737Ben Skeggs
86666004148353fa46e818772e496f6d09bd979737Ben Skeggs	if (!nouveau_pushbuf_space(push, 16, 0, 0) &&
87666004148353fa46e818772e496f6d09bd979737Ben Skeggs	    !nouveau_pushbuf_refn(push, &refn, 1)) {
88666004148353fa46e818772e496f6d09bd979737Ben Skeggs		PUSH_DATA(push, 0);
89666004148353fa46e818772e496f6d09bd979737Ben Skeggs		PUSH_KICK(push);
90666004148353fa46e818772e496f6d09bd979737Ben Skeggs	}
91666004148353fa46e818772e496f6d09bd979737Ben Skeggs
92666004148353fa46e818772e496f6d09bd979737Ben Skeggs	nouveau_bo_wait(nctx->fence, NOUVEAU_BO_RDWR, context_client(ctx));
93bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
94bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
95bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
96f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_clear(struct gl_context *ctx, GLbitfield buffers)
97bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
98bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_framebuffer *fb = ctx->DrawBuffer;
99bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int x, y, w, h;
100bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i, buf;
101bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
102bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nouveau_validate_framebuffer(ctx);
103bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	get_scissors(fb, &x, &y, &w, &h);
104bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
105bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = 0; i < BUFFER_COUNT; i++) {
106bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		struct nouveau_surface *s;
107bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		unsigned mask, value;
108bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
109bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		buf = buffers & (1 << i);
110bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (!buf)
111bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			continue;
112bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
113bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		s = &to_nouveau_renderbuffer(
11459a5b5a193d5d9c5776aa586b34657b6e315479dBrian Paul			fb->Attachment[i].Renderbuffer)->surface;
115bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
116bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (buf & BUFFER_BITS_COLOR) {
117bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			mask = pack_rgba_i(s->format, ctx->Color.ColorMask[0]);
118093dc9e548537e6c77e33064a584f849ad90dfa5Dave Airlie			value = pack_rgba_clamp_f(s->format, ctx->Color.ClearColor.f);
119bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
120bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			if (mask)
121bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				context_drv(ctx)->surface_fill(
122bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez					ctx, s, mask, value, x, y, w, h);
123bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
124bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			buffers &= ~buf;
125bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
126bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		} else if (buf & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) {
127bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			mask = pack_zs_i(s->format,
128bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez					 (buffers & BUFFER_BIT_DEPTH &&
129bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez					  ctx->Depth.Mask) ? ~0 : 0,
13091af398b32f0f63a1560fe023651be0861c08f8aFrancisco Jerez					 (buffers & BUFFER_BIT_STENCIL ?
13191af398b32f0f63a1560fe023651be0861c08f8aFrancisco Jerez					  ctx->Stencil.WriteMask[0] : 0));
132bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			value = pack_zs_f(s->format,
133bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez					  ctx->Depth.Clear,
134bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez					  ctx->Stencil.Clear);
135bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
136bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			if (mask)
137bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				context_drv(ctx)->surface_fill(
138bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez					ctx, s, mask, value, x, y, w, h);
139bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
140bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			buffers &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
141bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		}
142bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
143bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
144bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (buffers)
145bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		_mesa_meta_Clear(ctx, buffers);
146bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
147bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
148bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
149bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_driver_functions_init(struct dd_function_table *functions)
150bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
151bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->GetString = nouveau_get_string;
152bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->Flush = nouveau_flush;
153bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->Finish = nouveau_finish;
154bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->Clear = nouveau_clear;
155fc7890dc6c1f70a4f1c4bffb0fca7ae0cde30a2eFrancisco Jerez	functions->DrawPixels = _mesa_meta_DrawPixels;
156fc7890dc6c1f70a4f1c4bffb0fca7ae0cde30a2eFrancisco Jerez	functions->CopyPixels = _mesa_meta_CopyPixels;
157fc7890dc6c1f70a4f1c4bffb0fca7ae0cde30a2eFrancisco Jerez	functions->Bitmap = _mesa_meta_Bitmap;
15870f9f5f7d4f1daadfcddc0fb0fea324c38353004nobled#if FEATURE_EXT_framebuffer_blit
159fe7d0e6dc81c493b9ff7163c640d75db25386675Francisco Jerez	functions->BlitFramebuffer = _mesa_meta_BlitFramebuffer;
16070f9f5f7d4f1daadfcddc0fb0fea324c38353004nobled#endif
161bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
162