Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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.