14a49301eSmrg/********************************************************** 24a49301eSmrg * Copyright 2008-2009 VMware, Inc. All rights reserved. 34a49301eSmrg * 44a49301eSmrg * Permission is hereby granted, free of charge, to any person 54a49301eSmrg * obtaining a copy of this software and associated documentation 64a49301eSmrg * files (the "Software"), to deal in the Software without 74a49301eSmrg * restriction, including without limitation the rights to use, copy, 84a49301eSmrg * modify, merge, publish, distribute, sublicense, and/or sell copies 94a49301eSmrg * of the Software, and to permit persons to whom the Software is 104a49301eSmrg * furnished to do so, subject to the following conditions: 114a49301eSmrg * 124a49301eSmrg * The above copyright notice and this permission notice shall be 134a49301eSmrg * included in all copies or substantial portions of the Software. 144a49301eSmrg * 154a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 164a49301eSmrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 174a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 184a49301eSmrg * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 194a49301eSmrg * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 204a49301eSmrg * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 214a49301eSmrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 224a49301eSmrg * SOFTWARE. 234a49301eSmrg * 244a49301eSmrg **********************************************************/ 254a49301eSmrg 264a49301eSmrg 274a49301eSmrg#include "pipe/p_compiler.h" 284a49301eSmrg#include "pipe/p_shader_tokens.h" 294a49301eSmrg#include "pipe/p_defines.h" 304a49301eSmrg#include "tgsi/tgsi_parse.h" 314a49301eSmrg#include "tgsi/tgsi_dump.h" 324a49301eSmrg#include "tgsi/tgsi_scan.h" 33af69d88dSmrg#include "util/u_math.h" 344a49301eSmrg#include "util/u_memory.h" 354a49301eSmrg#include "util/u_bitmask.h" 364a49301eSmrg 374a49301eSmrg#include "svgadump/svga_shader_dump.h" 384a49301eSmrg 394a49301eSmrg#include "svga_context.h" 4001e04c3fSmrg#include "svga_shader.h" 414a49301eSmrg#include "svga_tgsi.h" 424a49301eSmrg#include "svga_tgsi_emit.h" 434a49301eSmrg#include "svga_debug.h" 444a49301eSmrg 454a49301eSmrg#include "svga_hw_reg.h" 464a49301eSmrg#include "svga3d_shaderdefs.h" 474a49301eSmrg 484a49301eSmrg 494a49301eSmrg/* Sinkhole used only in error conditions. 504a49301eSmrg */ 514a49301eSmrgstatic char err_buf[128]; 524a49301eSmrg 534a49301eSmrg 54af69d88dSmrgstatic boolean 55af69d88dSmrgsvga_shader_expand(struct svga_shader_emitter *emit) 564a49301eSmrg{ 574a49301eSmrg char *new_buf; 584a49301eSmrg unsigned newsize = emit->size * 2; 594a49301eSmrg 60af69d88dSmrg if (emit->buf != err_buf) 614a49301eSmrg new_buf = REALLOC(emit->buf, emit->size, newsize); 624a49301eSmrg else 634a49301eSmrg new_buf = NULL; 644a49301eSmrg 6501e04c3fSmrg if (!new_buf) { 664a49301eSmrg emit->ptr = err_buf; 674a49301eSmrg emit->buf = err_buf; 684a49301eSmrg emit->size = sizeof(err_buf); 694a49301eSmrg return FALSE; 704a49301eSmrg } 714a49301eSmrg 724a49301eSmrg emit->size = newsize; 734a49301eSmrg emit->ptr = new_buf + (emit->ptr - emit->buf); 744a49301eSmrg emit->buf = new_buf; 754a49301eSmrg return TRUE; 76af69d88dSmrg} 774a49301eSmrg 78af69d88dSmrg 7901e04c3fSmrgstatic inline boolean 80af69d88dSmrgreserve(struct svga_shader_emitter *emit, unsigned nr_dwords) 814a49301eSmrg{ 824a49301eSmrg if (emit->ptr - emit->buf + nr_dwords * sizeof(unsigned) >= emit->size) { 83af69d88dSmrg if (!svga_shader_expand(emit)) { 844a49301eSmrg return FALSE; 85af69d88dSmrg } 864a49301eSmrg } 874a49301eSmrg 884a49301eSmrg return TRUE; 894a49301eSmrg} 904a49301eSmrg 91af69d88dSmrg 92af69d88dSmrgboolean 93af69d88dSmrgsvga_shader_emit_dword(struct svga_shader_emitter * emit, unsigned dword) 944a49301eSmrg{ 954a49301eSmrg if (!reserve(emit, 1)) 964a49301eSmrg return FALSE; 974a49301eSmrg 98af69d88dSmrg *(unsigned *) emit->ptr = dword; 994a49301eSmrg emit->ptr += sizeof dword; 1004a49301eSmrg return TRUE; 1014a49301eSmrg} 1024a49301eSmrg 103af69d88dSmrg 104af69d88dSmrgboolean 105af69d88dSmrgsvga_shader_emit_dwords(struct svga_shader_emitter * emit, 106af69d88dSmrg const unsigned *dwords, unsigned nr) 1074a49301eSmrg{ 1084a49301eSmrg if (!reserve(emit, nr)) 1094a49301eSmrg return FALSE; 1104a49301eSmrg 111af69d88dSmrg memcpy(emit->ptr, dwords, nr * sizeof *dwords); 1124a49301eSmrg emit->ptr += nr * sizeof *dwords; 1134a49301eSmrg return TRUE; 1144a49301eSmrg} 1154a49301eSmrg 116af69d88dSmrg 117af69d88dSmrgboolean 118af69d88dSmrgsvga_shader_emit_opcode(struct svga_shader_emitter * emit, unsigned opcode) 1194a49301eSmrg{ 1204a49301eSmrg SVGA3dShaderInstToken *here; 1214a49301eSmrg 1224a49301eSmrg if (!reserve(emit, 1)) 1234a49301eSmrg return FALSE; 1244a49301eSmrg 125af69d88dSmrg here = (SVGA3dShaderInstToken *) emit->ptr; 1264a49301eSmrg here->value = opcode; 1274a49301eSmrg 1284a49301eSmrg if (emit->insn_offset) { 129af69d88dSmrg SVGA3dShaderInstToken *prev = 130af69d88dSmrg (SVGA3dShaderInstToken *) (emit->buf + emit->insn_offset); 1314a49301eSmrg prev->size = (here - prev) - 1; 1324a49301eSmrg } 133af69d88dSmrg 1344a49301eSmrg emit->insn_offset = emit->ptr - emit->buf; 1354a49301eSmrg emit->ptr += sizeof(unsigned); 1364a49301eSmrg return TRUE; 1374a49301eSmrg} 1384a49301eSmrg 1394a49301eSmrg 140af69d88dSmrgstatic boolean 141af69d88dSmrgsvga_shader_emit_header(struct svga_shader_emitter *emit) 1424a49301eSmrg{ 1434a49301eSmrg SVGA3dShaderVersion header; 1444a49301eSmrg 145af69d88dSmrg memset(&header, 0, sizeof header); 1464a49301eSmrg 1474a49301eSmrg switch (emit->unit) { 1484a49301eSmrg case PIPE_SHADER_FRAGMENT: 149af69d88dSmrg header.value = SVGA3D_PS_30; 1504a49301eSmrg break; 1514a49301eSmrg case PIPE_SHADER_VERTEX: 152af69d88dSmrg header.value = SVGA3D_VS_30; 1534a49301eSmrg break; 1544a49301eSmrg } 155af69d88dSmrg 156af69d88dSmrg return svga_shader_emit_dword(emit, header.value); 157af69d88dSmrg} 158af69d88dSmrg 159af69d88dSmrg 160af69d88dSmrg/** 161af69d88dSmrg * Parse TGSI shader and translate to SVGA/DX9 serialized 162af69d88dSmrg * representation. 1634a49301eSmrg * 1644a49301eSmrg * In this function SVGA shader is emitted to an in-memory buffer that 1654a49301eSmrg * can be dynamically grown. Once we've finished and know how large 1664a49301eSmrg * it is, it will be copied to a hardware buffer for upload. 1674a49301eSmrg */ 16801e04c3fSmrgstruct svga_shader_variant * 16901e04c3fSmrgsvga_tgsi_vgpu9_translate(struct svga_context *svga, 17001e04c3fSmrg const struct svga_shader *shader, 17101e04c3fSmrg const struct svga_compile_key *key, 17201e04c3fSmrg enum pipe_shader_type unit) 1734a49301eSmrg{ 174af69d88dSmrg struct svga_shader_variant *variant = NULL; 1754a49301eSmrg struct svga_shader_emitter emit; 1764a49301eSmrg 17701e04c3fSmrg SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_TGSIVGPU9TRANSLATE); 17801e04c3fSmrg 1794a49301eSmrg memset(&emit, 0, sizeof(emit)); 1804a49301eSmrg 1814a49301eSmrg emit.size = 1024; 1824a49301eSmrg emit.buf = MALLOC(emit.size); 1834a49301eSmrg if (emit.buf == NULL) { 1844a49301eSmrg goto fail; 1854a49301eSmrg } 1864a49301eSmrg 1874a49301eSmrg emit.ptr = emit.buf; 1884a49301eSmrg emit.unit = unit; 189af69d88dSmrg emit.key = *key; 1904a49301eSmrg 191af69d88dSmrg tgsi_scan_shader(shader->tokens, &emit.info); 1924a49301eSmrg 1934a49301eSmrg emit.imm_start = emit.info.file_max[TGSI_FILE_CONSTANT] + 1; 194af69d88dSmrg 1954a49301eSmrg if (unit == PIPE_SHADER_FRAGMENT) 19601e04c3fSmrg emit.imm_start += key->num_unnormalized_coords; 1974a49301eSmrg 1984a49301eSmrg if (unit == PIPE_SHADER_VERTEX) { 19901e04c3fSmrg emit.imm_start += key->vs.need_prescale ? 2 : 0; 2004a49301eSmrg } 2014a49301eSmrg 202af69d88dSmrg emit.nr_hw_float_const = 203af69d88dSmrg (emit.imm_start + emit.info.file_max[TGSI_FILE_IMMEDIATE] + 1); 2044a49301eSmrg 2054a49301eSmrg emit.nr_hw_temp = emit.info.file_max[TGSI_FILE_TEMPORARY] + 1; 206af69d88dSmrg 207af69d88dSmrg if (emit.nr_hw_temp >= SVGA3D_TEMPREG_MAX) { 208af69d88dSmrg debug_printf("svga: too many temporary registers (%u)\n", 209af69d88dSmrg emit.nr_hw_temp); 210af69d88dSmrg goto fail; 211af69d88dSmrg } 212af69d88dSmrg 21301e04c3fSmrg if (emit.info.indirect_files & (1 << TGSI_FILE_TEMPORARY)) { 21401e04c3fSmrg debug_printf( 21501e04c3fSmrg "svga: indirect indexing of temporary registers is not supported.\n"); 21601e04c3fSmrg goto fail; 21701e04c3fSmrg } 21801e04c3fSmrg 2194a49301eSmrg emit.in_main_func = TRUE; 2204a49301eSmrg 221af69d88dSmrg if (!svga_shader_emit_header(&emit)) { 222af69d88dSmrg debug_printf("svga: emit header failed\n"); 2234a49301eSmrg goto fail; 224af69d88dSmrg } 2254a49301eSmrg 226af69d88dSmrg if (!svga_shader_emit_instructions(&emit, shader->tokens)) { 227af69d88dSmrg debug_printf("svga: emit instructions failed\n"); 2284a49301eSmrg goto fail; 229af69d88dSmrg } 230af69d88dSmrg 2319f464c52Smaya variant = svga_new_shader_variant(svga, unit); 23201e04c3fSmrg if (!variant) 2334a49301eSmrg goto fail; 2344a49301eSmrg 235af69d88dSmrg variant->shader = shader; 236af69d88dSmrg variant->tokens = (const unsigned *) emit.buf; 237af69d88dSmrg variant->nr_tokens = (emit.ptr - emit.buf) / sizeof(unsigned); 238af69d88dSmrg memcpy(&variant->key, key, sizeof(*key)); 239af69d88dSmrg variant->id = UTIL_BITMASK_INVALID_INDEX; 240af69d88dSmrg 2417ec681f3Smrg if (unit == PIPE_SHADER_FRAGMENT) { 2427ec681f3Smrg struct svga_fs_variant *fs_variant = svga_fs_variant(variant); 2437ec681f3Smrg 2447ec681f3Smrg fs_variant->pstipple_sampler_unit = emit.pstipple_sampler_unit; 2457ec681f3Smrg 2467ec681f3Smrg /* If there was exactly one write to a fragment shader output register 2477ec681f3Smrg * and it came from a constant buffer, we know all fragments will have 2487ec681f3Smrg * the same color (except for blending). 2497ec681f3Smrg */ 2507ec681f3Smrg fs_variant->constant_color_output = 2517ec681f3Smrg emit.constant_color_output && emit.num_output_writes == 1; 2527ec681f3Smrg } 25301e04c3fSmrg 25401e04c3fSmrg#if 0 25501e04c3fSmrg if (!svga_shader_verify(variant->tokens, variant->nr_tokens) || 25601e04c3fSmrg SVGA_DEBUG & DEBUG_TGSI) { 257af69d88dSmrg debug_printf("#####################################\n"); 258af69d88dSmrg debug_printf("Shader %u below\n", shader->id); 259af69d88dSmrg tgsi_dump(shader->tokens, 0); 2604a49301eSmrg if (SVGA_DEBUG & DEBUG_TGSI) { 261af69d88dSmrg debug_printf("Shader %u compiled below\n", shader->id); 262af69d88dSmrg svga_shader_dump(variant->tokens, variant->nr_tokens, FALSE); 2634a49301eSmrg } 264af69d88dSmrg debug_printf("#####################################\n"); 2654a49301eSmrg } 26601e04c3fSmrg#endif 2674a49301eSmrg 26801e04c3fSmrg goto done; 2694a49301eSmrg 27001e04c3fSmrgfail: 271af69d88dSmrg FREE(variant); 27201e04c3fSmrg if (emit.buf != err_buf) 27301e04c3fSmrg FREE(emit.buf); 27401e04c3fSmrg variant = NULL; 2754a49301eSmrg 27601e04c3fSmrgdone: 27701e04c3fSmrg SVGA_STATS_TIME_POP(svga_sws(svga)); 27801e04c3fSmrg return variant; 2794a49301eSmrg} 280