brw_context.c revision fbf86c7f0f1f12e52b927e3870535073879d0a4d
1/* 2 Copyright (C) Intel Corp. 2006. All Rights Reserved. 3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to 4 develop this 3D driver. 5 6 Permission is hereby granted, free of charge, to any person obtaining 7 a copy of this software and associated documentation files (the 8 "Software"), to deal in the Software without restriction, including 9 without limitation the rights to use, copy, modify, merge, publish, 10 distribute, sublicense, and/or sell copies of the Software, and to 11 permit persons to whom the Software is furnished to do so, subject to 12 the following conditions: 13 14 The above copyright notice and this permission notice (including the 15 next paragraph) shall be included in all copies or substantial 16 portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 26 **********************************************************************/ 27 /* 28 * Authors: 29 * Keith Whitwell <keith@tungstengraphics.com> 30 */ 31 32 33#include "main/imports.h" 34#include "main/macros.h" 35#include "main/simple_list.h" 36 37#include "vbo/vbo_context.h" 38 39#include "brw_context.h" 40#include "brw_defines.h" 41#include "brw_draw.h" 42#include "brw_state.h" 43 44#include "intel_fbo.h" 45#include "intel_mipmap_tree.h" 46#include "intel_regions.h" 47#include "intel_span.h" 48#include "intel_tex.h" 49#include "intel_tex_obj.h" 50 51#include "tnl/t_pipeline.h" 52#include "glsl/ralloc.h" 53 54/*************************************** 55 * Mesa's Driver Functions 56 ***************************************/ 57 58static void brwInitDriverFunctions(struct intel_screen *screen, 59 struct dd_function_table *functions) 60{ 61 intelInitDriverFunctions( functions ); 62 63 brwInitFragProgFuncs( functions ); 64 brw_init_queryobj_functions(functions); 65 66 functions->BeginTransformFeedback = brw_begin_transform_feedback; 67 68 if (screen->gen >= 7) 69 functions->EndTransformFeedback = gen7_end_transform_feedback; 70 else 71 functions->EndTransformFeedback = brw_end_transform_feedback; 72} 73 74bool 75brwCreateContext(int api, 76 const struct gl_config *mesaVis, 77 __DRIcontext *driContextPriv, 78 void *sharedContextPrivate) 79{ 80 __DRIscreen *sPriv = driContextPriv->driScreenPriv; 81 struct intel_screen *screen = sPriv->driverPrivate; 82 struct dd_function_table functions; 83 struct brw_context *brw = rzalloc(NULL, struct brw_context); 84 struct intel_context *intel = &brw->intel; 85 struct gl_context *ctx = &intel->ctx; 86 unsigned i; 87 88 if (!brw) { 89 printf("%s: failed to alloc context\n", __FUNCTION__); 90 return false; 91 } 92 93 brwInitDriverFunctions(screen, &functions); 94 95 if (!intelInitContext( intel, api, mesaVis, driContextPriv, 96 sharedContextPrivate, &functions )) { 97 printf("%s: failed to init intel context\n", __FUNCTION__); 98 FREE(brw); 99 return false; 100 } 101 102 brwInitVtbl( brw ); 103 104 brw_init_surface_formats(brw); 105 106 /* Initialize swrast, tnl driver tables: */ 107 intelInitSpanFuncs(ctx); 108 109 TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline; 110 111 ctx->Const.MaxDualSourceDrawBuffers = 1; 112 ctx->Const.MaxDrawBuffers = BRW_MAX_DRAW_BUFFERS; 113 ctx->Const.MaxTextureImageUnits = BRW_MAX_TEX_UNIT; 114 ctx->Const.MaxTextureCoordUnits = 8; /* Mesa limit */ 115 ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits, 116 ctx->Const.MaxTextureImageUnits); 117 ctx->Const.MaxVertexTextureImageUnits = BRW_MAX_TEX_UNIT; 118 ctx->Const.MaxCombinedTextureImageUnits = 119 ctx->Const.MaxVertexTextureImageUnits + 120 ctx->Const.MaxTextureImageUnits; 121 122 ctx->Const.MaxTextureLevels = 14; /* 8192 */ 123 if (ctx->Const.MaxTextureLevels > MAX_TEXTURE_LEVELS) 124 ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS; 125 ctx->Const.Max3DTextureLevels = 9; 126 ctx->Const.MaxCubeTextureLevels = 12; 127 128 if (intel->gen >= 7) 129 ctx->Const.MaxArrayTextureLayers = 2048; 130 else 131 ctx->Const.MaxArrayTextureLayers = 512; 132 133 ctx->Const.MaxTextureRectSize = (1<<12); 134 135 ctx->Const.MaxTextureMaxAnisotropy = 16.0; 136 137 /* Hardware only supports a limited number of transform feedback buffers. 138 * So we need to override the Mesa default (which is based only on software 139 * limits). 140 */ 141 ctx->Const.MaxTransformFeedbackBuffers = BRW_MAX_SOL_BUFFERS; 142 143 /* On Gen6, in the worst case, we use up one binding table entry per 144 * transform feedback component (see comments above the definition of 145 * BRW_MAX_SOL_BINDINGS, in brw_context.h), so we need to advertise a value 146 * for MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS equal to 147 * BRW_MAX_SOL_BINDINGS. 148 * 149 * In "separate components" mode, we need to divide this value by 150 * BRW_MAX_SOL_BUFFERS, so that the total number of binding table entries 151 * used up by all buffers will not exceed BRW_MAX_SOL_BINDINGS. 152 */ 153 ctx->Const.MaxTransformFeedbackInterleavedComponents = BRW_MAX_SOL_BINDINGS; 154 ctx->Const.MaxTransformFeedbackSeparateComponents = 155 BRW_MAX_SOL_BINDINGS / BRW_MAX_SOL_BUFFERS; 156 157 if (intel->gen == 6) 158 ctx->Const.MaxSamples = 4; 159 else if (intel->gen >= 7) 160 ctx->Const.MaxSamples = 8; 161 162 /* if conformance mode is set, swrast can handle any size AA point */ 163 ctx->Const.MaxPointSizeAA = 255.0; 164 165 /* We want the GLSL compiler to emit code that uses condition codes */ 166 for (i = 0; i <= MESA_SHADER_FRAGMENT; i++) { 167 ctx->ShaderCompilerOptions[i].MaxIfDepth = intel->gen < 6 ? 16 : UINT_MAX; 168 ctx->ShaderCompilerOptions[i].EmitCondCodes = true; 169 ctx->ShaderCompilerOptions[i].EmitNVTempInitialization = true; 170 ctx->ShaderCompilerOptions[i].EmitNoNoise = true; 171 ctx->ShaderCompilerOptions[i].EmitNoMainReturn = true; 172 ctx->ShaderCompilerOptions[i].EmitNoIndirectInput = true; 173 ctx->ShaderCompilerOptions[i].EmitNoIndirectOutput = true; 174 175 ctx->ShaderCompilerOptions[i].EmitNoIndirectUniform = 176 (i == MESA_SHADER_FRAGMENT); 177 ctx->ShaderCompilerOptions[i].EmitNoIndirectTemp = 178 (i == MESA_SHADER_FRAGMENT); 179 ctx->ShaderCompilerOptions[i].LowerClipDistance = true; 180 } 181 182 ctx->Const.VertexProgram.MaxNativeInstructions = (16 * 1024); 183 ctx->Const.VertexProgram.MaxAluInstructions = 0; 184 ctx->Const.VertexProgram.MaxTexInstructions = 0; 185 ctx->Const.VertexProgram.MaxTexIndirections = 0; 186 ctx->Const.VertexProgram.MaxNativeAluInstructions = 0; 187 ctx->Const.VertexProgram.MaxNativeTexInstructions = 0; 188 ctx->Const.VertexProgram.MaxNativeTexIndirections = 0; 189 ctx->Const.VertexProgram.MaxNativeAttribs = 16; 190 ctx->Const.VertexProgram.MaxNativeTemps = 256; 191 ctx->Const.VertexProgram.MaxNativeAddressRegs = 1; 192 ctx->Const.VertexProgram.MaxNativeParameters = 1024; 193 ctx->Const.VertexProgram.MaxEnvParams = 194 MIN2(ctx->Const.VertexProgram.MaxNativeParameters, 195 ctx->Const.VertexProgram.MaxEnvParams); 196 197 ctx->Const.FragmentProgram.MaxNativeInstructions = (16 * 1024); 198 ctx->Const.FragmentProgram.MaxNativeAluInstructions = (16 * 1024); 199 ctx->Const.FragmentProgram.MaxNativeTexInstructions = (16 * 1024); 200 ctx->Const.FragmentProgram.MaxNativeTexIndirections = (16 * 1024); 201 ctx->Const.FragmentProgram.MaxNativeAttribs = 12; 202 ctx->Const.FragmentProgram.MaxNativeTemps = 256; 203 ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; 204 ctx->Const.FragmentProgram.MaxNativeParameters = 1024; 205 ctx->Const.FragmentProgram.MaxEnvParams = 206 MIN2(ctx->Const.FragmentProgram.MaxNativeParameters, 207 ctx->Const.FragmentProgram.MaxEnvParams); 208 209 /* Fragment shaders use real, 32-bit twos-complement integers for all 210 * integer types. 211 */ 212 ctx->Const.FragmentProgram.LowInt.RangeMin = 31; 213 ctx->Const.FragmentProgram.LowInt.RangeMax = 30; 214 ctx->Const.FragmentProgram.LowInt.Precision = 0; 215 ctx->Const.FragmentProgram.HighInt = ctx->Const.FragmentProgram.MediumInt 216 = ctx->Const.FragmentProgram.LowInt; 217 218 /* Gen6 converts quads to polygon in beginning of 3D pipeline, 219 but we're not sure how it's actually done for vertex order, 220 that affect provoking vertex decision. Always use last vertex 221 convention for quad primitive which works as expected for now. */ 222 if (intel->gen >= 6) 223 ctx->Const.QuadsFollowProvokingVertexConvention = false; 224 225 if (intel->is_g4x || intel->gen >= 5) { 226 brw->CMD_VF_STATISTICS = GM45_3DSTATE_VF_STATISTICS; 227 brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_GM45; 228 brw->has_surface_tile_offset = true; 229 if (intel->gen < 6) 230 brw->has_compr4 = true; 231 brw->has_aa_line_parameters = true; 232 brw->has_pln = true; 233 } else { 234 brw->CMD_VF_STATISTICS = GEN4_3DSTATE_VF_STATISTICS; 235 brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_965; 236 } 237 238 /* WM maximum threads is number of EUs times number of threads per EU. */ 239 if (intel->gen >= 7) { 240 if (intel->gt == 1) { 241 brw->max_wm_threads = 48; 242 brw->max_vs_threads = 36; 243 brw->max_gs_threads = 36; 244 brw->urb.size = 128; 245 brw->urb.max_vs_entries = 512; 246 brw->urb.max_gs_entries = 192; 247 } else if (intel->gt == 2) { 248 brw->max_wm_threads = 172; 249 brw->max_vs_threads = 128; 250 brw->max_gs_threads = 128; 251 brw->urb.size = 256; 252 brw->urb.max_vs_entries = 704; 253 brw->urb.max_gs_entries = 320; 254 } else { 255 assert(!"Unknown gen7 device."); 256 } 257 } else if (intel->gen == 6) { 258 if (intel->gt == 2) { 259 brw->max_wm_threads = 80; 260 brw->max_vs_threads = 60; 261 brw->max_gs_threads = 60; 262 brw->urb.size = 64; /* volume 5c.5 section 5.1 */ 263 brw->urb.max_vs_entries = 256; /* volume 2a (see 3DSTATE_URB) */ 264 brw->urb.max_gs_entries = 256; 265 } else { 266 brw->max_wm_threads = 40; 267 brw->max_vs_threads = 24; 268 brw->max_gs_threads = 21; /* conservative; 24 if rendering disabled */ 269 brw->urb.size = 32; /* volume 5c.5 section 5.1 */ 270 brw->urb.max_vs_entries = 256; /* volume 2a (see 3DSTATE_URB) */ 271 brw->urb.max_gs_entries = 256; 272 } 273 brw->urb.gen6_gs_previously_active = false; 274 } else if (intel->gen == 5) { 275 brw->urb.size = 1024; 276 brw->max_vs_threads = 72; 277 brw->max_gs_threads = 32; 278 brw->max_wm_threads = 12 * 6; 279 } else if (intel->is_g4x) { 280 brw->urb.size = 384; 281 brw->max_vs_threads = 32; 282 brw->max_gs_threads = 2; 283 brw->max_wm_threads = 10 * 5; 284 } else if (intel->gen < 6) { 285 brw->urb.size = 256; 286 brw->max_vs_threads = 16; 287 brw->max_gs_threads = 2; 288 brw->max_wm_threads = 8 * 4; 289 brw->has_negative_rhw_bug = true; 290 } 291 292 if (intel->gen <= 7) { 293 brw->needs_unlit_centroid_workaround = true; 294 } 295 296 brw->prim_restart.in_progress = false; 297 brw->prim_restart.enable_cut_index = false; 298 intel->hw_ctx = drm_intel_gem_context_create(intel->bufmgr); 299 300 brw_init_state( brw ); 301 302 brw->curbe.last_buf = calloc(1, 4096); 303 brw->curbe.next_buf = calloc(1, 4096); 304 305 brw->state.dirty.mesa = ~0; 306 brw->state.dirty.brw = ~0; 307 308 brw->emit_state_always = 0; 309 310 intel->batch.need_workaround_flush = true; 311 312 ctx->VertexProgram._MaintainTnlProgram = true; 313 ctx->FragmentProgram._MaintainTexEnvProgram = true; 314 315 brw_draw_init( brw ); 316 317 brw->precompile = driQueryOptionb(&intel->optionCache, "shader_precompile"); 318 319 ctx->Const.NativeIntegers = true; 320 ctx->Const.UniformBooleanTrue = 1; 321 322 ctx->Const.ForceGLSLExtensionsWarn = driQueryOptionb(&intel->optionCache, "force_glsl_extensions_warn"); 323 324 return true; 325} 326 327