14a49301eSmrg/************************************************************************** 27ec681f3Smrg * 3af69d88dSmrg * Copyright 2008 VMware, Inc. 44a49301eSmrg * All Rights Reserved. 57ec681f3Smrg * 64a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a 74a49301eSmrg * copy of this software and associated documentation files (the 84a49301eSmrg * "Software"), to deal in the Software without restriction, including 94a49301eSmrg * without limitation the rights to use, copy, modify, merge, publish, 104a49301eSmrg * distribute, sub license, and/or sell copies of the Software, and to 114a49301eSmrg * permit persons to whom the Software is furnished to do so, subject to 124a49301eSmrg * the following conditions: 137ec681f3Smrg * 144a49301eSmrg * The above copyright notice and this permission notice (including the 154a49301eSmrg * next paragraph) shall be included in all copies or substantial portions 164a49301eSmrg * of the Software. 177ec681f3Smrg * 184a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 194a49301eSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 204a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21af69d88dSmrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 224a49301eSmrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 234a49301eSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 244a49301eSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 257ec681f3Smrg * 264a49301eSmrg **************************************************************************/ 274a49301eSmrg 287ec681f3Smrg#include "compiler/nir/nir.h" 293464ebd5Sriastradh#include "draw/draw_context.h" 307ec681f3Smrg#include "util/format/u_format.h" 317ec681f3Smrg#include "util/format/u_format_s3tc.h" 3201e04c3fSmrg#include "util/os_misc.h" 33cdc920a0Smrg#include "util/u_inlines.h" 344a49301eSmrg#include "util/u_memory.h" 3501e04c3fSmrg#include "util/u_screen.h" 364a49301eSmrg#include "util/u_string.h" 374a49301eSmrg 384a49301eSmrg#include "i915_context.h" 397ec681f3Smrg#include "i915_debug.h" 407ec681f3Smrg#include "i915_public.h" 417ec681f3Smrg#include "i915_reg.h" 423464ebd5Sriastradh#include "i915_resource.h" 437ec681f3Smrg#include "i915_screen.h" 443464ebd5Sriastradh#include "i915_winsys.h" 454a49301eSmrg 464a49301eSmrg/* 474a49301eSmrg * Probe functions 484a49301eSmrg */ 494a49301eSmrg 504a49301eSmrgstatic const char * 514a49301eSmrgi915_get_vendor(struct pipe_screen *screen) 524a49301eSmrg{ 53af69d88dSmrg return "Mesa Project"; 544a49301eSmrg} 554a49301eSmrg 5601e04c3fSmrgstatic const char * 5701e04c3fSmrgi915_get_device_vendor(struct pipe_screen *screen) 5801e04c3fSmrg{ 5901e04c3fSmrg return "Intel"; 6001e04c3fSmrg} 6101e04c3fSmrg 624a49301eSmrgstatic const char * 634a49301eSmrgi915_get_name(struct pipe_screen *screen) 644a49301eSmrg{ 654a49301eSmrg static char buffer[128]; 664a49301eSmrg const char *chipset; 674a49301eSmrg 683464ebd5Sriastradh switch (i915_screen(screen)->iws->pci_id) { 694a49301eSmrg case PCI_CHIP_I915_G: 704a49301eSmrg chipset = "915G"; 714a49301eSmrg break; 724a49301eSmrg case PCI_CHIP_I915_GM: 734a49301eSmrg chipset = "915GM"; 744a49301eSmrg break; 754a49301eSmrg case PCI_CHIP_I945_G: 764a49301eSmrg chipset = "945G"; 774a49301eSmrg break; 784a49301eSmrg case PCI_CHIP_I945_GM: 794a49301eSmrg chipset = "945GM"; 804a49301eSmrg break; 814a49301eSmrg case PCI_CHIP_I945_GME: 824a49301eSmrg chipset = "945GME"; 834a49301eSmrg break; 844a49301eSmrg case PCI_CHIP_G33_G: 854a49301eSmrg chipset = "G33"; 864a49301eSmrg break; 874a49301eSmrg case PCI_CHIP_Q35_G: 884a49301eSmrg chipset = "Q35"; 894a49301eSmrg break; 904a49301eSmrg case PCI_CHIP_Q33_G: 914a49301eSmrg chipset = "Q33"; 924a49301eSmrg break; 933464ebd5Sriastradh case PCI_CHIP_PINEVIEW_G: 943464ebd5Sriastradh chipset = "Pineview G"; 953464ebd5Sriastradh break; 963464ebd5Sriastradh case PCI_CHIP_PINEVIEW_M: 973464ebd5Sriastradh chipset = "Pineview M"; 983464ebd5Sriastradh break; 994a49301eSmrg default: 1004a49301eSmrg chipset = "unknown"; 1014a49301eSmrg break; 1024a49301eSmrg } 1034a49301eSmrg 1047ec681f3Smrg snprintf(buffer, sizeof(buffer), "i915 (chipset: %s)", chipset); 1054a49301eSmrg return buffer; 1064a49301eSmrg} 1074a49301eSmrg 1087ec681f3Smrgstatic const nir_shader_compiler_options i915_compiler_options = { 1097ec681f3Smrg .fuse_ffma32 = true, 1107ec681f3Smrg .lower_bitops = true, /* required for !CAP_INTEGERS nir_to_tgsi */ 1117ec681f3Smrg .lower_extract_byte = true, 1127ec681f3Smrg .lower_extract_word = true, 1137ec681f3Smrg .lower_fdiv = true, 1147ec681f3Smrg .lower_fdph = true, 1157ec681f3Smrg .lower_flrp32 = true, 1167ec681f3Smrg .lower_fmod = true, 1177ec681f3Smrg .lower_rotate = true, 1187ec681f3Smrg .lower_uniforms_to_ubo = true, 1197ec681f3Smrg .lower_vector_cmp = true, 1207ec681f3Smrg .use_interpolated_input_intrinsics = true, 1217ec681f3Smrg .force_indirect_unrolling = ~0, 1227ec681f3Smrg}; 1237ec681f3Smrg 1247ec681f3Smrgstatic const struct nir_shader_compiler_options gallivm_nir_options = { 1257ec681f3Smrg .lower_bitops = true, /* required for !CAP_INTEGERS nir_to_tgsi */ 1267ec681f3Smrg .lower_scmp = true, 1277ec681f3Smrg .lower_flrp32 = true, 1287ec681f3Smrg .lower_flrp64 = true, 1297ec681f3Smrg .lower_fsat = true, 1307ec681f3Smrg .lower_bitfield_insert_to_shifts = true, 1317ec681f3Smrg .lower_bitfield_extract_to_shifts = true, 1327ec681f3Smrg .lower_fdph = true, 1337ec681f3Smrg .lower_ffma16 = true, 1347ec681f3Smrg .lower_ffma32 = true, 1357ec681f3Smrg .lower_ffma64 = true, 1367ec681f3Smrg .lower_fmod = true, 1377ec681f3Smrg .lower_hadd = true, 1387ec681f3Smrg .lower_uadd_sat = true, 1397ec681f3Smrg .lower_iadd_sat = true, 1407ec681f3Smrg .lower_ldexp = true, 1417ec681f3Smrg .lower_pack_snorm_2x16 = true, 1427ec681f3Smrg .lower_pack_snorm_4x8 = true, 1437ec681f3Smrg .lower_pack_unorm_2x16 = true, 1447ec681f3Smrg .lower_pack_unorm_4x8 = true, 1457ec681f3Smrg .lower_pack_half_2x16 = true, 1467ec681f3Smrg .lower_pack_split = true, 1477ec681f3Smrg .lower_unpack_snorm_2x16 = true, 1487ec681f3Smrg .lower_unpack_snorm_4x8 = true, 1497ec681f3Smrg .lower_unpack_unorm_2x16 = true, 1507ec681f3Smrg .lower_unpack_unorm_4x8 = true, 1517ec681f3Smrg .lower_unpack_half_2x16 = true, 1527ec681f3Smrg .lower_extract_byte = true, 1537ec681f3Smrg .lower_extract_word = true, 1547ec681f3Smrg .lower_rotate = true, 1557ec681f3Smrg .lower_uadd_carry = true, 1567ec681f3Smrg .lower_usub_borrow = true, 1577ec681f3Smrg .lower_mul_2x32_64 = true, 1587ec681f3Smrg .lower_ifind_msb = true, 1597ec681f3Smrg .max_unroll_iterations = 32, 1607ec681f3Smrg .use_interpolated_input_intrinsics = true, 1617ec681f3Smrg .lower_cs_local_index_from_id = true, 1627ec681f3Smrg .lower_uniforms_to_ubo = true, 1637ec681f3Smrg .lower_vector_cmp = true, 1647ec681f3Smrg .lower_device_index_to_zero = true, 1657ec681f3Smrg /* .support_16bit_alu = true, */ 1667ec681f3Smrg}; 1677ec681f3Smrg 1687ec681f3Smrgstatic const void * 1697ec681f3Smrgi915_get_compiler_options(struct pipe_screen *pscreen, enum pipe_shader_ir ir, 1707ec681f3Smrg enum pipe_shader_type shader) 1717ec681f3Smrg{ 1727ec681f3Smrg assert(ir == PIPE_SHADER_IR_NIR); 1737ec681f3Smrg if (shader == PIPE_SHADER_FRAGMENT) 1747ec681f3Smrg return &i915_compiler_options; 1757ec681f3Smrg else 1767ec681f3Smrg return &gallivm_nir_options; 1777ec681f3Smrg} 1787ec681f3Smrg 1797ec681f3Smrgstatic void 1807ec681f3Smrgi915_optimize_nir(struct nir_shader *s) 1817ec681f3Smrg{ 1827ec681f3Smrg bool progress; 1837ec681f3Smrg 1847ec681f3Smrg do { 1857ec681f3Smrg progress = false; 1867ec681f3Smrg 1877ec681f3Smrg NIR_PASS_V(s, nir_lower_vars_to_ssa); 1887ec681f3Smrg 1897ec681f3Smrg NIR_PASS(progress, s, nir_copy_prop); 1907ec681f3Smrg NIR_PASS(progress, s, nir_opt_algebraic); 1917ec681f3Smrg NIR_PASS(progress, s, nir_opt_constant_folding); 1927ec681f3Smrg NIR_PASS(progress, s, nir_opt_remove_phis); 1937ec681f3Smrg NIR_PASS(progress, s, nir_opt_conditional_discard); 1947ec681f3Smrg NIR_PASS(progress, s, nir_opt_dce); 1957ec681f3Smrg NIR_PASS(progress, s, nir_opt_dead_cf); 1967ec681f3Smrg NIR_PASS(progress, s, nir_opt_cse); 1977ec681f3Smrg NIR_PASS(progress, s, nir_opt_find_array_copies); 1987ec681f3Smrg NIR_PASS(progress, s, nir_opt_if, true); 1997ec681f3Smrg NIR_PASS(progress, s, nir_opt_peephole_select, ~0 /* flatten all IFs. */, 2007ec681f3Smrg true, true); 2017ec681f3Smrg NIR_PASS(progress, s, nir_opt_algebraic); 2027ec681f3Smrg NIR_PASS(progress, s, nir_opt_constant_folding); 2037ec681f3Smrg NIR_PASS(progress, s, nir_opt_shrink_vectors, true); 2047ec681f3Smrg NIR_PASS(progress, s, nir_opt_trivial_continues); 2057ec681f3Smrg NIR_PASS(progress, s, nir_opt_undef); 2067ec681f3Smrg NIR_PASS(progress, s, nir_opt_loop_unroll); 2077ec681f3Smrg 2087ec681f3Smrg } while (progress); 2097ec681f3Smrg 2107ec681f3Smrg NIR_PASS(progress, s, nir_remove_dead_variables, nir_var_function_temp, 2117ec681f3Smrg NULL); 2127ec681f3Smrg} 2137ec681f3Smrg 2147ec681f3Smrgstatic char *i915_check_control_flow(nir_shader *s) 2157ec681f3Smrg{ 2167ec681f3Smrg if (s->info.stage == MESA_SHADER_FRAGMENT) { 2177ec681f3Smrg nir_function_impl *impl = nir_shader_get_entrypoint(s); 2187ec681f3Smrg nir_block *first = nir_start_block(impl); 2197ec681f3Smrg nir_cf_node *next = nir_cf_node_next(&first->cf_node); 2207ec681f3Smrg 2217ec681f3Smrg if (next) { 2227ec681f3Smrg switch (next->type) { 2237ec681f3Smrg case nir_cf_node_if: 2247ec681f3Smrg return "if/then statements not supported by i915 fragment shaders, should have been flattened by peephole_select."; 2257ec681f3Smrg case nir_cf_node_loop: 2267ec681f3Smrg return "looping not supported i915 fragment shaders, all loops must be statically unrollable."; 2277ec681f3Smrg default: 2287ec681f3Smrg return "Unknown control flow type"; 2297ec681f3Smrg } 2307ec681f3Smrg } 2317ec681f3Smrg } 2327ec681f3Smrg 2337ec681f3Smrg return NULL; 2347ec681f3Smrg} 2357ec681f3Smrg 2367ec681f3Smrgstatic char * 2377ec681f3Smrgi915_finalize_nir(struct pipe_screen *pscreen, void *nir) 2387ec681f3Smrg{ 2397ec681f3Smrg nir_shader *s = nir; 2407ec681f3Smrg 2417ec681f3Smrg if (s->info.stage == MESA_SHADER_FRAGMENT) 2427ec681f3Smrg i915_optimize_nir(s); 2437ec681f3Smrg 2447ec681f3Smrg /* st_program.c's parameter list optimization requires that future nir 2457ec681f3Smrg * variants don't reallocate the uniform storage, so we have to remove 2467ec681f3Smrg * uniforms that occupy storage. But we don't want to remove samplers, 2477ec681f3Smrg * because they're needed for YUV variant lowering. 2487ec681f3Smrg */ 2497ec681f3Smrg nir_remove_dead_derefs(s); 2507ec681f3Smrg nir_foreach_uniform_variable_safe(var, s) 2517ec681f3Smrg { 2527ec681f3Smrg if (var->data.mode == nir_var_uniform && 2537ec681f3Smrg (glsl_type_get_image_count(var->type) || 2547ec681f3Smrg glsl_type_get_sampler_count(var->type))) 2557ec681f3Smrg continue; 2567ec681f3Smrg 2577ec681f3Smrg exec_node_remove(&var->node); 2587ec681f3Smrg } 2597ec681f3Smrg nir_validate_shader(s, "after uniform var removal"); 2607ec681f3Smrg 2617ec681f3Smrg nir_sweep(s); 2627ec681f3Smrg 2637ec681f3Smrg char *msg = i915_check_control_flow(s); 2647ec681f3Smrg if (msg) 2657ec681f3Smrg return strdup(msg); 2667ec681f3Smrg 2677ec681f3Smrg return NULL; 2687ec681f3Smrg} 2697ec681f3Smrg 270af69d88dSmrgstatic int 2717ec681f3Smrgi915_get_shader_param(struct pipe_screen *screen, enum pipe_shader_type shader, 27201e04c3fSmrg enum pipe_shader_cap cap) 273af69d88dSmrg{ 2747ec681f3Smrg switch (cap) { 2757ec681f3Smrg case PIPE_SHADER_CAP_PREFERRED_IR: 2767ec681f3Smrg return PIPE_SHADER_IR_NIR; 2777ec681f3Smrg case PIPE_SHADER_CAP_SUPPORTED_IRS: 2787ec681f3Smrg return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_TGSI); 2797ec681f3Smrg 2807ec681f3Smrg case PIPE_SHADER_CAP_INTEGERS: 2817ec681f3Smrg /* mesa/st requires that this cap is the same across stages, and the FS 2827ec681f3Smrg * can't do ints. 2837ec681f3Smrg */ 2847ec681f3Smrg return 0; 2857ec681f3Smrg 2867ec681f3Smrg /* i915 can't do these, and even if gallivm NIR can we call nir_to_tgsi 2877ec681f3Smrg * manually and TGSI can't. 2887ec681f3Smrg */ 2897ec681f3Smrg case PIPE_SHADER_CAP_INT16: 2907ec681f3Smrg case PIPE_SHADER_CAP_FP16: 2917ec681f3Smrg case PIPE_SHADER_CAP_FP16_DERIVATIVES: 2927ec681f3Smrg case PIPE_SHADER_CAP_FP16_CONST_BUFFERS: 2937ec681f3Smrg return 0; 2947ec681f3Smrg 2957ec681f3Smrg case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 2967ec681f3Smrg /* While draw could normally handle this for the VS, the NIR lowering 2977ec681f3Smrg * to regs can't handle our non-native-integers, so we have to lower to 2987ec681f3Smrg * if ladders. 2997ec681f3Smrg */ 3007ec681f3Smrg return 0; 3017ec681f3Smrg 3027ec681f3Smrg default: 3037ec681f3Smrg break; 3047ec681f3Smrg } 3057ec681f3Smrg 3067ec681f3Smrg switch (shader) { 307af69d88dSmrg case PIPE_SHADER_VERTEX: 308af69d88dSmrg switch (cap) { 309af69d88dSmrg case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 310af69d88dSmrg case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: 3117ec681f3Smrg return 0; 3127ec681f3Smrg case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS: 3137ec681f3Smrg case PIPE_SHADER_CAP_MAX_SHADER_IMAGES: 3147ec681f3Smrg return 0; 3157ec681f3Smrg default: 316af69d88dSmrg return draw_get_shader_param(shader, cap); 317af69d88dSmrg } 318af69d88dSmrg case PIPE_SHADER_FRAGMENT: 319af69d88dSmrg /* XXX: some of these are just shader model 2.0 values, fix this! */ 3207ec681f3Smrg switch (cap) { 321af69d88dSmrg case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 322af69d88dSmrg return I915_MAX_ALU_INSN + I915_MAX_TEX_INSN; 323af69d88dSmrg case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 324af69d88dSmrg return I915_MAX_ALU_INSN; 325af69d88dSmrg case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 326af69d88dSmrg return I915_MAX_TEX_INSN; 327af69d88dSmrg case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 3287ec681f3Smrg return 4; 329af69d88dSmrg case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 330af69d88dSmrg return 0; 331af69d88dSmrg case PIPE_SHADER_CAP_MAX_INPUTS: 332af69d88dSmrg return 10; 33301e04c3fSmrg case PIPE_SHADER_CAP_MAX_OUTPUTS: 33401e04c3fSmrg return 1; 335af69d88dSmrg case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE: 336af69d88dSmrg return 32 * sizeof(float[4]); 337af69d88dSmrg case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 338af69d88dSmrg return 1; 339af69d88dSmrg case PIPE_SHADER_CAP_MAX_TEMPS: 3407ec681f3Smrg /* 16 inter-phase temps, 3 intra-phase temps. i915c reported 16. too. */ 3417ec681f3Smrg return 16; 342af69d88dSmrg case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 343af69d88dSmrg case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: 344af69d88dSmrg return 0; 345af69d88dSmrg case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 346af69d88dSmrg case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 347af69d88dSmrg case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 348af69d88dSmrg case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 349af69d88dSmrg case PIPE_SHADER_CAP_SUBROUTINES: 350af69d88dSmrg return 0; 35101e04c3fSmrg case PIPE_SHADER_CAP_INT64_ATOMICS: 3527ec681f3Smrg case PIPE_SHADER_CAP_INT16: 3537ec681f3Smrg case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS: 354af69d88dSmrg return 0; 355af69d88dSmrg case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 356af69d88dSmrg case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: 357af69d88dSmrg return I915_TEX_UNITS; 35801e04c3fSmrg case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED: 35901e04c3fSmrg case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED: 36001e04c3fSmrg case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED: 36101e04c3fSmrg case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED: 36201e04c3fSmrg case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE: 36301e04c3fSmrg case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS: 36401e04c3fSmrg case PIPE_SHADER_CAP_MAX_SHADER_IMAGES: 36501e04c3fSmrg case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD: 36601e04c3fSmrg case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS: 3677ec681f3Smrg case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS: 3687ec681f3Smrg case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS: 36901e04c3fSmrg return 0; 3707ec681f3Smrg 37101e04c3fSmrg case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT: 37201e04c3fSmrg return 32; 373af69d88dSmrg default: 374af69d88dSmrg debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap); 375af69d88dSmrg return 0; 376af69d88dSmrg } 377af69d88dSmrg break; 378af69d88dSmrg default: 379af69d88dSmrg return 0; 380af69d88dSmrg } 381af69d88dSmrg} 382af69d88dSmrg 3834a49301eSmrgstatic int 3843464ebd5Sriastradhi915_get_param(struct pipe_screen *screen, enum pipe_cap cap) 3854a49301eSmrg{ 3863464ebd5Sriastradh struct i915_screen *is = i915_screen(screen); 3873464ebd5Sriastradh 3883464ebd5Sriastradh switch (cap) { 3893464ebd5Sriastradh /* Supported features (boolean caps). */ 3903464ebd5Sriastradh case PIPE_CAP_ANISOTROPIC_FILTER: 3914a49301eSmrg case PIPE_CAP_NPOT_TEXTURES: 392af69d88dSmrg case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: 3933464ebd5Sriastradh case PIPE_CAP_POINT_SPRITE: 3943464ebd5Sriastradh case PIPE_CAP_PRIMITIVE_RESTART: /* draw module */ 3957ec681f3Smrg case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX: 396af69d88dSmrg case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 3973464ebd5Sriastradh case PIPE_CAP_BLEND_EQUATION_SEPARATE: 398af69d88dSmrg case PIPE_CAP_TGSI_INSTANCEID: 399af69d88dSmrg case PIPE_CAP_VERTEX_COLOR_CLAMPED: 400af69d88dSmrg case PIPE_CAP_USER_VERTEX_BUFFERS: 40101e04c3fSmrg case PIPE_CAP_MIXED_COLOR_DEPTH_BITS: 4027ec681f3Smrg case PIPE_CAP_TGSI_TEXCOORD: 403af69d88dSmrg return 1; 4043464ebd5Sriastradh 405af69d88dSmrg case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: 40601e04c3fSmrg case PIPE_CAP_PCI_GROUP: 40701e04c3fSmrg case PIPE_CAP_PCI_BUS: 40801e04c3fSmrg case PIPE_CAP_PCI_DEVICE: 40901e04c3fSmrg case PIPE_CAP_PCI_FUNCTION: 4104a49301eSmrg return 0; 4113464ebd5Sriastradh 41201e04c3fSmrg case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY: 41301e04c3fSmrg case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION: 4147ec681f3Smrg return 0; 4157ec681f3Smrg 4167ec681f3Smrg case PIPE_CAP_SHAREABLE_SHADERS: 4177ec681f3Smrg /* Can't expose shareable shaders because the draw shaders reference the 4187ec681f3Smrg * draw module's state, which is per-context. 4197ec681f3Smrg */ 420af69d88dSmrg return 0; 421af69d88dSmrg 42201e04c3fSmrg case PIPE_CAP_MAX_GS_INVOCATIONS: 42301e04c3fSmrg return 32; 42401e04c3fSmrg 42501e04c3fSmrg case PIPE_CAP_MAX_SHADER_BUFFER_SIZE: 42601e04c3fSmrg return 1 << 27; 42701e04c3fSmrg 428af69d88dSmrg case PIPE_CAP_MAX_VIEWPORTS: 429af69d88dSmrg return 1; 430af69d88dSmrg 431af69d88dSmrg case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: 432af69d88dSmrg return 64; 433af69d88dSmrg 434af69d88dSmrg case PIPE_CAP_GLSL_FEATURE_LEVEL: 43501e04c3fSmrg case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY: 436af69d88dSmrg return 120; 437af69d88dSmrg 438af69d88dSmrg case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: 439af69d88dSmrg return 16; 440af69d88dSmrg 4413464ebd5Sriastradh /* Features we can lie about (boolean caps). */ 4424a49301eSmrg case PIPE_CAP_OCCLUSION_QUERY: 4433464ebd5Sriastradh return is->debug.lie ? 1 : 0; 4443464ebd5Sriastradh 4453464ebd5Sriastradh /* Texturing. */ 4467ec681f3Smrg case PIPE_CAP_MAX_TEXTURE_2D_SIZE: 4477ec681f3Smrg return 1 << (I915_MAX_TEXTURE_2D_LEVELS - 1); 4484a49301eSmrg case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 4493464ebd5Sriastradh return I915_MAX_TEXTURE_3D_LEVELS; 4504a49301eSmrg case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 4517ec681f3Smrg return 1 << (I915_MAX_TEXTURE_2D_LEVELS - 1); 4523464ebd5Sriastradh 4533464ebd5Sriastradh /* Render targets. */ 4543464ebd5Sriastradh case PIPE_CAP_MAX_RENDER_TARGETS: 4553464ebd5Sriastradh return 1; 4563464ebd5Sriastradh 45701e04c3fSmrg case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE: 45801e04c3fSmrg return 2048; 45901e04c3fSmrg 4603464ebd5Sriastradh /* Fragment coordinate conventions. */ 461cdc920a0Smrg case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 462cdc920a0Smrg case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 463cdc920a0Smrg return 1; 464af69d88dSmrg case PIPE_CAP_ENDIANNESS: 465af69d88dSmrg return PIPE_ENDIAN_LITTLE; 4669f464c52Smaya case PIPE_CAP_MAX_VARYINGS: 4679f464c52Smaya return 10; 468af69d88dSmrg 4697ec681f3Smrg case PIPE_CAP_NIR_IMAGES_AS_DEREF: 4707ec681f3Smrg return 0; 4717ec681f3Smrg 472af69d88dSmrg case PIPE_CAP_VENDOR_ID: 473af69d88dSmrg return 0x8086; 474af69d88dSmrg case PIPE_CAP_DEVICE_ID: 475af69d88dSmrg return is->iws->pci_id; 476af69d88dSmrg case PIPE_CAP_ACCELERATED: 477af69d88dSmrg return 1; 478af69d88dSmrg case PIPE_CAP_VIDEO_MEMORY: { 479af69d88dSmrg /* Once a batch uses more than 75% of the maximum mappable size, we 480af69d88dSmrg * assume that there's some fragmentation, and we start doing extra 481af69d88dSmrg * flushing, etc. That's the big cliff apps will care about. 482af69d88dSmrg */ 4837ec681f3Smrg const int gpu_mappable_megabytes = 4847ec681f3Smrg is->iws->aperture_size(is->iws) * 3 / 4; 485af69d88dSmrg uint64_t system_memory; 486af69d88dSmrg 487af69d88dSmrg if (!os_get_total_physical_memory(&system_memory)) 488af69d88dSmrg return 0; 4893464ebd5Sriastradh 490af69d88dSmrg return MIN2(gpu_mappable_megabytes, (int)(system_memory >> 20)); 4913464ebd5Sriastradh } 492af69d88dSmrg case PIPE_CAP_UMA: 493af69d88dSmrg return 1; 4943464ebd5Sriastradh 49501e04c3fSmrg default: 49601e04c3fSmrg return u_pipe_screen_get_param_defaults(screen, cap); 4974a49301eSmrg } 4984a49301eSmrg} 4994a49301eSmrg 5004a49301eSmrgstatic float 501af69d88dSmrgi915_get_paramf(struct pipe_screen *screen, enum pipe_capf cap) 5024a49301eSmrg{ 5037ec681f3Smrg switch (cap) { 504af69d88dSmrg case PIPE_CAPF_MAX_LINE_WIDTH: 5057ec681f3Smrg FALLTHROUGH; 506af69d88dSmrg case PIPE_CAPF_MAX_LINE_WIDTH_AA: 5074a49301eSmrg return 7.5; 5084a49301eSmrg 509af69d88dSmrg case PIPE_CAPF_MAX_POINT_WIDTH: 5107ec681f3Smrg FALLTHROUGH; 511af69d88dSmrg case PIPE_CAPF_MAX_POINT_WIDTH_AA: 5124a49301eSmrg return 255.0; 5134a49301eSmrg 514af69d88dSmrg case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 5154a49301eSmrg return 4.0; 5164a49301eSmrg 517af69d88dSmrg case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 5184a49301eSmrg return 16.0; 5194a49301eSmrg 52001e04c3fSmrg case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE: 5217ec681f3Smrg FALLTHROUGH; 52201e04c3fSmrg case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE: 5237ec681f3Smrg FALLTHROUGH; 52401e04c3fSmrg case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY: 52501e04c3fSmrg return 0.0f; 52601e04c3fSmrg 5274a49301eSmrg default: 5283464ebd5Sriastradh debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap); 5294a49301eSmrg return 0; 5304a49301eSmrg } 5314a49301eSmrg} 5324a49301eSmrg 5337ec681f3Smrgbool 5347ec681f3Smrgi915_is_format_supported(struct pipe_screen *screen, enum pipe_format format, 5357ec681f3Smrg enum pipe_texture_target target, unsigned sample_count, 5367ec681f3Smrg unsigned storage_sample_count, unsigned tex_usage) 5374a49301eSmrg{ 5384a49301eSmrg static const enum pipe_format tex_supported[] = { 5397ec681f3Smrg PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_B8G8R8A8_SRGB, 5407ec681f3Smrg PIPE_FORMAT_B8G8R8X8_UNORM, PIPE_FORMAT_R8G8B8A8_UNORM, 5417ec681f3Smrg PIPE_FORMAT_R8G8B8X8_UNORM, PIPE_FORMAT_B4G4R4A4_UNORM, 5427ec681f3Smrg PIPE_FORMAT_B5G6R5_UNORM, PIPE_FORMAT_B5G5R5A1_UNORM, 5437ec681f3Smrg PIPE_FORMAT_B10G10R10A2_UNORM, PIPE_FORMAT_L8_UNORM, PIPE_FORMAT_A8_UNORM, 5447ec681f3Smrg PIPE_FORMAT_I8_UNORM, PIPE_FORMAT_L8A8_UNORM, PIPE_FORMAT_UYVY, 545cdc920a0Smrg PIPE_FORMAT_YUYV, 5463464ebd5Sriastradh /* XXX why not? 5473464ebd5Sriastradh PIPE_FORMAT_Z16_UNORM, */ 5487ec681f3Smrg PIPE_FORMAT_DXT1_RGB, PIPE_FORMAT_DXT1_SRGB, PIPE_FORMAT_DXT1_RGBA, 5497ec681f3Smrg PIPE_FORMAT_DXT1_SRGBA, PIPE_FORMAT_DXT3_RGBA, PIPE_FORMAT_DXT3_SRGBA, 5507ec681f3Smrg PIPE_FORMAT_DXT5_RGBA, PIPE_FORMAT_DXT5_SRGBA, PIPE_FORMAT_Z24X8_UNORM, 5517ec681f3Smrg PIPE_FORMAT_FXT1_RGB, PIPE_FORMAT_FXT1_RGBA, 5527ec681f3Smrg PIPE_FORMAT_Z24_UNORM_S8_UINT, PIPE_FORMAT_NONE /* list terminator */ 5534a49301eSmrg }; 5543464ebd5Sriastradh static const enum pipe_format render_supported[] = { 5557ec681f3Smrg PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_B8G8R8X8_UNORM, 5567ec681f3Smrg PIPE_FORMAT_R8G8B8A8_UNORM, PIPE_FORMAT_R8G8B8X8_UNORM, 5577ec681f3Smrg PIPE_FORMAT_B5G6R5_UNORM, PIPE_FORMAT_B5G5R5A1_UNORM, 5587ec681f3Smrg PIPE_FORMAT_B4G4R4A4_UNORM, PIPE_FORMAT_B10G10R10A2_UNORM, 5597ec681f3Smrg PIPE_FORMAT_L8_UNORM, PIPE_FORMAT_A8_UNORM, 5607ec681f3Smrg PIPE_FORMAT_I8_UNORM, PIPE_FORMAT_NONE /* list terminator */ 5613464ebd5Sriastradh }; 5623464ebd5Sriastradh static const enum pipe_format depth_supported[] = { 5633464ebd5Sriastradh /* XXX why not? 5643464ebd5Sriastradh PIPE_FORMAT_Z16_UNORM, */ 5657ec681f3Smrg PIPE_FORMAT_Z24X8_UNORM, PIPE_FORMAT_Z24_UNORM_S8_UINT, 5667ec681f3Smrg PIPE_FORMAT_NONE /* list terminator */ 5674a49301eSmrg }; 5684a49301eSmrg const enum pipe_format *list; 5697ec681f3Smrg uint32_t i; 5704a49301eSmrg 5713464ebd5Sriastradh if (sample_count > 1) 5727ec681f3Smrg return false; 5733464ebd5Sriastradh 57401e04c3fSmrg if (MAX2(1, sample_count) != MAX2(1, storage_sample_count)) 57501e04c3fSmrg return false; 57601e04c3fSmrg 5777ec681f3Smrg if (tex_usage & PIPE_BIND_DEPTH_STENCIL) 5783464ebd5Sriastradh list = depth_supported; 5793464ebd5Sriastradh else if (tex_usage & PIPE_BIND_RENDER_TARGET) 5803464ebd5Sriastradh list = render_supported; 581af69d88dSmrg else if (tex_usage & PIPE_BIND_SAMPLER_VIEW) 5824a49301eSmrg list = tex_supported; 583af69d88dSmrg else 5847ec681f3Smrg return true; /* PIPE_BIND_{VERTEX,INDEX}_BUFFER */ 5854a49301eSmrg 5864a49301eSmrg for (i = 0; list[i] != PIPE_FORMAT_NONE; i++) { 5874a49301eSmrg if (list[i] == format) 5887ec681f3Smrg return true; 5894a49301eSmrg } 5904a49301eSmrg 5917ec681f3Smrg return false; 5924a49301eSmrg} 5934a49301eSmrg 5944a49301eSmrg/* 5954a49301eSmrg * Fence functions 5964a49301eSmrg */ 5974a49301eSmrg 5984a49301eSmrgstatic void 5997ec681f3Smrgi915_fence_reference(struct pipe_screen *screen, struct pipe_fence_handle **ptr, 6004a49301eSmrg struct pipe_fence_handle *fence) 6014a49301eSmrg{ 6024a49301eSmrg struct i915_screen *is = i915_screen(screen); 6034a49301eSmrg 6044a49301eSmrg is->iws->fence_reference(is->iws, ptr, fence); 6054a49301eSmrg} 6064a49301eSmrg 6077ec681f3Smrgstatic bool 6087ec681f3Smrgi915_fence_finish(struct pipe_screen *screen, struct pipe_context *ctx, 6097ec681f3Smrg struct pipe_fence_handle *fence, uint64_t timeout) 6104a49301eSmrg{ 6114a49301eSmrg struct i915_screen *is = i915_screen(screen); 6124a49301eSmrg 61301e04c3fSmrg if (!timeout) 61401e04c3fSmrg return is->iws->fence_signalled(is->iws, fence) == 1; 61501e04c3fSmrg 616af69d88dSmrg return is->iws->fence_finish(is->iws, fence) == 1; 6174a49301eSmrg} 6184a49301eSmrg 6194a49301eSmrg/* 6204a49301eSmrg * Generic functions 6214a49301eSmrg */ 6224a49301eSmrg 6233464ebd5Sriastradhstatic void 6247ec681f3Smrgi915_flush_frontbuffer(struct pipe_screen *screen, struct pipe_context *pipe, 6257ec681f3Smrg struct pipe_resource *resource, unsigned level, 6267ec681f3Smrg unsigned layer, void *winsys_drawable_handle, 627af69d88dSmrg struct pipe_box *sub_box) 6283464ebd5Sriastradh{ 6293464ebd5Sriastradh /* XXX: Dummy right now. */ 6303464ebd5Sriastradh (void)screen; 6317ec681f3Smrg (void)pipe; 6323464ebd5Sriastradh (void)resource; 6333464ebd5Sriastradh (void)level; 6343464ebd5Sriastradh (void)layer; 6353464ebd5Sriastradh (void)winsys_drawable_handle; 636af69d88dSmrg (void)sub_box; 6373464ebd5Sriastradh} 6383464ebd5Sriastradh 6394a49301eSmrgstatic void 6404a49301eSmrgi915_destroy_screen(struct pipe_screen *screen) 6414a49301eSmrg{ 6424a49301eSmrg struct i915_screen *is = i915_screen(screen); 6434a49301eSmrg 6444a49301eSmrg if (is->iws) 6454a49301eSmrg is->iws->destroy(is->iws); 6464a49301eSmrg 6474a49301eSmrg FREE(is); 6484a49301eSmrg} 6494a49301eSmrg 6504a49301eSmrg/** 6514a49301eSmrg * Create a new i915_screen object 6524a49301eSmrg */ 6534a49301eSmrgstruct pipe_screen * 6543464ebd5Sriastradhi915_screen_create(struct i915_winsys *iws) 6554a49301eSmrg{ 6564a49301eSmrg struct i915_screen *is = CALLOC_STRUCT(i915_screen); 6574a49301eSmrg 6584a49301eSmrg if (!is) 6594a49301eSmrg return NULL; 6604a49301eSmrg 6613464ebd5Sriastradh switch (iws->pci_id) { 6624a49301eSmrg case PCI_CHIP_I915_G: 6634a49301eSmrg case PCI_CHIP_I915_GM: 6647ec681f3Smrg is->is_i945 = false; 6654a49301eSmrg break; 6664a49301eSmrg 6674a49301eSmrg case PCI_CHIP_I945_G: 6684a49301eSmrg case PCI_CHIP_I945_GM: 6694a49301eSmrg case PCI_CHIP_I945_GME: 6704a49301eSmrg case PCI_CHIP_G33_G: 6714a49301eSmrg case PCI_CHIP_Q33_G: 6724a49301eSmrg case PCI_CHIP_Q35_G: 6733464ebd5Sriastradh case PCI_CHIP_PINEVIEW_G: 6743464ebd5Sriastradh case PCI_CHIP_PINEVIEW_M: 6757ec681f3Smrg is->is_i945 = true; 6764a49301eSmrg break; 6774a49301eSmrg 6784a49301eSmrg default: 6797ec681f3Smrg debug_printf("%s: unknown pci id 0x%x, cannot create screen\n", 6803464ebd5Sriastradh __FUNCTION__, iws->pci_id); 6814a49301eSmrg FREE(is); 6824a49301eSmrg return NULL; 6834a49301eSmrg } 6844a49301eSmrg 6854a49301eSmrg is->iws = iws; 6864a49301eSmrg 6874a49301eSmrg is->base.destroy = i915_destroy_screen; 6883464ebd5Sriastradh is->base.flush_frontbuffer = i915_flush_frontbuffer; 6894a49301eSmrg 6904a49301eSmrg is->base.get_name = i915_get_name; 6914a49301eSmrg is->base.get_vendor = i915_get_vendor; 69201e04c3fSmrg is->base.get_device_vendor = i915_get_device_vendor; 6934a49301eSmrg is->base.get_param = i915_get_param; 6943464ebd5Sriastradh is->base.get_shader_param = i915_get_shader_param; 6954a49301eSmrg is->base.get_paramf = i915_get_paramf; 6967ec681f3Smrg is->base.get_compiler_options = i915_get_compiler_options; 6977ec681f3Smrg is->base.finalize_nir = i915_finalize_nir; 6984a49301eSmrg is->base.is_format_supported = i915_is_format_supported; 6994a49301eSmrg 700cdc920a0Smrg is->base.context_create = i915_create_context; 701cdc920a0Smrg 7024a49301eSmrg is->base.fence_reference = i915_fence_reference; 7034a49301eSmrg is->base.fence_finish = i915_fence_finish; 7044a49301eSmrg 7053464ebd5Sriastradh i915_init_screen_resource_functions(is); 7063464ebd5Sriastradh 7073464ebd5Sriastradh i915_debug_init(is); 7083464ebd5Sriastradh 7094a49301eSmrg return &is->base; 7104a49301eSmrg} 711