u_surface.c revision e968975cb57eb854769292f7c6ff773c64a386c3
149b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul/**************************************************************************
249b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul *
349b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * Copyright 2009 VMware, Inc.  All Rights Reserved.
449b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul *
549b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a
649b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * copy of this software and associated documentation files (the
749b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * "Software"), to deal in the Software without restriction, including
849b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * without limitation the rights to use, copy, modify, merge, publish,
949b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * distribute, sub license, and/or sell copies of the Software, and to
1049b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * permit persons to whom the Software is furnished to do so, subject to
1149b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * the following conditions:
1249b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul *
1349b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * The above copyright notice and this permission notice (including the
1449b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * next paragraph) shall be included in all copies or substantial portions
1549b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * of the Software.
1649b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul *
1749b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1849b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1949b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
2049b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
2149b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2249b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2349b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2449b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul *
2549b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul **************************************************************************/
2649b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul
2749b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul/**
2849b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * @file
2949b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * Surface utility functions.
3049b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul *
3149b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * @author Brian Paul
3249b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul */
3349b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul
3449b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul
358b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul#include "pipe/p_defines.h"
3649b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul#include "pipe/p_screen.h"
3749b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul#include "pipe/p_state.h"
3849b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul
398b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul#include "util/u_format.h"
408b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul#include "util/u_inlines.h"
418b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul#include "util/u_rect.h"
4249b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul#include "util/u_surface.h"
43a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger#include "util/u_pack_color.h"
4449b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul
454c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheideggervoid
464c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheideggeru_surface_default_template(struct pipe_surface *view,
474c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                           const struct pipe_resource *texture,
484c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                           unsigned bind)
494c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger{
504c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   view->format = texture->format;
514c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   view->u.tex.level = 0;
524c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   view->u.tex.first_layer = 0;
534c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   view->u.tex.last_layer = 0;
544c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   /* XXX should filter out all non-rt/ds bind flags ? */
554c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   view->usage = bind;
564c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger}
5749b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul
5849b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul/**
5949b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * Helper to quickly create an RGBA rendering surface of a certain size.
6049b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * \param textureOut  returns the new texture
6149b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * \param surfaceOut  returns the new surface
6249b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * \return TRUE for success, FALSE if failure
6349b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul */
6449b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paulboolean
654c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheideggerutil_create_rgba_surface(struct pipe_context *pipe,
6649b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul                         uint width, uint height,
674c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                         uint bind,
68287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                         struct pipe_resource **textureOut,
6949b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul                         struct pipe_surface **surfaceOut)
7049b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul{
7149b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   static const enum pipe_format rgbaFormats[] = {
7249b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul      PIPE_FORMAT_B8G8R8A8_UNORM,
73712ba6e6b049c050af3ac1992aba009ebbe56ca5José Fonseca      PIPE_FORMAT_A8R8G8B8_UNORM,
74712ba6e6b049c050af3ac1992aba009ebbe56ca5José Fonseca      PIPE_FORMAT_A8B8G8R8_UNORM,
7549b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul      PIPE_FORMAT_NONE
7649b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   };
7749b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   const uint target = PIPE_TEXTURE_2D;
7849b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   enum pipe_format format = PIPE_FORMAT_NONE;
79287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct pipe_resource templ;
804c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   struct pipe_surface surf_templ;
814c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   struct pipe_screen *screen = pipe->screen;
8249b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   uint i;
8349b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul
8449b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   /* Choose surface format */
8549b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   for (i = 0; rgbaFormats[i]; i++) {
8649b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul      if (screen->is_format_supported(screen, rgbaFormats[i],
87e968975cb57eb854769292f7c6ff773c64a386c3Marek Olšák                                      target, 0, bind)) {
8849b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul         format = rgbaFormats[i];
8949b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul         break;
9049b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul      }
9149b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   }
9249b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   if (format == PIPE_FORMAT_NONE)
9349b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul      return FALSE;  /* unable to get an rgba format!?! */
9449b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul
9549b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   /* create texture */
9649b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   memset(&templ, 0, sizeof(templ));
9749b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   templ.target = target;
9849b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   templ.format = format;
9949b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   templ.last_level = 0;
100683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell   templ.width0 = width;
101683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell   templ.height0 = height;
102683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell   templ.depth0 = 1;
1034c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   templ.array_size = 1;
104287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   templ.bind = bind;
10549b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul
106287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   *textureOut = screen->resource_create(screen, &templ);
10749b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   if (!*textureOut)
10849b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul      return FALSE;
10949b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul
1104c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   /* create surface */
1114c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   memset(&surf_templ, 0, sizeof(surf_templ));
1124c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   u_surface_default_template(&surf_templ, *textureOut, bind);
11349b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   /* create surface / view into texture */
1144c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   *surfaceOut = pipe->create_surface(pipe,
1154c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                      *textureOut,
1164c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                      &surf_templ);
11749b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   if (!*surfaceOut) {
118287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe_resource_reference(textureOut, NULL);
11949b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul      return FALSE;
12049b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   }
12149b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul
12249b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   return TRUE;
12349b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul}
12449b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul
12549b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul
12649b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul/**
12749b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * Release the surface and texture from util_create_rgba_surface().
12849b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul */
12949b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paulvoid
130287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellutil_destroy_rgba_surface(struct pipe_resource *texture,
13149b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul                          struct pipe_surface *surface)
13249b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul{
13349b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul   pipe_surface_reference(&surface, NULL);
134287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   pipe_resource_reference(&texture, NULL);
13549b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul}
1368b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
1378b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
1388b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
1398b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul/**
140f4ad68a5288abe714f4c98307ed676869aa661faRoland Scheidegger * Fallback function for pipe->resource_copy_region().
1418b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul * Note: (X,Y)=(0,0) is always the upper-left corner.
1428b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul */
1438b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paulvoid
144815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheideggerutil_resource_copy_region(struct pipe_context *pipe,
145815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheidegger                          struct pipe_resource *dst,
1464c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                          unsigned dst_level,
147815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheidegger                          unsigned dst_x, unsigned dst_y, unsigned dst_z,
148815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheidegger                          struct pipe_resource *src,
1494c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                          unsigned src_level,
1504c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                          const struct pipe_box *src_box)
1518b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul{
1528b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   struct pipe_transfer *src_trans, *dst_trans;
1538b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   void *dst_map;
1548b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   const void *src_map;
1558b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   enum pipe_format src_format, dst_format;
1564c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   unsigned w = src_box->width;
1574c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   unsigned h = src_box->height;
1588b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
159815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheidegger   assert(src && dst);
160815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheidegger   if (!src || !dst)
1618b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul      return;
1628b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
163815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheidegger   src_format = src->format;
164815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheidegger   dst_format = dst->format;
1658b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
1668b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   src_trans = pipe_get_transfer(pipe,
1674c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 src,
1684c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 src_level,
1694c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 src_box->z,
1704c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 PIPE_TRANSFER_READ,
1714c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 src_box->x, src_box->y, w, h);
1728b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
1738b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   dst_trans = pipe_get_transfer(pipe,
1744c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 dst,
1754c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 dst_level,
1764c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 dst_z,
1774c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 PIPE_TRANSFER_WRITE,
1784c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 dst_x, dst_y, w, h);
1798b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
1808b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   assert(util_format_get_blocksize(dst_format) == util_format_get_blocksize(src_format));
1818b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   assert(util_format_get_blockwidth(dst_format) == util_format_get_blockwidth(src_format));
1828b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   assert(util_format_get_blockheight(dst_format) == util_format_get_blockheight(src_format));
1838b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
1848b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   src_map = pipe->transfer_map(pipe, src_trans);
1858b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   dst_map = pipe->transfer_map(pipe, dst_trans);
1868b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
1878b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   assert(src_map);
1888b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   assert(dst_map);
1898b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
1908b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   if (src_map && dst_map) {
1918b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul      util_copy_rect(dst_map,
1928b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul                     dst_format,
1938b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul                     dst_trans->stride,
1948b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul                     0, 0,
1958b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul                     w, h,
1968b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul                     src_map,
197815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheidegger                     src_trans->stride,
1988b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul                     0,
199815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheidegger                     0);
2008b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   }
2018b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
2028b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   pipe->transfer_unmap(pipe, src_trans);
2038b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   pipe->transfer_unmap(pipe, dst_trans);
2048b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
2058b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   pipe->transfer_destroy(pipe, src_trans);
2068b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   pipe->transfer_destroy(pipe, dst_trans);
2078b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul}
2088b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
2098b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
2108b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
2118b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8))
2128b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
2138b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
2148b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul/**
215a6e5c6c000df8655de3b41d5809547bb41c88c23Roland Scheidegger * Fallback for pipe->clear_render_target() function.
216a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger * XXX this looks too hackish to be really useful.
217a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger * cpp > 4 looks like a gross hack at best...
218a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger * Plus can't use these transfer fallbacks when clearing
219a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger * multisampled surfaces for instance.
2208b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul */
2218b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paulvoid
222a6e5c6c000df8655de3b41d5809547bb41c88c23Roland Scheideggerutil_clear_render_target(struct pipe_context *pipe,
223a6e5c6c000df8655de3b41d5809547bb41c88c23Roland Scheidegger                         struct pipe_surface *dst,
224a6e5c6c000df8655de3b41d5809547bb41c88c23Roland Scheidegger                         const float *rgba,
225a6e5c6c000df8655de3b41d5809547bb41c88c23Roland Scheidegger                         unsigned dstx, unsigned dsty,
226a6e5c6c000df8655de3b41d5809547bb41c88c23Roland Scheidegger                         unsigned width, unsigned height)
2278b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul{
2288b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   struct pipe_transfer *dst_trans;
2298b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   void *dst_map;
230a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger   union util_color uc;
2318b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
232a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger   assert(dst->texture);
233a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger   if (!dst->texture)
2348b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul      return;
2354c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   /* XXX: should handle multiple layers */
2368b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   dst_trans = pipe_get_transfer(pipe,
2374c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 dst->texture,
2384c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 dst->u.tex.level,
2394c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 dst->u.tex.first_layer,
2404c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 PIPE_TRANSFER_WRITE,
2414c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 dstx, dsty, width, height);
2428b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
2438b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   dst_map = pipe->transfer_map(pipe, dst_trans);
2448b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
2458b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   assert(dst_map);
2468b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
2478b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   if (dst_map) {
2488b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul      assert(dst_trans->stride > 0);
2498b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
250c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger      util_pack_color(rgba, dst->texture->format, &uc);
251c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger      util_fill_rect(dst_map, dst->texture->format,
252c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger                     dst_trans->stride,
253c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger                     0, 0, width, height, &uc);
2548b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   }
2558b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul
2568b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   pipe->transfer_unmap(pipe, dst_trans);
2578b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul   pipe->transfer_destroy(pipe, dst_trans);
2588b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul}
259a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger
260a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger/**
261a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger * Fallback for pipe->clear_stencil() function.
262a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger * sw fallback doesn't look terribly useful here.
263a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger * Plus can't use these transfer fallbacks when clearing
264a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger * multisampled surfaces for instance.
265a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger */
266a2bf4817bb735298ec9282971167e62612942c0dRoland Scheideggervoid
267a2bf4817bb735298ec9282971167e62612942c0dRoland Scheideggerutil_clear_depth_stencil(struct pipe_context *pipe,
268a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger                         struct pipe_surface *dst,
269a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger                         unsigned clear_flags,
270a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger                         double depth,
271a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger                         unsigned stencil,
272a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger                         unsigned dstx, unsigned dsty,
273a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger                         unsigned width, unsigned height)
274a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger{
275a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger   struct pipe_transfer *dst_trans;
276a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger   ubyte *dst_map;
277a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger   boolean need_rmw = FALSE;
278a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger
279a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger   if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) &&
280a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger       ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
281a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger       util_format_is_depth_and_stencil(dst->format))
282a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger      need_rmw = TRUE;
283a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger
284a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger   assert(dst->texture);
285a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger   if (!dst->texture)
286a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger      return;
287a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger   dst_trans = pipe_get_transfer(pipe,
288a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger                                 dst->texture,
2894c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 dst->u.tex.level,
2904c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 dst->u.tex.first_layer,
291a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger                                 (need_rmw ? PIPE_TRANSFER_READ_WRITE :
292a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger                                     PIPE_TRANSFER_WRITE),
293a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger                                 dstx, dsty, width, height);
294a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger
295a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger   dst_map = pipe->transfer_map(pipe, dst_trans);
296a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger
297a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger   assert(dst_map);
298a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger
299a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger   if (dst_map) {
300a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger      unsigned dst_stride = dst_trans->stride;
301a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger      unsigned zstencil = util_pack_z_stencil(dst->texture->format, depth, stencil);
302a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger      unsigned i, j;
303a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger      assert(dst_trans->stride > 0);
304a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger
305a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger      switch (util_format_get_blocksize(dst->format)) {
306a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger      case 1:
307a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger         assert(dst->format == PIPE_FORMAT_S8_USCALED);
308a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger         if(dst_stride == width)
309a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger            memset(dst_map, (ubyte) zstencil, height * width);
310a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger         else {
311a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger            for (i = 0; i < height; i++) {
312a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger               memset(dst_map, (ubyte) zstencil, width);
313a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger               dst_map += dst_stride;
314a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger            }
315a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger         }
316a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger         break;
317a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger      case 2:
318a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger         assert(dst->format == PIPE_FORMAT_Z16_UNORM);
319a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger         for (i = 0; i < height; i++) {
320a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger            uint16_t *row = (uint16_t *)dst_map;
321a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger            for (j = 0; j < width; j++)
322a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger               *row++ = (uint16_t) zstencil;
323a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger            dst_map += dst_stride;
324a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger            }
325a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger         break;
326a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger      case 4:
327a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger         if (!need_rmw) {
328a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger            for (i = 0; i < height; i++) {
329a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger               uint32_t *row = (uint32_t *)dst_map;
330a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger               for (j = 0; j < width; j++)
331a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger                  *row++ = zstencil;
332a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger               dst_map += dst_stride;
333a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger            }
334a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger         }
335a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger         else {
336a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger            uint32_t dst_mask;
337a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger            if (dst->format == PIPE_FORMAT_Z24_UNORM_S8_USCALED)
338a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger               dst_mask = 0xffffff00;
339a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger            else {
340a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger               assert(dst->format == PIPE_FORMAT_S8_USCALED_Z24_UNORM);
341a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger               dst_mask = 0xffffff;
342a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger            }
343a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger            if (clear_flags & PIPE_CLEAR_DEPTH)
344a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger               dst_mask = ~dst_mask;
345a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger            for (i = 0; i < height; i++) {
346a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger               uint32_t *row = (uint32_t *)dst_map;
347a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger               for (j = 0; j < width; j++) {
348a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger                  uint32_t tmp = *row & dst_mask;
349a01578c84ffcc03a98b3c3f20d05cdb0e0e4ada7Luca Barbieri                  *row++ = tmp | (zstencil & ~dst_mask);
350a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger               }
351a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger               dst_map += dst_stride;
352a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger            }
353a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger         }
354a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger        break;
355a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger      case 8:
356a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger      default:
357a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger         assert(0);
358a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger         break;
359a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger      }
360a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger   }
361a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger
362a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger   pipe->transfer_unmap(pipe, dst_trans);
363a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger   pipe->transfer_destroy(pipe, dst_trans);
364a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger}
365