2 * Copyright (C) 2009 Francisco Jerez.
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 #include "nouveau_driver.h"
28 #include "nouveau_context.h"
29 #include "nouveau_texture.h"
30 #include "nouveau_fbo.h"
31 #include "nouveau_util.h"
33 #include "main/texobj.h"
34 #include "main/texstore.h"
35 #include "main/texformat.h"
36 #include "main/texcompress.h"
37 #include "main/texgetimage.h"
38 #include "main/mipmap.h"
39 #include "main/texfetch.h"
40 #include "main/teximage.h"
42 static struct gl_texture_object
*
43 nouveau_texture_new(GLcontext
*ctx
, GLuint name
, GLenum target
)
45 struct nouveau_texture
*nt
= CALLOC_STRUCT(nouveau_texture
);
47 _mesa_initialize_texture_object(&nt
->base
, name
, target
);
53 nouveau_texture_free(GLcontext
*ctx
, struct gl_texture_object
*t
)
55 struct nouveau_texture
*nt
= to_nouveau_texture(t
);
58 for (i
= 0; i
< MAX_TEXTURE_LEVELS
; i
++)
59 nouveau_surface_ref(NULL
, &nt
->surfaces
[i
]);
61 _mesa_delete_texture_object(ctx
, t
);
64 static struct gl_texture_image
*
65 nouveau_teximage_new(GLcontext
*ctx
)
67 struct nouveau_teximage
*nti
= CALLOC_STRUCT(nouveau_teximage
);
73 nouveau_teximage_free(GLcontext
*ctx
, struct gl_texture_image
*ti
)
75 struct nouveau_teximage
*nti
= to_nouveau_teximage(ti
);
77 nouveau_surface_ref(NULL
, &nti
->surface
);
81 nouveau_teximage_map(GLcontext
*ctx
, struct gl_texture_image
*ti
)
83 struct nouveau_surface
*s
= &to_nouveau_teximage(ti
)->surface
;
87 ret
= nouveau_bo_map(s
->bo
, NOUVEAU_BO_RDWR
);
90 ti
->Data
= s
->bo
->map
;
95 nouveau_teximage_unmap(GLcontext
*ctx
, struct gl_texture_image
*ti
)
97 struct nouveau_surface
*s
= &to_nouveau_teximage(ti
)->surface
;
100 nouveau_bo_unmap(s
->bo
);
105 nouveau_choose_tex_format(GLcontext
*ctx
, GLint internalFormat
,
106 GLenum srcFormat
, GLenum srcType
)
108 switch (internalFormat
) {
120 return MESA_FORMAT_ARGB8888
;
122 return MESA_FORMAT_ARGB1555
;
128 return MESA_FORMAT_RGB565
;
135 return MESA_FORMAT_A8
;
143 return MESA_FORMAT_L8
;
146 case GL_LUMINANCE_ALPHA
:
147 case GL_LUMINANCE4_ALPHA4
:
148 case GL_LUMINANCE6_ALPHA2
:
149 case GL_LUMINANCE12_ALPHA4
:
150 case GL_LUMINANCE12_ALPHA12
:
151 case GL_LUMINANCE16_ALPHA16
:
152 case GL_LUMINANCE8_ALPHA8
:
153 return MESA_FORMAT_ARGB8888
;
160 return MESA_FORMAT_ARGB8888
;
163 case GL_COLOR_INDEX1_EXT
:
164 case GL_COLOR_INDEX2_EXT
:
165 case GL_COLOR_INDEX4_EXT
:
166 case GL_COLOR_INDEX12_EXT
:
167 case GL_COLOR_INDEX16_EXT
:
168 case GL_COLOR_INDEX8_EXT
:
169 return MESA_FORMAT_CI8
;
177 teximage_fits(struct gl_texture_object
*t
, int level
,
178 struct gl_texture_image
*ti
)
180 struct nouveau_surface
*s
= &to_nouveau_texture(t
)->surfaces
[level
];
182 return t
->Target
== GL_TEXTURE_RECTANGLE
||
183 (s
->bo
&& s
->width
== ti
->Width
&&
184 s
->height
== ti
->Height
&&
185 s
->format
== ti
->TexFormat
);
189 validate_teximage(GLcontext
*ctx
, struct gl_texture_object
*t
,
190 int level
, int x
, int y
, int z
,
191 int width
, int height
, int depth
)
193 struct gl_texture_image
*ti
= t
->Image
[0][level
];
195 if (ti
&& teximage_fits(t
, level
, ti
)) {
196 struct nouveau_surface
*ss
= to_nouveau_texture(t
)->surfaces
;
197 struct nouveau_surface
*s
= &to_nouveau_teximage(ti
)->surface
;
199 if (t
->Target
== GL_TEXTURE_RECTANGLE
)
200 nouveau_surface_ref(s
, &ss
[level
]);
202 context_drv(ctx
)->surface_copy(ctx
, &ss
[level
], s
,
213 get_last_level(struct gl_texture_object
*t
)
215 struct gl_texture_image
*base
= t
->Image
[0][t
->BaseLevel
];
217 if (t
->MinFilter
== GL_NEAREST
||
218 t
->MinFilter
== GL_LINEAR
|| !base
)
221 return MIN2(t
->BaseLevel
+ base
->MaxLog2
, t
->MaxLevel
);
225 relayout_texture(GLcontext
*ctx
, struct gl_texture_object
*t
)
227 struct gl_texture_image
*base
= t
->Image
[0][t
->BaseLevel
];
229 if (base
&& t
->Target
!= GL_TEXTURE_RECTANGLE
) {
230 struct nouveau_surface
*ss
= to_nouveau_texture(t
)->surfaces
;
231 struct nouveau_surface
*s
= &to_nouveau_teximage(base
)->surface
;
232 int i
, ret
, last
= get_last_level(t
);
233 unsigned size
, offset
= 0,
237 /* Deallocate the old storage. */
238 for (i
= 0; i
< MAX_TEXTURE_LEVELS
; i
++)
239 nouveau_bo_ref(NULL
, &ss
[i
].bo
);
241 /* Relayout the mipmap tree. */
242 for (i
= t
->BaseLevel
; i
<= last
; i
++) {
243 size
= width
* height
* s
->cpp
;
245 /* Images larger than 16B have to be aligned. */
247 offset
= align(offset
, 64);
249 ss
[i
] = (struct nouveau_surface
) {
256 .pitch
= width
* s
->cpp
,
260 width
= MAX2(1, width
/ 2);
261 height
= MAX2(1, height
/ 2);
264 /* Get new storage. */
265 size
= align(offset
, 64);
267 ret
= nouveau_bo_new(context_dev(ctx
), NOUVEAU_BO_MAP
|
268 NOUVEAU_BO_GART
| NOUVEAU_BO_VRAM
,
269 0, size
, &ss
[last
].bo
);
272 for (i
= t
->BaseLevel
; i
< last
; i
++)
273 nouveau_bo_ref(ss
[last
].bo
, &ss
[i
].bo
);
278 nouveau_texture_validate(GLcontext
*ctx
, struct gl_texture_object
*t
)
280 struct nouveau_texture
*nt
= to_nouveau_texture(t
);
281 int i
, last
= get_last_level(t
);
283 if (!nt
->surfaces
[last
].bo
)
287 nt
->dirty
= GL_FALSE
;
289 /* Copy the teximages to the actual miptree. */
290 for (i
= t
->BaseLevel
; i
<= last
; i
++) {
291 struct nouveau_surface
*s
= &nt
->surfaces
[i
];
293 validate_teximage(ctx
, t
, i
, 0, 0, 0,
294 s
->width
, s
->height
, 1);
302 nouveau_texture_reallocate(GLcontext
*ctx
, struct gl_texture_object
*t
)
305 relayout_texture(ctx
, t
);
306 nouveau_texture_validate(ctx
, t
);
310 get_teximage_placement(struct gl_texture_image
*ti
)
312 if (ti
->TexFormat
== MESA_FORMAT_A8
||
313 ti
->TexFormat
== MESA_FORMAT_L8
||
314 ti
->TexFormat
== MESA_FORMAT_I8
)
315 /* 1 cpp formats will have to be swizzled by the CPU,
316 * so leave them in system RAM for now. */
317 return NOUVEAU_BO_MAP
;
319 return NOUVEAU_BO_GART
| NOUVEAU_BO_MAP
;
323 nouveau_teximage(GLcontext
*ctx
, GLint dims
, GLenum target
, GLint level
,
324 GLint internalFormat
,
325 GLint width
, GLint height
, GLint depth
, GLint border
,
326 GLenum format
, GLenum type
, const GLvoid
*pixels
,
327 const struct gl_pixelstore_attrib
*packing
,
328 struct gl_texture_object
*t
,
329 struct gl_texture_image
*ti
)
331 struct nouveau_surface
*s
= &to_nouveau_teximage(ti
)->surface
;
334 /* Allocate a new bo for the image. */
335 nouveau_surface_alloc(ctx
, s
, LINEAR
, get_teximage_placement(ti
),
336 ti
->TexFormat
, width
, height
);
337 ti
->RowStride
= s
->pitch
/ s
->cpp
;
339 pixels
= _mesa_validate_pbo_teximage(ctx
, dims
, width
, height
, depth
,
340 format
, type
, pixels
, packing
,
343 /* Store the pixel data. */
344 nouveau_teximage_map(ctx
, ti
);
346 ret
= _mesa_texstore(ctx
, dims
, ti
->_BaseFormat
,
347 ti
->TexFormat
, ti
->Data
,
350 width
, height
, depth
,
351 format
, type
, pixels
, packing
);
354 nouveau_teximage_unmap(ctx
, ti
);
355 _mesa_unmap_teximage_pbo(ctx
, packing
);
357 if (!validate_teximage(ctx
, t
, level
, 0, 0, 0,
358 width
, height
, depth
))
359 /* It doesn't fit, mark it as dirty. */
363 if (level
== t
->BaseLevel
) {
364 if (!teximage_fits(t
, level
, ti
))
365 relayout_texture(ctx
, t
);
366 nouveau_texture_validate(ctx
, t
);
369 context_dirty_i(ctx
, TEX_OBJ
, ctx
->Texture
.CurrentUnit
);
370 context_dirty_i(ctx
, TEX_ENV
, ctx
->Texture
.CurrentUnit
);
374 nouveau_teximage_1d(GLcontext
*ctx
, GLenum target
, GLint level
,
375 GLint internalFormat
,
376 GLint width
, GLint border
,
377 GLenum format
, GLenum type
, const GLvoid
*pixels
,
378 const struct gl_pixelstore_attrib
*packing
,
379 struct gl_texture_object
*t
,
380 struct gl_texture_image
*ti
)
382 nouveau_teximage(ctx
, 1, target
, level
, internalFormat
,
383 width
, 1, 1, border
, format
, type
, pixels
,
388 nouveau_teximage_2d(GLcontext
*ctx
, GLenum target
, GLint level
,
389 GLint internalFormat
,
390 GLint width
, GLint height
, GLint border
,
391 GLenum format
, GLenum type
, const GLvoid
*pixels
,
392 const struct gl_pixelstore_attrib
*packing
,
393 struct gl_texture_object
*t
,
394 struct gl_texture_image
*ti
)
396 nouveau_teximage(ctx
, 2, target
, level
, internalFormat
,
397 width
, height
, 1, border
, format
, type
, pixels
,
402 nouveau_teximage_3d(GLcontext
*ctx
, GLenum target
, GLint level
,
403 GLint internalFormat
,
404 GLint width
, GLint height
, GLint depth
, GLint border
,
405 GLenum format
, GLenum type
, const GLvoid
*pixels
,
406 const struct gl_pixelstore_attrib
*packing
,
407 struct gl_texture_object
*t
,
408 struct gl_texture_image
*ti
)
410 nouveau_teximage(ctx
, 3, target
, level
, internalFormat
,
411 width
, height
, depth
, border
, format
, type
, pixels
,
416 nouveau_texsubimage_3d(GLcontext
*ctx
, GLenum target
, GLint level
,
417 GLint xoffset
, GLint yoffset
, GLint zoffset
,
418 GLint width
, GLint height
, GLint depth
,
419 GLenum format
, GLenum type
, const void *pixels
,
420 const struct gl_pixelstore_attrib
*packing
,
421 struct gl_texture_object
*t
,
422 struct gl_texture_image
*ti
)
424 nouveau_teximage_map(ctx
, ti
);
425 _mesa_store_texsubimage3d(ctx
, target
, level
, xoffset
, yoffset
, zoffset
,
426 width
, height
, depth
, format
, type
, pixels
,
428 nouveau_teximage_unmap(ctx
, ti
);
430 if (!to_nouveau_texture(t
)->dirty
)
431 validate_teximage(ctx
, t
, level
, xoffset
, yoffset
, zoffset
,
432 width
, height
, depth
);
436 nouveau_texsubimage_2d(GLcontext
*ctx
, GLenum target
, GLint level
,
437 GLint xoffset
, GLint yoffset
,
438 GLint width
, GLint height
,
439 GLenum format
, GLenum type
, const void *pixels
,
440 const struct gl_pixelstore_attrib
*packing
,
441 struct gl_texture_object
*t
,
442 struct gl_texture_image
*ti
)
444 nouveau_teximage_map(ctx
, ti
);
445 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
,
446 width
, height
, format
, type
, pixels
,
448 nouveau_teximage_unmap(ctx
, ti
);
450 if (!to_nouveau_texture(t
)->dirty
)
451 validate_teximage(ctx
, t
, level
, xoffset
, yoffset
, 0,
456 nouveau_texsubimage_1d(GLcontext
*ctx
, GLenum target
, GLint level
,
457 GLint xoffset
, GLint width
,
458 GLenum format
, GLenum type
, const void *pixels
,
459 const struct gl_pixelstore_attrib
*packing
,
460 struct gl_texture_object
*t
,
461 struct gl_texture_image
*ti
)
463 nouveau_teximage_map(ctx
, ti
);
464 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
,
465 width
, format
, type
, pixels
,
467 nouveau_teximage_unmap(ctx
, ti
);
469 if (!to_nouveau_texture(t
)->dirty
)
470 validate_teximage(ctx
, t
, level
, xoffset
, 0, 0,
475 nouveau_get_teximage(GLcontext
*ctx
, GLenum target
, GLint level
,
476 GLenum format
, GLenum type
, GLvoid
*pixels
,
477 struct gl_texture_object
*t
,
478 struct gl_texture_image
*ti
)
480 nouveau_teximage_map(ctx
, ti
);
481 _mesa_get_teximage(ctx
, target
, level
, format
, type
, pixels
,
483 nouveau_teximage_unmap(ctx
, ti
);
487 nouveau_bind_texture(GLcontext
*ctx
, GLenum target
,
488 struct gl_texture_object
*t
)
490 context_dirty_i(ctx
, TEX_OBJ
, ctx
->Texture
.CurrentUnit
);
491 context_dirty_i(ctx
, TEX_ENV
, ctx
->Texture
.CurrentUnit
);
495 get_texbuffer_format(struct gl_renderbuffer
*rb
, GLint format
)
497 struct nouveau_surface
*s
= &to_nouveau_renderbuffer(rb
)->surface
;
501 else if (format
== __DRI_TEXTURE_FORMAT_RGBA
)
502 return MESA_FORMAT_ARGB8888
;
504 return MESA_FORMAT_XRGB8888
;
508 nouveau_set_texbuffer(__DRIcontext
*dri_ctx
,
509 GLint target
, GLint format
,
512 struct nouveau_context
*nctx
= dri_ctx
->driverPrivate
;
513 GLcontext
*ctx
= &nctx
->base
;
514 struct gl_framebuffer
*fb
= draw
->driverPrivate
;
515 struct gl_renderbuffer
*rb
=
516 fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
517 struct gl_texture_object
*t
= _mesa_get_current_tex_object(ctx
, target
);
518 struct gl_texture_image
*ti
;
519 struct nouveau_surface
*s
;
521 _mesa_lock_texture(ctx
, t
);
522 ti
= _mesa_get_tex_image(ctx
, t
, target
, 0);
523 s
= &to_nouveau_teximage(ti
)->surface
;
525 /* Update the texture surface with the given drawable. */
526 nouveau_update_renderbuffers(dri_ctx
, draw
);
527 nouveau_surface_ref(&to_nouveau_renderbuffer(rb
)->surface
, s
);
529 /* Update the image fields. */
530 _mesa_init_teximage_fields(ctx
, target
, ti
, s
->width
, s
->height
,
532 ti
->RowStride
= s
->pitch
/ s
->cpp
;
533 ti
->TexFormat
= s
->format
= get_texbuffer_format(rb
, format
);
535 /* Try to validate it. */
536 if (!validate_teximage(ctx
, t
, 0, 0, 0, 0, s
->width
, s
->height
, 1))
537 nouveau_texture_reallocate(ctx
, t
);
539 context_dirty_i(ctx
, TEX_OBJ
, ctx
->Texture
.CurrentUnit
);
540 context_dirty_i(ctx
, TEX_ENV
, ctx
->Texture
.CurrentUnit
);
542 _mesa_unlock_texture(ctx
, t
);
546 nouveau_texture_map(GLcontext
*ctx
, struct gl_texture_object
*t
)
550 for (i
= t
->BaseLevel
; i
< t
->_MaxLevel
; i
++) {
552 nouveau_teximage_map(ctx
, t
->Image
[0][i
]);
557 nouveau_texture_unmap(GLcontext
*ctx
, struct gl_texture_object
*t
)
561 for (i
= t
->BaseLevel
; i
< t
->_MaxLevel
; i
++) {
563 nouveau_teximage_unmap(ctx
, t
->Image
[0][i
]);
568 nouveau_texture_functions_init(struct dd_function_table
*functions
)
570 functions
->NewTextureObject
= nouveau_texture_new
;
571 functions
->DeleteTexture
= nouveau_texture_free
;
572 functions
->NewTextureImage
= nouveau_teximage_new
;
573 functions
->FreeTexImageData
= nouveau_teximage_free
;
574 functions
->ChooseTextureFormat
= nouveau_choose_tex_format
;
575 functions
->TexImage1D
= nouveau_teximage_1d
;
576 functions
->TexImage2D
= nouveau_teximage_2d
;
577 functions
->TexImage3D
= nouveau_teximage_3d
;
578 functions
->TexSubImage1D
= nouveau_texsubimage_1d
;
579 functions
->TexSubImage2D
= nouveau_texsubimage_2d
;
580 functions
->TexSubImage3D
= nouveau_texsubimage_3d
;
581 functions
->GetTexImage
= nouveau_get_teximage
;
582 functions
->BindTexture
= nouveau_bind_texture
;
583 functions
->MapTexture
= nouveau_texture_map
;
584 functions
->UnmapTexture
= nouveau_texture_unmap
;