u_surface.c revision 64f55216e4c11e8acb787bfe40e6dd25e862cd43
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) { 19164f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { 19264f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák memcpy(dst_map, src_map, w); 19364f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák } else { 19464f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák util_copy_rect(dst_map, 19564f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák dst_format, 19664f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák dst_trans->stride, 19764f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák 0, 0, 19864f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák w, h, 19964f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák src_map, 20064f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák src_trans->stride, 20164f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák 0, 20264f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák 0); 20364f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák } 2048b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul } 2058b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2068b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul pipe->transfer_unmap(pipe, src_trans); 2078b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul pipe->transfer_unmap(pipe, dst_trans); 2088b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2098b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul pipe->transfer_destroy(pipe, src_trans); 2108b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul pipe->transfer_destroy(pipe, dst_trans); 2118b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul} 2128b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2138b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2148b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2158b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8)) 2168b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2178b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2188b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul/** 219a6e5c6c000df8655de3b41d5809547bb41c88c23Roland Scheidegger * Fallback for pipe->clear_render_target() function. 220a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger * XXX this looks too hackish to be really useful. 221a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger * cpp > 4 looks like a gross hack at best... 222a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger * Plus can't use these transfer fallbacks when clearing 223a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger * multisampled surfaces for instance. 2248b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul */ 2258b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paulvoid 226a6e5c6c000df8655de3b41d5809547bb41c88c23Roland Scheideggerutil_clear_render_target(struct pipe_context *pipe, 227a6e5c6c000df8655de3b41d5809547bb41c88c23Roland Scheidegger struct pipe_surface *dst, 228a6e5c6c000df8655de3b41d5809547bb41c88c23Roland Scheidegger const float *rgba, 229a6e5c6c000df8655de3b41d5809547bb41c88c23Roland Scheidegger unsigned dstx, unsigned dsty, 230a6e5c6c000df8655de3b41d5809547bb41c88c23Roland Scheidegger unsigned width, unsigned height) 2318b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul{ 2328b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul struct pipe_transfer *dst_trans; 2338b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul void *dst_map; 234a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger union util_color uc; 2358b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 236a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger assert(dst->texture); 237a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger if (!dst->texture) 2388b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul return; 2394c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger /* XXX: should handle multiple layers */ 2408b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul dst_trans = pipe_get_transfer(pipe, 2414c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger dst->texture, 2424c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger dst->u.tex.level, 2434c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger dst->u.tex.first_layer, 2444c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger PIPE_TRANSFER_WRITE, 2454c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger dstx, dsty, width, height); 2468b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2478b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul dst_map = pipe->transfer_map(pipe, dst_trans); 2488b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2498b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul assert(dst_map); 2508b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2518b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul if (dst_map) { 2528b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul assert(dst_trans->stride > 0); 2538b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 254c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger util_pack_color(rgba, dst->texture->format, &uc); 255c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger util_fill_rect(dst_map, dst->texture->format, 256c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger dst_trans->stride, 257c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger 0, 0, width, height, &uc); 2588b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul } 2598b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2608b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul pipe->transfer_unmap(pipe, dst_trans); 2618b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul pipe->transfer_destroy(pipe, dst_trans); 2628b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul} 263a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger 264a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger/** 265a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger * Fallback for pipe->clear_stencil() function. 266a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger * sw fallback doesn't look terribly useful here. 267a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger * Plus can't use these transfer fallbacks when clearing 268a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger * multisampled surfaces for instance. 269a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger */ 270a2bf4817bb735298ec9282971167e62612942c0dRoland Scheideggervoid 271a2bf4817bb735298ec9282971167e62612942c0dRoland Scheideggerutil_clear_depth_stencil(struct pipe_context *pipe, 272a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger struct pipe_surface *dst, 273a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger unsigned clear_flags, 274a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger double depth, 275a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger unsigned stencil, 276a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger unsigned dstx, unsigned dsty, 277a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger unsigned width, unsigned height) 278a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger{ 279a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger struct pipe_transfer *dst_trans; 280a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger ubyte *dst_map; 281a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger boolean need_rmw = FALSE; 282a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger 283a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) && 284a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) && 285a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger util_format_is_depth_and_stencil(dst->format)) 286a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger need_rmw = TRUE; 287a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger 288a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger assert(dst->texture); 289a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger if (!dst->texture) 290a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger return; 291a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst_trans = pipe_get_transfer(pipe, 292a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst->texture, 2934c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger dst->u.tex.level, 2944c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger dst->u.tex.first_layer, 295a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger (need_rmw ? PIPE_TRANSFER_READ_WRITE : 296a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger PIPE_TRANSFER_WRITE), 297a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dstx, dsty, width, height); 298a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger 299a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst_map = pipe->transfer_map(pipe, dst_trans); 300a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger 301a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger assert(dst_map); 302a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger 303a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger if (dst_map) { 304a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger unsigned dst_stride = dst_trans->stride; 305a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger unsigned zstencil = util_pack_z_stencil(dst->texture->format, depth, stencil); 306a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger unsigned i, j; 307a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger assert(dst_trans->stride > 0); 308a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger 309a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger switch (util_format_get_blocksize(dst->format)) { 310a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger case 1: 311a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger assert(dst->format == PIPE_FORMAT_S8_USCALED); 312a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger if(dst_stride == width) 313a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger memset(dst_map, (ubyte) zstencil, height * width); 314a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger else { 315a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger for (i = 0; i < height; i++) { 316a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger memset(dst_map, (ubyte) zstencil, width); 317a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst_map += dst_stride; 318a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 319a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 320a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger break; 321a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger case 2: 322a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger assert(dst->format == PIPE_FORMAT_Z16_UNORM); 323a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger for (i = 0; i < height; i++) { 324a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger uint16_t *row = (uint16_t *)dst_map; 325a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger for (j = 0; j < width; j++) 326a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger *row++ = (uint16_t) zstencil; 327a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst_map += dst_stride; 328a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 329a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger break; 330a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger case 4: 331a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger if (!need_rmw) { 332a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger for (i = 0; i < height; i++) { 333a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger uint32_t *row = (uint32_t *)dst_map; 334a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger for (j = 0; j < width; j++) 335a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger *row++ = zstencil; 336a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst_map += dst_stride; 337a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 338a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 339a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger else { 340a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger uint32_t dst_mask; 341a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger if (dst->format == PIPE_FORMAT_Z24_UNORM_S8_USCALED) 342a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst_mask = 0xffffff00; 343a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger else { 344a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger assert(dst->format == PIPE_FORMAT_S8_USCALED_Z24_UNORM); 345a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst_mask = 0xffffff; 346a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 347a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger if (clear_flags & PIPE_CLEAR_DEPTH) 348a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst_mask = ~dst_mask; 349a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger for (i = 0; i < height; i++) { 350a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger uint32_t *row = (uint32_t *)dst_map; 351a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger for (j = 0; j < width; j++) { 352a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger uint32_t tmp = *row & dst_mask; 353a01578c84ffcc03a98b3c3f20d05cdb0e0e4ada7Luca Barbieri *row++ = tmp | (zstencil & ~dst_mask); 354a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 355a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst_map += dst_stride; 356a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 357a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 358a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger break; 359a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger case 8: 360a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger default: 361a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger assert(0); 362a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger break; 363a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 364a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 365a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger 366a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger pipe->transfer_unmap(pipe, dst_trans); 367a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger pipe->transfer_destroy(pipe, dst_trans); 368a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger} 369