1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2008 VMware, Inc. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * Copyright 2009 Marek Olšák <maraeo@gmail.com> 6bf215546Sopenharmony_ci * 7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 9bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 10bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 11bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 12bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 13bf215546Sopenharmony_ci * the following conditions: 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 16bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 17bf215546Sopenharmony_ci * of the Software. 18bf215546Sopenharmony_ci * 19bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 23bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26bf215546Sopenharmony_ci * 27bf215546Sopenharmony_ci **************************************************************************/ 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci/** 30bf215546Sopenharmony_ci * @file 31bf215546Sopenharmony_ci * Simple vertex/fragment shader generators. 32bf215546Sopenharmony_ci * 33bf215546Sopenharmony_ci * @author Brian Paul 34bf215546Sopenharmony_ci Marek Olšák 35bf215546Sopenharmony_ci */ 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci#include "pipe/p_context.h" 39bf215546Sopenharmony_ci#include "pipe/p_shader_tokens.h" 40bf215546Sopenharmony_ci#include "pipe/p_state.h" 41bf215546Sopenharmony_ci#include "util/u_simple_shaders.h" 42bf215546Sopenharmony_ci#include "util/u_debug.h" 43bf215546Sopenharmony_ci#include "util/u_memory.h" 44bf215546Sopenharmony_ci#include "util/u_string.h" 45bf215546Sopenharmony_ci#include "tgsi/tgsi_dump.h" 46bf215546Sopenharmony_ci#include "tgsi/tgsi_strings.h" 47bf215546Sopenharmony_ci#include "tgsi/tgsi_ureg.h" 48bf215546Sopenharmony_ci#include "tgsi/tgsi_text.h" 49bf215546Sopenharmony_ci#include <stdio.h> /* include last */ 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_ci/** 54bf215546Sopenharmony_ci * Make simple vertex pass-through shader. 55bf215546Sopenharmony_ci * \param num_attribs number of attributes to pass through 56bf215546Sopenharmony_ci * \param semantic_names array of semantic names for each attribute 57bf215546Sopenharmony_ci * \param semantic_indexes array of semantic indexes for each attribute 58bf215546Sopenharmony_ci */ 59bf215546Sopenharmony_civoid * 60bf215546Sopenharmony_ciutil_make_vertex_passthrough_shader(struct pipe_context *pipe, 61bf215546Sopenharmony_ci uint num_attribs, 62bf215546Sopenharmony_ci const enum tgsi_semantic *semantic_names, 63bf215546Sopenharmony_ci const uint *semantic_indexes, 64bf215546Sopenharmony_ci bool window_space) 65bf215546Sopenharmony_ci{ 66bf215546Sopenharmony_ci return util_make_vertex_passthrough_shader_with_so(pipe, num_attribs, 67bf215546Sopenharmony_ci semantic_names, 68bf215546Sopenharmony_ci semantic_indexes, 69bf215546Sopenharmony_ci window_space, false, NULL); 70bf215546Sopenharmony_ci} 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_civoid * 73bf215546Sopenharmony_ciutil_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe, 74bf215546Sopenharmony_ci uint num_attribs, 75bf215546Sopenharmony_ci const enum tgsi_semantic *semantic_names, 76bf215546Sopenharmony_ci const uint *semantic_indexes, 77bf215546Sopenharmony_ci bool window_space, bool layered, 78bf215546Sopenharmony_ci const struct pipe_stream_output_info *so) 79bf215546Sopenharmony_ci{ 80bf215546Sopenharmony_ci struct ureg_program *ureg; 81bf215546Sopenharmony_ci uint i; 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci ureg = ureg_create( PIPE_SHADER_VERTEX ); 84bf215546Sopenharmony_ci if (!ureg) 85bf215546Sopenharmony_ci return NULL; 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci if (window_space) 88bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION, TRUE); 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci for (i = 0; i < num_attribs; i++) { 91bf215546Sopenharmony_ci struct ureg_src src; 92bf215546Sopenharmony_ci struct ureg_dst dst; 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci src = ureg_DECL_vs_input( ureg, i ); 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci dst = ureg_DECL_output( ureg, 97bf215546Sopenharmony_ci semantic_names[i], 98bf215546Sopenharmony_ci semantic_indexes[i]); 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci ureg_MOV( ureg, dst, src ); 101bf215546Sopenharmony_ci } 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci if (layered) { 104bf215546Sopenharmony_ci struct ureg_src instance_id = 105bf215546Sopenharmony_ci ureg_DECL_system_value(ureg, TGSI_SEMANTIC_INSTANCEID, 0); 106bf215546Sopenharmony_ci struct ureg_dst layer = ureg_DECL_output(ureg, TGSI_SEMANTIC_LAYER, 0); 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci ureg_MOV(ureg, ureg_writemask(layer, TGSI_WRITEMASK_X), 109bf215546Sopenharmony_ci ureg_scalar(instance_id, TGSI_SWIZZLE_X)); 110bf215546Sopenharmony_ci } 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci ureg_END( ureg ); 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci return ureg_create_shader_with_so_and_destroy( ureg, pipe, so ); 115bf215546Sopenharmony_ci} 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_civoid *util_make_layered_clear_vertex_shader(struct pipe_context *pipe) 119bf215546Sopenharmony_ci{ 120bf215546Sopenharmony_ci const enum tgsi_semantic semantic_names[] = {TGSI_SEMANTIC_POSITION, 121bf215546Sopenharmony_ci TGSI_SEMANTIC_GENERIC}; 122bf215546Sopenharmony_ci const unsigned semantic_indices[] = {0, 0}; 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci return util_make_vertex_passthrough_shader_with_so(pipe, 2, semantic_names, 125bf215546Sopenharmony_ci semantic_indices, false, 126bf215546Sopenharmony_ci true, NULL); 127bf215546Sopenharmony_ci} 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_ci/** 130bf215546Sopenharmony_ci * Takes position and color, and outputs position, color, and instance id. 131bf215546Sopenharmony_ci */ 132bf215546Sopenharmony_civoid *util_make_layered_clear_helper_vertex_shader(struct pipe_context *pipe) 133bf215546Sopenharmony_ci{ 134bf215546Sopenharmony_ci static const char text[] = 135bf215546Sopenharmony_ci "VERT\n" 136bf215546Sopenharmony_ci "DCL IN[0]\n" 137bf215546Sopenharmony_ci "DCL IN[1]\n" 138bf215546Sopenharmony_ci "DCL SV[0], INSTANCEID\n" 139bf215546Sopenharmony_ci "DCL OUT[0], POSITION\n" 140bf215546Sopenharmony_ci "DCL OUT[1], GENERIC[0]\n" 141bf215546Sopenharmony_ci "DCL OUT[2], GENERIC[1]\n" 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci "MOV OUT[0], IN[0]\n" 144bf215546Sopenharmony_ci "MOV OUT[1], IN[1]\n" 145bf215546Sopenharmony_ci "MOV OUT[2].x, SV[0].xxxx\n" 146bf215546Sopenharmony_ci "END\n"; 147bf215546Sopenharmony_ci struct tgsi_token tokens[1000]; 148bf215546Sopenharmony_ci struct pipe_shader_state state = {0}; 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) { 151bf215546Sopenharmony_ci assert(0); 152bf215546Sopenharmony_ci return NULL; 153bf215546Sopenharmony_ci } 154bf215546Sopenharmony_ci pipe_shader_state_from_tgsi(&state, tokens); 155bf215546Sopenharmony_ci return pipe->create_vs_state(pipe, &state); 156bf215546Sopenharmony_ci} 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci/** 159bf215546Sopenharmony_ci * Takes position, color, and target layer, and emits vertices on that target 160bf215546Sopenharmony_ci * layer, with the specified color. 161bf215546Sopenharmony_ci */ 162bf215546Sopenharmony_civoid *util_make_layered_clear_geometry_shader(struct pipe_context *pipe) 163bf215546Sopenharmony_ci{ 164bf215546Sopenharmony_ci static const char text[] = 165bf215546Sopenharmony_ci "GEOM\n" 166bf215546Sopenharmony_ci "PROPERTY GS_INPUT_PRIMITIVE TRIANGLES\n" 167bf215546Sopenharmony_ci "PROPERTY GS_OUTPUT_PRIMITIVE TRIANGLE_STRIP\n" 168bf215546Sopenharmony_ci "PROPERTY GS_MAX_OUTPUT_VERTICES 3\n" 169bf215546Sopenharmony_ci "PROPERTY GS_INVOCATIONS 1\n" 170bf215546Sopenharmony_ci "DCL IN[][0], POSITION\n" /* position */ 171bf215546Sopenharmony_ci "DCL IN[][1], GENERIC[0]\n" /* color */ 172bf215546Sopenharmony_ci "DCL IN[][2], GENERIC[1]\n" /* vs invocation */ 173bf215546Sopenharmony_ci "DCL OUT[0], POSITION\n" 174bf215546Sopenharmony_ci "DCL OUT[1], GENERIC[0]\n" 175bf215546Sopenharmony_ci "DCL OUT[2], LAYER\n" 176bf215546Sopenharmony_ci "IMM[0] INT32 {0, 0, 0, 0}\n" 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci "MOV OUT[0], IN[0][0]\n" 179bf215546Sopenharmony_ci "MOV OUT[1], IN[0][1]\n" 180bf215546Sopenharmony_ci "MOV OUT[2].x, IN[0][2].xxxx\n" 181bf215546Sopenharmony_ci "EMIT IMM[0].xxxx\n" 182bf215546Sopenharmony_ci "MOV OUT[0], IN[1][0]\n" 183bf215546Sopenharmony_ci "MOV OUT[1], IN[1][1]\n" 184bf215546Sopenharmony_ci "MOV OUT[2].x, IN[1][2].xxxx\n" 185bf215546Sopenharmony_ci "EMIT IMM[0].xxxx\n" 186bf215546Sopenharmony_ci "MOV OUT[0], IN[2][0]\n" 187bf215546Sopenharmony_ci "MOV OUT[1], IN[2][1]\n" 188bf215546Sopenharmony_ci "MOV OUT[2].x, IN[2][2].xxxx\n" 189bf215546Sopenharmony_ci "EMIT IMM[0].xxxx\n" 190bf215546Sopenharmony_ci "END\n"; 191bf215546Sopenharmony_ci struct tgsi_token tokens[1000]; 192bf215546Sopenharmony_ci struct pipe_shader_state state = {0}; 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) { 195bf215546Sopenharmony_ci assert(0); 196bf215546Sopenharmony_ci return NULL; 197bf215546Sopenharmony_ci } 198bf215546Sopenharmony_ci pipe_shader_state_from_tgsi(&state, tokens); 199bf215546Sopenharmony_ci return pipe->create_gs_state(pipe, &state); 200bf215546Sopenharmony_ci} 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_cistatic void 203bf215546Sopenharmony_ciureg_load_tex(struct ureg_program *ureg, struct ureg_dst out, 204bf215546Sopenharmony_ci struct ureg_src coord, struct ureg_src sampler, 205bf215546Sopenharmony_ci enum tgsi_texture_type tex_target, 206bf215546Sopenharmony_ci bool load_level_zero, bool use_txf) 207bf215546Sopenharmony_ci{ 208bf215546Sopenharmony_ci if (use_txf) { 209bf215546Sopenharmony_ci struct ureg_dst temp = ureg_DECL_temporary(ureg); 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci ureg_F2I(ureg, temp, coord); 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci if (load_level_zero) 214bf215546Sopenharmony_ci ureg_TXF_LZ(ureg, out, tex_target, ureg_src(temp), sampler); 215bf215546Sopenharmony_ci else 216bf215546Sopenharmony_ci ureg_TXF(ureg, out, tex_target, ureg_src(temp), sampler); 217bf215546Sopenharmony_ci } else { 218bf215546Sopenharmony_ci if (load_level_zero) 219bf215546Sopenharmony_ci ureg_TEX_LZ(ureg, out, tex_target, coord, sampler); 220bf215546Sopenharmony_ci else 221bf215546Sopenharmony_ci ureg_TEX(ureg, out, tex_target, coord, sampler); 222bf215546Sopenharmony_ci } 223bf215546Sopenharmony_ci} 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci/** 226bf215546Sopenharmony_ci * Make simple fragment texture shader, with xrbias->float conversion: 227bf215546Sopenharmony_ci * IMM {1023/510, -384/510, 0, 1} 228bf215546Sopenharmony_ci * TEX TEMP[0], IN[0], SAMP[0], 2D; 229bf215546Sopenharmony_ci * MAD TEMP[0].xyz TEMP[0], IMM[0].xxxx, IMM[0].yyyy 230bf215546Sopenharmony_ci * MOV OUT[0], TEMP[0] 231bf215546Sopenharmony_ci * END; 232bf215546Sopenharmony_ci * 233bf215546Sopenharmony_ci * \param tex_target one of PIPE_TEXTURE_x 234bf215546Sopenharmony_ci */ 235bf215546Sopenharmony_civoid * 236bf215546Sopenharmony_ciutil_make_fragment_tex_shader_xrbias(struct pipe_context *pipe, 237bf215546Sopenharmony_ci enum tgsi_texture_type tex_target) 238bf215546Sopenharmony_ci{ 239bf215546Sopenharmony_ci struct ureg_program *ureg; 240bf215546Sopenharmony_ci struct ureg_src sampler; 241bf215546Sopenharmony_ci struct ureg_src coord; 242bf215546Sopenharmony_ci struct ureg_dst temp; 243bf215546Sopenharmony_ci struct ureg_dst out; 244bf215546Sopenharmony_ci struct ureg_src imm; 245bf215546Sopenharmony_ci enum tgsi_return_type stype = TGSI_RETURN_TYPE_FLOAT; 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_ci ureg = ureg_create(PIPE_SHADER_FRAGMENT); 248bf215546Sopenharmony_ci if (!ureg) 249bf215546Sopenharmony_ci return NULL; 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci imm = ureg_imm4f(ureg, 1023.0f/510.0f, -384.0f/510.0f, 0.0f, 1.0f); 252bf215546Sopenharmony_ci sampler = ureg_DECL_sampler(ureg, 0); 253bf215546Sopenharmony_ci ureg_DECL_sampler_view(ureg, 0, tex_target, stype, stype, stype, stype); 254bf215546Sopenharmony_ci coord = ureg_DECL_fs_input(ureg, 255bf215546Sopenharmony_ci TGSI_SEMANTIC_GENERIC, 0, 256bf215546Sopenharmony_ci TGSI_INTERPOLATE_LINEAR); 257bf215546Sopenharmony_ci out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); 258bf215546Sopenharmony_ci temp = ureg_DECL_temporary(ureg); 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci ureg_TEX(ureg, temp, tex_target, coord, sampler); 261bf215546Sopenharmony_ci ureg_MAD(ureg, ureg_writemask(temp, TGSI_WRITEMASK_XYZ), 262bf215546Sopenharmony_ci ureg_src(temp), 263bf215546Sopenharmony_ci ureg_scalar(imm, TGSI_SWIZZLE_X), 264bf215546Sopenharmony_ci ureg_scalar(imm, TGSI_SWIZZLE_Y)); 265bf215546Sopenharmony_ci ureg_MOV(ureg, out, ureg_src(temp)); 266bf215546Sopenharmony_ci ureg_END(ureg); 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci return ureg_create_shader_and_destroy(ureg, pipe); 269bf215546Sopenharmony_ci} 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci/** 273bf215546Sopenharmony_ci * Make simple fragment texture shader: 274bf215546Sopenharmony_ci * IMM {0,0,0,1} // (if writemask != 0xf) 275bf215546Sopenharmony_ci * MOV TEMP[0], IMM[0] // (if writemask != 0xf) 276bf215546Sopenharmony_ci * TEX TEMP[0].writemask, IN[0], SAMP[0], 2D; 277bf215546Sopenharmony_ci * .. optional SINT <-> UINT clamping .. 278bf215546Sopenharmony_ci * MOV OUT[0], TEMP[0] 279bf215546Sopenharmony_ci * END; 280bf215546Sopenharmony_ci * 281bf215546Sopenharmony_ci * \param tex_target one of TGSI_TEXTURE_x 282bf215546Sopenharmony_ci * \parma interp_mode either TGSI_INTERPOLATE_LINEAR or PERSPECTIVE 283bf215546Sopenharmony_ci * \param writemask mask of TGSI_WRITEMASK_x 284bf215546Sopenharmony_ci */ 285bf215546Sopenharmony_civoid * 286bf215546Sopenharmony_ciutil_make_fragment_tex_shader_writemask(struct pipe_context *pipe, 287bf215546Sopenharmony_ci enum tgsi_texture_type tex_target, 288bf215546Sopenharmony_ci enum tgsi_interpolate_mode interp_mode, 289bf215546Sopenharmony_ci unsigned writemask, 290bf215546Sopenharmony_ci enum tgsi_return_type stype, 291bf215546Sopenharmony_ci enum tgsi_return_type dtype, 292bf215546Sopenharmony_ci bool load_level_zero, 293bf215546Sopenharmony_ci bool use_txf) 294bf215546Sopenharmony_ci{ 295bf215546Sopenharmony_ci struct ureg_program *ureg; 296bf215546Sopenharmony_ci struct ureg_src sampler; 297bf215546Sopenharmony_ci struct ureg_src tex; 298bf215546Sopenharmony_ci struct ureg_dst temp; 299bf215546Sopenharmony_ci struct ureg_dst out; 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci assert((stype == TGSI_RETURN_TYPE_FLOAT) == (dtype == TGSI_RETURN_TYPE_FLOAT)); 302bf215546Sopenharmony_ci assert(interp_mode == TGSI_INTERPOLATE_LINEAR || 303bf215546Sopenharmony_ci interp_mode == TGSI_INTERPOLATE_PERSPECTIVE); 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci ureg = ureg_create( PIPE_SHADER_FRAGMENT ); 306bf215546Sopenharmony_ci if (!ureg) 307bf215546Sopenharmony_ci return NULL; 308bf215546Sopenharmony_ci 309bf215546Sopenharmony_ci sampler = ureg_DECL_sampler( ureg, 0 ); 310bf215546Sopenharmony_ci 311bf215546Sopenharmony_ci ureg_DECL_sampler_view(ureg, 0, tex_target, stype, stype, stype, stype); 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci tex = ureg_DECL_fs_input( ureg, 314bf215546Sopenharmony_ci TGSI_SEMANTIC_GENERIC, 0, 315bf215546Sopenharmony_ci interp_mode ); 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci out = ureg_DECL_output( ureg, 318bf215546Sopenharmony_ci TGSI_SEMANTIC_COLOR, 319bf215546Sopenharmony_ci 0 ); 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_ci temp = ureg_DECL_temporary(ureg); 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci if (writemask != TGSI_WRITEMASK_XYZW) { 324bf215546Sopenharmony_ci struct ureg_src imm = ureg_imm4f( ureg, 0, 0, 0, 1 ); 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci ureg_MOV(ureg, temp, imm); 327bf215546Sopenharmony_ci } 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci if (tex_target == TGSI_TEXTURE_BUFFER) 330bf215546Sopenharmony_ci ureg_TXF(ureg, 331bf215546Sopenharmony_ci ureg_writemask(temp, writemask), 332bf215546Sopenharmony_ci tex_target, tex, sampler); 333bf215546Sopenharmony_ci else 334bf215546Sopenharmony_ci ureg_load_tex(ureg, ureg_writemask(temp, writemask), tex, sampler, 335bf215546Sopenharmony_ci tex_target, load_level_zero, use_txf); 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_ci if (stype != dtype) { 338bf215546Sopenharmony_ci if (stype == TGSI_RETURN_TYPE_SINT) { 339bf215546Sopenharmony_ci assert(dtype == TGSI_RETURN_TYPE_UINT); 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci ureg_IMAX(ureg, temp, ureg_src(temp), ureg_imm1i(ureg, 0)); 342bf215546Sopenharmony_ci } else { 343bf215546Sopenharmony_ci assert(stype == TGSI_RETURN_TYPE_UINT); 344bf215546Sopenharmony_ci assert(dtype == TGSI_RETURN_TYPE_SINT); 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci ureg_UMIN(ureg, temp, ureg_src(temp), ureg_imm1u(ureg, (1u << 31) - 1)); 347bf215546Sopenharmony_ci } 348bf215546Sopenharmony_ci } 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci ureg_MOV(ureg, out, ureg_src(temp)); 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci ureg_END( ureg ); 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ci return ureg_create_shader_and_destroy( ureg, pipe ); 355bf215546Sopenharmony_ci} 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_ci 358bf215546Sopenharmony_ci/** 359bf215546Sopenharmony_ci * Make a simple fragment shader that sets the output color to a color 360bf215546Sopenharmony_ci * taken from a texture. 361bf215546Sopenharmony_ci * \param tex_target one of TGSI_TEXTURE_x 362bf215546Sopenharmony_ci */ 363bf215546Sopenharmony_civoid * 364bf215546Sopenharmony_ciutil_make_fragment_tex_shader(struct pipe_context *pipe, 365bf215546Sopenharmony_ci enum tgsi_texture_type tex_target, 366bf215546Sopenharmony_ci enum tgsi_interpolate_mode interp_mode, 367bf215546Sopenharmony_ci enum tgsi_return_type stype, 368bf215546Sopenharmony_ci enum tgsi_return_type dtype, 369bf215546Sopenharmony_ci bool load_level_zero, 370bf215546Sopenharmony_ci bool use_txf) 371bf215546Sopenharmony_ci{ 372bf215546Sopenharmony_ci return util_make_fragment_tex_shader_writemask( pipe, 373bf215546Sopenharmony_ci tex_target, 374bf215546Sopenharmony_ci interp_mode, 375bf215546Sopenharmony_ci TGSI_WRITEMASK_XYZW, 376bf215546Sopenharmony_ci stype, dtype, load_level_zero, 377bf215546Sopenharmony_ci use_txf); 378bf215546Sopenharmony_ci} 379bf215546Sopenharmony_ci 380bf215546Sopenharmony_ci 381bf215546Sopenharmony_ci/** 382bf215546Sopenharmony_ci * Make a simple fragment texture shader which reads the texture unit 0 and 1 383bf215546Sopenharmony_ci * and writes it as depth and stencil, respectively. 384bf215546Sopenharmony_ci */ 385bf215546Sopenharmony_civoid * 386bf215546Sopenharmony_ciutil_make_fs_blit_zs(struct pipe_context *pipe, unsigned zs_mask, 387bf215546Sopenharmony_ci enum tgsi_texture_type tex_target, 388bf215546Sopenharmony_ci bool load_level_zero, bool use_txf) 389bf215546Sopenharmony_ci{ 390bf215546Sopenharmony_ci struct ureg_program *ureg; 391bf215546Sopenharmony_ci struct ureg_src depth_sampler, stencil_sampler, coord; 392bf215546Sopenharmony_ci struct ureg_dst depth, stencil, tmp; 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci ureg = ureg_create(PIPE_SHADER_FRAGMENT); 395bf215546Sopenharmony_ci if (!ureg) 396bf215546Sopenharmony_ci return NULL; 397bf215546Sopenharmony_ci 398bf215546Sopenharmony_ci coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0, 399bf215546Sopenharmony_ci TGSI_INTERPOLATE_LINEAR); 400bf215546Sopenharmony_ci tmp = ureg_DECL_temporary(ureg); 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ci if (zs_mask & PIPE_MASK_Z) { 403bf215546Sopenharmony_ci depth_sampler = ureg_DECL_sampler(ureg, 0); 404bf215546Sopenharmony_ci ureg_DECL_sampler_view(ureg, 0, tex_target, 405bf215546Sopenharmony_ci TGSI_RETURN_TYPE_FLOAT, 406bf215546Sopenharmony_ci TGSI_RETURN_TYPE_FLOAT, 407bf215546Sopenharmony_ci TGSI_RETURN_TYPE_FLOAT, 408bf215546Sopenharmony_ci TGSI_RETURN_TYPE_FLOAT); 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_ci ureg_load_tex(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_X), coord, 411bf215546Sopenharmony_ci depth_sampler, tex_target, load_level_zero, use_txf); 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_ci depth = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); 414bf215546Sopenharmony_ci ureg_MOV(ureg, ureg_writemask(depth, TGSI_WRITEMASK_Z), 415bf215546Sopenharmony_ci ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X)); 416bf215546Sopenharmony_ci } 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_ci if (zs_mask & PIPE_MASK_S) { 419bf215546Sopenharmony_ci stencil_sampler = ureg_DECL_sampler(ureg, zs_mask & PIPE_MASK_Z ? 1 : 0); 420bf215546Sopenharmony_ci ureg_DECL_sampler_view(ureg, zs_mask & PIPE_MASK_Z ? 1 : 0, tex_target, 421bf215546Sopenharmony_ci TGSI_RETURN_TYPE_UINT, 422bf215546Sopenharmony_ci TGSI_RETURN_TYPE_UINT, 423bf215546Sopenharmony_ci TGSI_RETURN_TYPE_UINT, 424bf215546Sopenharmony_ci TGSI_RETURN_TYPE_UINT); 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci ureg_load_tex(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_X), coord, 427bf215546Sopenharmony_ci stencil_sampler, tex_target, load_level_zero, use_txf); 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci stencil = ureg_DECL_output(ureg, TGSI_SEMANTIC_STENCIL, 0); 430bf215546Sopenharmony_ci ureg_MOV(ureg, ureg_writemask(stencil, TGSI_WRITEMASK_Y), 431bf215546Sopenharmony_ci ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X)); 432bf215546Sopenharmony_ci } 433bf215546Sopenharmony_ci 434bf215546Sopenharmony_ci ureg_END(ureg); 435bf215546Sopenharmony_ci 436bf215546Sopenharmony_ci return ureg_create_shader_and_destroy(ureg, pipe); 437bf215546Sopenharmony_ci} 438bf215546Sopenharmony_ci 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_ci/** 441bf215546Sopenharmony_ci * Make simple fragment color pass-through shader that replicates OUT[0] 442bf215546Sopenharmony_ci * to all bound colorbuffers. 443bf215546Sopenharmony_ci */ 444bf215546Sopenharmony_civoid * 445bf215546Sopenharmony_ciutil_make_fragment_passthrough_shader(struct pipe_context *pipe, 446bf215546Sopenharmony_ci int input_semantic, 447bf215546Sopenharmony_ci int input_interpolate, 448bf215546Sopenharmony_ci boolean write_all_cbufs) 449bf215546Sopenharmony_ci{ 450bf215546Sopenharmony_ci static const char shader_templ[] = 451bf215546Sopenharmony_ci "FRAG\n" 452bf215546Sopenharmony_ci "%s" 453bf215546Sopenharmony_ci "DCL IN[0], %s[0], %s\n" 454bf215546Sopenharmony_ci "DCL OUT[0], COLOR[0]\n" 455bf215546Sopenharmony_ci 456bf215546Sopenharmony_ci "MOV OUT[0], IN[0]\n" 457bf215546Sopenharmony_ci "END\n"; 458bf215546Sopenharmony_ci 459bf215546Sopenharmony_ci char text[sizeof(shader_templ)+100]; 460bf215546Sopenharmony_ci struct tgsi_token tokens[1000]; 461bf215546Sopenharmony_ci struct pipe_shader_state state = {0}; 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_ci sprintf(text, shader_templ, 464bf215546Sopenharmony_ci write_all_cbufs ? "PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1\n" : "", 465bf215546Sopenharmony_ci tgsi_semantic_names[input_semantic], 466bf215546Sopenharmony_ci tgsi_interpolate_names[input_interpolate]); 467bf215546Sopenharmony_ci 468bf215546Sopenharmony_ci if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) { 469bf215546Sopenharmony_ci assert(0); 470bf215546Sopenharmony_ci return NULL; 471bf215546Sopenharmony_ci } 472bf215546Sopenharmony_ci pipe_shader_state_from_tgsi(&state, tokens); 473bf215546Sopenharmony_ci#if 0 474bf215546Sopenharmony_ci tgsi_dump(state.tokens, 0); 475bf215546Sopenharmony_ci#endif 476bf215546Sopenharmony_ci 477bf215546Sopenharmony_ci return pipe->create_fs_state(pipe, &state); 478bf215546Sopenharmony_ci} 479bf215546Sopenharmony_ci 480bf215546Sopenharmony_ci 481bf215546Sopenharmony_civoid * 482bf215546Sopenharmony_ciutil_make_empty_fragment_shader(struct pipe_context *pipe) 483bf215546Sopenharmony_ci{ 484bf215546Sopenharmony_ci struct ureg_program *ureg = ureg_create(PIPE_SHADER_FRAGMENT); 485bf215546Sopenharmony_ci if (!ureg) 486bf215546Sopenharmony_ci return NULL; 487bf215546Sopenharmony_ci 488bf215546Sopenharmony_ci ureg_END(ureg); 489bf215546Sopenharmony_ci return ureg_create_shader_and_destroy(ureg, pipe); 490bf215546Sopenharmony_ci} 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci 493bf215546Sopenharmony_ci/** 494bf215546Sopenharmony_ci * Make a fragment shader that copies the input color to N output colors. 495bf215546Sopenharmony_ci */ 496bf215546Sopenharmony_civoid * 497bf215546Sopenharmony_ciutil_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs, 498bf215546Sopenharmony_ci int input_semantic, 499bf215546Sopenharmony_ci int input_interpolate) 500bf215546Sopenharmony_ci{ 501bf215546Sopenharmony_ci struct ureg_program *ureg; 502bf215546Sopenharmony_ci struct ureg_src src; 503bf215546Sopenharmony_ci struct ureg_dst dst[PIPE_MAX_COLOR_BUFS]; 504bf215546Sopenharmony_ci int i; 505bf215546Sopenharmony_ci 506bf215546Sopenharmony_ci assert(num_cbufs <= PIPE_MAX_COLOR_BUFS); 507bf215546Sopenharmony_ci 508bf215546Sopenharmony_ci ureg = ureg_create( PIPE_SHADER_FRAGMENT ); 509bf215546Sopenharmony_ci if (!ureg) 510bf215546Sopenharmony_ci return NULL; 511bf215546Sopenharmony_ci 512bf215546Sopenharmony_ci src = ureg_DECL_fs_input( ureg, input_semantic, 0, 513bf215546Sopenharmony_ci input_interpolate ); 514bf215546Sopenharmony_ci 515bf215546Sopenharmony_ci for (i = 0; i < num_cbufs; i++) 516bf215546Sopenharmony_ci dst[i] = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, i ); 517bf215546Sopenharmony_ci 518bf215546Sopenharmony_ci for (i = 0; i < num_cbufs; i++) 519bf215546Sopenharmony_ci ureg_MOV( ureg, dst[i], src ); 520bf215546Sopenharmony_ci 521bf215546Sopenharmony_ci ureg_END( ureg ); 522bf215546Sopenharmony_ci 523bf215546Sopenharmony_ci return ureg_create_shader_and_destroy( ureg, pipe ); 524bf215546Sopenharmony_ci} 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci 527bf215546Sopenharmony_cistatic void * 528bf215546Sopenharmony_ciutil_make_fs_blit_msaa_gen(struct pipe_context *pipe, 529bf215546Sopenharmony_ci enum tgsi_texture_type tgsi_tex, 530bf215546Sopenharmony_ci bool sample_shading, 531bf215546Sopenharmony_ci const char *samp_type, 532bf215546Sopenharmony_ci const char *output_semantic, 533bf215546Sopenharmony_ci const char *output_mask, 534bf215546Sopenharmony_ci const char *conversion_decl, 535bf215546Sopenharmony_ci const char *conversion) 536bf215546Sopenharmony_ci{ 537bf215546Sopenharmony_ci static const char shader_templ[] = 538bf215546Sopenharmony_ci "FRAG\n" 539bf215546Sopenharmony_ci "DCL IN[0], GENERIC[0], LINEAR\n" 540bf215546Sopenharmony_ci "DCL SAMP[0]\n" 541bf215546Sopenharmony_ci "DCL SVIEW[0], %s, %s\n" 542bf215546Sopenharmony_ci "DCL OUT[0], %s\n" 543bf215546Sopenharmony_ci "DCL TEMP[0]\n" 544bf215546Sopenharmony_ci "%s" 545bf215546Sopenharmony_ci "%s" 546bf215546Sopenharmony_ci 547bf215546Sopenharmony_ci "F2U TEMP[0], IN[0]\n" 548bf215546Sopenharmony_ci "%s" 549bf215546Sopenharmony_ci "TXF TEMP[0], TEMP[0], SAMP[0], %s\n" 550bf215546Sopenharmony_ci "%s" 551bf215546Sopenharmony_ci "MOV OUT[0]%s, TEMP[0]\n" 552bf215546Sopenharmony_ci "END\n"; 553bf215546Sopenharmony_ci 554bf215546Sopenharmony_ci const char *type = tgsi_texture_names[tgsi_tex]; 555bf215546Sopenharmony_ci char text[sizeof(shader_templ)+400]; 556bf215546Sopenharmony_ci struct tgsi_token tokens[1000]; 557bf215546Sopenharmony_ci struct pipe_shader_state state = {0}; 558bf215546Sopenharmony_ci 559bf215546Sopenharmony_ci assert(tgsi_tex == TGSI_TEXTURE_2D_MSAA || 560bf215546Sopenharmony_ci tgsi_tex == TGSI_TEXTURE_2D_ARRAY_MSAA); 561bf215546Sopenharmony_ci 562bf215546Sopenharmony_ci snprintf(text, sizeof(text), shader_templ, type, samp_type, 563bf215546Sopenharmony_ci output_semantic, sample_shading ? "DCL SV[0], SAMPLEID\n" : "", 564bf215546Sopenharmony_ci conversion_decl, sample_shading ? "MOV TEMP[0].w, SV[0].xxxx\n" : "", 565bf215546Sopenharmony_ci type, conversion, output_mask); 566bf215546Sopenharmony_ci 567bf215546Sopenharmony_ci if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) { 568bf215546Sopenharmony_ci puts(text); 569bf215546Sopenharmony_ci assert(0); 570bf215546Sopenharmony_ci return NULL; 571bf215546Sopenharmony_ci } 572bf215546Sopenharmony_ci pipe_shader_state_from_tgsi(&state, tokens); 573bf215546Sopenharmony_ci#if 0 574bf215546Sopenharmony_ci tgsi_dump(state.tokens, 0); 575bf215546Sopenharmony_ci#endif 576bf215546Sopenharmony_ci 577bf215546Sopenharmony_ci return pipe->create_fs_state(pipe, &state); 578bf215546Sopenharmony_ci} 579bf215546Sopenharmony_ci 580bf215546Sopenharmony_ci 581bf215546Sopenharmony_ci/** 582bf215546Sopenharmony_ci * Make a fragment shader that sets the output color to a color 583bf215546Sopenharmony_ci * fetched from a multisample texture. 584bf215546Sopenharmony_ci * \param tex_target one of PIPE_TEXTURE_x 585bf215546Sopenharmony_ci */ 586bf215546Sopenharmony_civoid * 587bf215546Sopenharmony_ciutil_make_fs_blit_msaa_color(struct pipe_context *pipe, 588bf215546Sopenharmony_ci enum tgsi_texture_type tgsi_tex, 589bf215546Sopenharmony_ci enum tgsi_return_type stype, 590bf215546Sopenharmony_ci enum tgsi_return_type dtype, 591bf215546Sopenharmony_ci bool sample_shading) 592bf215546Sopenharmony_ci{ 593bf215546Sopenharmony_ci const char *samp_type; 594bf215546Sopenharmony_ci const char *conversion_decl = ""; 595bf215546Sopenharmony_ci const char *conversion = ""; 596bf215546Sopenharmony_ci 597bf215546Sopenharmony_ci if (stype == TGSI_RETURN_TYPE_UINT) { 598bf215546Sopenharmony_ci samp_type = "UINT"; 599bf215546Sopenharmony_ci 600bf215546Sopenharmony_ci if (dtype == TGSI_RETURN_TYPE_SINT) { 601bf215546Sopenharmony_ci conversion_decl = "IMM[0] UINT32 {2147483647, 0, 0, 0}\n"; 602bf215546Sopenharmony_ci conversion = "UMIN TEMP[0], TEMP[0], IMM[0].xxxx\n"; 603bf215546Sopenharmony_ci } 604bf215546Sopenharmony_ci } else if (stype == TGSI_RETURN_TYPE_SINT) { 605bf215546Sopenharmony_ci samp_type = "SINT"; 606bf215546Sopenharmony_ci 607bf215546Sopenharmony_ci if (dtype == TGSI_RETURN_TYPE_UINT) { 608bf215546Sopenharmony_ci conversion_decl = "IMM[0] INT32 {0, 0, 0, 0}\n"; 609bf215546Sopenharmony_ci conversion = "IMAX TEMP[0], TEMP[0], IMM[0].xxxx\n"; 610bf215546Sopenharmony_ci } 611bf215546Sopenharmony_ci } else { 612bf215546Sopenharmony_ci assert(dtype == TGSI_RETURN_TYPE_FLOAT); 613bf215546Sopenharmony_ci samp_type = "FLOAT"; 614bf215546Sopenharmony_ci } 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, sample_shading, samp_type, 617bf215546Sopenharmony_ci "COLOR[0]", "", conversion_decl, 618bf215546Sopenharmony_ci conversion); 619bf215546Sopenharmony_ci} 620bf215546Sopenharmony_ci 621bf215546Sopenharmony_ci 622bf215546Sopenharmony_ci/** 623bf215546Sopenharmony_ci * Make a fragment shader that sets the output depth to a depth value 624bf215546Sopenharmony_ci * fetched from a multisample texture. 625bf215546Sopenharmony_ci * \param tex_target one of PIPE_TEXTURE_x 626bf215546Sopenharmony_ci */ 627bf215546Sopenharmony_civoid * 628bf215546Sopenharmony_ciutil_make_fs_blit_msaa_depth(struct pipe_context *pipe, 629bf215546Sopenharmony_ci enum tgsi_texture_type tgsi_tex, 630bf215546Sopenharmony_ci bool sample_shading) 631bf215546Sopenharmony_ci{ 632bf215546Sopenharmony_ci return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, sample_shading, "FLOAT", 633bf215546Sopenharmony_ci "POSITION", ".z", "", 634bf215546Sopenharmony_ci "MOV TEMP[0].z, TEMP[0].xxxx\n"); 635bf215546Sopenharmony_ci} 636bf215546Sopenharmony_ci 637bf215546Sopenharmony_ci 638bf215546Sopenharmony_ci/** 639bf215546Sopenharmony_ci * Make a fragment shader that sets the output stencil to a stencil value 640bf215546Sopenharmony_ci * fetched from a multisample texture. 641bf215546Sopenharmony_ci * \param tex_target one of PIPE_TEXTURE_x 642bf215546Sopenharmony_ci */ 643bf215546Sopenharmony_civoid * 644bf215546Sopenharmony_ciutil_make_fs_blit_msaa_stencil(struct pipe_context *pipe, 645bf215546Sopenharmony_ci enum tgsi_texture_type tgsi_tex, 646bf215546Sopenharmony_ci bool sample_shading) 647bf215546Sopenharmony_ci{ 648bf215546Sopenharmony_ci return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, sample_shading, "UINT", 649bf215546Sopenharmony_ci "STENCIL", ".y", "", 650bf215546Sopenharmony_ci "MOV TEMP[0].y, TEMP[0].xxxx\n"); 651bf215546Sopenharmony_ci} 652bf215546Sopenharmony_ci 653bf215546Sopenharmony_ci 654bf215546Sopenharmony_ci/** 655bf215546Sopenharmony_ci * Make a fragment shader that sets the output depth and stencil to depth 656bf215546Sopenharmony_ci * and stencil values fetched from two multisample textures / samplers. 657bf215546Sopenharmony_ci * The sizes of both textures should match (it should be one depth-stencil 658bf215546Sopenharmony_ci * texture). 659bf215546Sopenharmony_ci * \param tex_target one of PIPE_TEXTURE_x 660bf215546Sopenharmony_ci */ 661bf215546Sopenharmony_civoid * 662bf215546Sopenharmony_ciutil_make_fs_blit_msaa_depthstencil(struct pipe_context *pipe, 663bf215546Sopenharmony_ci enum tgsi_texture_type tgsi_tex, 664bf215546Sopenharmony_ci bool sample_shading) 665bf215546Sopenharmony_ci{ 666bf215546Sopenharmony_ci static const char shader_templ[] = 667bf215546Sopenharmony_ci "FRAG\n" 668bf215546Sopenharmony_ci "DCL IN[0], GENERIC[0], LINEAR\n" 669bf215546Sopenharmony_ci "DCL SAMP[0..1]\n" 670bf215546Sopenharmony_ci "DCL SVIEW[0], %s, FLOAT\n" 671bf215546Sopenharmony_ci "DCL SVIEW[1], %s, UINT\n" 672bf215546Sopenharmony_ci "DCL OUT[0], POSITION\n" 673bf215546Sopenharmony_ci "DCL OUT[1], STENCIL\n" 674bf215546Sopenharmony_ci "DCL TEMP[0]\n" 675bf215546Sopenharmony_ci "%s" 676bf215546Sopenharmony_ci 677bf215546Sopenharmony_ci "F2U TEMP[0], IN[0]\n" 678bf215546Sopenharmony_ci "%s" 679bf215546Sopenharmony_ci "TXF OUT[0].z, TEMP[0], SAMP[0], %s\n" 680bf215546Sopenharmony_ci "TXF OUT[1].y, TEMP[0], SAMP[1], %s\n" 681bf215546Sopenharmony_ci "END\n"; 682bf215546Sopenharmony_ci 683bf215546Sopenharmony_ci const char *type = tgsi_texture_names[tgsi_tex]; 684bf215546Sopenharmony_ci char text[sizeof(shader_templ)+400]; 685bf215546Sopenharmony_ci struct tgsi_token tokens[1000]; 686bf215546Sopenharmony_ci struct pipe_shader_state state = {0}; 687bf215546Sopenharmony_ci 688bf215546Sopenharmony_ci assert(tgsi_tex == TGSI_TEXTURE_2D_MSAA || 689bf215546Sopenharmony_ci tgsi_tex == TGSI_TEXTURE_2D_ARRAY_MSAA); 690bf215546Sopenharmony_ci 691bf215546Sopenharmony_ci sprintf(text, shader_templ, type, type, 692bf215546Sopenharmony_ci sample_shading ? "DCL SV[0], SAMPLEID\n" : "", 693bf215546Sopenharmony_ci sample_shading ? "MOV TEMP[0].w, SV[0].xxxx\n" : "", 694bf215546Sopenharmony_ci type, type); 695bf215546Sopenharmony_ci 696bf215546Sopenharmony_ci if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) { 697bf215546Sopenharmony_ci assert(0); 698bf215546Sopenharmony_ci return NULL; 699bf215546Sopenharmony_ci } 700bf215546Sopenharmony_ci pipe_shader_state_from_tgsi(&state, tokens); 701bf215546Sopenharmony_ci#if 0 702bf215546Sopenharmony_ci tgsi_dump(state.tokens, 0); 703bf215546Sopenharmony_ci#endif 704bf215546Sopenharmony_ci 705bf215546Sopenharmony_ci return pipe->create_fs_state(pipe, &state); 706bf215546Sopenharmony_ci} 707bf215546Sopenharmony_ci 708bf215546Sopenharmony_ci 709bf215546Sopenharmony_civoid * 710bf215546Sopenharmony_ciutil_make_fs_msaa_resolve(struct pipe_context *pipe, 711bf215546Sopenharmony_ci enum tgsi_texture_type tgsi_tex, unsigned nr_samples, 712bf215546Sopenharmony_ci enum tgsi_return_type stype) 713bf215546Sopenharmony_ci{ 714bf215546Sopenharmony_ci struct ureg_program *ureg; 715bf215546Sopenharmony_ci struct ureg_src sampler, coord; 716bf215546Sopenharmony_ci struct ureg_dst out, tmp_sum, tmp_coord, tmp; 717bf215546Sopenharmony_ci unsigned i; 718bf215546Sopenharmony_ci 719bf215546Sopenharmony_ci ureg = ureg_create(PIPE_SHADER_FRAGMENT); 720bf215546Sopenharmony_ci if (!ureg) 721bf215546Sopenharmony_ci return NULL; 722bf215546Sopenharmony_ci 723bf215546Sopenharmony_ci /* Declarations. */ 724bf215546Sopenharmony_ci sampler = ureg_DECL_sampler(ureg, 0); 725bf215546Sopenharmony_ci ureg_DECL_sampler_view(ureg, 0, tgsi_tex, stype, stype, stype, stype); 726bf215546Sopenharmony_ci coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0, 727bf215546Sopenharmony_ci TGSI_INTERPOLATE_LINEAR); 728bf215546Sopenharmony_ci out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); 729bf215546Sopenharmony_ci tmp_sum = ureg_DECL_temporary(ureg); 730bf215546Sopenharmony_ci tmp_coord = ureg_DECL_temporary(ureg); 731bf215546Sopenharmony_ci tmp = ureg_DECL_temporary(ureg); 732bf215546Sopenharmony_ci 733bf215546Sopenharmony_ci /* Instructions. */ 734bf215546Sopenharmony_ci ureg_MOV(ureg, tmp_sum, ureg_imm1f(ureg, 0)); 735bf215546Sopenharmony_ci ureg_F2U(ureg, tmp_coord, coord); 736bf215546Sopenharmony_ci 737bf215546Sopenharmony_ci for (i = 0; i < nr_samples; i++) { 738bf215546Sopenharmony_ci /* Read one sample. */ 739bf215546Sopenharmony_ci ureg_MOV(ureg, ureg_writemask(tmp_coord, TGSI_WRITEMASK_W), 740bf215546Sopenharmony_ci ureg_imm1u(ureg, i)); 741bf215546Sopenharmony_ci ureg_TXF(ureg, tmp, tgsi_tex, ureg_src(tmp_coord), sampler); 742bf215546Sopenharmony_ci 743bf215546Sopenharmony_ci if (stype == TGSI_RETURN_TYPE_UINT) 744bf215546Sopenharmony_ci ureg_U2F(ureg, tmp, ureg_src(tmp)); 745bf215546Sopenharmony_ci else if (stype == TGSI_RETURN_TYPE_SINT) 746bf215546Sopenharmony_ci ureg_I2F(ureg, tmp, ureg_src(tmp)); 747bf215546Sopenharmony_ci 748bf215546Sopenharmony_ci /* Add it to the sum.*/ 749bf215546Sopenharmony_ci ureg_ADD(ureg, tmp_sum, ureg_src(tmp_sum), ureg_src(tmp)); 750bf215546Sopenharmony_ci } 751bf215546Sopenharmony_ci 752bf215546Sopenharmony_ci /* Calculate the average and return. */ 753bf215546Sopenharmony_ci ureg_MUL(ureg, tmp_sum, ureg_src(tmp_sum), 754bf215546Sopenharmony_ci ureg_imm1f(ureg, 1.0 / nr_samples)); 755bf215546Sopenharmony_ci 756bf215546Sopenharmony_ci if (stype == TGSI_RETURN_TYPE_UINT) 757bf215546Sopenharmony_ci ureg_F2U(ureg, out, ureg_src(tmp_sum)); 758bf215546Sopenharmony_ci else if (stype == TGSI_RETURN_TYPE_SINT) 759bf215546Sopenharmony_ci ureg_F2I(ureg, out, ureg_src(tmp_sum)); 760bf215546Sopenharmony_ci else 761bf215546Sopenharmony_ci ureg_MOV(ureg, out, ureg_src(tmp_sum)); 762bf215546Sopenharmony_ci 763bf215546Sopenharmony_ci ureg_END(ureg); 764bf215546Sopenharmony_ci 765bf215546Sopenharmony_ci return ureg_create_shader_and_destroy(ureg, pipe); 766bf215546Sopenharmony_ci} 767bf215546Sopenharmony_ci 768bf215546Sopenharmony_ci 769bf215546Sopenharmony_civoid * 770bf215546Sopenharmony_ciutil_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe, 771bf215546Sopenharmony_ci enum tgsi_texture_type tgsi_tex, 772bf215546Sopenharmony_ci unsigned nr_samples, 773bf215546Sopenharmony_ci enum tgsi_return_type stype) 774bf215546Sopenharmony_ci{ 775bf215546Sopenharmony_ci struct ureg_program *ureg; 776bf215546Sopenharmony_ci struct ureg_src sampler, coord; 777bf215546Sopenharmony_ci struct ureg_dst out, tmp, top, bottom; 778bf215546Sopenharmony_ci struct ureg_dst tmp_coord[4], tmp_sum[4]; 779bf215546Sopenharmony_ci unsigned i, c; 780bf215546Sopenharmony_ci 781bf215546Sopenharmony_ci ureg = ureg_create(PIPE_SHADER_FRAGMENT); 782bf215546Sopenharmony_ci if (!ureg) 783bf215546Sopenharmony_ci return NULL; 784bf215546Sopenharmony_ci 785bf215546Sopenharmony_ci /* Declarations. */ 786bf215546Sopenharmony_ci sampler = ureg_DECL_sampler(ureg, 0); 787bf215546Sopenharmony_ci ureg_DECL_sampler_view(ureg, 0, tgsi_tex, stype, stype, stype, stype); 788bf215546Sopenharmony_ci coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0, 789bf215546Sopenharmony_ci TGSI_INTERPOLATE_LINEAR); 790bf215546Sopenharmony_ci out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); 791bf215546Sopenharmony_ci for (c = 0; c < 4; c++) 792bf215546Sopenharmony_ci tmp_sum[c] = ureg_DECL_temporary(ureg); 793bf215546Sopenharmony_ci for (c = 0; c < 4; c++) 794bf215546Sopenharmony_ci tmp_coord[c] = ureg_DECL_temporary(ureg); 795bf215546Sopenharmony_ci tmp = ureg_DECL_temporary(ureg); 796bf215546Sopenharmony_ci top = ureg_DECL_temporary(ureg); 797bf215546Sopenharmony_ci bottom = ureg_DECL_temporary(ureg); 798bf215546Sopenharmony_ci 799bf215546Sopenharmony_ci /* Instructions. */ 800bf215546Sopenharmony_ci for (c = 0; c < 4; c++) 801bf215546Sopenharmony_ci ureg_MOV(ureg, tmp_sum[c], ureg_imm1f(ureg, 0)); 802bf215546Sopenharmony_ci 803bf215546Sopenharmony_ci /* Get 4 texture coordinates for the bilinear filter. */ 804bf215546Sopenharmony_ci ureg_F2U(ureg, tmp_coord[0], coord); /* top-left */ 805bf215546Sopenharmony_ci ureg_UADD(ureg, tmp_coord[1], ureg_src(tmp_coord[0]), 806bf215546Sopenharmony_ci ureg_imm4u(ureg, 1, 0, 0, 0)); /* top-right */ 807bf215546Sopenharmony_ci ureg_UADD(ureg, tmp_coord[2], ureg_src(tmp_coord[0]), 808bf215546Sopenharmony_ci ureg_imm4u(ureg, 0, 1, 0, 0)); /* bottom-left */ 809bf215546Sopenharmony_ci ureg_UADD(ureg, tmp_coord[3], ureg_src(tmp_coord[0]), 810bf215546Sopenharmony_ci ureg_imm4u(ureg, 1, 1, 0, 0)); /* bottom-right */ 811bf215546Sopenharmony_ci 812bf215546Sopenharmony_ci for (i = 0; i < nr_samples; i++) { 813bf215546Sopenharmony_ci for (c = 0; c < 4; c++) { 814bf215546Sopenharmony_ci /* Read one sample. */ 815bf215546Sopenharmony_ci ureg_MOV(ureg, ureg_writemask(tmp_coord[c], TGSI_WRITEMASK_W), 816bf215546Sopenharmony_ci ureg_imm1u(ureg, i)); 817bf215546Sopenharmony_ci ureg_TXF(ureg, tmp, tgsi_tex, ureg_src(tmp_coord[c]), sampler); 818bf215546Sopenharmony_ci 819bf215546Sopenharmony_ci if (stype == TGSI_RETURN_TYPE_UINT) 820bf215546Sopenharmony_ci ureg_U2F(ureg, tmp, ureg_src(tmp)); 821bf215546Sopenharmony_ci else if (stype == TGSI_RETURN_TYPE_SINT) 822bf215546Sopenharmony_ci ureg_I2F(ureg, tmp, ureg_src(tmp)); 823bf215546Sopenharmony_ci 824bf215546Sopenharmony_ci /* Add it to the sum.*/ 825bf215546Sopenharmony_ci ureg_ADD(ureg, tmp_sum[c], ureg_src(tmp_sum[c]), ureg_src(tmp)); 826bf215546Sopenharmony_ci } 827bf215546Sopenharmony_ci } 828bf215546Sopenharmony_ci 829bf215546Sopenharmony_ci /* Calculate the average. */ 830bf215546Sopenharmony_ci for (c = 0; c < 4; c++) 831bf215546Sopenharmony_ci ureg_MUL(ureg, tmp_sum[c], ureg_src(tmp_sum[c]), 832bf215546Sopenharmony_ci ureg_imm1f(ureg, 1.0 / nr_samples)); 833bf215546Sopenharmony_ci 834bf215546Sopenharmony_ci /* Take the 4 average values and apply a standard bilinear filter. */ 835bf215546Sopenharmony_ci ureg_FRC(ureg, tmp, coord); 836bf215546Sopenharmony_ci 837bf215546Sopenharmony_ci ureg_LRP(ureg, top, 838bf215546Sopenharmony_ci ureg_scalar(ureg_src(tmp), 0), 839bf215546Sopenharmony_ci ureg_src(tmp_sum[1]), 840bf215546Sopenharmony_ci ureg_src(tmp_sum[0])); 841bf215546Sopenharmony_ci 842bf215546Sopenharmony_ci ureg_LRP(ureg, bottom, 843bf215546Sopenharmony_ci ureg_scalar(ureg_src(tmp), 0), 844bf215546Sopenharmony_ci ureg_src(tmp_sum[3]), 845bf215546Sopenharmony_ci ureg_src(tmp_sum[2])); 846bf215546Sopenharmony_ci 847bf215546Sopenharmony_ci ureg_LRP(ureg, tmp, 848bf215546Sopenharmony_ci ureg_scalar(ureg_src(tmp), 1), 849bf215546Sopenharmony_ci ureg_src(bottom), 850bf215546Sopenharmony_ci ureg_src(top)); 851bf215546Sopenharmony_ci 852bf215546Sopenharmony_ci /* Convert to the texture format and return. */ 853bf215546Sopenharmony_ci if (stype == TGSI_RETURN_TYPE_UINT) 854bf215546Sopenharmony_ci ureg_F2U(ureg, out, ureg_src(tmp)); 855bf215546Sopenharmony_ci else if (stype == TGSI_RETURN_TYPE_SINT) 856bf215546Sopenharmony_ci ureg_F2I(ureg, out, ureg_src(tmp)); 857bf215546Sopenharmony_ci else 858bf215546Sopenharmony_ci ureg_MOV(ureg, out, ureg_src(tmp)); 859bf215546Sopenharmony_ci 860bf215546Sopenharmony_ci ureg_END(ureg); 861bf215546Sopenharmony_ci 862bf215546Sopenharmony_ci return ureg_create_shader_and_destroy(ureg, pipe); 863bf215546Sopenharmony_ci} 864bf215546Sopenharmony_ci 865bf215546Sopenharmony_civoid * 866bf215546Sopenharmony_ciutil_make_geometry_passthrough_shader(struct pipe_context *pipe, 867bf215546Sopenharmony_ci uint num_attribs, 868bf215546Sopenharmony_ci const ubyte *semantic_names, 869bf215546Sopenharmony_ci const ubyte *semantic_indexes) 870bf215546Sopenharmony_ci{ 871bf215546Sopenharmony_ci static const unsigned zero[4] = {0, 0, 0, 0}; 872bf215546Sopenharmony_ci 873bf215546Sopenharmony_ci struct ureg_program *ureg; 874bf215546Sopenharmony_ci struct ureg_dst dst[PIPE_MAX_SHADER_OUTPUTS]; 875bf215546Sopenharmony_ci struct ureg_src src[PIPE_MAX_SHADER_INPUTS]; 876bf215546Sopenharmony_ci struct ureg_src imm; 877bf215546Sopenharmony_ci 878bf215546Sopenharmony_ci unsigned i; 879bf215546Sopenharmony_ci 880bf215546Sopenharmony_ci ureg = ureg_create(PIPE_SHADER_GEOMETRY); 881bf215546Sopenharmony_ci if (!ureg) 882bf215546Sopenharmony_ci return NULL; 883bf215546Sopenharmony_ci 884bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_GS_INPUT_PRIM, PIPE_PRIM_POINTS); 885bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_GS_OUTPUT_PRIM, PIPE_PRIM_POINTS); 886bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES, 1); 887bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_GS_INVOCATIONS, 1); 888bf215546Sopenharmony_ci imm = ureg_DECL_immediate_uint(ureg, zero, 4); 889bf215546Sopenharmony_ci 890bf215546Sopenharmony_ci /** 891bf215546Sopenharmony_ci * Loop over all the attribs and declare the corresponding 892bf215546Sopenharmony_ci * declarations in the geometry shader 893bf215546Sopenharmony_ci */ 894bf215546Sopenharmony_ci for (i = 0; i < num_attribs; i++) { 895bf215546Sopenharmony_ci src[i] = ureg_DECL_input(ureg, semantic_names[i], 896bf215546Sopenharmony_ci semantic_indexes[i], 0, 1); 897bf215546Sopenharmony_ci src[i] = ureg_src_dimension(src[i], 0); 898bf215546Sopenharmony_ci dst[i] = ureg_DECL_output(ureg, semantic_names[i], semantic_indexes[i]); 899bf215546Sopenharmony_ci } 900bf215546Sopenharmony_ci 901bf215546Sopenharmony_ci /* MOV dst[i] src[i] */ 902bf215546Sopenharmony_ci for (i = 0; i < num_attribs; i++) { 903bf215546Sopenharmony_ci ureg_MOV(ureg, dst[i], src[i]); 904bf215546Sopenharmony_ci } 905bf215546Sopenharmony_ci 906bf215546Sopenharmony_ci /* EMIT IMM[0] */ 907bf215546Sopenharmony_ci ureg_insn(ureg, TGSI_OPCODE_EMIT, NULL, 0, &imm, 1, 0); 908bf215546Sopenharmony_ci 909bf215546Sopenharmony_ci /* END */ 910bf215546Sopenharmony_ci ureg_END(ureg); 911bf215546Sopenharmony_ci 912bf215546Sopenharmony_ci return ureg_create_shader_and_destroy(ureg, pipe); 913bf215546Sopenharmony_ci} 914bf215546Sopenharmony_ci 915bf215546Sopenharmony_ci 916bf215546Sopenharmony_ci/** 917bf215546Sopenharmony_ci * Blit from color to ZS or from ZS to color in a manner that is equivalent 918bf215546Sopenharmony_ci * to memcpy. 919bf215546Sopenharmony_ci * 920bf215546Sopenharmony_ci * Color is either R32_UINT (for Z24S8 / S8Z24) or R32G32_UINT (Z32_S8X24). 921bf215546Sopenharmony_ci * 922bf215546Sopenharmony_ci * Depth and stencil samplers are used to load depth and stencil, 923bf215546Sopenharmony_ci * and they are packed and the result is written to a color output. 924bf215546Sopenharmony_ci * OR 925bf215546Sopenharmony_ci * A color sampler is used to load a color value, which is unpacked and 926bf215546Sopenharmony_ci * written to depth and stencil shader outputs. 927bf215546Sopenharmony_ci */ 928bf215546Sopenharmony_civoid * 929bf215546Sopenharmony_ciutil_make_fs_pack_color_zs(struct pipe_context *pipe, 930bf215546Sopenharmony_ci enum tgsi_texture_type tex_target, 931bf215546Sopenharmony_ci enum pipe_format zs_format, 932bf215546Sopenharmony_ci bool dst_is_color) 933bf215546Sopenharmony_ci{ 934bf215546Sopenharmony_ci struct ureg_program *ureg; 935bf215546Sopenharmony_ci struct ureg_src depth_sampler, stencil_sampler, color_sampler, coord; 936bf215546Sopenharmony_ci struct ureg_dst out, depth, depth_x, stencil, out_depth, out_stencil, color; 937bf215546Sopenharmony_ci 938bf215546Sopenharmony_ci assert(zs_format == PIPE_FORMAT_Z24_UNORM_S8_UINT || /* color is R32_UINT */ 939bf215546Sopenharmony_ci zs_format == PIPE_FORMAT_S8_UINT_Z24_UNORM || /* color is R32_UINT */ 940bf215546Sopenharmony_ci zs_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT || /* color is R32G32_UINT */ 941bf215546Sopenharmony_ci zs_format == PIPE_FORMAT_Z24X8_UNORM || /* color is R32_UINT */ 942bf215546Sopenharmony_ci zs_format == PIPE_FORMAT_X8Z24_UNORM); /* color is R32_UINT */ 943bf215546Sopenharmony_ci 944bf215546Sopenharmony_ci bool has_stencil = zs_format != PIPE_FORMAT_Z24X8_UNORM && 945bf215546Sopenharmony_ci zs_format != PIPE_FORMAT_X8Z24_UNORM; 946bf215546Sopenharmony_ci bool is_z24 = zs_format != PIPE_FORMAT_Z32_FLOAT_S8X24_UINT; 947bf215546Sopenharmony_ci bool z24_is_high = zs_format == PIPE_FORMAT_S8_UINT_Z24_UNORM || 948bf215546Sopenharmony_ci zs_format == PIPE_FORMAT_X8Z24_UNORM; 949bf215546Sopenharmony_ci 950bf215546Sopenharmony_ci ureg = ureg_create(PIPE_SHADER_FRAGMENT); 951bf215546Sopenharmony_ci if (!ureg) 952bf215546Sopenharmony_ci return NULL; 953bf215546Sopenharmony_ci 954bf215546Sopenharmony_ci coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0, 955bf215546Sopenharmony_ci TGSI_INTERPOLATE_LINEAR); 956bf215546Sopenharmony_ci 957bf215546Sopenharmony_ci if (dst_is_color) { 958bf215546Sopenharmony_ci /* Load depth. */ 959bf215546Sopenharmony_ci depth_sampler = ureg_DECL_sampler(ureg, 0); 960bf215546Sopenharmony_ci ureg_DECL_sampler_view(ureg, 0, tex_target, 961bf215546Sopenharmony_ci TGSI_RETURN_TYPE_FLOAT, 962bf215546Sopenharmony_ci TGSI_RETURN_TYPE_FLOAT, 963bf215546Sopenharmony_ci TGSI_RETURN_TYPE_FLOAT, 964bf215546Sopenharmony_ci TGSI_RETURN_TYPE_FLOAT); 965bf215546Sopenharmony_ci 966bf215546Sopenharmony_ci depth = ureg_DECL_temporary(ureg); 967bf215546Sopenharmony_ci depth_x = ureg_writemask(depth, TGSI_WRITEMASK_X); 968bf215546Sopenharmony_ci ureg_load_tex(ureg, depth_x, coord, depth_sampler, tex_target, true, true); 969bf215546Sopenharmony_ci 970bf215546Sopenharmony_ci /* Pack to Z24. */ 971bf215546Sopenharmony_ci if (is_z24) { 972bf215546Sopenharmony_ci double imm = 0xffffff; 973bf215546Sopenharmony_ci struct ureg_src imm_f64 = ureg_DECL_immediate_f64(ureg, &imm, 2); 974bf215546Sopenharmony_ci struct ureg_dst tmp_xy = ureg_writemask(ureg_DECL_temporary(ureg), 975bf215546Sopenharmony_ci TGSI_WRITEMASK_XY); 976bf215546Sopenharmony_ci 977bf215546Sopenharmony_ci ureg_F2D(ureg, tmp_xy, ureg_src(depth)); 978bf215546Sopenharmony_ci ureg_DMUL(ureg, tmp_xy, ureg_src(tmp_xy), imm_f64); 979bf215546Sopenharmony_ci ureg_D2U(ureg, depth_x, ureg_src(tmp_xy)); 980bf215546Sopenharmony_ci 981bf215546Sopenharmony_ci if (z24_is_high) 982bf215546Sopenharmony_ci ureg_SHL(ureg, depth_x, ureg_src(depth), ureg_imm1u(ureg, 8)); 983bf215546Sopenharmony_ci else 984bf215546Sopenharmony_ci ureg_AND(ureg, depth_x, ureg_src(depth), ureg_imm1u(ureg, 0xffffff)); 985bf215546Sopenharmony_ci } 986bf215546Sopenharmony_ci 987bf215546Sopenharmony_ci if (has_stencil) { 988bf215546Sopenharmony_ci /* Load stencil. */ 989bf215546Sopenharmony_ci stencil_sampler = ureg_DECL_sampler(ureg, 1); 990bf215546Sopenharmony_ci ureg_DECL_sampler_view(ureg, 0, tex_target, 991bf215546Sopenharmony_ci TGSI_RETURN_TYPE_UINT, 992bf215546Sopenharmony_ci TGSI_RETURN_TYPE_UINT, 993bf215546Sopenharmony_ci TGSI_RETURN_TYPE_UINT, 994bf215546Sopenharmony_ci TGSI_RETURN_TYPE_UINT); 995bf215546Sopenharmony_ci 996bf215546Sopenharmony_ci stencil = ureg_writemask(ureg_DECL_temporary(ureg), TGSI_WRITEMASK_X); 997bf215546Sopenharmony_ci ureg_load_tex(ureg, stencil, coord, stencil_sampler, tex_target, 998bf215546Sopenharmony_ci true, true); 999bf215546Sopenharmony_ci 1000bf215546Sopenharmony_ci /* Pack stencil into depth. */ 1001bf215546Sopenharmony_ci if (is_z24) { 1002bf215546Sopenharmony_ci if (!z24_is_high) 1003bf215546Sopenharmony_ci ureg_SHL(ureg, stencil, ureg_src(stencil), ureg_imm1u(ureg, 24)); 1004bf215546Sopenharmony_ci 1005bf215546Sopenharmony_ci ureg_OR(ureg, depth_x, ureg_src(depth), ureg_src(stencil)); 1006bf215546Sopenharmony_ci } 1007bf215546Sopenharmony_ci } 1008bf215546Sopenharmony_ci 1009bf215546Sopenharmony_ci out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); 1010bf215546Sopenharmony_ci 1011bf215546Sopenharmony_ci if (is_z24) { 1012bf215546Sopenharmony_ci ureg_MOV(ureg, ureg_writemask(out, TGSI_WRITEMASK_X), ureg_src(depth)); 1013bf215546Sopenharmony_ci } else { 1014bf215546Sopenharmony_ci /* Z32_S8X24 */ 1015bf215546Sopenharmony_ci ureg_MOV(ureg, ureg_writemask(depth, TGSI_WRITEMASK_Y), 1016bf215546Sopenharmony_ci ureg_scalar(ureg_src(stencil), TGSI_SWIZZLE_X)); 1017bf215546Sopenharmony_ci ureg_MOV(ureg, ureg_writemask(out, TGSI_WRITEMASK_XY), ureg_src(depth)); 1018bf215546Sopenharmony_ci } 1019bf215546Sopenharmony_ci } else { 1020bf215546Sopenharmony_ci color_sampler = ureg_DECL_sampler(ureg, 0); 1021bf215546Sopenharmony_ci ureg_DECL_sampler_view(ureg, 0, tex_target, 1022bf215546Sopenharmony_ci TGSI_RETURN_TYPE_UINT, 1023bf215546Sopenharmony_ci TGSI_RETURN_TYPE_UINT, 1024bf215546Sopenharmony_ci TGSI_RETURN_TYPE_UINT, 1025bf215546Sopenharmony_ci TGSI_RETURN_TYPE_UINT); 1026bf215546Sopenharmony_ci 1027bf215546Sopenharmony_ci color = ureg_DECL_temporary(ureg); 1028bf215546Sopenharmony_ci ureg_load_tex(ureg, color, coord, color_sampler, tex_target, true, true); 1029bf215546Sopenharmony_ci 1030bf215546Sopenharmony_ci depth = ureg_writemask(ureg_DECL_temporary(ureg), TGSI_WRITEMASK_X); 1031bf215546Sopenharmony_ci stencil = ureg_writemask(ureg_DECL_temporary(ureg), TGSI_WRITEMASK_X); 1032bf215546Sopenharmony_ci 1033bf215546Sopenharmony_ci if (is_z24) { 1034bf215546Sopenharmony_ci double imm = 1.0 / 0xffffff; 1035bf215546Sopenharmony_ci struct ureg_src imm_f64 = ureg_DECL_immediate_f64(ureg, &imm, 2); 1036bf215546Sopenharmony_ci struct ureg_dst tmp_xy = ureg_writemask(ureg_DECL_temporary(ureg), 1037bf215546Sopenharmony_ci TGSI_WRITEMASK_XY); 1038bf215546Sopenharmony_ci 1039bf215546Sopenharmony_ci ureg_UBFE(ureg, depth, ureg_src(color), 1040bf215546Sopenharmony_ci ureg_imm1u(ureg, z24_is_high ? 8 : 0), 1041bf215546Sopenharmony_ci ureg_imm1u(ureg, 24)); 1042bf215546Sopenharmony_ci ureg_U2D(ureg, tmp_xy, ureg_src(depth)); 1043bf215546Sopenharmony_ci ureg_DMUL(ureg, tmp_xy, ureg_src(tmp_xy), imm_f64); 1044bf215546Sopenharmony_ci ureg_D2F(ureg, depth, ureg_src(tmp_xy)); 1045bf215546Sopenharmony_ci } else { 1046bf215546Sopenharmony_ci /* depth = color.x; (Z32_S8X24) */ 1047bf215546Sopenharmony_ci ureg_MOV(ureg, depth, ureg_src(color)); 1048bf215546Sopenharmony_ci } 1049bf215546Sopenharmony_ci 1050bf215546Sopenharmony_ci out_depth = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); 1051bf215546Sopenharmony_ci ureg_MOV(ureg, ureg_writemask(out_depth, TGSI_WRITEMASK_Z), 1052bf215546Sopenharmony_ci ureg_scalar(ureg_src(depth), TGSI_SWIZZLE_X)); 1053bf215546Sopenharmony_ci 1054bf215546Sopenharmony_ci if (has_stencil) { 1055bf215546Sopenharmony_ci if (is_z24) { 1056bf215546Sopenharmony_ci ureg_UBFE(ureg, stencil, ureg_src(color), 1057bf215546Sopenharmony_ci ureg_imm1u(ureg, z24_is_high ? 0 : 24), 1058bf215546Sopenharmony_ci ureg_imm1u(ureg, 8)); 1059bf215546Sopenharmony_ci } else { 1060bf215546Sopenharmony_ci /* stencil = color.y[0:7]; (Z32_S8X24) */ 1061bf215546Sopenharmony_ci ureg_UBFE(ureg, stencil, 1062bf215546Sopenharmony_ci ureg_scalar(ureg_src(color), TGSI_SWIZZLE_Y), 1063bf215546Sopenharmony_ci ureg_imm1u(ureg, 0), 1064bf215546Sopenharmony_ci ureg_imm1u(ureg, 8)); 1065bf215546Sopenharmony_ci } 1066bf215546Sopenharmony_ci 1067bf215546Sopenharmony_ci out_stencil = ureg_DECL_output(ureg, TGSI_SEMANTIC_STENCIL, 0); 1068bf215546Sopenharmony_ci ureg_MOV(ureg, ureg_writemask(out_stencil, TGSI_WRITEMASK_Y), 1069bf215546Sopenharmony_ci ureg_scalar(ureg_src(stencil), TGSI_SWIZZLE_X)); 1070bf215546Sopenharmony_ci } 1071bf215546Sopenharmony_ci } 1072bf215546Sopenharmony_ci 1073bf215546Sopenharmony_ci ureg_END(ureg); 1074bf215546Sopenharmony_ci 1075bf215546Sopenharmony_ci return ureg_create_shader_and_destroy(ureg, pipe); 1076bf215546Sopenharmony_ci} 1077bf215546Sopenharmony_ci 1078bf215546Sopenharmony_ci 1079bf215546Sopenharmony_ci/** 1080bf215546Sopenharmony_ci * Create passthrough tessellation control shader. 1081bf215546Sopenharmony_ci * Passthrough tessellation control shader has output of vertex shader 1082bf215546Sopenharmony_ci * as input and input of tessellation eval shader as output. 1083bf215546Sopenharmony_ci */ 1084bf215546Sopenharmony_civoid * 1085bf215546Sopenharmony_ciutil_make_tess_ctrl_passthrough_shader(struct pipe_context *pipe, 1086bf215546Sopenharmony_ci uint num_vs_outputs, 1087bf215546Sopenharmony_ci uint num_tes_inputs, 1088bf215546Sopenharmony_ci const ubyte *vs_semantic_names, 1089bf215546Sopenharmony_ci const ubyte *vs_semantic_indexes, 1090bf215546Sopenharmony_ci const ubyte *tes_semantic_names, 1091bf215546Sopenharmony_ci const ubyte *tes_semantic_indexes, 1092bf215546Sopenharmony_ci const unsigned vertices_per_patch) 1093bf215546Sopenharmony_ci{ 1094bf215546Sopenharmony_ci unsigned i, j; 1095bf215546Sopenharmony_ci unsigned num_regs; 1096bf215546Sopenharmony_ci 1097bf215546Sopenharmony_ci struct ureg_program *ureg; 1098bf215546Sopenharmony_ci struct ureg_dst temp, addr; 1099bf215546Sopenharmony_ci struct ureg_src invocationID; 1100bf215546Sopenharmony_ci struct ureg_dst dst[PIPE_MAX_SHADER_OUTPUTS]; 1101bf215546Sopenharmony_ci struct ureg_src src[PIPE_MAX_SHADER_INPUTS]; 1102bf215546Sopenharmony_ci 1103bf215546Sopenharmony_ci ureg = ureg_create(PIPE_SHADER_TESS_CTRL); 1104bf215546Sopenharmony_ci 1105bf215546Sopenharmony_ci if (!ureg) 1106bf215546Sopenharmony_ci return NULL; 1107bf215546Sopenharmony_ci 1108bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_TCS_VERTICES_OUT, vertices_per_patch); 1109bf215546Sopenharmony_ci 1110bf215546Sopenharmony_ci num_regs = 0; 1111bf215546Sopenharmony_ci 1112bf215546Sopenharmony_ci for (i = 0; i < num_tes_inputs; i++) { 1113bf215546Sopenharmony_ci switch (tes_semantic_names[i]) { 1114bf215546Sopenharmony_ci case TGSI_SEMANTIC_POSITION: 1115bf215546Sopenharmony_ci case TGSI_SEMANTIC_PSIZE: 1116bf215546Sopenharmony_ci case TGSI_SEMANTIC_COLOR: 1117bf215546Sopenharmony_ci case TGSI_SEMANTIC_BCOLOR: 1118bf215546Sopenharmony_ci case TGSI_SEMANTIC_CLIPDIST: 1119bf215546Sopenharmony_ci case TGSI_SEMANTIC_CLIPVERTEX: 1120bf215546Sopenharmony_ci case TGSI_SEMANTIC_TEXCOORD: 1121bf215546Sopenharmony_ci case TGSI_SEMANTIC_FOG: 1122bf215546Sopenharmony_ci case TGSI_SEMANTIC_GENERIC: 1123bf215546Sopenharmony_ci for (j = 0; j < num_vs_outputs; j++) { 1124bf215546Sopenharmony_ci if (tes_semantic_names[i] == vs_semantic_names[j] && 1125bf215546Sopenharmony_ci tes_semantic_indexes[i] == vs_semantic_indexes[j]) { 1126bf215546Sopenharmony_ci 1127bf215546Sopenharmony_ci dst[num_regs] = ureg_DECL_output(ureg, 1128bf215546Sopenharmony_ci tes_semantic_names[i], 1129bf215546Sopenharmony_ci tes_semantic_indexes[i]); 1130bf215546Sopenharmony_ci src[num_regs] = ureg_DECL_input(ureg, vs_semantic_names[j], 1131bf215546Sopenharmony_ci vs_semantic_indexes[j], 1132bf215546Sopenharmony_ci 0, 1); 1133bf215546Sopenharmony_ci 1134bf215546Sopenharmony_ci if (tes_semantic_names[i] == TGSI_SEMANTIC_GENERIC || 1135bf215546Sopenharmony_ci tes_semantic_names[i] == TGSI_SEMANTIC_POSITION) { 1136bf215546Sopenharmony_ci src[num_regs] = ureg_src_dimension(src[num_regs], 0); 1137bf215546Sopenharmony_ci dst[num_regs] = ureg_dst_dimension(dst[num_regs], 0); 1138bf215546Sopenharmony_ci } 1139bf215546Sopenharmony_ci 1140bf215546Sopenharmony_ci num_regs++; 1141bf215546Sopenharmony_ci break; 1142bf215546Sopenharmony_ci } 1143bf215546Sopenharmony_ci } 1144bf215546Sopenharmony_ci break; 1145bf215546Sopenharmony_ci default: 1146bf215546Sopenharmony_ci break; 1147bf215546Sopenharmony_ci } 1148bf215546Sopenharmony_ci } 1149bf215546Sopenharmony_ci 1150bf215546Sopenharmony_ci dst[num_regs] = ureg_DECL_output(ureg, TGSI_SEMANTIC_TESSOUTER, 1151bf215546Sopenharmony_ci num_regs); 1152bf215546Sopenharmony_ci src[num_regs] = ureg_DECL_constant(ureg, 0); 1153bf215546Sopenharmony_ci num_regs++; 1154bf215546Sopenharmony_ci dst[num_regs] = ureg_DECL_output(ureg, TGSI_SEMANTIC_TESSINNER, 1155bf215546Sopenharmony_ci num_regs); 1156bf215546Sopenharmony_ci src[num_regs] = ureg_DECL_constant(ureg, 1); 1157bf215546Sopenharmony_ci num_regs++; 1158bf215546Sopenharmony_ci 1159bf215546Sopenharmony_ci if (vertices_per_patch > 1) { 1160bf215546Sopenharmony_ci invocationID = ureg_DECL_system_value(ureg, 1161bf215546Sopenharmony_ci TGSI_SEMANTIC_INVOCATIONID, 0); 1162bf215546Sopenharmony_ci temp = ureg_DECL_local_temporary(ureg); 1163bf215546Sopenharmony_ci addr = ureg_DECL_address(ureg); 1164bf215546Sopenharmony_ci ureg_UARL(ureg, ureg_writemask(addr, TGSI_WRITEMASK_X), 1165bf215546Sopenharmony_ci ureg_scalar(invocationID, TGSI_SWIZZLE_X)); 1166bf215546Sopenharmony_ci } 1167bf215546Sopenharmony_ci 1168bf215546Sopenharmony_ci for (i = 0; i < num_regs; i++) { 1169bf215546Sopenharmony_ci if (dst[i].Dimension && vertices_per_patch > 1) { 1170bf215546Sopenharmony_ci struct ureg_src addr_x = ureg_scalar(ureg_src(addr), TGSI_SWIZZLE_X); 1171bf215546Sopenharmony_ci ureg_MOV(ureg, temp, ureg_src_dimension_indirect(src[i], 1172bf215546Sopenharmony_ci addr_x, 0)); 1173bf215546Sopenharmony_ci ureg_MOV(ureg, ureg_dst_dimension_indirect(dst[i], 1174bf215546Sopenharmony_ci addr_x, 0), ureg_src(temp)); 1175bf215546Sopenharmony_ci } 1176bf215546Sopenharmony_ci else 1177bf215546Sopenharmony_ci ureg_MOV(ureg, dst[i], src[i]); 1178bf215546Sopenharmony_ci } 1179bf215546Sopenharmony_ci 1180bf215546Sopenharmony_ci ureg_END(ureg); 1181bf215546Sopenharmony_ci 1182bf215546Sopenharmony_ci return ureg_create_shader_and_destroy(ureg, pipe); 1183bf215546Sopenharmony_ci} 1184bf215546Sopenharmony_ci 1185bf215546Sopenharmony_civoid * 1186bf215546Sopenharmony_ciutil_make_fs_stencil_blit(struct pipe_context *pipe, bool msaa_src) 1187bf215546Sopenharmony_ci{ 1188bf215546Sopenharmony_ci static const char shader_templ[] = 1189bf215546Sopenharmony_ci "FRAG\n" 1190bf215546Sopenharmony_ci "DCL IN[0], GENERIC[0], LINEAR\n" 1191bf215546Sopenharmony_ci "DCL SAMP[0]\n" 1192bf215546Sopenharmony_ci "DCL SVIEW[0], %s, UINT\n" 1193bf215546Sopenharmony_ci "DCL CONST[0][0]\n" 1194bf215546Sopenharmony_ci "DCL TEMP[0]\n" 1195bf215546Sopenharmony_ci 1196bf215546Sopenharmony_ci "F2U TEMP[0], IN[0]\n" 1197bf215546Sopenharmony_ci "TXF_LZ TEMP[0].x, TEMP[0], SAMP[0], %s\n" 1198bf215546Sopenharmony_ci "AND TEMP[0].x, TEMP[0], CONST[0][0]\n" 1199bf215546Sopenharmony_ci "USNE TEMP[0].x, TEMP[0], CONST[0][0]\n" 1200bf215546Sopenharmony_ci "U2F TEMP[0].x, TEMP[0]\n" 1201bf215546Sopenharmony_ci "KILL_IF -TEMP[0].xxxx\n" 1202bf215546Sopenharmony_ci "END\n"; 1203bf215546Sopenharmony_ci 1204bf215546Sopenharmony_ci char text[sizeof(shader_templ)+100]; 1205bf215546Sopenharmony_ci struct tgsi_token tokens[1000]; 1206bf215546Sopenharmony_ci struct pipe_shader_state state = { 0 }; 1207bf215546Sopenharmony_ci 1208bf215546Sopenharmony_ci enum tgsi_texture_type tgsi_tex = msaa_src ? TGSI_TEXTURE_2D_MSAA : 1209bf215546Sopenharmony_ci TGSI_TEXTURE_2D; 1210bf215546Sopenharmony_ci 1211bf215546Sopenharmony_ci sprintf(text, shader_templ, tgsi_texture_names[tgsi_tex], tgsi_texture_names[tgsi_tex]); 1212bf215546Sopenharmony_ci 1213bf215546Sopenharmony_ci if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) { 1214bf215546Sopenharmony_ci assert(0); 1215bf215546Sopenharmony_ci return NULL; 1216bf215546Sopenharmony_ci } 1217bf215546Sopenharmony_ci 1218bf215546Sopenharmony_ci pipe_shader_state_from_tgsi(&state, tokens); 1219bf215546Sopenharmony_ci 1220bf215546Sopenharmony_ci return pipe->create_fs_state(pipe, &state); 1221bf215546Sopenharmony_ci} 1222bf215546Sopenharmony_ci 1223bf215546Sopenharmony_civoid * 1224bf215546Sopenharmony_ciutil_make_fs_clear_all_cbufs(struct pipe_context *pipe) 1225bf215546Sopenharmony_ci{ 1226bf215546Sopenharmony_ci static const char text[] = 1227bf215546Sopenharmony_ci "FRAG\n" 1228bf215546Sopenharmony_ci "PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1\n" 1229bf215546Sopenharmony_ci "DCL OUT[0], COLOR[0]\n" 1230bf215546Sopenharmony_ci "DCL CONST[0][0]\n" 1231bf215546Sopenharmony_ci 1232bf215546Sopenharmony_ci "MOV OUT[0], CONST[0][0]\n" 1233bf215546Sopenharmony_ci "END\n"; 1234bf215546Sopenharmony_ci 1235bf215546Sopenharmony_ci struct tgsi_token tokens[1000]; 1236bf215546Sopenharmony_ci struct pipe_shader_state state = { 0 }; 1237bf215546Sopenharmony_ci 1238bf215546Sopenharmony_ci if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) { 1239bf215546Sopenharmony_ci assert(0); 1240bf215546Sopenharmony_ci return NULL; 1241bf215546Sopenharmony_ci } 1242bf215546Sopenharmony_ci 1243bf215546Sopenharmony_ci pipe_shader_state_from_tgsi(&state, tokens); 1244bf215546Sopenharmony_ci 1245bf215546Sopenharmony_ci return pipe->create_fs_state(pipe, &state); 1246bf215546Sopenharmony_ci} 1247