brw_context.c revision 642247883fb9e6dce9bad724f7f6503321e0ef6f
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 "gen6_hiz.h" 45 46#include "intel_fbo.h" 47#include "intel_mipmap_tree.h" 48#include "intel_regions.h" 49#include "intel_span.h" 50#include "intel_tex.h" 51#include "intel_tex_obj.h" 52 53#include "tnl/t_pipeline.h" 54#include "glsl/ralloc.h" 55 56/*************************************** 57 * Mesa's Driver Functions 58 ***************************************/ 59 60/** 61 * \brief Prepare for entry into glBegin/glEnd block. 62 * 63 * Resolve buffers before entering a glBegin/glEnd block. This is 64 * necessary to prevent recursive calls to FLUSH_VERTICES. 65 * 66 * This resolves the depth buffer of each enabled depth texture and the HiZ 67 * buffer of the attached depth renderbuffer. 68 * 69 * Details 70 * ------- 71 * When vertices are queued during a glBegin/glEnd block, those vertices must 72 * be drawn before any rendering state changes. To ensure this, Mesa calls 73 * FLUSH_VERTICES as a prehook to such state changes. Therefore, 74 * FLUSH_VERTICES itself cannot change rendering state without falling into a 75 * recursive trap. 76 * 77 * This precludes meta-ops, namely buffer resolves, from occurring while any 78 * vertices are queued. To prevent that situation, we resolve some buffers on 79 * entering a glBegin/glEnd 80 * 81 * \see brwCleanupExecEnd() 82 */ 83static void brwPrepareExecBegin(struct gl_context *ctx) 84{ 85 struct brw_context *brw = brw_context(ctx); 86 struct intel_context *intel = &brw->intel; 87 struct intel_renderbuffer *draw_irb; 88 struct intel_texture_object *tex_obj; 89 90 if (!intel->has_hiz) { 91 /* The context uses no feature that requires buffer resolves. */ 92 return; 93 } 94 95 /* Resolve each enabled texture. */ 96 for (int i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { 97 if (!ctx->Texture.Unit[i]._ReallyEnabled) 98 continue; 99 tex_obj = intel_texture_object(ctx->Texture.Unit[i]._Current); 100 if (!tex_obj || !tex_obj->mt) 101 continue; 102 intel_miptree_all_slices_resolve_depth(intel, tex_obj->mt); 103 } 104 105 /* Resolve the attached depth buffer. */ 106 draw_irb = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_DEPTH); 107 if (draw_irb) { 108 intel_renderbuffer_resolve_hiz(intel, draw_irb); 109 } 110} 111 112static void brwInitDriverFunctions(struct intel_screen *screen, 113 struct dd_function_table *functions) 114{ 115 intelInitDriverFunctions( functions ); 116 117 brwInitFragProgFuncs( functions ); 118 brw_init_queryobj_functions(functions); 119 120 functions->PrepareExecBegin = brwPrepareExecBegin; 121 functions->BeginTransformFeedback = brw_begin_transform_feedback; 122 123 if (screen->gen >= 7) 124 functions->EndTransformFeedback = gen7_end_transform_feedback; 125 else 126 functions->EndTransformFeedback = brw_end_transform_feedback; 127} 128 129bool 130brwCreateContext(int api, 131 const struct gl_config *mesaVis, 132 __DRIcontext *driContextPriv, 133 void *sharedContextPrivate) 134{ 135 __DRIscreen *sPriv = driContextPriv->driScreenPriv; 136 struct intel_screen *screen = sPriv->driverPrivate; 137 struct dd_function_table functions; 138 struct brw_context *brw = rzalloc(NULL, struct brw_context); 139 struct intel_context *intel = &brw->intel; 140 struct gl_context *ctx = &intel->ctx; 141 unsigned i; 142 143 if (!brw) { 144 printf("%s: failed to alloc context\n", __FUNCTION__); 145 return false; 146 } 147 148 brwInitDriverFunctions(screen, &functions); 149 150 if (!intelInitContext( intel, api, mesaVis, driContextPriv, 151 sharedContextPrivate, &functions )) { 152 printf("%s: failed to init intel context\n", __FUNCTION__); 153 FREE(brw); 154 return false; 155 } 156 157 brwInitVtbl( brw ); 158 159 brw_init_surface_formats(brw); 160 161 /* Initialize swrast, tnl driver tables: */ 162 intelInitSpanFuncs(ctx); 163 164 TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline; 165 166 ctx->Const.MaxDrawBuffers = BRW_MAX_DRAW_BUFFERS; 167 ctx->Const.MaxTextureImageUnits = BRW_MAX_TEX_UNIT; 168 ctx->Const.MaxTextureCoordUnits = 8; /* Mesa limit */ 169 ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits, 170 ctx->Const.MaxTextureImageUnits); 171 ctx->Const.MaxVertexTextureImageUnits = BRW_MAX_TEX_UNIT; 172 ctx->Const.MaxCombinedTextureImageUnits = 173 ctx->Const.MaxVertexTextureImageUnits + 174 ctx->Const.MaxTextureImageUnits; 175 176 ctx->Const.MaxTextureLevels = 14; /* 8192 */ 177 if (ctx->Const.MaxTextureLevels > MAX_TEXTURE_LEVELS) 178 ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS; 179 ctx->Const.Max3DTextureLevels = 9; 180 ctx->Const.MaxCubeTextureLevels = 12; 181 182 if (intel->gen >= 7) 183 ctx->Const.MaxArrayTextureLayers = 2048; 184 else 185 ctx->Const.MaxArrayTextureLayers = 512; 186 187 ctx->Const.MaxTextureRectSize = (1<<12); 188 189 ctx->Const.MaxTextureMaxAnisotropy = 16.0; 190 191 /* Hardware only supports a limited number of transform feedback buffers. 192 * So we need to override the Mesa default (which is based only on software 193 * limits). 194 */ 195 ctx->Const.MaxTransformFeedbackSeparateAttribs = BRW_MAX_SOL_BUFFERS; 196 197 /* On Gen6, in the worst case, we use up one binding table entry per 198 * transform feedback component (see comments above the definition of 199 * BRW_MAX_SOL_BINDINGS, in brw_context.h), so we need to advertise a value 200 * for MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS equal to 201 * BRW_MAX_SOL_BINDINGS. 202 * 203 * In "separate components" mode, we need to divide this value by 204 * BRW_MAX_SOL_BUFFERS, so that the total number of binding table entries 205 * used up by all buffers will not exceed BRW_MAX_SOL_BINDINGS. 206 */ 207 ctx->Const.MaxTransformFeedbackInterleavedComponents = BRW_MAX_SOL_BINDINGS; 208 ctx->Const.MaxTransformFeedbackSeparateComponents = 209 BRW_MAX_SOL_BINDINGS / BRW_MAX_SOL_BUFFERS; 210 211 /* Claim to support 4 multisamples, even though we don't. This is a 212 * requirement for GL 3.0 that we missed until the last minute. Go ahead and 213 * claim the limit, so that usage of the 4 multisample-based API that is 214 * guaranteed in 3.0 succeeds, even though we only rasterize a single sample. 215 */ 216 if (intel->gen >= 6) 217 ctx->Const.MaxSamples = 4; 218 219 /* if conformance mode is set, swrast can handle any size AA point */ 220 ctx->Const.MaxPointSizeAA = 255.0; 221 222 /* We want the GLSL compiler to emit code that uses condition codes */ 223 for (i = 0; i <= MESA_SHADER_FRAGMENT; i++) { 224 ctx->ShaderCompilerOptions[i].MaxIfDepth = intel->gen < 6 ? 16 : UINT_MAX; 225 ctx->ShaderCompilerOptions[i].EmitCondCodes = true; 226 ctx->ShaderCompilerOptions[i].EmitNVTempInitialization = true; 227 ctx->ShaderCompilerOptions[i].EmitNoNoise = true; 228 ctx->ShaderCompilerOptions[i].EmitNoMainReturn = true; 229 ctx->ShaderCompilerOptions[i].EmitNoIndirectInput = true; 230 ctx->ShaderCompilerOptions[i].EmitNoIndirectOutput = true; 231 232 ctx->ShaderCompilerOptions[i].EmitNoIndirectUniform = 233 (i == MESA_SHADER_FRAGMENT); 234 ctx->ShaderCompilerOptions[i].EmitNoIndirectTemp = 235 (i == MESA_SHADER_FRAGMENT); 236 ctx->ShaderCompilerOptions[i].LowerClipDistance = true; 237 } 238 239 ctx->Const.VertexProgram.MaxNativeInstructions = (16 * 1024); 240 ctx->Const.VertexProgram.MaxAluInstructions = 0; 241 ctx->Const.VertexProgram.MaxTexInstructions = 0; 242 ctx->Const.VertexProgram.MaxTexIndirections = 0; 243 ctx->Const.VertexProgram.MaxNativeAluInstructions = 0; 244 ctx->Const.VertexProgram.MaxNativeTexInstructions = 0; 245 ctx->Const.VertexProgram.MaxNativeTexIndirections = 0; 246 ctx->Const.VertexProgram.MaxNativeAttribs = 16; 247 ctx->Const.VertexProgram.MaxNativeTemps = 256; 248 ctx->Const.VertexProgram.MaxNativeAddressRegs = 1; 249 ctx->Const.VertexProgram.MaxNativeParameters = 1024; 250 ctx->Const.VertexProgram.MaxEnvParams = 251 MIN2(ctx->Const.VertexProgram.MaxNativeParameters, 252 ctx->Const.VertexProgram.MaxEnvParams); 253 254 ctx->Const.FragmentProgram.MaxNativeInstructions = (16 * 1024); 255 ctx->Const.FragmentProgram.MaxNativeAluInstructions = (16 * 1024); 256 ctx->Const.FragmentProgram.MaxNativeTexInstructions = (16 * 1024); 257 ctx->Const.FragmentProgram.MaxNativeTexIndirections = (16 * 1024); 258 ctx->Const.FragmentProgram.MaxNativeAttribs = 12; 259 ctx->Const.FragmentProgram.MaxNativeTemps = 256; 260 ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; 261 ctx->Const.FragmentProgram.MaxNativeParameters = 1024; 262 ctx->Const.FragmentProgram.MaxEnvParams = 263 MIN2(ctx->Const.FragmentProgram.MaxNativeParameters, 264 ctx->Const.FragmentProgram.MaxEnvParams); 265 266 /* Fragment shaders use real, 32-bit twos-complement integers for all 267 * integer types. 268 */ 269 ctx->Const.FragmentProgram.LowInt.RangeMin = 31; 270 ctx->Const.FragmentProgram.LowInt.RangeMax = 30; 271 ctx->Const.FragmentProgram.LowInt.Precision = 0; 272 ctx->Const.FragmentProgram.HighInt = ctx->Const.FragmentProgram.MediumInt 273 = ctx->Const.FragmentProgram.LowInt; 274 275 /* Gen6 converts quads to polygon in beginning of 3D pipeline, 276 but we're not sure how it's actually done for vertex order, 277 that affect provoking vertex decision. Always use last vertex 278 convention for quad primitive which works as expected for now. */ 279 if (intel->gen >= 6) 280 ctx->Const.QuadsFollowProvokingVertexConvention = false; 281 282 if (intel->is_g4x || intel->gen >= 5) { 283 brw->CMD_VF_STATISTICS = GM45_3DSTATE_VF_STATISTICS; 284 brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_GM45; 285 brw->has_surface_tile_offset = true; 286 if (intel->gen < 6) 287 brw->has_compr4 = true; 288 brw->has_aa_line_parameters = true; 289 brw->has_pln = true; 290 } else { 291 brw->CMD_VF_STATISTICS = GEN4_3DSTATE_VF_STATISTICS; 292 brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_965; 293 } 294 295 /* WM maximum threads is number of EUs times number of threads per EU. */ 296 if (intel->gen >= 7) { 297 if (intel->gt == 1) { 298 brw->max_wm_threads = 86; 299 brw->max_vs_threads = 36; 300 brw->max_gs_threads = 36; 301 brw->urb.size = 128; 302 brw->urb.max_vs_entries = 512; 303 brw->urb.max_gs_entries = 192; 304 } else if (intel->gt == 2) { 305 brw->max_wm_threads = 86; 306 brw->max_vs_threads = 128; 307 brw->max_gs_threads = 128; 308 brw->urb.size = 256; 309 brw->urb.max_vs_entries = 704; 310 brw->urb.max_gs_entries = 320; 311 } else { 312 assert(!"Unknown gen7 device."); 313 } 314 } else if (intel->gen == 6) { 315 if (intel->gt == 2) { 316 /* This could possibly be 80, but is supposed to require 317 * disabling of WIZ hashing (bit 6 of GT_MODE, 0x20d0) and a 318 * GPU reset to change. 319 */ 320 brw->max_wm_threads = 40; 321 brw->max_vs_threads = 60; 322 brw->max_gs_threads = 60; 323 brw->urb.size = 64; /* volume 5c.5 section 5.1 */ 324 brw->urb.max_vs_entries = 256; /* volume 2a (see 3DSTATE_URB) */ 325 brw->urb.max_gs_entries = 256; 326 } else { 327 brw->max_wm_threads = 40; 328 brw->max_vs_threads = 24; 329 brw->max_gs_threads = 21; /* conservative; 24 if rendering disabled */ 330 brw->urb.size = 32; /* volume 5c.5 section 5.1 */ 331 brw->urb.max_vs_entries = 256; /* volume 2a (see 3DSTATE_URB) */ 332 brw->urb.max_gs_entries = 256; 333 } 334 brw->urb.gen6_gs_previously_active = false; 335 } else if (intel->gen == 5) { 336 brw->urb.size = 1024; 337 brw->max_vs_threads = 72; 338 brw->max_gs_threads = 32; 339 brw->max_wm_threads = 12 * 6; 340 } else if (intel->is_g4x) { 341 brw->urb.size = 384; 342 brw->max_vs_threads = 32; 343 brw->max_gs_threads = 2; 344 brw->max_wm_threads = 10 * 5; 345 } else if (intel->gen < 6) { 346 brw->urb.size = 256; 347 brw->max_vs_threads = 16; 348 brw->max_gs_threads = 2; 349 brw->max_wm_threads = 8 * 4; 350 brw->has_negative_rhw_bug = true; 351 } 352 353 brw_init_state( brw ); 354 355 brw->curbe.last_buf = calloc(1, 4096); 356 brw->curbe.next_buf = calloc(1, 4096); 357 358 brw->state.dirty.mesa = ~0; 359 brw->state.dirty.brw = ~0; 360 361 brw->emit_state_always = 0; 362 363 intel->batch.need_workaround_flush = true; 364 365 ctx->VertexProgram._MaintainTnlProgram = true; 366 ctx->FragmentProgram._MaintainTexEnvProgram = true; 367 368 brw_draw_init( brw ); 369 370 brw->precompile = driQueryOptionb(&intel->optionCache, "shader_precompile"); 371 372 ctx->Const.NativeIntegers = true; 373 ctx->Const.UniformBooleanTrue = 1; 374 375 ctx->Const.ForceGLSLExtensionsWarn = driQueryOptionb(&intel->optionCache, "force_glsl_extensions_warn"); 376 377 return true; 378} 379 380