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
27bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_driver.h"
28bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_fbo.h"
29bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_context.h"
30bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_texture.h"
31bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
32bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "main/framebuffer.h"
33bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "main/renderbuffer.h"
34bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "main/fbobject.h"
351933e97034a1774e37268035f67ca5973220e8c6Vinson Lee#include "main/mfeatures.h"
36bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
37bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic GLboolean
38bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezset_renderbuffer_format(struct gl_renderbuffer *rb, GLenum internalFormat)
39bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
40bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
41bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
42bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->InternalFormat  = internalFormat;
43bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
44bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	switch (internalFormat) {
45bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB:
46bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB8:
47bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->_BaseFormat  = GL_RGB;
48bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->Format = MESA_FORMAT_XRGB8888;
49bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		s->cpp = 4;
50bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
51bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGBA:
52bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGBA8:
53bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->_BaseFormat  = GL_RGBA;
54bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->Format = MESA_FORMAT_ARGB8888;
55bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		s->cpp = 4;
56bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
57bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB5:
58bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->_BaseFormat  = GL_RGB;
59bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->Format = MESA_FORMAT_RGB565;
60bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		s->cpp = 2;
61bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
62bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_DEPTH_COMPONENT16:
63bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->_BaseFormat  = GL_DEPTH_COMPONENT;
64bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->Format = MESA_FORMAT_Z16;
65bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		s->cpp = 2;
66bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
6739658f32eaf1acc9603a9a5a2242fba8fd49e08fFrancisco Jerez	case GL_DEPTH_COMPONENT:
68bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_DEPTH_COMPONENT24:
69bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_STENCIL_INDEX8_EXT:
70bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_DEPTH24_STENCIL8_EXT:
719a8e374c46079d40ef577842cbf917af1c131dc0Francisco Jerez		rb->_BaseFormat  = GL_DEPTH_STENCIL;
72bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->Format = MESA_FORMAT_Z24_S8;
73bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		s->cpp = 4;
74bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
75bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	default:
76bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return GL_FALSE;
77bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
78bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
79bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	s->format = rb->Format;
80bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
81bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return GL_TRUE;
82bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
83bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
84bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic GLboolean
85f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
86bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			     GLenum internalFormat,
87bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			     GLuint width, GLuint height)
88bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
89bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
90bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
91bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!set_renderbuffer_format(rb, internalFormat))
92bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return GL_FALSE;
93bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
94bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->Width = width;
95bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->Height = height;
96bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
97bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nouveau_surface_alloc(ctx, s, TILED, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP,
98bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			      rb->Format, width, height);
99bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
100bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	context_dirty(ctx, FRAMEBUFFER);
101bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return GL_TRUE;
102bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
103bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
104bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
1059d4ab9a663d4088ec553edaae0eeafb746d2490dBrian Paulnouveau_renderbuffer_del(struct gl_context *ctx, struct gl_renderbuffer *rb)
106bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
107bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
108bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
109bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nouveau_surface_ref(NULL, s);
1109d4ab9a663d4088ec553edaae0eeafb746d2490dBrian Paul	_mesa_delete_renderbuffer(ctx, rb);
111bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
112bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
113bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic struct gl_renderbuffer *
114f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_renderbuffer_new(struct gl_context *ctx, GLuint name)
115bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
116bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_renderbuffer *rb;
117bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
118bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb = (struct gl_renderbuffer *)
119bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		CALLOC_STRUCT(nouveau_renderbuffer);
120bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!rb)
121bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return NULL;
122bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
123bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	_mesa_init_renderbuffer(rb, name);
124bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
125bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->AllocStorage = nouveau_renderbuffer_storage;
126bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->Delete = nouveau_renderbuffer_del;
127bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
128bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return rb;
129bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
130bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
1314b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholtstatic void
1324b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholtnouveau_renderbuffer_map(struct gl_context *ctx,
1334b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt			 struct gl_renderbuffer *rb,
1344b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt			 GLuint x, GLuint y, GLuint w, GLuint h,
1354b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt			 GLbitfield mode,
1364b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt			 GLubyte **out_map,
1374b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt			 GLint *out_stride)
1384b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt{
1394b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt	struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
1404b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt	GLubyte *map;
1414b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt	int stride;
1424b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt	int flags = 0;
1434b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt
1444b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt	if (mode & GL_MAP_READ_BIT)
1454b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt		flags |= NOUVEAU_BO_RD;
1464b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt	if (mode & GL_MAP_WRITE_BIT)
1474b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt		flags |= NOUVEAU_BO_WR;
1484b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt
1492e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs	nouveau_bo_map(s->bo, flags, context_client(ctx));
1504b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt
1514b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt	map = s->bo->map;
1524b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt	stride = s->pitch;
1534b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt
1544b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt	if (rb->Name == 0) {
1554b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt		map += stride * (rb->Height - 1);
1564b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt		stride = -stride;
1574b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt	}
1584b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt
1594b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt	map += x * s->cpp;
1604b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt	map += (int)y * stride;
1614b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt
1624b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt	*out_map = map;
1634b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt	*out_stride = stride;
1644b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt}
1654b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt
1664b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholtstatic void
1674b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholtnouveau_renderbuffer_unmap(struct gl_context *ctx,
1684b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt			   struct gl_renderbuffer *rb)
1694b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt{
1704b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt}
1714b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt
172bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic GLboolean
173f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_renderbuffer_dri_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
174bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				 GLenum internalFormat,
175bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				 GLuint width, GLuint height)
176bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
177bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!set_renderbuffer_format(rb, internalFormat))
178bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return GL_FALSE;
179bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
180bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->Width = width;
181bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->Height = height;
182bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
183bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return GL_TRUE;
184bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
185bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
186bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstruct gl_renderbuffer *
187bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_renderbuffer_dri_new(GLenum format, __DRIdrawable *drawable)
188bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
189bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_renderbuffer *rb;
190bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
191bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb = nouveau_renderbuffer_new(NULL, 0);
192bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!rb)
193bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return NULL;
194bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
195bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->AllocStorage = nouveau_renderbuffer_dri_storage;
196bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
197bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!set_renderbuffer_format(rb, format)) {
19815693b7925ccdd45bbb60b375ce6b7a3f60bfa3eBrian Paul		nouveau_renderbuffer_del(NULL, rb);
199bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return NULL;
200bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
201bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
202bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return rb;
203bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
204bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
205bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic struct gl_framebuffer *
206f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_framebuffer_new(struct gl_context *ctx, GLuint name)
207bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
208bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_framebuffer *nfb;
209bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
210bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nfb = CALLOC_STRUCT(nouveau_framebuffer);
211bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!nfb)
212bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return NULL;
213bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
214bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	_mesa_initialize_user_framebuffer(&nfb->base, name);
215bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
216bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return &nfb->base;
217bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
218bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
219bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstruct gl_framebuffer *
220d3491e775fb07f891463b2185d74bbad62f3ed24Kristian Høgsbergnouveau_framebuffer_dri_new(const struct gl_config *visual)
221bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
222bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_framebuffer *nfb;
223bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
224bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nfb = CALLOC_STRUCT(nouveau_framebuffer);
225bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!nfb)
226bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return NULL;
227bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
228bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	_mesa_initialize_window_framebuffer(&nfb->base, visual);
229bfc7518ab993b006dffaad5f605137e94ff9d7bcFrancisco Jerez	nfb->need_front = !visual->doubleBufferMode;
230bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
231bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return &nfb->base;
232bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
233bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
234bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
235f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_bind_framebuffer(struct gl_context *ctx, GLenum target,
236bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			 struct gl_framebuffer *dfb,
237bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			 struct gl_framebuffer *rfb)
238bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
239bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	context_dirty(ctx, FRAMEBUFFER);
240bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
241bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
242bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
243f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_framebuffer_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
244bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				 GLenum attachment, struct gl_renderbuffer *rb)
245bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
246bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	_mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
247bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
248bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	context_dirty(ctx, FRAMEBUFFER);
249bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
250bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
251bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic GLenum
252bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezget_tex_format(struct gl_texture_image *ti)
253bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
254bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	switch (ti->TexFormat) {
255bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case MESA_FORMAT_ARGB8888:
256bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return GL_RGBA8;
257949587d1692f4e528f54b598ffc22a1906e4baf3Andrew Randrianasulu	case MESA_FORMAT_XRGB8888:
258949587d1692f4e528f54b598ffc22a1906e4baf3Andrew Randrianasulu		return GL_RGB8;
259bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case MESA_FORMAT_RGB565:
260bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return GL_RGB5;
261bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	default:
262e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez		return GL_NONE;
263bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
264bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
265bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
266bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
267f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_render_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
268bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       struct gl_renderbuffer_attachment *att)
269bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
270bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_renderbuffer *rb = att->Renderbuffer;
271bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_texture_image *ti =
272bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		att->Texture->Image[att->CubeMapFace][att->TextureLevel];
273bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
274bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	/* Allocate a renderbuffer object for the texture if we
275bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	 * haven't already done so. */
276bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!rb) {
277bfdea90f251c1bc3cf4f8096f8c62a37b9ac78c1Francisco Jerez		rb = nouveau_renderbuffer_new(ctx, ~0);
278bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		assert(rb);
279bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
280bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->AllocStorage = NULL;
281bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		_mesa_reference_renderbuffer(&att->Renderbuffer, rb);
282bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
283bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
284bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	/* Update the renderbuffer fields from the texture. */
285e96a52e9933eea7264a42983db1428368bcb4962Francisco Jerez	set_renderbuffer_format(rb, get_tex_format(ti));
286bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->Width = ti->Width;
287bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->Height = ti->Height;
288bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nouveau_surface_ref(&to_nouveau_teximage(ti)->surface,
289bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			    &to_nouveau_renderbuffer(rb)->surface);
290bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
291bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	context_dirty(ctx, FRAMEBUFFER);
292bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
293bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
294bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
295f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_finish_render_texture(struct gl_context *ctx,
296bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			      struct gl_renderbuffer_attachment *att)
297bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
298bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	texture_dirty(att->Texture);
299bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
300bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
301bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
302bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_fbo_functions_init(struct dd_function_table *functions)
303bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
30470f9f5f7d4f1daadfcddc0fb0fea324c38353004nobled#if FEATURE_EXT_framebuffer_object
305bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->NewFramebuffer = nouveau_framebuffer_new;
306bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->NewRenderbuffer = nouveau_renderbuffer_new;
3074b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt	functions->MapRenderbuffer = nouveau_renderbuffer_map;
3084b8f4e7ce17aeaa7fba1140897ab66f74d715b0aEric Anholt	functions->UnmapRenderbuffer = nouveau_renderbuffer_unmap;
309bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->BindFramebuffer = nouveau_bind_framebuffer;
310bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->FramebufferRenderbuffer = nouveau_framebuffer_renderbuffer;
311bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->RenderTexture = nouveau_render_texture;
312bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->FinishRenderTexture = nouveau_finish_render_texture;
31370f9f5f7d4f1daadfcddc0fb0fea324c38353004nobled#endif
314bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
315