1 /* 2 * Copyright (C) 2009 Francisco Jerez. 3 * All Rights Reserved. 4 * 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: 12 * 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. 16 * 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. 24 * 25 */ 26 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" 32 33 #include "main/pbo.h" 34 #include "main/texobj.h" 35 #include "main/texstore.h" 36 #include "main/texformat.h" 37 #include "main/texcompress.h" 38 #include "main/texgetimage.h" 39 #include "main/mipmap.h" 40 #include "main/teximage.h" 41 #include "drivers/common/meta.h" 42 #include "swrast/s_texfetch.h" 43 44 static struct gl_texture_object * 45 nouveau_texture_new(struct gl_context *ctx, GLuint name, GLenum target) 46 { 47 struct nouveau_texture *nt = CALLOC_STRUCT(nouveau_texture); 48 49 _mesa_initialize_texture_object(ctx, &nt->base, name, target); 50 51 return &nt->base; 52 } 53 54 static void 55 nouveau_texture_free(struct gl_context *ctx, struct gl_texture_object *t) 56 { 57 struct nouveau_texture *nt = to_nouveau_texture(t); 58 int i; 59 60 for (i = 0; i < MAX_TEXTURE_LEVELS; i++) 61 nouveau_surface_ref(NULL, &nt->surfaces[i]); 62 63 _mesa_delete_texture_object(ctx, t); 64 } 65 66 static struct gl_texture_image * 67 nouveau_teximage_new(struct gl_context *ctx) 68 { 69 struct nouveau_teximage *nti = CALLOC_STRUCT(nouveau_teximage); 70 71 return &nti->base.Base; 72 } 73 74 static void 75 nouveau_teximage_free(struct gl_context *ctx, struct gl_texture_image *ti) 76 { 77 struct nouveau_teximage *nti = to_nouveau_teximage(ti); 78 79 nouveau_surface_ref(NULL, &nti->surface); 80 } 81 82 static void 83 nouveau_map_texture_image(struct gl_context *ctx, 84 struct gl_texture_image *ti, 85 GLuint slice, 86 GLuint x, GLuint y, GLuint w, GLuint h, 87 GLbitfield mode, 88 GLubyte **map, 89 GLint *stride) 90 { 91 struct nouveau_teximage *nti = to_nouveau_teximage(ti); 92 struct nouveau_surface *s = &nti->surface; 93 struct nouveau_surface *st = &nti->transfer.surface; 94 struct nouveau_client *client = context_client(ctx); 95 96 /* Nouveau has no support for 3D or cubemap textures. */ 97 assert(slice == 0); 98 99 if (s->bo) { 100 if (!(mode & GL_MAP_READ_BIT) && 101 nouveau_pushbuf_refd(context_push(ctx), s->bo)) { 102 unsigned size; 103 /* 104 * Heuristic: use a bounce buffer to pipeline 105 * teximage transfers. 106 */ 107 st->layout = LINEAR; 108 st->format = s->format; 109 st->cpp = s->cpp; 110 st->width = w; 111 st->height = h; 112 st->pitch = s->pitch; 113 nti->transfer.x = x; 114 nti->transfer.y = y; 115 116 size = get_format_blocksy(st->format, h) * st->pitch; 117 *map = nouveau_get_scratch(ctx, size, 118 &st->bo, &st->offset); 119 *stride = st->pitch; 120 } else { 121 int ret, flags = 0; 122 123 if (mode & GL_MAP_READ_BIT) 124 flags |= NOUVEAU_BO_RD; 125 if (mode & GL_MAP_WRITE_BIT) 126 flags |= NOUVEAU_BO_WR; 127 128 if (!s->bo->map) { 129 ret = nouveau_bo_map(s->bo, flags, client); 130 assert(!ret); 131 } 132 133 *map = s->bo->map + 134 get_format_blocksy(s->format, y) * s->pitch + 135 get_format_blocksx(s->format, x) * s->cpp; 136 *stride = s->pitch; 137 } 138 } else { 139 *map = nti->base.Buffer + 140 get_format_blocksy(s->format, y) * s->pitch + 141 get_format_blocksx(s->format, x) * s->cpp; 142 *stride = s->pitch; 143 } 144 } 145 146 static void 147 nouveau_unmap_texture_image(struct gl_context *ctx, struct gl_texture_image *ti, 148 GLuint slice) 149 { 150 struct nouveau_teximage *nti = to_nouveau_teximage(ti); 151 struct nouveau_surface *s = &nti->surface; 152 struct nouveau_surface *st = &nti->transfer.surface; 153 154 if (st->bo) { 155 context_drv(ctx)->surface_copy(ctx, s, st, nti->transfer.x, 156 nti->transfer.y, 0, 0, 157 st->width, st->height); 158 nouveau_surface_ref(NULL, st); 159 160 } 161 } 162 163 static mesa_format 164 nouveau_choose_tex_format(struct gl_context *ctx, GLenum target, 165 GLint internalFormat, 166 GLenum srcFormat, GLenum srcType) 167 { 168 switch (internalFormat) { 169 case 4: 170 case GL_RGBA: 171 case GL_RGBA2: 172 case GL_RGBA4: 173 case GL_RGBA8: 174 case GL_RGBA12: 175 case GL_RGBA16: 176 case GL_RGB10_A2: 177 case GL_COMPRESSED_RGBA: 178 return MESA_FORMAT_B8G8R8A8_UNORM; 179 case GL_RGB5_A1: 180 return MESA_FORMAT_B5G5R5A1_UNORM; 181 182 case GL_RGB: 183 case GL_RGB8: 184 case GL_RGB10: 185 case GL_RGB12: 186 case GL_RGB16: 187 case GL_COMPRESSED_RGB: 188 return MESA_FORMAT_B8G8R8X8_UNORM; 189 case 3: 190 case GL_R3_G3_B2: 191 case GL_RGB4: 192 case GL_RGB5: 193 return MESA_FORMAT_B5G6R5_UNORM; 194 195 case 2: 196 case GL_LUMINANCE_ALPHA: 197 case GL_LUMINANCE4_ALPHA4: 198 case GL_LUMINANCE6_ALPHA2: 199 case GL_LUMINANCE12_ALPHA4: 200 case GL_LUMINANCE12_ALPHA12: 201 case GL_LUMINANCE16_ALPHA16: 202 case GL_LUMINANCE8_ALPHA8: 203 case GL_COMPRESSED_LUMINANCE_ALPHA: 204 return MESA_FORMAT_B8G8R8A8_UNORM; 205 206 case 1: 207 case GL_LUMINANCE: 208 case GL_LUMINANCE4: 209 case GL_LUMINANCE12: 210 case GL_LUMINANCE16: 211 case GL_LUMINANCE8: 212 case GL_COMPRESSED_LUMINANCE: 213 return MESA_FORMAT_L_UNORM8; 214 215 case GL_ALPHA: 216 case GL_ALPHA4: 217 case GL_ALPHA12: 218 case GL_ALPHA16: 219 case GL_ALPHA8: 220 case GL_COMPRESSED_ALPHA: 221 return MESA_FORMAT_A_UNORM8; 222 223 case GL_INTENSITY: 224 case GL_INTENSITY4: 225 case GL_INTENSITY12: 226 case GL_INTENSITY16: 227 case GL_INTENSITY8: 228 case GL_COMPRESSED_INTENSITY: 229 return MESA_FORMAT_I_UNORM8; 230 231 case GL_RGB_S3TC: 232 case GL_RGB4_S3TC: 233 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 234 return MESA_FORMAT_RGB_DXT1; 235 236 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 237 return MESA_FORMAT_RGBA_DXT1; 238 239 case GL_RGBA_S3TC: 240 case GL_RGBA4_S3TC: 241 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 242 return MESA_FORMAT_RGBA_DXT3; 243 244 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: 245 return MESA_FORMAT_RGBA_DXT5; 246 247 default: 248 assert(0); 249 } 250 } 251 252 static GLboolean 253 teximage_fits(struct gl_texture_object *t, int level) 254 { 255 struct nouveau_surface *s = &to_nouveau_texture(t)->surfaces[level]; 256 struct gl_texture_image *ti = t->Image[0][level]; 257 258 if (!ti || !to_nouveau_teximage(ti)->surface.bo) 259 return GL_FALSE; 260 261 if (level == t->BaseLevel && (s->offset & 0x7f)) 262 return GL_FALSE; 263 264 return t->Target == GL_TEXTURE_RECTANGLE || 265 (s->bo && s->format == ti->TexFormat && 266 s->width == ti->Width && s->height == ti->Height); 267 } 268 269 static GLboolean 270 validate_teximage(struct gl_context *ctx, struct gl_texture_object *t, 271 int level, int x, int y, int z, 272 int width, int height, int depth) 273 { 274 struct gl_texture_image *ti = t->Image[0][level]; 275 276 if (teximage_fits(t, level)) { 277 struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces; 278 struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface; 279 280 if (t->Target == GL_TEXTURE_RECTANGLE) 281 nouveau_surface_ref(s, &ss[level]); 282 else 283 context_drv(ctx)->surface_copy(ctx, &ss[level], s, 284 x, y, x, y, 285 width, height); 286 287 return GL_TRUE; 288 } 289 290 return GL_FALSE; 291 } 292 293 static int 294 get_last_level(struct gl_texture_object *t) 295 { 296 struct gl_texture_image *base = t->Image[0][t->BaseLevel]; 297 298 if (t->Sampler.MinFilter == GL_NEAREST || 299 t->Sampler.MinFilter == GL_LINEAR || !base) 300 return t->BaseLevel; 301 else 302 return MIN2(t->BaseLevel + base->MaxNumLevels - 1, t->MaxLevel); 303 } 304 305 static void 306 relayout_texture(struct gl_context *ctx, struct gl_texture_object *t) 307 { 308 struct gl_texture_image *base = t->Image[0][t->BaseLevel]; 309 310 if (base && t->Target != GL_TEXTURE_RECTANGLE) { 311 struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces; 312 struct nouveau_surface *s = &to_nouveau_teximage(base)->surface; 313 int i, ret, last = get_last_level(t); 314 enum nouveau_surface_layout layout = 315 (_mesa_is_format_compressed(s->format) ? LINEAR : SWIZZLED); 316 unsigned size, pitch, offset = 0, 317 width = s->width, 318 height = s->height; 319 320 /* Deallocate the old storage. */ 321 for (i = 0; i < MAX_TEXTURE_LEVELS; i++) 322 nouveau_bo_ref(NULL, &ss[i].bo); 323 324 /* Relayout the mipmap tree. */ 325 for (i = t->BaseLevel; i <= last; i++) { 326 pitch = _mesa_format_row_stride(s->format, width); 327 size = get_format_blocksy(s->format, height) * pitch; 328 329 /* Images larger than 16B have to be aligned. */ 330 if (size > 16) 331 offset = align(offset, 64); 332 333 ss[i] = (struct nouveau_surface) { 334 .offset = offset, 335 .layout = layout, 336 .format = s->format, 337 .width = width, 338 .height = height, 339 .cpp = s->cpp, 340 .pitch = pitch, 341 }; 342 343 offset += size; 344 width = minify(width, 1); 345 height = minify(height, 1); 346 } 347 348 if (t->BaseLevel <= last) { 349 /* Get new storage. */ 350 size = align(offset, 64); 351 assert(size); 352 353 ret = nouveau_bo_new(context_dev(ctx), NOUVEAU_BO_MAP | 354 NOUVEAU_BO_GART | NOUVEAU_BO_VRAM, 355 0, size, NULL, &ss[last].bo); 356 assert(!ret); 357 358 for (i = t->BaseLevel; i < last; i++) 359 nouveau_bo_ref(ss[last].bo, &ss[i].bo); 360 } 361 } 362 } 363 364 GLboolean 365 nouveau_texture_validate(struct gl_context *ctx, struct gl_texture_object *t) 366 { 367 struct nouveau_texture *nt = to_nouveau_texture(t); 368 int i, last = get_last_level(t); 369 370 if (!teximage_fits(t, t->BaseLevel) || 371 !teximage_fits(t, last)) 372 return GL_FALSE; 373 374 if (nt->dirty) { 375 nt->dirty = GL_FALSE; 376 377 /* Copy the teximages to the actual miptree. */ 378 for (i = t->BaseLevel; i <= last; i++) { 379 struct nouveau_surface *s = &nt->surfaces[i]; 380 381 validate_teximage(ctx, t, i, 0, 0, 0, 382 s->width, s->height, 1); 383 } 384 385 PUSH_KICK(context_push(ctx)); 386 } 387 388 return GL_TRUE; 389 } 390 391 void 392 nouveau_texture_reallocate(struct gl_context *ctx, struct gl_texture_object *t) 393 { 394 if (!teximage_fits(t, t->BaseLevel) || 395 !teximage_fits(t, get_last_level(t))) { 396 texture_dirty(t); 397 relayout_texture(ctx, t); 398 nouveau_texture_validate(ctx, t); 399 } 400 } 401 402 static unsigned 403 get_teximage_placement(struct gl_texture_image *ti) 404 { 405 if (ti->TexFormat == MESA_FORMAT_A_UNORM8 || 406 ti->TexFormat == MESA_FORMAT_L_UNORM8 || 407 ti->TexFormat == MESA_FORMAT_I_UNORM8) 408 /* 1 cpp formats will have to be swizzled by the CPU, 409 * so leave them in system RAM for now. */ 410 return NOUVEAU_BO_MAP; 411 else 412 return NOUVEAU_BO_GART | NOUVEAU_BO_MAP; 413 } 414 415 static void 416 nouveau_compressed_copy(struct gl_context *ctx, GLint dims, 417 struct gl_texture_image *ti, 418 GLsizei width, GLsizei height, GLsizei depth, 419 const GLvoid *src, GLvoid *dst, int row_stride) 420 { 421 struct compressed_pixelstore store; 422 int i; 423 424 _mesa_compute_compressed_pixelstore(dims, ti->TexFormat, 425 width, height, depth, 426 &ctx->Unpack, &store); 427 428 src += store.SkipBytes; 429 430 assert(store.CopySlices == 1); 431 432 /* copy rows of blocks */ 433 for (i = 0; i < store.CopyRowsPerSlice; i++) { 434 memcpy(dst, src, store.CopyBytesPerRow); 435 dst += row_stride; 436 src += store.TotalBytesPerRow; 437 } 438 } 439 440 static void 441 nouveau_teximage(struct gl_context *ctx, GLint dims, 442 struct gl_texture_image *ti, 443 GLsizei imageSize, 444 GLenum format, GLenum type, const GLvoid *pixels, 445 const struct gl_pixelstore_attrib *packing, 446 GLboolean compressed) 447 { 448 struct gl_texture_object *t = ti->TexObject; 449 const GLuint level = ti->Level; 450 struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface; 451 struct nouveau_teximage *nti = to_nouveau_teximage(ti); 452 int ret; 453 GLuint depth = compressed ? 1 : ti->Depth; 454 455 /* Allocate a new bo for the image. */ 456 nouveau_surface_alloc(ctx, s, LINEAR, get_teximage_placement(ti), 457 ti->TexFormat, ti->Width, ti->Height); 458 nti->base.RowStride = s->pitch / s->cpp; 459 460 if (compressed) 461 pixels = _mesa_validate_pbo_compressed_teximage(ctx, 462 dims, imageSize, 463 pixels, packing, "glCompressedTexImage"); 464 else 465 pixels = _mesa_validate_pbo_teximage(ctx, 466 dims, ti->Width, ti->Height, depth, format, type, 467 pixels, packing, "glTexImage"); 468 469 if (pixels) { 470 GLubyte *map; 471 int row_stride; 472 473 /* Store the pixel data. */ 474 nouveau_map_texture_image(ctx, ti, 0, 475 0, 0, ti->Width, ti->Height, 476 GL_MAP_WRITE_BIT, 477 &map, &row_stride); 478 479 if (compressed) { 480 nouveau_compressed_copy(ctx, dims, ti, 481 ti->Width, ti->Height, depth, 482 pixels, map, row_stride); 483 } else { 484 ret = _mesa_texstore(ctx, dims, ti->_BaseFormat, 485 ti->TexFormat, 486 row_stride, 487 &map, 488 ti->Width, ti->Height, depth, 489 format, type, pixels, packing); 490 assert(ret); 491 } 492 493 nouveau_unmap_texture_image(ctx, ti, 0); 494 _mesa_unmap_teximage_pbo(ctx, packing); 495 496 if (!validate_teximage(ctx, t, level, 0, 0, 0, 497 ti->Width, ti->Height, depth)) 498 /* It doesn't fit, mark it as dirty. */ 499 texture_dirty(t); 500 } 501 502 if (level == t->BaseLevel) { 503 if (!teximage_fits(t, level)) 504 relayout_texture(ctx, t); 505 nouveau_texture_validate(ctx, t); 506 } 507 508 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); 509 context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit); 510 } 511 512 513 static void 514 nouveau_teximage_123d(struct gl_context *ctx, GLuint dims, 515 struct gl_texture_image *ti, 516 GLenum format, GLenum type, const GLvoid *pixels, 517 const struct gl_pixelstore_attrib *packing) 518 { 519 nouveau_teximage(ctx, dims, ti, 0, format, type, pixels, 520 packing, GL_FALSE); 521 } 522 523 static void 524 nouveau_compressed_teximage(struct gl_context *ctx, GLuint dims, 525 struct gl_texture_image *ti, 526 GLsizei imageSize, const GLvoid *data) 527 { 528 nouveau_teximage(ctx, 2, ti, imageSize, 0, 0, data, 529 &ctx->Unpack, GL_TRUE); 530 } 531 532 static GLboolean 533 nouveau_teximage_alloc(struct gl_context *ctx, struct gl_texture_image *ti) 534 { 535 nouveau_teximage(ctx, 3, ti, 0, 0, 0, NULL, 536 &ctx->DefaultPacking, 537 _mesa_is_format_compressed(ti->TexFormat)); 538 return GL_TRUE; 539 } 540 541 static void 542 nouveau_texsubimage(struct gl_context *ctx, GLint dims, 543 struct gl_texture_image *ti, 544 GLint xoffset, GLint yoffset, GLint zoffset, 545 GLint width, GLint height, GLint depth, 546 GLsizei imageSize, 547 GLenum format, GLenum type, const void *pixels, 548 const struct gl_pixelstore_attrib *packing, 549 GLboolean compressed) 550 { 551 int ret; 552 553 if (compressed) 554 pixels = _mesa_validate_pbo_compressed_teximage(ctx, 555 dims, imageSize, 556 pixels, packing, "glCompressedTexSubImage"); 557 else 558 pixels = _mesa_validate_pbo_teximage(ctx, 559 dims, width, height, depth, format, type, 560 pixels, packing, "glTexSubImage"); 561 562 if (pixels) { 563 GLubyte *map; 564 int row_stride; 565 566 nouveau_map_texture_image(ctx, ti, 0, 567 xoffset, yoffset, width, height, 568 GL_MAP_WRITE_BIT, &map, &row_stride); 569 570 if (compressed) { 571 nouveau_compressed_copy(ctx, dims, ti, 572 width, height, depth, 573 pixels, map, row_stride); 574 } else { 575 ret = _mesa_texstore(ctx, dims, ti->_BaseFormat, 576 ti->TexFormat, 577 row_stride, &map, 578 width, height, depth, 579 format, type, pixels, packing); 580 assert(ret); 581 } 582 583 nouveau_unmap_texture_image(ctx, ti, 0); 584 _mesa_unmap_teximage_pbo(ctx, packing); 585 } 586 587 if (!to_nouveau_texture(ti->TexObject)->dirty) 588 validate_teximage(ctx, ti->TexObject, ti->Level, 589 xoffset, yoffset, zoffset, 590 width, height, depth); 591 } 592 593 static void 594 nouveau_texsubimage_123d(struct gl_context *ctx, GLuint dims, 595 struct gl_texture_image *ti, 596 GLint xoffset, GLint yoffset, GLint zoffset, 597 GLint width, GLint height, GLint depth, 598 GLenum format, GLenum type, const void *pixels, 599 const struct gl_pixelstore_attrib *packing) 600 { 601 nouveau_texsubimage(ctx, dims, ti, xoffset, yoffset, zoffset, 602 width, height, depth, 0, format, type, pixels, 603 packing, GL_FALSE); 604 } 605 606 static void 607 nouveau_compressed_texsubimage(struct gl_context *ctx, GLuint dims, 608 struct gl_texture_image *ti, 609 GLint xoffset, GLint yoffset, GLint zoffset, 610 GLsizei width, GLint height, GLint depth, 611 GLenum format, 612 GLint imageSize, const void *data) 613 { 614 nouveau_texsubimage(ctx, dims, ti, xoffset, yoffset, zoffset, 615 width, height, depth, imageSize, format, 0, data, 616 &ctx->Unpack, GL_TRUE); 617 } 618 619 static void 620 nouveau_bind_texture(struct gl_context *ctx, GLuint texUnit, 621 GLenum target, struct gl_texture_object *t) 622 { 623 context_dirty_i(ctx, TEX_OBJ, texUnit); 624 context_dirty_i(ctx, TEX_ENV, texUnit); 625 } 626 627 static mesa_format 628 get_texbuffer_format(struct gl_renderbuffer *rb, GLint format) 629 { 630 struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; 631 632 if (s->cpp < 4) 633 return s->format; 634 else if (format == __DRI_TEXTURE_FORMAT_RGBA) 635 return MESA_FORMAT_B8G8R8A8_UNORM; 636 else 637 return MESA_FORMAT_B8G8R8X8_UNORM; 638 } 639 640 void 641 nouveau_set_texbuffer(__DRIcontext *dri_ctx, 642 GLint target, GLint format, 643 __DRIdrawable *draw) 644 { 645 struct nouveau_context *nctx = dri_ctx->driverPrivate; 646 struct gl_context *ctx = &nctx->base; 647 struct gl_framebuffer *fb = draw->driverPrivate; 648 struct gl_renderbuffer *rb = 649 fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; 650 struct gl_texture_object *t = _mesa_get_current_tex_object(ctx, target); 651 struct gl_texture_image *ti; 652 struct nouveau_teximage *nti; 653 struct nouveau_surface *s; 654 655 _mesa_lock_texture(ctx, t); 656 ti = _mesa_get_tex_image(ctx, t, target, 0); 657 nti = to_nouveau_teximage(ti); 658 s = &to_nouveau_teximage(ti)->surface; 659 660 /* Update the texture surface with the given drawable. */ 661 nouveau_update_renderbuffers(dri_ctx, draw); 662 nouveau_surface_ref(&to_nouveau_renderbuffer(rb)->surface, s); 663 664 s->format = get_texbuffer_format(rb, format); 665 666 /* Update the image fields. */ 667 _mesa_init_teximage_fields(ctx, ti, s->width, s->height, 668 1, 0, s->cpp, s->format); 669 nti->base.RowStride = s->pitch / s->cpp; 670 671 /* Try to validate it. */ 672 if (!validate_teximage(ctx, t, 0, 0, 0, 0, s->width, s->height, 1)) 673 nouveau_texture_reallocate(ctx, t); 674 675 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); 676 context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit); 677 678 _mesa_unlock_texture(ctx, t); 679 } 680 681 void 682 nouveau_texture_functions_init(struct dd_function_table *functions) 683 { 684 functions->NewTextureObject = nouveau_texture_new; 685 functions->DeleteTexture = nouveau_texture_free; 686 functions->NewTextureImage = nouveau_teximage_new; 687 functions->FreeTextureImageBuffer = nouveau_teximage_free; 688 functions->AllocTextureImageBuffer = nouveau_teximage_alloc; 689 functions->ChooseTextureFormat = nouveau_choose_tex_format; 690 functions->TexImage = nouveau_teximage_123d; 691 functions->TexSubImage = nouveau_texsubimage_123d; 692 functions->CompressedTexImage = nouveau_compressed_teximage; 693 functions->CompressedTexSubImage = nouveau_compressed_texsubimage; 694 functions->BindTexture = nouveau_bind_texture; 695 functions->MapTextureImage = nouveau_map_texture_image; 696 functions->UnmapTextureImage = nouveau_unmap_texture_image; 697 } 698