1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2010-2021 VMware, Inc. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 17bf215546Sopenharmony_ci * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 18bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. 21bf215546Sopenharmony_ci * 22bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 23bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 24bf215546Sopenharmony_ci * of the Software. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "pipe/p_config.h" 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#include "util/u_math.h" 32bf215546Sopenharmony_ci#include "util/u_cpu_detect.h" 33bf215546Sopenharmony_ci#include "util/u_pack_color.h" 34bf215546Sopenharmony_ci#include "util/u_surface.h" 35bf215546Sopenharmony_ci#include "util/u_sse.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include "lp_jit.h" 38bf215546Sopenharmony_ci#include "lp_rast.h" 39bf215546Sopenharmony_ci#include "lp_debug.h" 40bf215546Sopenharmony_ci#include "lp_state_fs.h" 41bf215546Sopenharmony_ci#include "lp_linear_priv.h" 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci/* This file contains various special-case fastpaths which implement 45bf215546Sopenharmony_ci * the entire linear pipeline in a single funciton. 46bf215546Sopenharmony_ci * 47bf215546Sopenharmony_ci * These include simple blits and some debug code. 48bf215546Sopenharmony_ci * 49bf215546Sopenharmony_ci * These functions fully implement the linear path and do not need to 50bf215546Sopenharmony_ci * be combined with blending, interpolation or sampling routines. 51bf215546Sopenharmony_ci */ 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_ci#if defined(PIPE_ARCH_SSE) 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci/* Linear shader which implements the BLIT_RGBA shader with the 57bf215546Sopenharmony_ci * additional constraints imposed by lp_setup_is_blit(). 58bf215546Sopenharmony_ci */ 59bf215546Sopenharmony_cistatic boolean 60bf215546Sopenharmony_cilp_linear_blit_rgba_blit(const struct lp_rast_state *state, 61bf215546Sopenharmony_ci unsigned x, unsigned y, 62bf215546Sopenharmony_ci unsigned width, unsigned height, 63bf215546Sopenharmony_ci const float (*a0)[4], 64bf215546Sopenharmony_ci const float (*dadx)[4], 65bf215546Sopenharmony_ci const float (*dady)[4], 66bf215546Sopenharmony_ci uint8_t *color, 67bf215546Sopenharmony_ci unsigned stride) 68bf215546Sopenharmony_ci{ 69bf215546Sopenharmony_ci const struct lp_jit_context *context = &state->jit_context; 70bf215546Sopenharmony_ci const struct lp_jit_texture *texture = &context->textures[0]; 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci /* Require w==1.0: 75bf215546Sopenharmony_ci */ 76bf215546Sopenharmony_ci if (a0[0][3] != 1.0 || 77bf215546Sopenharmony_ci dadx[0][3] != 0.0 || 78bf215546Sopenharmony_ci dady[0][3] != 0.0) 79bf215546Sopenharmony_ci return FALSE; 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci const int src_x = x + util_iround(a0[1][0]*texture->width - 0.5f); 82bf215546Sopenharmony_ci const int src_y = y + util_iround(a0[1][1]*texture->height - 0.5f); 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci const uint8_t *src = texture->base; 85bf215546Sopenharmony_ci const unsigned src_stride = texture->row_stride[0]; 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci /* Fall back to blit_rgba() if clamping required: 88bf215546Sopenharmony_ci */ 89bf215546Sopenharmony_ci if (src_x < 0 || 90bf215546Sopenharmony_ci src_y < 0 || 91bf215546Sopenharmony_ci src_x + width > texture->width || 92bf215546Sopenharmony_ci src_y + height > texture->height) 93bf215546Sopenharmony_ci return FALSE; 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci util_copy_rect(color, PIPE_FORMAT_B8G8R8A8_UNORM, stride, 96bf215546Sopenharmony_ci x, y, 97bf215546Sopenharmony_ci width, height, 98bf215546Sopenharmony_ci src, src_stride, 99bf215546Sopenharmony_ci src_x, src_y); 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci return TRUE; 102bf215546Sopenharmony_ci} 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci/* Linear shader which implements the BLIT_RGB1 shader, with the 106bf215546Sopenharmony_ci * additional constraints imposed by lp_setup_is_blit(). 107bf215546Sopenharmony_ci */ 108bf215546Sopenharmony_cistatic boolean 109bf215546Sopenharmony_cilp_linear_blit_rgb1_blit(const struct lp_rast_state *state, 110bf215546Sopenharmony_ci unsigned x, unsigned y, 111bf215546Sopenharmony_ci unsigned width, unsigned height, 112bf215546Sopenharmony_ci const float (*a0)[4], 113bf215546Sopenharmony_ci const float (*dadx)[4], 114bf215546Sopenharmony_ci const float (*dady)[4], 115bf215546Sopenharmony_ci uint8_t *color, 116bf215546Sopenharmony_ci unsigned stride) 117bf215546Sopenharmony_ci{ 118bf215546Sopenharmony_ci const struct lp_jit_context *context = &state->jit_context; 119bf215546Sopenharmony_ci const struct lp_jit_texture *texture = &context->textures[0]; 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_ci LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci /* Require w==1.0: 124bf215546Sopenharmony_ci */ 125bf215546Sopenharmony_ci if (a0[0][3] != 1.0 || 126bf215546Sopenharmony_ci dadx[0][3] != 0.0 || 127bf215546Sopenharmony_ci dady[0][3] != 0.0) 128bf215546Sopenharmony_ci return FALSE; 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci color += x * 4 + y * stride; 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci const int src_x = x + util_iround(a0[1][0]*texture->width - 0.5f); 133bf215546Sopenharmony_ci const int src_y = y + util_iround(a0[1][1]*texture->height - 0.5f); 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci const uint8_t *src = texture->base; 136bf215546Sopenharmony_ci const unsigned src_stride = texture->row_stride[0]; 137bf215546Sopenharmony_ci src += src_x * 4; 138bf215546Sopenharmony_ci src += src_y * src_stride; 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_ci if (src_x < 0 || 141bf215546Sopenharmony_ci src_y < 0 || 142bf215546Sopenharmony_ci src_x + width > texture->width || 143bf215546Sopenharmony_ci src_y + height > texture->height) 144bf215546Sopenharmony_ci return FALSE; 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci for (y = 0; y < height; y++) { 147bf215546Sopenharmony_ci const uint32_t *src_row = (const uint32_t *)src; 148bf215546Sopenharmony_ci uint32_t *dst_row = (uint32_t *)color; 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci for (x = 0; x < width; x++) { 151bf215546Sopenharmony_ci *dst_row++ = *src_row++ | 0xff000000; 152bf215546Sopenharmony_ci } 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci color += stride; 155bf215546Sopenharmony_ci src += src_stride; 156bf215546Sopenharmony_ci } 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci return TRUE; 159bf215546Sopenharmony_ci} 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci/* Linear shader which always emits purple. Used for debugging. 163bf215546Sopenharmony_ci */ 164bf215546Sopenharmony_cistatic boolean 165bf215546Sopenharmony_cilp_linear_purple(const struct lp_rast_state *state, 166bf215546Sopenharmony_ci unsigned x, unsigned y, 167bf215546Sopenharmony_ci unsigned width, unsigned height, 168bf215546Sopenharmony_ci const float (*a0)[4], 169bf215546Sopenharmony_ci const float (*dadx)[4], 170bf215546Sopenharmony_ci const float (*dady)[4], 171bf215546Sopenharmony_ci uint8_t *color, 172bf215546Sopenharmony_ci unsigned stride) 173bf215546Sopenharmony_ci{ 174bf215546Sopenharmony_ci union util_color uc; 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci util_pack_color_ub(0xff, 0, 0xff, 0xff, 177bf215546Sopenharmony_ci PIPE_FORMAT_B8G8R8A8_UNORM, &uc); 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci util_fill_rect(color, 180bf215546Sopenharmony_ci PIPE_FORMAT_B8G8R8A8_UNORM, 181bf215546Sopenharmony_ci stride, 182bf215546Sopenharmony_ci x, 183bf215546Sopenharmony_ci y, 184bf215546Sopenharmony_ci width, 185bf215546Sopenharmony_ci height, 186bf215546Sopenharmony_ci &uc); 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci return TRUE; 189bf215546Sopenharmony_ci} 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_ci/* Examine the fragment shader variant and determine whether we can 193bf215546Sopenharmony_ci * substitute a fastpath linear shader implementation. 194bf215546Sopenharmony_ci */ 195bf215546Sopenharmony_ciboolean 196bf215546Sopenharmony_cilp_linear_check_fastpath(struct lp_fragment_shader_variant *variant) 197bf215546Sopenharmony_ci{ 198bf215546Sopenharmony_ci struct lp_sampler_static_state *samp0 = 199bf215546Sopenharmony_ci lp_fs_variant_key_sampler_idx(&variant->key, 0); 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ci if (!samp0) 202bf215546Sopenharmony_ci return false; 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci const enum pipe_format tex_format = samp0->texture_state.format; 205bf215546Sopenharmony_ci if (variant->shader->kind == LP_FS_KIND_BLIT_RGBA && 206bf215546Sopenharmony_ci tex_format == PIPE_FORMAT_B8G8R8A8_UNORM && 207bf215546Sopenharmony_ci is_nearest_clamp_sampler(samp0) && 208bf215546Sopenharmony_ci variant->opaque) { 209bf215546Sopenharmony_ci variant->jit_linear_blit = lp_linear_blit_rgba_blit; 210bf215546Sopenharmony_ci } 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_ci if (variant->shader->kind == LP_FS_KIND_BLIT_RGB1 && 213bf215546Sopenharmony_ci variant->opaque && 214bf215546Sopenharmony_ci (tex_format == PIPE_FORMAT_B8G8R8A8_UNORM || 215bf215546Sopenharmony_ci tex_format == PIPE_FORMAT_B8G8R8X8_UNORM) && 216bf215546Sopenharmony_ci is_nearest_clamp_sampler(samp0)) { 217bf215546Sopenharmony_ci variant->jit_linear_blit = lp_linear_blit_rgb1_blit; 218bf215546Sopenharmony_ci } 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_ci if (0) { 221bf215546Sopenharmony_ci variant->jit_linear = lp_linear_purple; 222bf215546Sopenharmony_ci } 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci /* Stop now if jit_linear has been initialized. Otherwise keep 226bf215546Sopenharmony_ci * searching - even if jit_linear_blit has been instantiated. 227bf215546Sopenharmony_ci */ 228bf215546Sopenharmony_ci return variant->jit_linear != NULL; 229bf215546Sopenharmony_ci} 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci#else 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ciboolean 234bf215546Sopenharmony_cilp_linear_check_fastpath(struct lp_fragment_shader_variant *variant) 235bf215546Sopenharmony_ci{ 236bf215546Sopenharmony_ci return FALSE; 237bf215546Sopenharmony_ci} 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci#endif 240