u_rect.c revision 8604a896a60a5f3f81d6ebecf827aeaddf8c640c
1e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer/**************************************************************************
2e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer *
3e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * All Rights Reserved.
5e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer *
6e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * Permission is hereby granted, free of charge, to any person obtaining a
7e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * copy of this software and associated documentation files (the
8e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * "Software"), to deal in the Software without restriction, including
9e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * without limitation the rights to use, copy, modify, merge, publish,
10e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * distribute, sub license, and/or sell copies of the Software, and to
11e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * permit persons to whom the Software is furnished to do so, subject to
12e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * the following conditions:
13e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer *
14e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * The above copyright notice and this permission notice (including the
15e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * next paragraph) shall be included in all copies or substantial portions
16e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * of the Software.
17e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer *
18e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer *
26e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer **************************************************************************/
27e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer
28e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer/**
292b87174ec306673c59386102890f35907be497efBrian Paul * Rectangle-related helper functions.
30e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer */
31e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer
32e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer
33e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer#include "pipe/p_defines.h"
344ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca#include "pipe/p_format.h"
35ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul#include "pipe/p_context.h"
36ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul#include "pipe/p_screen.h"
37fe1e39afbb147deab60ecc932c24f921b46f1364Brian Paul#include "util/u_rect.h"
38e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer
39e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer
40e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer/**
41e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * Copy 2D rect from one place to another.
42e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer * Position and sizes are in pixels.
43f738c3acaca235c68a26c7b7d41903c64a36ae9fBrian Paul * src_pitch may be negative to do vertical flip of pixels from source.
44e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer */
45e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzervoid
468604a896a60a5f3f81d6ebecf827aeaddf8c640cBrian Paulutil_copy_rect(ubyte * dst,
474ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca               const struct pipe_format_block *block,
484ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca               unsigned dst_stride,
49e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer               unsigned dst_x,
50e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer               unsigned dst_y,
51e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer               unsigned width,
52e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer               unsigned height,
53e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer               const ubyte * src,
544ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca               int src_stride,
55e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer               unsigned src_x,
56e922adbe1d6c1764968377658ea92ae6de0585dbMichel Dänzer               int src_y)
57e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer{
58e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer   unsigned i;
594ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
60e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer
614ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   assert(block->size > 0);
624ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   assert(block->width > 0);
634ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   assert(block->height > 0);
64016dbb0cf395702cfad046f827e3cc4541ae5818Brian Paul   assert(src_x >= 0);
65016dbb0cf395702cfad046f827e3cc4541ae5818Brian Paul   assert(src_y >= 0);
66016dbb0cf395702cfad046f827e3cc4541ae5818Brian Paul   assert(dst_x >= 0);
67016dbb0cf395702cfad046f827e3cc4541ae5818Brian Paul   assert(dst_y >= 0);
68016dbb0cf395702cfad046f827e3cc4541ae5818Brian Paul
694ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   dst_x /= block->width;
704ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   dst_y /= block->height;
714ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   width = (width + block->width - 1)/block->width;
724ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   height = (height + block->height - 1)/block->height;
734ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   src_x /= block->width;
744ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   src_y /= block->height;
754ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca
764ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   dst += dst_x * block->size;
774ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   src += src_x * block->size;
784ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   dst += dst_y * dst_stride;
794ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   src += src_y * src_stride_pos;
804ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   width *= block->size;
81e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer
824ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   if (width == dst_stride && width == src_stride)
83e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer      memcpy(dst, src, height * width);
84e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer   else {
85e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer      for (i = 0; i < height; i++) {
86e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer         memcpy(dst, src, width);
874ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca         dst += dst_stride;
884ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca         src += src_stride;
89e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer      }
90e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer   }
91e44bdcf9789caf9971c3c94605fbff7ce66af7baMichel Dänzer}
924ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca
934ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonsecavoid
948604a896a60a5f3f81d6ebecf827aeaddf8c640cBrian Paulutil_fill_rect(ubyte * dst,
954ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca               const struct pipe_format_block *block,
964ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca               unsigned dst_stride,
974ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca               unsigned dst_x,
984ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca               unsigned dst_y,
994ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca               unsigned width,
1004ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca               unsigned height,
1014ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca               uint32_t value)
1024ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca{
1034ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   unsigned i, j;
1044ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   unsigned width_size;
1054ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca
1064ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   assert(block->size > 0);
1074ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   assert(block->width > 0);
1084ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   assert(block->height > 0);
1094ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   assert(dst_x >= 0);
1104ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   assert(dst_y >= 0);
1114ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca
1124ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   dst_x /= block->width;
1134ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   dst_y /= block->height;
1144ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   width = (width + block->width - 1)/block->width;
1154ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   height = (height + block->height - 1)/block->height;
1164ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca
1174ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   dst += dst_x * block->size;
1184ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   dst += dst_y * dst_stride;
1194ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   width_size = width * block->size;
1204ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca
1214ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   switch (block->size) {
1224ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   case 1:
1234ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      if(dst_stride == width_size)
1244ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca	 memset(dst, (ubyte) value, height * width_size);
1254ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      else {
1264ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca	 for (i = 0; i < height; i++) {
1274ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca	    memset(dst, (ubyte) value, width_size);
1284ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca	    dst += dst_stride;
1294ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca	 }
1304ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      }
1314ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      break;
1324ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   case 2:
1334ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      for (i = 0; i < height; i++) {
1344ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca	 uint16_t *row = (uint16_t *)dst;
1354ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca	 for (j = 0; j < width; j++)
1364ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca	    *row++ = (uint16_t) value;
1374ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca	 dst += dst_stride;
1384ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      }
1394ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      break;
1404ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   case 4:
1414ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      for (i = 0; i < height; i++) {
1424ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca	 uint32_t *row = (uint32_t *)dst;
1434ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca	 for (j = 0; j < width; j++)
1444ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca	    *row++ = value;
1454ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca	 dst += dst_stride;
1464ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      }
1474ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca      break;
1484ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   default:
1494ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca	 assert(0);
1504ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca	 break;
1514ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca   }
1524ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca}
153ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
154ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
155ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
156ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul/**
157ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul * Fallback function for pipe->surface_copy().
158ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul * Note: (X,Y)=(0,0) is always the upper-left corner.
159ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul * if do_flip, flip the image vertically on its way from src rect to dst rect.
160ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul * XXX should probably put this in new u_surface.c file...
161ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul */
162ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paulvoid
163ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paulutil_surface_copy(struct pipe_context *pipe,
164ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                  boolean do_flip,
165ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                  struct pipe_surface *dst,
166ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                  unsigned dst_x, unsigned dst_y,
167ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                  struct pipe_surface *src,
168ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                  unsigned src_x, unsigned src_y,
169ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                  unsigned w, unsigned h)
170ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul{
171ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul   struct pipe_screen *screen = pipe->screen;
1724617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer   struct pipe_transfer *src_trans, *dst_trans;
173ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul   void *dst_map;
174ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul   const void *src_map;
175ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
1764617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer   assert(src->texture && dst->texture);
1774617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer   if (!src->texture || !dst->texture)
1784617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer      return;
1794617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer   src_trans = screen->get_tex_transfer(screen,
180ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                                        src->texture,
181ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                                        src->face,
182ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                                        src->level,
183ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                                        src->zslice,
1844617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer                                        PIPE_TRANSFER_READ,
1854617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer                                        src_x, src_y, w, h);
186ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
1874617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer   dst_trans = screen->get_tex_transfer(screen,
188ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                                        dst->texture,
189ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                                        dst->face,
190ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                                        dst->level,
191ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                                        dst->zslice,
1924617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer                                        PIPE_TRANSFER_WRITE,
1934617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer                                        dst_x, dst_y, w, h);
194ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
1955af34758e3bba55cb8c227ae1256818e8f112727Michel Dänzer   assert(dst_trans->block.size == src_trans->block.size);
1965af34758e3bba55cb8c227ae1256818e8f112727Michel Dänzer   assert(dst_trans->block.width == src_trans->block.width);
1975af34758e3bba55cb8c227ae1256818e8f112727Michel Dänzer   assert(dst_trans->block.height == src_trans->block.height);
1985af34758e3bba55cb8c227ae1256818e8f112727Michel Dänzer
1994617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer   src_map = pipe->screen->transfer_map(screen, src_trans);
2004617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer   dst_map = pipe->screen->transfer_map(screen, dst_trans);
201ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
202ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul   assert(src_map);
203ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul   assert(dst_map);
204ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
205ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul   if (src_map && dst_map) {
206ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul      /* If do_flip, invert src_y position and pass negative src stride */
2078604a896a60a5f3f81d6ebecf827aeaddf8c640cBrian Paul      util_copy_rect(dst_map,
2084617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer                     &dst_trans->block,
2094617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer                     dst_trans->stride,
2104617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer                     0, 0,
211ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                     w, h,
212ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                     src_map,
2134617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer                     do_flip ? -(int) src_trans->stride : src_trans->stride,
2144617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer                     0,
2154617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer                     do_flip ? h - 1 : 0);
216ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul   }
217ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
2184617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer   pipe->screen->transfer_unmap(pipe->screen, src_trans);
2194617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer   pipe->screen->transfer_unmap(pipe->screen, dst_trans);
220ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
2215e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer   screen->tex_transfer_destroy(src_trans);
2225e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer   screen->tex_transfer_destroy(dst_trans);
223ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul}
224ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
225ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
226ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
227ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8))
228ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
229ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
230ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul/**
231ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul * Fallback for pipe->surface_fill() function.
232ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul * XXX should probably put this in new u_surface.c file...
233ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul */
234ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paulvoid
235ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paulutil_surface_fill(struct pipe_context *pipe,
236ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                  struct pipe_surface *dst,
237ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                  unsigned dstx, unsigned dsty,
238ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                  unsigned width, unsigned height, unsigned value)
239ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul{
240ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul   struct pipe_screen *screen = pipe->screen;
2414617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer   struct pipe_transfer *dst_trans;
242ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul   void *dst_map;
243ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
2444617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer   assert(dst->texture);
2454617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer   if (!dst->texture)
2464617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer      return;
2474617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer   dst_trans = screen->get_tex_transfer(screen,
248ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                                        dst->texture,
249ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                                        dst->face,
250ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                                        dst->level,
251ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                                        dst->zslice,
2524617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer                                        PIPE_TRANSFER_WRITE,
2534617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer                                        dstx, dsty, width, height);
254ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
2554617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer   dst_map = pipe->screen->transfer_map(screen, dst_trans);
256ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
257ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul   assert(dst_map);
258ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
259ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul   if (dst_map) {
2604617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer      assert(dst_trans->stride > 0);
261ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
2624617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer      switch (dst_trans->block.size) {
263ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul      case 1:
264ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul      case 2:
265ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul      case 4:
2668604a896a60a5f3f81d6ebecf827aeaddf8c640cBrian Paul         util_fill_rect(dst_map, &dst_trans->block, dst_trans->stride,
2674617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer                        0, 0, width, height, value);
268ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul         break;
269ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul      case 8:
270ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul         {
271ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul            /* expand the 4-byte clear value to an 8-byte value */
2724617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer            ushort *row = (ushort *) dst_map;
273ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul            ushort val0 = UBYTE_TO_USHORT((value >>  0) & 0xff);
274ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul            ushort val1 = UBYTE_TO_USHORT((value >>  8) & 0xff);
275ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul            ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff);
276ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul            ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff);
277ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul            unsigned i, j;
278ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul            val0 = (val0 << 8) | val0;
279ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul            val1 = (val1 << 8) | val1;
280ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul            val2 = (val2 << 8) | val2;
281ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul            val3 = (val3 << 8) | val3;
282ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul            for (i = 0; i < height; i++) {
283ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul               for (j = 0; j < width; j++) {
284ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                  row[j*4+0] = val0;
285ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                  row[j*4+1] = val1;
286ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                  row[j*4+2] = val2;
287ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul                  row[j*4+3] = val3;
288ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul               }
2894617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer               row += dst_trans->stride/2;
290ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul            }
291ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul         }
292ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul         break;
293ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul      default:
294ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul         assert(0);
295ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul         break;
296ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul      }
297ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul   }
298ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul
2994617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer   pipe->screen->transfer_unmap(pipe->screen, dst_trans);
3005e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer   screen->tex_transfer_destroy(dst_trans);
301ce8c08c2b03d8dc363deb14124372a6bbb4efd99Brian Paul}
302