static struct st_context * st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe ) { uint i; struct st_context *st = CALLOC_STRUCT( st_context ); ctx->st = st; st->ctx = ctx; st->pipe = pipe; /* state tracker needs the VBO module */ _vbo_CreateContext(ctx); #if FEATURE_feedback || FEATURE_drawpix st->draw = draw_create(); /* for selection/feedback */ /* Disable draw options that might convert points/lines to tris, etc. * as that would foul-up feedback/selection mode. */ draw_wide_line_threshold(st->draw, 1000.0f); draw_wide_point_threshold(st->draw, 1000.0f); draw_enable_line_stipple(st->draw, FALSE); draw_enable_point_sprites(st->draw, FALSE); #endif st->dirty.mesa = ~0; st->dirty.st = ~0; st->cso_context = cso_create_context(pipe); st_init_atoms( st ); st_init_bitmap(st); st_init_clear(st); st_init_draw( st ); st_init_generate_mipmap(st); st_init_blit(st); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) st->state.sampler_list[i] = &st->state.samplers[i]; /* we want all vertex data to be placed in buffer objects */ vbo_use_buffer_objects(ctx); /* Need these flags: */ st->ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; st->ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE; st->ctx->VertexProgram._MaintainTnlProgram = GL_TRUE; st->pixel_xfer.cache = _mesa_new_program_cache(); /* GL limits and extensions */ st_init_limits(st); st_init_extensions(st); return st; }
static struct st_context * st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe, const struct st_config_options *options) { struct pipe_screen *screen = pipe->screen; uint i; struct st_context *st = ST_CALLOC_STRUCT( st_context ); st->options = *options; ctx->st = st; st->ctx = ctx; st->pipe = pipe; /* XXX: this is one-off, per-screen init: */ st_debug_init(); /* state tracker needs the VBO module */ _vbo_CreateContext(ctx); st->dirty.mesa = ~0; st->dirty.st = ~0; /* Create upload manager for vertex data for glBitmap, glDrawPixels, * glClear, etc. */ st->uploader = u_upload_create(st->pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER); if (!screen->get_param(screen, PIPE_CAP_USER_INDEX_BUFFERS)) { st->indexbuf_uploader = u_upload_create(st->pipe, 128 * 1024, 4, PIPE_BIND_INDEX_BUFFER); } if (!screen->get_param(screen, PIPE_CAP_USER_CONSTANT_BUFFERS)) { unsigned alignment = screen->get_param(screen, PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT); st->constbuf_uploader = u_upload_create(pipe, 128 * 1024, alignment, PIPE_BIND_CONSTANT_BUFFER); } st->cso_context = cso_create_context(pipe); st_init_atoms( st ); st_init_bitmap(st); st_init_clear(st); st_init_draw( st ); st_init_generate_mipmap(st); /* Choose texture target for glDrawPixels, glBitmap, renderbuffers */ if (pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES)) st->internal_target = PIPE_TEXTURE_2D; else st->internal_target = PIPE_TEXTURE_RECT; /* Vertex element objects used for drawing rectangles for glBitmap, * glDrawPixels, glClear, etc. */ for (i = 0; i < Elements(st->velems_util_draw); i++) { memset(&st->velems_util_draw[i], 0, sizeof(struct pipe_vertex_element)); st->velems_util_draw[i].src_offset = i * 4 * sizeof(float); st->velems_util_draw[i].instance_divisor = 0; st->velems_util_draw[i].vertex_buffer_index = cso_get_aux_vertex_buffer_slot(st->cso_context); st->velems_util_draw[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; } /* we want all vertex data to be placed in buffer objects */ vbo_use_buffer_objects(ctx); /* make sure that no VBOs are left mapped when we're drawing. */ vbo_always_unmap_buffers(ctx); /* Need these flags: */ st->ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; st->ctx->VertexProgram._MaintainTnlProgram = GL_TRUE; st->pixel_xfer.cache = _mesa_new_program_cache(); st->has_stencil_export = screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT); st->has_shader_model3 = screen->get_param(screen, PIPE_CAP_SM3); st->prefer_blit_based_texture_transfer = screen->get_param(screen, PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER); st->needs_texcoord_semantic = screen->get_param(screen, PIPE_CAP_TGSI_TEXCOORD); st->apply_texture_swizzle_to_border_color = !!(screen->get_param(screen, PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK) & (PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 | PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600)); /* GL limits and extensions */ st_init_limits(st); st_init_extensions(st); _mesa_compute_version(ctx); _mesa_initialize_dispatch_tables(ctx); _mesa_initialize_vbo_vtxfmt(ctx); return st; }
static struct st_context * st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe, const struct st_config_options *options) { struct pipe_screen *screen = pipe->screen; uint i; struct st_context *st = ST_CALLOC_STRUCT( st_context ); st->options = *options; ctx->st = st; st->ctx = ctx; st->pipe = pipe; /* XXX: this is one-off, per-screen init: */ st_debug_init(); /* state tracker needs the VBO module */ _vbo_CreateContext(ctx); st->dirty.mesa = ~0; st->dirty.st = ~0; /* Create upload manager for vertex data for glBitmap, glDrawPixels, * glClear, etc. */ st->uploader = u_upload_create(st->pipe, 65536, PIPE_BIND_VERTEX_BUFFER, PIPE_USAGE_STREAM); if (!screen->get_param(screen, PIPE_CAP_USER_INDEX_BUFFERS)) { st->indexbuf_uploader = u_upload_create(st->pipe, 128 * 1024, PIPE_BIND_INDEX_BUFFER, PIPE_USAGE_STREAM); } if (!screen->get_param(screen, PIPE_CAP_USER_CONSTANT_BUFFERS)) st->constbuf_uploader = u_upload_create(pipe, 128 * 1024, PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_STREAM); st->cso_context = cso_create_context(pipe); st_init_atoms( st ); st_init_bitmap(st); st_init_clear(st); st_init_draw( st ); /* Choose texture target for glDrawPixels, glBitmap, renderbuffers */ if (pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES)) st->internal_target = PIPE_TEXTURE_2D; else st->internal_target = PIPE_TEXTURE_RECT; /* Vertex element objects used for drawing rectangles for glBitmap, * glDrawPixels, glClear, etc. */ for (i = 0; i < ARRAY_SIZE(st->velems_util_draw); i++) { memset(&st->velems_util_draw[i], 0, sizeof(struct pipe_vertex_element)); st->velems_util_draw[i].src_offset = i * 4 * sizeof(float); st->velems_util_draw[i].instance_divisor = 0; st->velems_util_draw[i].vertex_buffer_index = cso_get_aux_vertex_buffer_slot(st->cso_context); st->velems_util_draw[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; } /* we want all vertex data to be placed in buffer objects */ vbo_use_buffer_objects(ctx); /* make sure that no VBOs are left mapped when we're drawing. */ vbo_always_unmap_buffers(ctx); /* Need these flags: */ st->ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; st->ctx->VertexProgram._MaintainTnlProgram = GL_TRUE; st->has_stencil_export = screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT); st->has_shader_model3 = screen->get_param(screen, PIPE_CAP_SM3); st->has_etc1 = screen->is_format_supported(screen, PIPE_FORMAT_ETC1_RGB8, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW); st->has_etc2 = screen->is_format_supported(screen, PIPE_FORMAT_ETC2_RGB8, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW); st->prefer_blit_based_texture_transfer = screen->get_param(screen, PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER); st->force_persample_in_shader = screen->get_param(screen, PIPE_CAP_SAMPLE_SHADING) && !screen->get_param(screen, PIPE_CAP_FORCE_PERSAMPLE_INTERP); st->has_shareable_shaders = screen->get_param(screen, PIPE_CAP_SHAREABLE_SHADERS); st->needs_texcoord_semantic = screen->get_param(screen, PIPE_CAP_TGSI_TEXCOORD); st->apply_texture_swizzle_to_border_color = !!(screen->get_param(screen, PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK) & (PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 | PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600)); st->has_time_elapsed = screen->get_param(screen, PIPE_CAP_QUERY_TIME_ELAPSED); st->has_half_float_packing = screen->get_param(screen, PIPE_CAP_TGSI_PACK_HALF_FLOAT); st->has_multi_draw_indirect = screen->get_param(screen, PIPE_CAP_MULTI_DRAW_INDIRECT); /* GL limits and extensions */ st_init_limits(st->pipe->screen, &ctx->Const, &ctx->Extensions); st_init_extensions(st->pipe->screen, &ctx->Const, &ctx->Extensions, &st->options, ctx->Mesa_DXTn); if (st_have_perfmon(st)) { ctx->Extensions.AMD_performance_monitor = GL_TRUE; } /* Enable shader-based fallbacks for ARB_color_buffer_float if needed. */ if (screen->get_param(screen, PIPE_CAP_VERTEX_COLOR_UNCLAMPED)) { if (!screen->get_param(screen, PIPE_CAP_VERTEX_COLOR_CLAMPED)) { st->clamp_vert_color_in_shader = GL_TRUE; } if (!screen->get_param(screen, PIPE_CAP_FRAGMENT_COLOR_CLAMPED)) { st->clamp_frag_color_in_shader = GL_TRUE; } /* For drivers which cannot do color clamping, it's better to just * disable ARB_color_buffer_float in the core profile, because * the clamping is deprecated there anyway. */ if (ctx->API == API_OPENGL_CORE && (st->clamp_frag_color_in_shader || st->clamp_vert_color_in_shader)) { st->clamp_vert_color_in_shader = GL_FALSE; st->clamp_frag_color_in_shader = GL_FALSE; ctx->Extensions.ARB_color_buffer_float = GL_FALSE; } } /* called after _mesa_create_context/_mesa_init_point, fix default user * settable max point size up */ st->ctx->Point.MaxSize = MAX2(ctx->Const.MaxPointSize, ctx->Const.MaxPointSizeAA); /* For vertex shaders, make sure not to emit saturate when SM 3.0 is not supported */ ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].EmitNoSat = !st->has_shader_model3; if (!ctx->Extensions.ARB_gpu_shader5) { for (i = 0; i < MESA_SHADER_STAGES; i++) ctx->Const.ShaderCompilerOptions[i].EmitNoIndirectSampler = true; } /* Set which shader types can be compiled at link time. */ st->shader_has_one_variant[MESA_SHADER_VERTEX] = st->has_shareable_shaders && !st->clamp_vert_color_in_shader; st->shader_has_one_variant[MESA_SHADER_FRAGMENT] = st->has_shareable_shaders && !st->clamp_frag_color_in_shader && !st->force_persample_in_shader; st->shader_has_one_variant[MESA_SHADER_TESS_CTRL] = st->has_shareable_shaders; st->shader_has_one_variant[MESA_SHADER_TESS_EVAL] = st->has_shareable_shaders; st->shader_has_one_variant[MESA_SHADER_GEOMETRY] = st->has_shareable_shaders; _mesa_compute_version(ctx); if (ctx->Version == 0) { /* This can happen when a core profile was requested, but the driver * does not support some features of GL 3.1 or later. */ st_destroy_context_priv(st); return NULL; } _mesa_initialize_dispatch_tables(ctx); _mesa_initialize_vbo_vtxfmt(ctx); return st; }
GLboolean brwCreateContext(gl_api api, const struct gl_config *mesaVis, __DRIcontext *driContextPriv, unsigned major_version, unsigned minor_version, uint32_t flags, bool notify_reset, unsigned *dri_ctx_error, void *sharedContextPrivate) { __DRIscreen *sPriv = driContextPriv->driScreenPriv; struct gl_context *shareCtx = (struct gl_context *) sharedContextPrivate; struct intel_screen *screen = sPriv->driverPrivate; const struct brw_device_info *devinfo = screen->devinfo; struct dd_function_table functions; /* Only allow the __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS flag if the kernel * provides us with context reset notifications. */ uint32_t allowed_flags = __DRI_CTX_FLAG_DEBUG | __DRI_CTX_FLAG_FORWARD_COMPATIBLE; if (screen->has_context_reset_notification) allowed_flags |= __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS; if (flags & ~allowed_flags) { *dri_ctx_error = __DRI_CTX_ERROR_UNKNOWN_FLAG; return false; } struct brw_context *brw = rzalloc(NULL, struct brw_context); if (!brw) { fprintf(stderr, "%s: failed to alloc context\n", __FUNCTION__); *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY; return false; } driContextPriv->driverPrivate = brw; brw->driContext = driContextPriv; brw->intelScreen = screen; brw->bufmgr = screen->bufmgr; brw->gen = devinfo->gen; brw->gt = devinfo->gt; brw->is_g4x = devinfo->is_g4x; brw->is_baytrail = devinfo->is_baytrail; brw->is_haswell = devinfo->is_haswell; brw->has_llc = devinfo->has_llc; brw->has_hiz = devinfo->has_hiz_and_separate_stencil; brw->has_separate_stencil = devinfo->has_hiz_and_separate_stencil; brw->has_pln = devinfo->has_pln; brw->has_compr4 = devinfo->has_compr4; brw->has_surface_tile_offset = devinfo->has_surface_tile_offset; brw->has_negative_rhw_bug = devinfo->has_negative_rhw_bug; brw->needs_unlit_centroid_workaround = devinfo->needs_unlit_centroid_workaround; brw->must_use_separate_stencil = screen->hw_must_use_separate_stencil; brw->has_swizzling = screen->hw_has_swizzling; brw->vs.base.stage = MESA_SHADER_VERTEX; brw->gs.base.stage = MESA_SHADER_GEOMETRY; brw->wm.base.stage = MESA_SHADER_FRAGMENT; if (brw->gen >= 8) { gen8_init_vtable_surface_functions(brw); gen7_init_vtable_sampler_functions(brw); brw->vtbl.emit_depth_stencil_hiz = gen8_emit_depth_stencil_hiz; } else if (brw->gen >= 7) { gen7_init_vtable_surface_functions(brw); gen7_init_vtable_sampler_functions(brw); brw->vtbl.emit_depth_stencil_hiz = gen7_emit_depth_stencil_hiz; } else { gen4_init_vtable_surface_functions(brw); gen4_init_vtable_sampler_functions(brw); brw->vtbl.emit_depth_stencil_hiz = brw_emit_depth_stencil_hiz; } brw_init_driver_functions(brw, &functions); if (notify_reset) functions.GetGraphicsResetStatus = brw_get_graphics_reset_status; struct gl_context *ctx = &brw->ctx; if (!_mesa_initialize_context(ctx, api, mesaVis, shareCtx, &functions)) { *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY; fprintf(stderr, "%s: failed to init mesa context\n", __FUNCTION__); intelDestroyContext(driContextPriv); return false; } driContextSetFlags(ctx, flags); /* Initialize the software rasterizer and helper modules. * * As of GL 3.1 core, the gen4+ driver doesn't need the swrast context for * software fallbacks (which we have to support on legacy GL to do weird * glDrawPixels(), glBitmap(), and other functions). */ if (api != API_OPENGL_CORE && api != API_OPENGLES2) { _swrast_CreateContext(ctx); } _vbo_CreateContext(ctx); if (ctx->swrast_context) { _tnl_CreateContext(ctx); TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline; _swsetup_CreateContext(ctx); /* Configure swrast to match hardware characteristics: */ _swrast_allow_pixel_fog(ctx, false); _swrast_allow_vertex_fog(ctx, true); } _mesa_meta_init(ctx); brw_process_driconf_options(brw); brw_process_intel_debug_variable(brw); brw_initialize_context_constants(brw); ctx->Const.ResetStrategy = notify_reset ? GL_LOSE_CONTEXT_ON_RESET_ARB : GL_NO_RESET_NOTIFICATION_ARB; /* Reinitialize the context point state. It depends on ctx->Const values. */ _mesa_init_point(ctx); intel_fbo_init(brw); intel_batchbuffer_init(brw); if (brw->gen >= 6) { /* Create a new hardware context. Using a hardware context means that * our GPU state will be saved/restored on context switch, allowing us * to assume that the GPU is in the same state we left it in. * * This is required for transform feedback buffer offsets, query objects, * and also allows us to reduce how much state we have to emit. */ brw->hw_ctx = drm_intel_gem_context_create(brw->bufmgr); if (!brw->hw_ctx) { fprintf(stderr, "Gen6+ requires Kernel 3.6 or later.\n"); intelDestroyContext(driContextPriv); return false; } } brw_init_state(brw); intelInitExtensions(ctx); brw_init_surface_formats(brw); brw->max_vs_threads = devinfo->max_vs_threads; brw->max_gs_threads = devinfo->max_gs_threads; brw->max_wm_threads = devinfo->max_wm_threads; brw->urb.size = devinfo->urb.size; brw->urb.min_vs_entries = devinfo->urb.min_vs_entries; brw->urb.max_vs_entries = devinfo->urb.max_vs_entries; brw->urb.max_gs_entries = devinfo->urb.max_gs_entries; /* Estimate the size of the mappable aperture into the GTT. There's an * ioctl to get the whole GTT size, but not one to get the mappable subset. * It turns out it's basically always 256MB, though some ancient hardware * was smaller. */ uint32_t gtt_size = 256 * 1024 * 1024; /* We don't want to map two objects such that a memcpy between them would * just fault one mapping in and then the other over and over forever. So * we would need to divide the GTT size by 2. Additionally, some GTT is * taken up by things like the framebuffer and the ringbuffer and such, so * be more conservative. */ brw->max_gtt_map_object_size = gtt_size / 4; if (brw->gen == 6) brw->urb.gen6_gs_previously_active = false; brw->prim_restart.in_progress = false; brw->prim_restart.enable_cut_index = false; brw->gs.enabled = false; if (brw->gen < 6) { brw->curbe.last_buf = calloc(1, 4096); brw->curbe.next_buf = calloc(1, 4096); } ctx->VertexProgram._MaintainTnlProgram = true; ctx->FragmentProgram._MaintainTexEnvProgram = true; brw_draw_init( brw ); if ((flags & __DRI_CTX_FLAG_DEBUG) != 0) { /* Turn on some extra GL_ARB_debug_output generation. */ brw->perf_debug = true; } if ((flags & __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS) != 0) ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB; if (INTEL_DEBUG & DEBUG_SHADER_TIME) brw_init_shader_time(brw); _mesa_compute_version(ctx); _mesa_initialize_dispatch_tables(ctx); _mesa_initialize_vbo_vtxfmt(ctx); if (ctx->Extensions.AMD_performance_monitor) { brw_init_performance_monitors(brw); } vbo_use_buffer_objects(ctx); vbo_always_unmap_buffers(ctx); return true; }
static struct st_context * st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe ) { uint i; struct st_context *st = ST_CALLOC_STRUCT( st_context ); ctx->st = st; st->ctx = ctx; st->pipe = pipe; /* XXX: this is one-off, per-screen init: */ st_debug_init(); /* state tracker needs the VBO module */ _vbo_CreateContext(ctx); st->dirty.mesa = ~0; st->dirty.st = ~0; st->cso_context = cso_create_context(pipe); st_init_atoms( st ); st_init_bitmap(st); st_init_clear(st); st_init_draw( st ); st_init_generate_mipmap(st); st_init_blit(st); if(pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES)) st->internal_target = PIPE_TEXTURE_2D; else st->internal_target = PIPE_TEXTURE_RECT; for (i = 0; i < PIPE_MAX_SAMPLERS; i++) st->state.sampler_list[i] = &st->state.samplers[i]; for (i = 0; i < 3; i++) { memset(&st->velems_util_draw[i], 0, sizeof(struct pipe_vertex_element)); st->velems_util_draw[i].src_offset = i * 4 * sizeof(float); st->velems_util_draw[i].instance_divisor = 0; st->velems_util_draw[i].vertex_buffer_index = 0; st->velems_util_draw[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; } /* we want all vertex data to be placed in buffer objects */ vbo_use_buffer_objects(ctx); /* Need these flags: */ st->ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; st->ctx->VertexProgram._MaintainTnlProgram = GL_TRUE; st->pixel_xfer.cache = _mesa_new_program_cache(); st->force_msaa = st_get_msaa(); /* GL limits and extensions */ st_init_limits(st); st_init_extensions(st); return st; }