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 452e87660ca6deba9ba866a8012cf82f41374b5adbBrian Paul 462e87660ca6deba9ba866a8012cf82f41374b5adbBrian Paul/** 472e87660ca6deba9ba866a8012cf82f41374b5adbBrian Paul * Initialize a pipe_surface object. 'view' is considered to have 482e87660ca6deba9ba866a8012cf82f41374b5adbBrian Paul * uninitialized contents. 492e87660ca6deba9ba866a8012cf82f41374b5adbBrian Paul */ 504c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheideggervoid 512e87660ca6deba9ba866a8012cf82f41374b5adbBrian Paulu_surface_default_template(struct pipe_surface *surf, 524c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger const struct pipe_resource *texture, 534c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger unsigned bind) 544c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger{ 552e87660ca6deba9ba866a8012cf82f41374b5adbBrian Paul memset(surf, 0, sizeof(*surf)); 562e87660ca6deba9ba866a8012cf82f41374b5adbBrian Paul 572e87660ca6deba9ba866a8012cf82f41374b5adbBrian Paul surf->format = texture->format; 584c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger /* XXX should filter out all non-rt/ds bind flags ? */ 592e87660ca6deba9ba866a8012cf82f41374b5adbBrian Paul surf->usage = bind; 604c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger} 6149b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul 6249b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul/** 6349b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * Helper to quickly create an RGBA rendering surface of a certain size. 6449b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * \param textureOut returns the new texture 6549b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * \param surfaceOut returns the new surface 6649b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * \return TRUE for success, FALSE if failure 6749b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul */ 6849b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paulboolean 694c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheideggerutil_create_rgba_surface(struct pipe_context *pipe, 7049b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul uint width, uint height, 714c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger uint bind, 72287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_resource **textureOut, 7349b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul struct pipe_surface **surfaceOut) 7449b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul{ 7549b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul static const enum pipe_format rgbaFormats[] = { 7649b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul PIPE_FORMAT_B8G8R8A8_UNORM, 77712ba6e6b049c050af3ac1992aba009ebbe56ca5José Fonseca PIPE_FORMAT_A8R8G8B8_UNORM, 78712ba6e6b049c050af3ac1992aba009ebbe56ca5José Fonseca PIPE_FORMAT_A8B8G8R8_UNORM, 7949b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul PIPE_FORMAT_NONE 8049b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul }; 8149b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul const uint target = PIPE_TEXTURE_2D; 8249b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul enum pipe_format format = PIPE_FORMAT_NONE; 83287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_resource templ; 844c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger struct pipe_surface surf_templ; 854c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger struct pipe_screen *screen = pipe->screen; 8649b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul uint i; 8749b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul 8849b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul /* Choose surface format */ 8949b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul for (i = 0; rgbaFormats[i]; i++) { 9049b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul if (screen->is_format_supported(screen, rgbaFormats[i], 91e968975cb57eb854769292f7c6ff773c64a386c3Marek Olšák target, 0, bind)) { 9249b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul format = rgbaFormats[i]; 9349b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul break; 9449b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul } 9549b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul } 9649b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul if (format == PIPE_FORMAT_NONE) 9749b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul return FALSE; /* unable to get an rgba format!?! */ 9849b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul 9949b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul /* create texture */ 10049b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul memset(&templ, 0, sizeof(templ)); 10149b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul templ.target = target; 10249b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul templ.format = format; 10349b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul templ.last_level = 0; 104683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell templ.width0 = width; 105683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell templ.height0 = height; 106683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell templ.depth0 = 1; 1074c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger templ.array_size = 1; 108287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell templ.bind = bind; 10949b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul 110287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell *textureOut = screen->resource_create(screen, &templ); 11149b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul if (!*textureOut) 11249b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul return FALSE; 11349b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul 1144c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger /* create surface */ 1154c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger u_surface_default_template(&surf_templ, *textureOut, bind); 11649b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul /* create surface / view into texture */ 1174c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger *surfaceOut = pipe->create_surface(pipe, 1184c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger *textureOut, 1194c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger &surf_templ); 12049b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul if (!*surfaceOut) { 121287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_resource_reference(textureOut, NULL); 12249b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul return FALSE; 12349b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul } 12449b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul 12549b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul return TRUE; 12649b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul} 12749b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul 12849b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul 12949b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul/** 13049b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul * Release the surface and texture from util_create_rgba_surface(). 13149b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul */ 13249b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paulvoid 133287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellutil_destroy_rgba_surface(struct pipe_resource *texture, 13449b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul struct pipe_surface *surface) 13549b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul{ 13649b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul pipe_surface_reference(&surface, NULL); 137287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_resource_reference(&texture, NULL); 13849b40f9bf4aef3a32ddb88f7e8d378f08e26b081Brian Paul} 1398b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 1408b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 1418b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 1428b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul/** 143f4ad68a5288abe714f4c98307ed676869aa661faRoland Scheidegger * Fallback function for pipe->resource_copy_region(). 1448b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul * Note: (X,Y)=(0,0) is always the upper-left corner. 1458b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul */ 1468b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paulvoid 147815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheideggerutil_resource_copy_region(struct pipe_context *pipe, 148815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheidegger struct pipe_resource *dst, 1494c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger unsigned dst_level, 150815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheidegger unsigned dst_x, unsigned dst_y, unsigned dst_z, 151815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheidegger struct pipe_resource *src, 1524c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger unsigned src_level, 1534c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger const struct pipe_box *src_box) 1548b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul{ 1558b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul struct pipe_transfer *src_trans, *dst_trans; 1568b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul void *dst_map; 1578b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul const void *src_map; 1588b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul enum pipe_format src_format, dst_format; 1594c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger unsigned w = src_box->width; 1604c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger unsigned h = src_box->height; 1618b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 162815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheidegger assert(src && dst); 163815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheidegger if (!src || !dst) 1648b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul return; 1658b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 1663e7b3a04bf7667583dac18f1267d213aa7f33800Vinson Lee assert((src->target == PIPE_BUFFER && dst->target == PIPE_BUFFER) || 1673e7b3a04bf7667583dac18f1267d213aa7f33800Vinson Lee (src->target != PIPE_BUFFER && dst->target != PIPE_BUFFER)); 1683e7b3a04bf7667583dac18f1267d213aa7f33800Vinson Lee 169815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheidegger src_format = src->format; 170815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheidegger dst_format = dst->format; 1718b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 1728b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul src_trans = pipe_get_transfer(pipe, 1734c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger src, 1744c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger src_level, 1754c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger src_box->z, 1764c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger PIPE_TRANSFER_READ, 1774c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger src_box->x, src_box->y, w, h); 1788b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 1798b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul dst_trans = pipe_get_transfer(pipe, 1804c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger dst, 1814c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger dst_level, 1824c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger dst_z, 1834c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger PIPE_TRANSFER_WRITE, 1844c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger dst_x, dst_y, w, h); 1858b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 1868b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul assert(util_format_get_blocksize(dst_format) == util_format_get_blocksize(src_format)); 1878b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul assert(util_format_get_blockwidth(dst_format) == util_format_get_blockwidth(src_format)); 1888b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul assert(util_format_get_blockheight(dst_format) == util_format_get_blockheight(src_format)); 1898b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 1908b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul src_map = pipe->transfer_map(pipe, src_trans); 1918b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul dst_map = pipe->transfer_map(pipe, dst_trans); 1928b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 1938b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul assert(src_map); 1948b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul assert(dst_map); 1958b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 1968b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul if (src_map && dst_map) { 19764f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { 19864f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák memcpy(dst_map, src_map, w); 19964f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák } else { 20064f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák util_copy_rect(dst_map, 20164f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák dst_format, 20264f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák dst_trans->stride, 20364f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák 0, 0, 20464f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák w, h, 20564f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák src_map, 20664f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák src_trans->stride, 20764f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák 0, 20864f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák 0); 20964f55216e4c11e8acb787bfe40e6dd25e862cd43Marek Olšák } 2108b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul } 2118b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2128b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul pipe->transfer_unmap(pipe, src_trans); 2138b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul pipe->transfer_unmap(pipe, dst_trans); 2148b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2158b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul pipe->transfer_destroy(pipe, src_trans); 2168b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul pipe->transfer_destroy(pipe, dst_trans); 2178b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul} 2188b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2198b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2208b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2218b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8)) 2228b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2238b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2248b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul/** 225a6e5c6c000df8655de3b41d5809547bb41c88c23Roland Scheidegger * Fallback for pipe->clear_render_target() function. 226a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger * XXX this looks too hackish to be really useful. 227a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger * cpp > 4 looks like a gross hack at best... 228a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger * Plus can't use these transfer fallbacks when clearing 229a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger * multisampled surfaces for instance. 2308b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul */ 2318b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paulvoid 232a6e5c6c000df8655de3b41d5809547bb41c88c23Roland Scheideggerutil_clear_render_target(struct pipe_context *pipe, 233a6e5c6c000df8655de3b41d5809547bb41c88c23Roland Scheidegger struct pipe_surface *dst, 2346dd284f7c8fac22f64c13fdf9909094f5ec59086Dave Airlie const union pipe_color_union *color, 235a6e5c6c000df8655de3b41d5809547bb41c88c23Roland Scheidegger unsigned dstx, unsigned dsty, 236a6e5c6c000df8655de3b41d5809547bb41c88c23Roland Scheidegger unsigned width, unsigned height) 2378b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul{ 2388b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul struct pipe_transfer *dst_trans; 2398b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul void *dst_map; 240a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger union util_color uc; 2418b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 242a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger assert(dst->texture); 243a1d5131d2eaa5f5ccc8b38f9379f9c6bc989bc1aRoland Scheidegger if (!dst->texture) 2448b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul return; 2454c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger /* XXX: should handle multiple layers */ 2468b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul dst_trans = pipe_get_transfer(pipe, 2474c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger dst->texture, 2484c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger dst->u.tex.level, 2494c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger dst->u.tex.first_layer, 2504c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger PIPE_TRANSFER_WRITE, 2514c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger dstx, dsty, width, height); 2528b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2538b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul dst_map = pipe->transfer_map(pipe, dst_trans); 2548b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2558b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul assert(dst_map); 2568b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2578b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul if (dst_map) { 2588b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul assert(dst_trans->stride > 0); 2598b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2606dd284f7c8fac22f64c13fdf9909094f5ec59086Dave Airlie util_pack_color(color->f, dst->texture->format, &uc); 261c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger util_fill_rect(dst_map, dst->texture->format, 262c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger dst_trans->stride, 263c2f074d8a4b93f3f3a81311f9a114b11bc5f80d8Roland Scheidegger 0, 0, width, height, &uc); 2648b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul } 2658b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul 2668b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul pipe->transfer_unmap(pipe, dst_trans); 2678b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul pipe->transfer_destroy(pipe, dst_trans); 2688b0c217f2bc123bffd25cc4977d6abb1b3fa8186Brian Paul} 269a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger 270a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger/** 271a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger * Fallback for pipe->clear_stencil() function. 272a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger * sw fallback doesn't look terribly useful here. 273a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger * Plus can't use these transfer fallbacks when clearing 274a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger * multisampled surfaces for instance. 275a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger */ 276a2bf4817bb735298ec9282971167e62612942c0dRoland Scheideggervoid 277a2bf4817bb735298ec9282971167e62612942c0dRoland Scheideggerutil_clear_depth_stencil(struct pipe_context *pipe, 278a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger struct pipe_surface *dst, 279a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger unsigned clear_flags, 280a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger double depth, 281a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger unsigned stencil, 282a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger unsigned dstx, unsigned dsty, 283a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger unsigned width, unsigned height) 284a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger{ 285a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger struct pipe_transfer *dst_trans; 286a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger ubyte *dst_map; 287a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger boolean need_rmw = FALSE; 288a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger 289a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) && 290a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) && 291a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger util_format_is_depth_and_stencil(dst->format)) 292a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger need_rmw = TRUE; 293a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger 294a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger assert(dst->texture); 295a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger if (!dst->texture) 296a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger return; 297a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst_trans = pipe_get_transfer(pipe, 298a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst->texture, 2994c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger dst->u.tex.level, 3004c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger dst->u.tex.first_layer, 301a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger (need_rmw ? PIPE_TRANSFER_READ_WRITE : 302a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger PIPE_TRANSFER_WRITE), 303a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dstx, dsty, width, height); 304a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger 305a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst_map = pipe->transfer_map(pipe, dst_trans); 306a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger 307a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger assert(dst_map); 308a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger 309a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger if (dst_map) { 310a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger unsigned dst_stride = dst_trans->stride; 311a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger unsigned zstencil = util_pack_z_stencil(dst->texture->format, depth, stencil); 312a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger unsigned i, j; 313a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger assert(dst_trans->stride > 0); 314a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger 315a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger switch (util_format_get_blocksize(dst->format)) { 316a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger case 1: 317866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie assert(dst->format == PIPE_FORMAT_S8_UINT); 318a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger if(dst_stride == width) 319a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger memset(dst_map, (ubyte) zstencil, height * width); 320a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger else { 321a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger for (i = 0; i < height; i++) { 322a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger memset(dst_map, (ubyte) zstencil, width); 323a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst_map += dst_stride; 324a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 325a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 326a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger break; 327a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger case 2: 328a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger assert(dst->format == PIPE_FORMAT_Z16_UNORM); 329a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger for (i = 0; i < height; i++) { 330a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger uint16_t *row = (uint16_t *)dst_map; 331a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger for (j = 0; j < width; j++) 332a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger *row++ = (uint16_t) zstencil; 333a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst_map += dst_stride; 334a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 335a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger break; 336a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger case 4: 337a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger if (!need_rmw) { 338a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger for (i = 0; i < height; i++) { 339a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger uint32_t *row = (uint32_t *)dst_map; 340a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger for (j = 0; j < width; j++) 341a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger *row++ = zstencil; 342a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst_map += dst_stride; 343a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 344a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 345a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger else { 346a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger uint32_t dst_mask; 347866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie if (dst->format == PIPE_FORMAT_Z24_UNORM_S8_UINT) 348a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst_mask = 0xffffff00; 349a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger else { 350866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie assert(dst->format == PIPE_FORMAT_S8_UINT_Z24_UNORM); 351a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst_mask = 0xffffff; 352a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 353a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger if (clear_flags & PIPE_CLEAR_DEPTH) 354a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst_mask = ~dst_mask; 355a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger for (i = 0; i < height; i++) { 356a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger uint32_t *row = (uint32_t *)dst_map; 357a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger for (j = 0; j < width; j++) { 358a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger uint32_t tmp = *row & dst_mask; 359a01578c84ffcc03a98b3c3f20d05cdb0e0e4ada7Luca Barbieri *row++ = tmp | (zstencil & ~dst_mask); 360a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 361a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger dst_map += dst_stride; 362a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 363a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 364e860cb64dbcb170207641fc280e47858fae74891Marek Olšák break; 365a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger case 8: 366e860cb64dbcb170207641fc280e47858fae74891Marek Olšák { 367e860cb64dbcb170207641fc280e47858fae74891Marek Olšák uint64_t zstencil = util_pack64_z_stencil(dst->texture->format, 368e860cb64dbcb170207641fc280e47858fae74891Marek Olšák depth, stencil); 369e860cb64dbcb170207641fc280e47858fae74891Marek Olšák 370866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie assert(dst->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT); 371e860cb64dbcb170207641fc280e47858fae74891Marek Olšák 372e860cb64dbcb170207641fc280e47858fae74891Marek Olšák if (!need_rmw) { 373e860cb64dbcb170207641fc280e47858fae74891Marek Olšák for (i = 0; i < height; i++) { 374e860cb64dbcb170207641fc280e47858fae74891Marek Olšák uint64_t *row = (uint64_t *)dst_map; 375e860cb64dbcb170207641fc280e47858fae74891Marek Olšák for (j = 0; j < width; j++) 376e860cb64dbcb170207641fc280e47858fae74891Marek Olšák *row++ = zstencil; 377e860cb64dbcb170207641fc280e47858fae74891Marek Olšák dst_map += dst_stride; 378e860cb64dbcb170207641fc280e47858fae74891Marek Olšák } 379e860cb64dbcb170207641fc280e47858fae74891Marek Olšák } 380e860cb64dbcb170207641fc280e47858fae74891Marek Olšák else { 381e860cb64dbcb170207641fc280e47858fae74891Marek Olšák uint64_t src_mask; 382e860cb64dbcb170207641fc280e47858fae74891Marek Olšák 383e860cb64dbcb170207641fc280e47858fae74891Marek Olšák if (clear_flags & PIPE_CLEAR_DEPTH) 384e860cb64dbcb170207641fc280e47858fae74891Marek Olšák src_mask = 0x00000000ffffffffull; 385e860cb64dbcb170207641fc280e47858fae74891Marek Olšák else 386e860cb64dbcb170207641fc280e47858fae74891Marek Olšák src_mask = 0x000000ff00000000ull; 387e860cb64dbcb170207641fc280e47858fae74891Marek Olšák 388e860cb64dbcb170207641fc280e47858fae74891Marek Olšák for (i = 0; i < height; i++) { 389e860cb64dbcb170207641fc280e47858fae74891Marek Olšák uint64_t *row = (uint64_t *)dst_map; 390e860cb64dbcb170207641fc280e47858fae74891Marek Olšák for (j = 0; j < width; j++) { 391e860cb64dbcb170207641fc280e47858fae74891Marek Olšák uint64_t tmp = *row & ~src_mask; 392e860cb64dbcb170207641fc280e47858fae74891Marek Olšák *row++ = tmp | (zstencil & src_mask); 393e860cb64dbcb170207641fc280e47858fae74891Marek Olšák } 394e860cb64dbcb170207641fc280e47858fae74891Marek Olšák dst_map += dst_stride; 395e860cb64dbcb170207641fc280e47858fae74891Marek Olšák } 396e860cb64dbcb170207641fc280e47858fae74891Marek Olšák } 397e860cb64dbcb170207641fc280e47858fae74891Marek Olšák break; 398e860cb64dbcb170207641fc280e47858fae74891Marek Olšák } 399a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger default: 400a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger assert(0); 401a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger break; 402a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 403a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger } 404a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger 405a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger pipe->transfer_unmap(pipe, dst_trans); 406a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger pipe->transfer_destroy(pipe, dst_trans); 407a2bf4817bb735298ec9282971167e62612942c0dRoland Scheidegger} 408