nouveau_fbo.c revision 949587d1692f4e528f54b598ffc22a1906e4baf3
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"
35bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
36bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic GLboolean
37bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezset_renderbuffer_format(struct gl_renderbuffer *rb, GLenum internalFormat)
38bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
39bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
40bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
41bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->InternalFormat  = internalFormat;
42bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
43bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	switch (internalFormat) {
44bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB:
45bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB8:
46bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->_BaseFormat  = GL_RGB;
47bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->Format = MESA_FORMAT_XRGB8888;
48bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->DataType = GL_UNSIGNED_BYTE;
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		rb->DataType = GL_UNSIGNED_BYTE;
56bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		s->cpp = 4;
57bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
58bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_RGB5:
59bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->_BaseFormat  = GL_RGB;
60bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->Format = MESA_FORMAT_RGB565;
61bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->DataType = GL_UNSIGNED_BYTE;
62bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		s->cpp = 2;
63bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
64bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_DEPTH_COMPONENT16:
65bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->_BaseFormat  = GL_DEPTH_COMPONENT;
66bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->Format = MESA_FORMAT_Z16;
67bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->DataType = GL_UNSIGNED_SHORT;
68bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		s->cpp = 2;
69bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
70bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_DEPTH_COMPONENT24:
71bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_STENCIL_INDEX8_EXT:
72bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case GL_DEPTH24_STENCIL8_EXT:
739a8e374c46079d40ef577842cbf917af1c131dc0Francisco Jerez		rb->_BaseFormat  = GL_DEPTH_STENCIL;
74bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->Format = MESA_FORMAT_Z24_S8;
75bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->DataType = GL_UNSIGNED_INT;
76bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		s->cpp = 4;
77bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		break;
78bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	default:
79bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return GL_FALSE;
80bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
81bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
82bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	s->format = rb->Format;
83bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
84bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return GL_TRUE;
85bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
86bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
87bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic GLboolean
88bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
89bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			     GLenum internalFormat,
90bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			     GLuint width, GLuint height)
91bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
92bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
93bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
94bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!set_renderbuffer_format(rb, internalFormat))
95bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return GL_FALSE;
96bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
97bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->Width = width;
98bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->Height = height;
99bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
100bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nouveau_surface_alloc(ctx, s, TILED, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP,
101bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			      rb->Format, width, height);
102bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
103bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	context_dirty(ctx, FRAMEBUFFER);
104bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return GL_TRUE;
105bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
106bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
107bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
108bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_renderbuffer_del(struct gl_renderbuffer *rb)
109bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
110bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
111bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
112bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nouveau_surface_ref(NULL, s);
113bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	FREE(rb);
114bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
115bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
116bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic struct gl_renderbuffer *
117bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_renderbuffer_new(GLcontext *ctx, GLuint name)
118bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
119bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_renderbuffer *rb;
120bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
121bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb = (struct gl_renderbuffer *)
122bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		CALLOC_STRUCT(nouveau_renderbuffer);
123bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!rb)
124bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return NULL;
125bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
126bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	_mesa_init_renderbuffer(rb, name);
127bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
128bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->AllocStorage = nouveau_renderbuffer_storage;
129bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->Delete = nouveau_renderbuffer_del;
130bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
131bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return rb;
132bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
133bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
134bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic GLboolean
135bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_renderbuffer_dri_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
136bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				 GLenum internalFormat,
137bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				 GLuint width, GLuint height)
138bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
139bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!set_renderbuffer_format(rb, internalFormat))
140bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return GL_FALSE;
141bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
142bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->Width = width;
143bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->Height = height;
144bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
145bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return GL_TRUE;
146bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
147bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
148bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstruct gl_renderbuffer *
149bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_renderbuffer_dri_new(GLenum format, __DRIdrawable *drawable)
150bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
151bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_renderbuffer *rb;
152bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
153bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb = nouveau_renderbuffer_new(NULL, 0);
154bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!rb)
155bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return NULL;
156bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
157bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->AllocStorage = nouveau_renderbuffer_dri_storage;
158bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
159bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!set_renderbuffer_format(rb, format)) {
160bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		nouveau_renderbuffer_del(rb);
161bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return NULL;
162bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
163bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
164bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return rb;
165bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
166bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
167bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic struct gl_framebuffer *
168bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_framebuffer_new(GLcontext *ctx, GLuint name)
169bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
170bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_framebuffer *nfb;
171bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
172bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nfb = CALLOC_STRUCT(nouveau_framebuffer);
173bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!nfb)
174bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return NULL;
175bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
176bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	_mesa_initialize_user_framebuffer(&nfb->base, name);
177bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
178bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return &nfb->base;
179bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
180bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
181bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstruct gl_framebuffer *
182bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_framebuffer_dri_new(const GLvisual *visual)
183bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
184bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_framebuffer *nfb;
185bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
186bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nfb = CALLOC_STRUCT(nouveau_framebuffer);
187bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!nfb)
188bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return NULL;
189bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
190bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	_mesa_initialize_window_framebuffer(&nfb->base, visual);
191bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
192bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return &nfb->base;
193bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
194bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
195bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
196bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_bind_framebuffer(GLcontext *ctx, GLenum target,
197bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			 struct gl_framebuffer *dfb,
198bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			 struct gl_framebuffer *rfb)
199bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
200bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	context_dirty(ctx, FRAMEBUFFER);
201bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
202bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
203bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
204bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
205bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				 GLenum attachment, struct gl_renderbuffer *rb)
206bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
207bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	_mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
208bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
209bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	context_dirty(ctx, FRAMEBUFFER);
210bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
211bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
212bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic GLenum
213bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezget_tex_format(struct gl_texture_image *ti)
214bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
215bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	switch (ti->TexFormat) {
216bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case MESA_FORMAT_ARGB8888:
217bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return GL_RGBA8;
218949587d1692f4e528f54b598ffc22a1906e4baf3Andrew Randrianasulu	case MESA_FORMAT_XRGB8888:
219949587d1692f4e528f54b598ffc22a1906e4baf3Andrew Randrianasulu		return GL_RGB8;
220bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	case MESA_FORMAT_RGB565:
221bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return GL_RGB5;
222bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	default:
223bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		assert(0);
224bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
225bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
226bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
227bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
228bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_render_texture(GLcontext *ctx, struct gl_framebuffer *fb,
229bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		       struct gl_renderbuffer_attachment *att)
230bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
231bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_renderbuffer *rb = att->Renderbuffer;
232bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct gl_texture_image *ti =
233bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		att->Texture->Image[att->CubeMapFace][att->TextureLevel];
234bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int ret;
235bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
236bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	/* Allocate a renderbuffer object for the texture if we
237bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	 * haven't already done so. */
238bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!rb) {
239bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb = nouveau_renderbuffer_new(ctx, 0);
240bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		assert(rb);
241bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
242bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		rb->AllocStorage = NULL;
243bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		_mesa_reference_renderbuffer(&att->Renderbuffer, rb);
244bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
245bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
246bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	/* Update the renderbuffer fields from the texture. */
247bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	ret = set_renderbuffer_format(rb, get_tex_format(ti));
248bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	assert(ret);
249bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
250bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->Width = ti->Width;
251bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	rb->Height = ti->Height;
252bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nouveau_surface_ref(&to_nouveau_teximage(ti)->surface,
253bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			    &to_nouveau_renderbuffer(rb)->surface);
254bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
255bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	context_dirty(ctx, FRAMEBUFFER);
256bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
257bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
258bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
259bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_finish_render_texture(GLcontext *ctx,
260bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			      struct gl_renderbuffer_attachment *att)
261bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
262bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_renderbuffer *nrb
263bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		= to_nouveau_renderbuffer(att->Renderbuffer);
264bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
265bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	texture_dirty(att->Texture);
266bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	nouveau_surface_ref(NULL, &nrb->surface);
267bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
268bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
269bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid
270bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_fbo_functions_init(struct dd_function_table *functions)
271bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
272bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->NewFramebuffer = nouveau_framebuffer_new;
273bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->NewRenderbuffer = nouveau_renderbuffer_new;
274bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->BindFramebuffer = nouveau_bind_framebuffer;
275bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->FramebufferRenderbuffer = nouveau_framebuffer_renderbuffer;
276bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->RenderTexture = nouveau_render_texture;
277bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	functions->FinishRenderTexture = nouveau_finish_render_texture;
278bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
279