1848b8605Smrg/************************************************************************** 2b8e80941Smrg * 3848b8605Smrg * Copyright 2007 VMware, Inc. 4848b8605Smrg * All Rights Reserved. 5b8e80941Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the 8848b8605Smrg * "Software"), to deal in the Software without restriction, including 9848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish, 10848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to 11848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to 12848b8605Smrg * the following conditions: 13b8e80941Smrg * 14848b8605Smrg * The above copyright notice and this permission notice (including the 15848b8605Smrg * next paragraph) shall be included in all copies or substantial portions 16848b8605Smrg * of the Software. 17b8e80941Smrg * 18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21848b8605Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25b8e80941Smrg * 26848b8605Smrg **************************************************************************/ 27848b8605Smrg 28848b8605Smrg#include "main/imports.h" 29848b8605Smrg#include "main/accum.h" 30848b8605Smrg#include "main/api_exec.h" 31848b8605Smrg#include "main/context.h" 32b8e80941Smrg#include "main/glthread.h" 33848b8605Smrg#include "main/samplerobj.h" 34848b8605Smrg#include "main/shaderobj.h" 35848b8605Smrg#include "main/version.h" 36848b8605Smrg#include "main/vtxfmt.h" 37848b8605Smrg#include "main/hash.h" 38848b8605Smrg#include "program/prog_cache.h" 39848b8605Smrg#include "vbo/vbo.h" 40848b8605Smrg#include "glapi/glapi.h" 41b8e80941Smrg#include "st_manager.h" 42848b8605Smrg#include "st_context.h" 43848b8605Smrg#include "st_debug.h" 44848b8605Smrg#include "st_cb_bitmap.h" 45848b8605Smrg#include "st_cb_blit.h" 46848b8605Smrg#include "st_cb_bufferobjects.h" 47848b8605Smrg#include "st_cb_clear.h" 48b8e80941Smrg#include "st_cb_compute.h" 49848b8605Smrg#include "st_cb_condrender.h" 50b8e80941Smrg#include "st_cb_copyimage.h" 51848b8605Smrg#include "st_cb_drawpixels.h" 52848b8605Smrg#include "st_cb_rasterpos.h" 53848b8605Smrg#include "st_cb_drawtex.h" 54848b8605Smrg#include "st_cb_eglimage.h" 55848b8605Smrg#include "st_cb_fbo.h" 56848b8605Smrg#include "st_cb_feedback.h" 57b8e80941Smrg#include "st_cb_memoryobjects.h" 58848b8605Smrg#include "st_cb_msaa.h" 59b8e80941Smrg#include "st_cb_perfmon.h" 60848b8605Smrg#include "st_cb_program.h" 61848b8605Smrg#include "st_cb_queryobj.h" 62848b8605Smrg#include "st_cb_readpixels.h" 63b8e80941Smrg#include "st_cb_semaphoreobjects.h" 64848b8605Smrg#include "st_cb_texture.h" 65848b8605Smrg#include "st_cb_xformfb.h" 66848b8605Smrg#include "st_cb_flush.h" 67848b8605Smrg#include "st_cb_syncobj.h" 68848b8605Smrg#include "st_cb_strings.h" 69848b8605Smrg#include "st_cb_texturebarrier.h" 70848b8605Smrg#include "st_cb_viewport.h" 71848b8605Smrg#include "st_atom.h" 72848b8605Smrg#include "st_draw.h" 73848b8605Smrg#include "st_extensions.h" 74848b8605Smrg#include "st_gen_mipmap.h" 75b8e80941Smrg#include "st_pbo.h" 76848b8605Smrg#include "st_program.h" 77b8e80941Smrg#include "st_sampler_view.h" 78b8e80941Smrg#include "st_shader_cache.h" 79848b8605Smrg#include "st_vdpau.h" 80848b8605Smrg#include "st_texture.h" 81b8e80941Smrg#include "st_util.h" 82848b8605Smrg#include "pipe/p_context.h" 83b8e80941Smrg#include "util/u_cpu_detect.h" 84848b8605Smrg#include "util/u_inlines.h" 85848b8605Smrg#include "util/u_upload_mgr.h" 86b8e80941Smrg#include "util/u_vbuf.h" 87848b8605Smrg#include "cso_cache/cso_context.h" 88b8e80941Smrg#include "compiler/glsl/glsl_parser_extras.h" 89848b8605Smrg 90848b8605Smrg 91848b8605SmrgDEBUG_GET_ONCE_BOOL_OPTION(mesa_mvp_dp4, "MESA_MVP_DP4", FALSE) 92848b8605Smrg 93848b8605Smrg 94b8e80941Smrg/** 95b8e80941Smrg * Called via ctx->Driver.Enable() 96b8e80941Smrg */ 97b8e80941Smrgstatic void 98b8e80941Smrgst_Enable(struct gl_context *ctx, GLenum cap, GLboolean state) 99b8e80941Smrg{ 100b8e80941Smrg struct st_context *st = st_context(ctx); 101b8e80941Smrg 102b8e80941Smrg switch (cap) { 103b8e80941Smrg case GL_DEBUG_OUTPUT: 104b8e80941Smrg case GL_DEBUG_OUTPUT_SYNCHRONOUS: 105b8e80941Smrg st_update_debug_callback(st); 106b8e80941Smrg break; 107b8e80941Smrg default: 108b8e80941Smrg break; 109b8e80941Smrg } 110b8e80941Smrg} 111b8e80941Smrg 112b8e80941Smrg 113b8e80941Smrg/** 114b8e80941Smrg * Called via ctx->Driver.QueryMemoryInfo() 115b8e80941Smrg */ 116b8e80941Smrgstatic void 117b8e80941Smrgst_query_memory_info(struct gl_context *ctx, struct gl_memory_info *out) 118b8e80941Smrg{ 119b8e80941Smrg struct pipe_screen *screen = st_context(ctx)->pipe->screen; 120b8e80941Smrg struct pipe_memory_info info; 121b8e80941Smrg 122b8e80941Smrg assert(screen->query_memory_info); 123b8e80941Smrg if (!screen->query_memory_info) 124b8e80941Smrg return; 125b8e80941Smrg 126b8e80941Smrg screen->query_memory_info(screen, &info); 127b8e80941Smrg 128b8e80941Smrg out->total_device_memory = info.total_device_memory; 129b8e80941Smrg out->avail_device_memory = info.avail_device_memory; 130b8e80941Smrg out->total_staging_memory = info.total_staging_memory; 131b8e80941Smrg out->avail_staging_memory = info.avail_staging_memory; 132b8e80941Smrg out->device_memory_evicted = info.device_memory_evicted; 133b8e80941Smrg out->nr_device_memory_evictions = info.nr_device_memory_evictions; 134b8e80941Smrg} 135b8e80941Smrg 136b8e80941Smrg 137b8e80941Smrgstatic uint64_t 138b8e80941Smrgst_get_active_states(struct gl_context *ctx) 139b8e80941Smrg{ 140b8e80941Smrg struct st_vertex_program *vp = 141b8e80941Smrg st_vertex_program(ctx->VertexProgram._Current); 142b8e80941Smrg struct st_common_program *tcp = 143b8e80941Smrg st_common_program(ctx->TessCtrlProgram._Current); 144b8e80941Smrg struct st_common_program *tep = 145b8e80941Smrg st_common_program(ctx->TessEvalProgram._Current); 146b8e80941Smrg struct st_common_program *gp = 147b8e80941Smrg st_common_program(ctx->GeometryProgram._Current); 148b8e80941Smrg struct st_fragment_program *fp = 149b8e80941Smrg st_fragment_program(ctx->FragmentProgram._Current); 150b8e80941Smrg struct st_compute_program *cp = 151b8e80941Smrg st_compute_program(ctx->ComputeProgram._Current); 152b8e80941Smrg uint64_t active_shader_states = 0; 153b8e80941Smrg 154b8e80941Smrg if (vp) 155b8e80941Smrg active_shader_states |= vp->affected_states; 156b8e80941Smrg if (tcp) 157b8e80941Smrg active_shader_states |= tcp->affected_states; 158b8e80941Smrg if (tep) 159b8e80941Smrg active_shader_states |= tep->affected_states; 160b8e80941Smrg if (gp) 161b8e80941Smrg active_shader_states |= gp->affected_states; 162b8e80941Smrg if (fp) 163b8e80941Smrg active_shader_states |= fp->affected_states; 164b8e80941Smrg if (cp) 165b8e80941Smrg active_shader_states |= cp->affected_states; 166b8e80941Smrg 167b8e80941Smrg /* Mark non-shader-resource shader states as "always active". */ 168b8e80941Smrg return active_shader_states | ~ST_ALL_SHADER_RESOURCES; 169b8e80941Smrg} 170b8e80941Smrg 171b8e80941Smrg 172b8e80941Smrgvoid 173b8e80941Smrgst_invalidate_buffers(struct st_context *st) 174b8e80941Smrg{ 175b8e80941Smrg st->dirty |= ST_NEW_BLEND | 176b8e80941Smrg ST_NEW_DSA | 177b8e80941Smrg ST_NEW_FB_STATE | 178b8e80941Smrg ST_NEW_SAMPLE_STATE | 179b8e80941Smrg ST_NEW_SAMPLE_SHADING | 180b8e80941Smrg ST_NEW_FS_STATE | 181b8e80941Smrg ST_NEW_POLY_STIPPLE | 182b8e80941Smrg ST_NEW_VIEWPORT | 183b8e80941Smrg ST_NEW_RASTERIZER | 184b8e80941Smrg ST_NEW_SCISSOR | 185b8e80941Smrg ST_NEW_WINDOW_RECTANGLES; 186b8e80941Smrg} 187b8e80941Smrg 188b8e80941Smrg 189b8e80941Smrgstatic inline bool 190b8e80941Smrgst_vp_uses_current_values(const struct gl_context *ctx) 191b8e80941Smrg{ 192b8e80941Smrg const uint64_t inputs = ctx->VertexProgram._Current->info.inputs_read; 193b8e80941Smrg return _mesa_draw_current_bits(ctx) & inputs; 194b8e80941Smrg} 195b8e80941Smrg 196b8e80941Smrg 197848b8605Smrg/** 198848b8605Smrg * Called via ctx->Driver.UpdateState() 199848b8605Smrg */ 200b8e80941Smrgstatic void 201b8e80941Smrgst_invalidate_state(struct gl_context *ctx) 202848b8605Smrg{ 203b8e80941Smrg GLbitfield new_state = ctx->NewState; 204848b8605Smrg struct st_context *st = st_context(ctx); 205848b8605Smrg 206b8e80941Smrg if (new_state & _NEW_BUFFERS) { 207b8e80941Smrg st_invalidate_buffers(st); 208b8e80941Smrg } else { 209b8e80941Smrg /* These set a subset of flags set by _NEW_BUFFERS, so we only have to 210b8e80941Smrg * check them when _NEW_BUFFERS isn't set. 211b8e80941Smrg */ 212b8e80941Smrg if (new_state & _NEW_PROGRAM) 213b8e80941Smrg st->dirty |= ST_NEW_RASTERIZER; 214b8e80941Smrg 215b8e80941Smrg if (new_state & _NEW_FOG) 216b8e80941Smrg st->dirty |= ST_NEW_FS_STATE; 217b8e80941Smrg 218b8e80941Smrg if (new_state & _NEW_FRAG_CLAMP) { 219b8e80941Smrg if (st->clamp_frag_color_in_shader) 220b8e80941Smrg st->dirty |= ST_NEW_FS_STATE; 221b8e80941Smrg else 222b8e80941Smrg st->dirty |= ST_NEW_RASTERIZER; 223b8e80941Smrg } 224848b8605Smrg } 225848b8605Smrg 226b8e80941Smrg if (new_state & (_NEW_LIGHT | 227b8e80941Smrg _NEW_POINT)) 228b8e80941Smrg st->dirty |= ST_NEW_RASTERIZER; 229b8e80941Smrg 230b8e80941Smrg if (new_state & _NEW_PROJECTION && 231b8e80941Smrg st_user_clip_planes_enabled(ctx)) 232b8e80941Smrg st->dirty |= ST_NEW_CLIP_STATE; 233b8e80941Smrg 234b8e80941Smrg if (new_state & _NEW_PIXEL) 235b8e80941Smrg st->dirty |= ST_NEW_PIXEL_TRANSFER; 236b8e80941Smrg 237b8e80941Smrg if (new_state & _NEW_CURRENT_ATTRIB && st_vp_uses_current_values(ctx)) 238b8e80941Smrg st->dirty |= ST_NEW_VERTEX_ARRAYS; 239b8e80941Smrg 240848b8605Smrg /* Update the vertex shader if ctx->Light._ClampVertexColor was changed. */ 241b8e80941Smrg if (st->clamp_vert_color_in_shader && (new_state & _NEW_LIGHT)) 242b8e80941Smrg st->dirty |= ST_NEW_VS_STATE; 243b8e80941Smrg 244b8e80941Smrg /* Which shaders are dirty will be determined manually. */ 245b8e80941Smrg if (new_state & _NEW_PROGRAM) { 246b8e80941Smrg st->gfx_shaders_may_be_dirty = true; 247b8e80941Smrg st->compute_shader_may_be_dirty = true; 248b8e80941Smrg /* This will mask out unused shader resources. */ 249b8e80941Smrg st->active_states = st_get_active_states(ctx); 250b8e80941Smrg } 251b8e80941Smrg 252b8e80941Smrg if (new_state & _NEW_TEXTURE_OBJECT) { 253b8e80941Smrg st->dirty |= st->active_states & 254b8e80941Smrg (ST_NEW_SAMPLER_VIEWS | 255b8e80941Smrg ST_NEW_SAMPLERS | 256b8e80941Smrg ST_NEW_IMAGE_UNITS); 257b8e80941Smrg if (ctx->FragmentProgram._Current && 258b8e80941Smrg ctx->FragmentProgram._Current->ExternalSamplersUsed) { 259b8e80941Smrg st->dirty |= ST_NEW_FS_STATE; 260b8e80941Smrg } 261848b8605Smrg } 262b8e80941Smrg} 263b8e80941Smrg 264b8e80941Smrg 265b8e80941Smrg/* 266b8e80941Smrg * In some circumstances (such as running google-chrome) the state 267b8e80941Smrg * tracker may try to delete a resource view from a context different 268b8e80941Smrg * than when it was created. We don't want to do that. 269b8e80941Smrg * 270b8e80941Smrg * In that situation, st_texture_release_all_sampler_views() calls this 271b8e80941Smrg * function to transfer the sampler view reference to this context (expected 272b8e80941Smrg * to be the context which created the view.) 273b8e80941Smrg */ 274b8e80941Smrgvoid 275b8e80941Smrgst_save_zombie_sampler_view(struct st_context *st, 276b8e80941Smrg struct pipe_sampler_view *view) 277b8e80941Smrg{ 278b8e80941Smrg struct st_zombie_sampler_view_node *entry; 279b8e80941Smrg 280b8e80941Smrg assert(view->context == st->pipe); 281b8e80941Smrg 282b8e80941Smrg entry = MALLOC_STRUCT(st_zombie_sampler_view_node); 283b8e80941Smrg if (!entry) 284b8e80941Smrg return; 285b8e80941Smrg 286b8e80941Smrg entry->view = view; 287b8e80941Smrg 288b8e80941Smrg /* We need a mutex since this function may be called from one thread 289b8e80941Smrg * while free_zombie_resource_views() is called from another. 290b8e80941Smrg */ 291b8e80941Smrg mtx_lock(&st->zombie_sampler_views.mutex); 292b8e80941Smrg LIST_ADDTAIL(&entry->node, &st->zombie_sampler_views.list.node); 293b8e80941Smrg mtx_unlock(&st->zombie_sampler_views.mutex); 294b8e80941Smrg} 295b8e80941Smrg 296b8e80941Smrg 297b8e80941Smrg/* 298b8e80941Smrg * Since OpenGL shaders may be shared among contexts, we can wind up 299b8e80941Smrg * with variants of a shader created with different contexts. 300b8e80941Smrg * When we go to destroy a gallium shader, we want to free it with the 301b8e80941Smrg * same context that it was created with, unless the driver reports 302b8e80941Smrg * PIPE_CAP_SHAREABLE_SHADERS = TRUE. 303b8e80941Smrg */ 304b8e80941Smrgvoid 305b8e80941Smrgst_save_zombie_shader(struct st_context *st, 306b8e80941Smrg enum pipe_shader_type type, 307b8e80941Smrg struct pipe_shader_state *shader) 308b8e80941Smrg{ 309b8e80941Smrg struct st_zombie_shader_node *entry; 310b8e80941Smrg 311b8e80941Smrg /* we shouldn't be here if the driver supports shareable shaders */ 312b8e80941Smrg assert(!st->has_shareable_shaders); 313848b8605Smrg 314b8e80941Smrg entry = MALLOC_STRUCT(st_zombie_shader_node); 315b8e80941Smrg if (!entry) 316b8e80941Smrg return; 317848b8605Smrg 318b8e80941Smrg entry->shader = shader; 319b8e80941Smrg entry->type = type; 320b8e80941Smrg 321b8e80941Smrg /* We need a mutex since this function may be called from one thread 322b8e80941Smrg * while free_zombie_shaders() is called from another. 323848b8605Smrg */ 324b8e80941Smrg mtx_lock(&st->zombie_shaders.mutex); 325b8e80941Smrg LIST_ADDTAIL(&entry->node, &st->zombie_shaders.list.node); 326b8e80941Smrg mtx_unlock(&st->zombie_shaders.mutex); 327b8e80941Smrg} 328b8e80941Smrg 329b8e80941Smrg 330b8e80941Smrg/* 331b8e80941Smrg * Free any zombie sampler views that may be attached to this context. 332b8e80941Smrg */ 333b8e80941Smrgstatic void 334b8e80941Smrgfree_zombie_sampler_views(struct st_context *st) 335b8e80941Smrg{ 336b8e80941Smrg struct st_zombie_sampler_view_node *entry, *next; 337b8e80941Smrg 338b8e80941Smrg if (LIST_IS_EMPTY(&st->zombie_sampler_views.list.node)) { 339b8e80941Smrg return; 340b8e80941Smrg } 341b8e80941Smrg 342b8e80941Smrg mtx_lock(&st->zombie_sampler_views.mutex); 343b8e80941Smrg 344b8e80941Smrg LIST_FOR_EACH_ENTRY_SAFE(entry, next, 345b8e80941Smrg &st->zombie_sampler_views.list.node, node) { 346b8e80941Smrg LIST_DEL(&entry->node); // remove this entry from the list 347b8e80941Smrg 348b8e80941Smrg assert(entry->view->context == st->pipe); 349b8e80941Smrg pipe_sampler_view_reference(&entry->view, NULL); 350b8e80941Smrg 351b8e80941Smrg free(entry); 352b8e80941Smrg } 353b8e80941Smrg 354b8e80941Smrg assert(LIST_IS_EMPTY(&st->zombie_sampler_views.list.node)); 355b8e80941Smrg 356b8e80941Smrg mtx_unlock(&st->zombie_sampler_views.mutex); 357b8e80941Smrg} 358b8e80941Smrg 359b8e80941Smrg 360b8e80941Smrg/* 361b8e80941Smrg * Free any zombie shaders that may be attached to this context. 362b8e80941Smrg */ 363b8e80941Smrgstatic void 364b8e80941Smrgfree_zombie_shaders(struct st_context *st) 365b8e80941Smrg{ 366b8e80941Smrg struct st_zombie_shader_node *entry, *next; 367b8e80941Smrg 368b8e80941Smrg if (LIST_IS_EMPTY(&st->zombie_shaders.list.node)) { 369b8e80941Smrg return; 370b8e80941Smrg } 371b8e80941Smrg 372b8e80941Smrg mtx_lock(&st->zombie_shaders.mutex); 373b8e80941Smrg 374b8e80941Smrg LIST_FOR_EACH_ENTRY_SAFE(entry, next, 375b8e80941Smrg &st->zombie_shaders.list.node, node) { 376b8e80941Smrg LIST_DEL(&entry->node); // remove this entry from the list 377b8e80941Smrg 378b8e80941Smrg switch (entry->type) { 379b8e80941Smrg case PIPE_SHADER_VERTEX: 380b8e80941Smrg cso_delete_vertex_shader(st->cso_context, entry->shader); 381b8e80941Smrg break; 382b8e80941Smrg case PIPE_SHADER_FRAGMENT: 383b8e80941Smrg cso_delete_fragment_shader(st->cso_context, entry->shader); 384b8e80941Smrg break; 385b8e80941Smrg case PIPE_SHADER_GEOMETRY: 386b8e80941Smrg cso_delete_geometry_shader(st->cso_context, entry->shader); 387b8e80941Smrg break; 388b8e80941Smrg case PIPE_SHADER_TESS_CTRL: 389b8e80941Smrg cso_delete_tessctrl_shader(st->cso_context, entry->shader); 390b8e80941Smrg break; 391b8e80941Smrg case PIPE_SHADER_TESS_EVAL: 392b8e80941Smrg cso_delete_tesseval_shader(st->cso_context, entry->shader); 393b8e80941Smrg break; 394b8e80941Smrg case PIPE_SHADER_COMPUTE: 395b8e80941Smrg cso_delete_compute_shader(st->cso_context, entry->shader); 396b8e80941Smrg break; 397b8e80941Smrg default: 398b8e80941Smrg unreachable("invalid shader type in free_zombie_shaders()"); 399b8e80941Smrg } 400b8e80941Smrg free(entry); 401b8e80941Smrg } 402b8e80941Smrg 403b8e80941Smrg assert(LIST_IS_EMPTY(&st->zombie_shaders.list.node)); 404b8e80941Smrg 405b8e80941Smrg mtx_unlock(&st->zombie_shaders.mutex); 406b8e80941Smrg} 407b8e80941Smrg 408b8e80941Smrg 409b8e80941Smrg/* 410b8e80941Smrg * This function is called periodically to free any zombie objects 411b8e80941Smrg * which are attached to this context. 412b8e80941Smrg */ 413b8e80941Smrgvoid 414b8e80941Smrgst_context_free_zombie_objects(struct st_context *st) 415b8e80941Smrg{ 416b8e80941Smrg free_zombie_sampler_views(st); 417b8e80941Smrg free_zombie_shaders(st); 418b8e80941Smrg} 419b8e80941Smrg 420b8e80941Smrg 421b8e80941Smrgstatic void 422b8e80941Smrgst_destroy_context_priv(struct st_context *st, bool destroy_pipe) 423b8e80941Smrg{ 424b8e80941Smrg uint i; 425b8e80941Smrg 426b8e80941Smrg st_destroy_atoms(st); 427b8e80941Smrg st_destroy_draw(st); 428b8e80941Smrg st_destroy_clear(st); 429b8e80941Smrg st_destroy_bitmap(st); 430b8e80941Smrg st_destroy_drawpix(st); 431b8e80941Smrg st_destroy_drawtex(st); 432b8e80941Smrg st_destroy_perfmon(st); 433b8e80941Smrg st_destroy_pbo_helpers(st); 434b8e80941Smrg st_destroy_bound_texture_handles(st); 435b8e80941Smrg st_destroy_bound_image_handles(st); 436b8e80941Smrg 437b8e80941Smrg for (i = 0; i < ARRAY_SIZE(st->state.frag_sampler_views); i++) { 438b8e80941Smrg pipe_sampler_view_reference(&st->state.frag_sampler_views[i], NULL); 439b8e80941Smrg } 440b8e80941Smrg 441b8e80941Smrg /* free glReadPixels cache data */ 442b8e80941Smrg st_invalidate_readpix_cache(st); 443b8e80941Smrg util_throttle_deinit(st->pipe->screen, &st->throttle); 444b8e80941Smrg 445b8e80941Smrg cso_destroy_context(st->cso_context); 446b8e80941Smrg 447b8e80941Smrg if (st->pipe && destroy_pipe) 448b8e80941Smrg st->pipe->destroy(st->pipe); 449b8e80941Smrg 450b8e80941Smrg free(st); 451848b8605Smrg} 452848b8605Smrg 453b8e80941Smrg 454b8e80941Smrgstatic void 455b8e80941Smrgst_init_driver_flags(struct st_context *st) 456b8e80941Smrg{ 457b8e80941Smrg struct gl_driver_flags *f = &st->ctx->DriverFlags; 458b8e80941Smrg 459b8e80941Smrg f->NewArray = ST_NEW_VERTEX_ARRAYS; 460b8e80941Smrg f->NewRasterizerDiscard = ST_NEW_RASTERIZER; 461b8e80941Smrg f->NewTileRasterOrder = ST_NEW_RASTERIZER; 462b8e80941Smrg f->NewUniformBuffer = ST_NEW_UNIFORM_BUFFER; 463b8e80941Smrg f->NewDefaultTessLevels = ST_NEW_TESS_STATE; 464b8e80941Smrg 465b8e80941Smrg /* Shader resources */ 466b8e80941Smrg f->NewTextureBuffer = ST_NEW_SAMPLER_VIEWS; 467b8e80941Smrg if (st->has_hw_atomics) 468b8e80941Smrg f->NewAtomicBuffer = ST_NEW_HW_ATOMICS | ST_NEW_CS_ATOMICS; 469b8e80941Smrg else 470b8e80941Smrg f->NewAtomicBuffer = ST_NEW_ATOMIC_BUFFER; 471b8e80941Smrg f->NewShaderStorageBuffer = ST_NEW_STORAGE_BUFFER; 472b8e80941Smrg f->NewImageUnits = ST_NEW_IMAGE_UNITS; 473b8e80941Smrg 474b8e80941Smrg f->NewShaderConstants[MESA_SHADER_VERTEX] = ST_NEW_VS_CONSTANTS; 475b8e80941Smrg f->NewShaderConstants[MESA_SHADER_TESS_CTRL] = ST_NEW_TCS_CONSTANTS; 476b8e80941Smrg f->NewShaderConstants[MESA_SHADER_TESS_EVAL] = ST_NEW_TES_CONSTANTS; 477b8e80941Smrg f->NewShaderConstants[MESA_SHADER_GEOMETRY] = ST_NEW_GS_CONSTANTS; 478b8e80941Smrg f->NewShaderConstants[MESA_SHADER_FRAGMENT] = ST_NEW_FS_CONSTANTS; 479b8e80941Smrg f->NewShaderConstants[MESA_SHADER_COMPUTE] = ST_NEW_CS_CONSTANTS; 480b8e80941Smrg 481b8e80941Smrg f->NewWindowRectangles = ST_NEW_WINDOW_RECTANGLES; 482b8e80941Smrg f->NewFramebufferSRGB = ST_NEW_FB_STATE; 483b8e80941Smrg f->NewScissorRect = ST_NEW_SCISSOR; 484b8e80941Smrg f->NewScissorTest = ST_NEW_SCISSOR | ST_NEW_RASTERIZER; 485b8e80941Smrg f->NewAlphaTest = ST_NEW_DSA; 486b8e80941Smrg f->NewBlend = ST_NEW_BLEND; 487b8e80941Smrg f->NewBlendColor = ST_NEW_BLEND_COLOR; 488b8e80941Smrg f->NewColorMask = ST_NEW_BLEND; 489b8e80941Smrg f->NewDepth = ST_NEW_DSA; 490b8e80941Smrg f->NewLogicOp = ST_NEW_BLEND; 491b8e80941Smrg f->NewStencil = ST_NEW_DSA; 492b8e80941Smrg f->NewMultisampleEnable = ST_NEW_BLEND | ST_NEW_RASTERIZER | 493b8e80941Smrg ST_NEW_SAMPLE_STATE | ST_NEW_SAMPLE_SHADING; 494b8e80941Smrg f->NewSampleAlphaToXEnable = ST_NEW_BLEND; 495b8e80941Smrg f->NewSampleMask = ST_NEW_SAMPLE_STATE; 496b8e80941Smrg f->NewSampleLocations = ST_NEW_SAMPLE_STATE; 497b8e80941Smrg f->NewSampleShading = ST_NEW_SAMPLE_SHADING; 498b8e80941Smrg 499b8e80941Smrg /* This depends on what the gallium driver wants. */ 500b8e80941Smrg if (st->force_persample_in_shader) { 501b8e80941Smrg f->NewMultisampleEnable |= ST_NEW_FS_STATE; 502b8e80941Smrg f->NewSampleShading |= ST_NEW_FS_STATE; 503b8e80941Smrg } else { 504b8e80941Smrg f->NewSampleShading |= ST_NEW_RASTERIZER; 505b8e80941Smrg } 506b8e80941Smrg 507b8e80941Smrg f->NewClipControl = ST_NEW_VIEWPORT | ST_NEW_RASTERIZER; 508b8e80941Smrg f->NewClipPlane = ST_NEW_CLIP_STATE; 509b8e80941Smrg f->NewClipPlaneEnable = ST_NEW_RASTERIZER; 510b8e80941Smrg f->NewDepthClamp = ST_NEW_RASTERIZER; 511b8e80941Smrg f->NewLineState = ST_NEW_RASTERIZER; 512b8e80941Smrg f->NewPolygonState = ST_NEW_RASTERIZER; 513b8e80941Smrg f->NewPolygonStipple = ST_NEW_POLY_STIPPLE; 514b8e80941Smrg f->NewViewport = ST_NEW_VIEWPORT; 515b8e80941Smrg f->NewNvConservativeRasterization = ST_NEW_RASTERIZER; 516b8e80941Smrg f->NewNvConservativeRasterizationParams = ST_NEW_RASTERIZER; 517b8e80941Smrg f->NewIntelConservativeRasterization = ST_NEW_RASTERIZER; 518b8e80941Smrg} 519b8e80941Smrg 520b8e80941Smrg 521848b8605Smrgstatic struct st_context * 522b8e80941Smrgst_create_context_priv(struct gl_context *ctx, struct pipe_context *pipe, 523b8e80941Smrg const struct st_config_options *options, bool no_error) 524848b8605Smrg{ 525848b8605Smrg struct pipe_screen *screen = pipe->screen; 526848b8605Smrg uint i; 527b8e80941Smrg struct st_context *st = ST_CALLOC_STRUCT( st_context); 528b8e80941Smrg 529848b8605Smrg st->options = *options; 530848b8605Smrg 531848b8605Smrg ctx->st = st; 532848b8605Smrg 533848b8605Smrg st->ctx = ctx; 534848b8605Smrg st->pipe = pipe; 535848b8605Smrg 536848b8605Smrg /* state tracker needs the VBO module */ 537848b8605Smrg _vbo_CreateContext(ctx); 538848b8605Smrg 539b8e80941Smrg st->dirty = ST_ALL_STATES_MASK; 540848b8605Smrg 541b8e80941Smrg st->can_bind_const_buffer_as_vertex = 542b8e80941Smrg screen->get_param(screen, PIPE_CAP_CAN_BIND_CONST_BUFFER_AS_VERTEX); 543848b8605Smrg 544b8e80941Smrg /* st/mesa always uploads zero-stride vertex attribs, and other user 545b8e80941Smrg * vertex buffers are only possible with a compatibility profile. 546b8e80941Smrg * So tell the u_vbuf module that user VBOs are not possible with the Core 547b8e80941Smrg * profile, so that u_vbuf is bypassed completely if there is nothing else 548b8e80941Smrg * to do. 549b8e80941Smrg */ 550b8e80941Smrg unsigned vbuf_flags = 551b8e80941Smrg ctx->API == API_OPENGL_CORE ? U_VBUF_FLAG_NO_USER_VBOS : 0; 552b8e80941Smrg st->cso_context = cso_create_context(pipe, vbuf_flags); 553848b8605Smrg 554b8e80941Smrg st_init_atoms(st); 555848b8605Smrg st_init_clear(st); 556b8e80941Smrg st_init_pbo_helpers(st); 557848b8605Smrg 558848b8605Smrg /* Choose texture target for glDrawPixels, glBitmap, renderbuffers */ 559848b8605Smrg if (pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES)) 560848b8605Smrg st->internal_target = PIPE_TEXTURE_2D; 561848b8605Smrg else 562848b8605Smrg st->internal_target = PIPE_TEXTURE_RECT; 563848b8605Smrg 564b8e80941Smrg /* Setup vertex element info for 'struct st_util_vertex'. 565848b8605Smrg */ 566b8e80941Smrg { 567b8e80941Smrg STATIC_ASSERT(sizeof(struct st_util_vertex) == 9 * sizeof(float)); 568b8e80941Smrg 569b8e80941Smrg memset(&st->util_velems, 0, sizeof(st->util_velems)); 570b8e80941Smrg st->util_velems[0].src_offset = 0; 571b8e80941Smrg st->util_velems[0].vertex_buffer_index = 0; 572b8e80941Smrg st->util_velems[0].src_format = PIPE_FORMAT_R32G32B32_FLOAT; 573b8e80941Smrg st->util_velems[1].src_offset = 3 * sizeof(float); 574b8e80941Smrg st->util_velems[1].vertex_buffer_index = 0; 575b8e80941Smrg st->util_velems[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 576b8e80941Smrg st->util_velems[2].src_offset = 7 * sizeof(float); 577b8e80941Smrg st->util_velems[2].vertex_buffer_index = 0; 578b8e80941Smrg st->util_velems[2].src_format = PIPE_FORMAT_R32G32_FLOAT; 579848b8605Smrg } 580848b8605Smrg 581848b8605Smrg /* we want all vertex data to be placed in buffer objects */ 582848b8605Smrg vbo_use_buffer_objects(ctx); 583848b8605Smrg 584848b8605Smrg 585848b8605Smrg /* make sure that no VBOs are left mapped when we're drawing. */ 586848b8605Smrg vbo_always_unmap_buffers(ctx); 587848b8605Smrg 588848b8605Smrg /* Need these flags: 589848b8605Smrg */ 590b8e80941Smrg ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; 591848b8605Smrg 592b8e80941Smrg ctx->VertexProgram._MaintainTnlProgram = GL_TRUE; 593848b8605Smrg 594b8e80941Smrg if (no_error) 595b8e80941Smrg ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR; 596b8e80941Smrg 597b8e80941Smrg ctx->Const.PackedDriverUniformStorage = 598b8e80941Smrg screen->get_param(screen, PIPE_CAP_PACKED_UNIFORMS); 599848b8605Smrg 600848b8605Smrg st->has_stencil_export = 601848b8605Smrg screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT); 602848b8605Smrg st->has_shader_model3 = screen->get_param(screen, PIPE_CAP_SM3); 603848b8605Smrg st->has_etc1 = screen->is_format_supported(screen, PIPE_FORMAT_ETC1_RGB8, 604b8e80941Smrg PIPE_TEXTURE_2D, 0, 0, 605b8e80941Smrg PIPE_BIND_SAMPLER_VIEW); 606b8e80941Smrg st->has_etc2 = screen->is_format_supported(screen, PIPE_FORMAT_ETC2_RGB8, 607b8e80941Smrg PIPE_TEXTURE_2D, 0, 0, 608848b8605Smrg PIPE_BIND_SAMPLER_VIEW); 609b8e80941Smrg st->has_astc_2d_ldr = 610b8e80941Smrg screen->is_format_supported(screen, PIPE_FORMAT_ASTC_4x4_SRGB, 611b8e80941Smrg PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SAMPLER_VIEW); 612848b8605Smrg st->prefer_blit_based_texture_transfer = screen->get_param(screen, 613848b8605Smrg PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER); 614b8e80941Smrg st->force_persample_in_shader = 615b8e80941Smrg screen->get_param(screen, PIPE_CAP_SAMPLE_SHADING) && 616b8e80941Smrg !screen->get_param(screen, PIPE_CAP_FORCE_PERSAMPLE_INTERP); 617b8e80941Smrg st->has_shareable_shaders = screen->get_param(screen, 618b8e80941Smrg PIPE_CAP_SHAREABLE_SHADERS); 619848b8605Smrg st->needs_texcoord_semantic = 620848b8605Smrg screen->get_param(screen, PIPE_CAP_TGSI_TEXCOORD); 621848b8605Smrg st->apply_texture_swizzle_to_border_color = 622848b8605Smrg !!(screen->get_param(screen, PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK) & 623848b8605Smrg (PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 | 624848b8605Smrg PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600)); 625848b8605Smrg st->has_time_elapsed = 626848b8605Smrg screen->get_param(screen, PIPE_CAP_QUERY_TIME_ELAPSED); 627b8e80941Smrg st->has_half_float_packing = 628b8e80941Smrg screen->get_param(screen, PIPE_CAP_TGSI_PACK_HALF_FLOAT); 629b8e80941Smrg st->has_multi_draw_indirect = 630b8e80941Smrg screen->get_param(screen, PIPE_CAP_MULTI_DRAW_INDIRECT); 631b8e80941Smrg st->has_single_pipe_stat = 632b8e80941Smrg screen->get_param(screen, PIPE_CAP_QUERY_PIPELINE_STATISTICS_SINGLE); 633b8e80941Smrg st->has_indep_blend_func = 634b8e80941Smrg screen->get_param(screen, PIPE_CAP_INDEP_BLEND_FUNC); 635b8e80941Smrg st->needs_rgb_dst_alpha_override = 636b8e80941Smrg screen->get_param(screen, PIPE_CAP_RGB_OVERRIDE_DST_ALPHA_BLEND); 637b8e80941Smrg 638b8e80941Smrg st->has_hw_atomics = 639b8e80941Smrg screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT, 640b8e80941Smrg PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS) 641b8e80941Smrg ? true : false; 642b8e80941Smrg 643b8e80941Smrg util_throttle_init(&st->throttle, 644b8e80941Smrg screen->get_param(screen, 645b8e80941Smrg PIPE_CAP_MAX_TEXTURE_UPLOAD_MEMORY_BUDGET)); 646848b8605Smrg 647848b8605Smrg /* GL limits and extensions */ 648b8e80941Smrg st_init_limits(pipe->screen, &ctx->Const, &ctx->Extensions); 649b8e80941Smrg st_init_extensions(pipe->screen, &ctx->Const, 650b8e80941Smrg &ctx->Extensions, &st->options, ctx->API); 651b8e80941Smrg 652b8e80941Smrg if (st_have_perfmon(st)) { 653b8e80941Smrg ctx->Extensions.AMD_performance_monitor = GL_TRUE; 654b8e80941Smrg } 655848b8605Smrg 656848b8605Smrg /* Enable shader-based fallbacks for ARB_color_buffer_float if needed. */ 657848b8605Smrg if (screen->get_param(screen, PIPE_CAP_VERTEX_COLOR_UNCLAMPED)) { 658848b8605Smrg if (!screen->get_param(screen, PIPE_CAP_VERTEX_COLOR_CLAMPED)) { 659848b8605Smrg st->clamp_vert_color_in_shader = GL_TRUE; 660848b8605Smrg } 661848b8605Smrg 662848b8605Smrg if (!screen->get_param(screen, PIPE_CAP_FRAGMENT_COLOR_CLAMPED)) { 663848b8605Smrg st->clamp_frag_color_in_shader = GL_TRUE; 664848b8605Smrg } 665848b8605Smrg 666848b8605Smrg /* For drivers which cannot do color clamping, it's better to just 667848b8605Smrg * disable ARB_color_buffer_float in the core profile, because 668848b8605Smrg * the clamping is deprecated there anyway. */ 669848b8605Smrg if (ctx->API == API_OPENGL_CORE && 670848b8605Smrg (st->clamp_frag_color_in_shader || st->clamp_vert_color_in_shader)) { 671848b8605Smrg st->clamp_vert_color_in_shader = GL_FALSE; 672848b8605Smrg st->clamp_frag_color_in_shader = GL_FALSE; 673848b8605Smrg ctx->Extensions.ARB_color_buffer_float = GL_FALSE; 674848b8605Smrg } 675848b8605Smrg } 676848b8605Smrg 677848b8605Smrg /* called after _mesa_create_context/_mesa_init_point, fix default user 678848b8605Smrg * settable max point size up 679848b8605Smrg */ 680b8e80941Smrg ctx->Point.MaxSize = MAX2(ctx->Const.MaxPointSize, 681b8e80941Smrg ctx->Const.MaxPointSizeAA); 682b8e80941Smrg /* For vertex shaders, make sure not to emit saturate when SM 3.0 683b8e80941Smrg * is not supported 684b8e80941Smrg */ 685b8e80941Smrg ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].EmitNoSat = 686b8e80941Smrg !st->has_shader_model3; 687b8e80941Smrg 688b8e80941Smrg if (!ctx->Extensions.ARB_gpu_shader5) { 689b8e80941Smrg for (i = 0; i < MESA_SHADER_STAGES; i++) 690b8e80941Smrg ctx->Const.ShaderCompilerOptions[i].EmitNoIndirectSampler = true; 691b8e80941Smrg } 692b8e80941Smrg 693b8e80941Smrg /* Set which shader types can be compiled at link time. */ 694b8e80941Smrg st->shader_has_one_variant[MESA_SHADER_VERTEX] = 695b8e80941Smrg st->has_shareable_shaders && 696b8e80941Smrg !st->clamp_vert_color_in_shader; 697848b8605Smrg 698b8e80941Smrg st->shader_has_one_variant[MESA_SHADER_FRAGMENT] = 699b8e80941Smrg st->has_shareable_shaders && 700b8e80941Smrg !st->clamp_frag_color_in_shader && 701b8e80941Smrg !st->force_persample_in_shader; 702b8e80941Smrg 703b8e80941Smrg st->shader_has_one_variant[MESA_SHADER_TESS_CTRL] = st->has_shareable_shaders; 704b8e80941Smrg st->shader_has_one_variant[MESA_SHADER_TESS_EVAL] = st->has_shareable_shaders; 705b8e80941Smrg st->shader_has_one_variant[MESA_SHADER_GEOMETRY] = st->has_shareable_shaders; 706b8e80941Smrg st->shader_has_one_variant[MESA_SHADER_COMPUTE] = st->has_shareable_shaders; 707b8e80941Smrg 708b8e80941Smrg st->bitmap.cache.empty = true; 709b8e80941Smrg 710b8e80941Smrg _mesa_override_extensions(ctx); 711848b8605Smrg _mesa_compute_version(ctx); 712848b8605Smrg 713b8e80941Smrg if (ctx->Version == 0) { 714b8e80941Smrg /* This can happen when a core profile was requested, but the driver 715b8e80941Smrg * does not support some features of GL 3.1 or later. 716b8e80941Smrg */ 717b8e80941Smrg st_destroy_context_priv(st, false); 718b8e80941Smrg return NULL; 719b8e80941Smrg } 720b8e80941Smrg 721848b8605Smrg _mesa_initialize_dispatch_tables(ctx); 722848b8605Smrg _mesa_initialize_vbo_vtxfmt(ctx); 723b8e80941Smrg st_init_driver_flags(st); 724b8e80941Smrg 725b8e80941Smrg /* Initialize context's winsys buffers list */ 726b8e80941Smrg LIST_INITHEAD(&st->winsys_buffers); 727b8e80941Smrg 728b8e80941Smrg LIST_INITHEAD(&st->zombie_sampler_views.list.node); 729b8e80941Smrg mtx_init(&st->zombie_sampler_views.mutex, mtx_plain); 730b8e80941Smrg LIST_INITHEAD(&st->zombie_shaders.list.node); 731b8e80941Smrg mtx_init(&st->zombie_shaders.mutex, mtx_plain); 732848b8605Smrg 733848b8605Smrg return st; 734848b8605Smrg} 735848b8605Smrg 736b8e80941Smrg 737b8e80941Smrgstatic void 738b8e80941Smrgst_emit_string_marker(struct gl_context *ctx, const GLchar *string, GLsizei len) 739848b8605Smrg{ 740b8e80941Smrg struct st_context *st = ctx->st; 741b8e80941Smrg st->pipe->emit_string_marker(st->pipe, string, len); 742b8e80941Smrg} 743b8e80941Smrg 744b8e80941Smrg 745b8e80941Smrgstatic void 746b8e80941Smrgst_set_background_context(struct gl_context *ctx, 747b8e80941Smrg struct util_queue_monitoring *queue_info) 748b8e80941Smrg{ 749b8e80941Smrg struct st_context *st = ctx->st; 750b8e80941Smrg struct st_manager *smapi = 751b8e80941Smrg (struct st_manager *) st->iface.st_context_private; 752b8e80941Smrg 753b8e80941Smrg assert(smapi->set_background_context); 754b8e80941Smrg smapi->set_background_context(&st->iface, queue_info); 755b8e80941Smrg} 756b8e80941Smrg 757b8e80941Smrg 758b8e80941Smrgstatic void 759b8e80941Smrgst_get_device_uuid(struct gl_context *ctx, char *uuid) 760b8e80941Smrg{ 761b8e80941Smrg struct pipe_screen *screen = st_context(ctx)->pipe->screen; 762b8e80941Smrg 763b8e80941Smrg assert(GL_UUID_SIZE_EXT >= PIPE_UUID_SIZE); 764b8e80941Smrg memset(uuid, 0, GL_UUID_SIZE_EXT); 765b8e80941Smrg screen->get_device_uuid(screen, uuid); 766b8e80941Smrg} 767b8e80941Smrg 768b8e80941Smrg 769b8e80941Smrgstatic void 770b8e80941Smrgst_get_driver_uuid(struct gl_context *ctx, char *uuid) 771b8e80941Smrg{ 772b8e80941Smrg struct pipe_screen *screen = st_context(ctx)->pipe->screen; 773b8e80941Smrg 774b8e80941Smrg assert(GL_UUID_SIZE_EXT >= PIPE_UUID_SIZE); 775b8e80941Smrg memset(uuid, 0, GL_UUID_SIZE_EXT); 776b8e80941Smrg screen->get_driver_uuid(screen, uuid); 777b8e80941Smrg} 778b8e80941Smrg 779b8e80941Smrg 780b8e80941Smrgstatic void 781b8e80941Smrgst_init_driver_functions(struct pipe_screen *screen, 782b8e80941Smrg struct dd_function_table *functions) 783b8e80941Smrg{ 784b8e80941Smrg _mesa_init_sampler_object_functions(functions); 785b8e80941Smrg 786b8e80941Smrg st_init_draw_functions(functions); 787b8e80941Smrg st_init_blit_functions(functions); 788b8e80941Smrg st_init_bufferobject_functions(screen, functions); 789b8e80941Smrg st_init_clear_functions(functions); 790b8e80941Smrg st_init_bitmap_functions(functions); 791b8e80941Smrg st_init_copy_image_functions(functions); 792b8e80941Smrg st_init_drawpixels_functions(functions); 793b8e80941Smrg st_init_rasterpos_functions(functions); 794b8e80941Smrg 795b8e80941Smrg st_init_drawtex_functions(functions); 796b8e80941Smrg 797b8e80941Smrg st_init_eglimage_functions(functions); 798b8e80941Smrg 799b8e80941Smrg st_init_fbo_functions(functions); 800b8e80941Smrg st_init_feedback_functions(functions); 801b8e80941Smrg st_init_memoryobject_functions(functions); 802b8e80941Smrg st_init_msaa_functions(functions); 803b8e80941Smrg st_init_perfmon_functions(functions); 804b8e80941Smrg st_init_program_functions(functions); 805b8e80941Smrg st_init_query_functions(functions); 806b8e80941Smrg st_init_cond_render_functions(functions); 807b8e80941Smrg st_init_readpixels_functions(functions); 808b8e80941Smrg st_init_semaphoreobject_functions(functions); 809b8e80941Smrg st_init_texture_functions(functions); 810b8e80941Smrg st_init_texture_barrier_functions(functions); 811b8e80941Smrg st_init_flush_functions(screen, functions); 812b8e80941Smrg st_init_string_functions(functions); 813b8e80941Smrg st_init_viewport_functions(functions); 814b8e80941Smrg st_init_compute_functions(functions); 815b8e80941Smrg 816b8e80941Smrg st_init_xformfb_functions(functions); 817b8e80941Smrg st_init_syncobj_functions(functions); 818b8e80941Smrg 819b8e80941Smrg st_init_vdpau_functions(functions); 820b8e80941Smrg 821b8e80941Smrg if (screen->get_param(screen, PIPE_CAP_STRING_MARKER)) 822b8e80941Smrg functions->EmitStringMarker = st_emit_string_marker; 823b8e80941Smrg 824b8e80941Smrg functions->Enable = st_Enable; 825b8e80941Smrg functions->UpdateState = st_invalidate_state; 826b8e80941Smrg functions->QueryMemoryInfo = st_query_memory_info; 827b8e80941Smrg functions->SetBackgroundContext = st_set_background_context; 828b8e80941Smrg functions->GetDriverUuid = st_get_driver_uuid; 829b8e80941Smrg functions->GetDeviceUuid = st_get_device_uuid; 830b8e80941Smrg 831b8e80941Smrg /* GL_ARB_get_program_binary */ 832b8e80941Smrg functions->GetProgramBinaryDriverSHA1 = st_get_program_binary_driver_sha1; 833b8e80941Smrg 834b8e80941Smrg enum pipe_shader_ir preferred_ir = (enum pipe_shader_ir) 835b8e80941Smrg screen->get_shader_param(screen, PIPE_SHADER_VERTEX, 836b8e80941Smrg PIPE_SHADER_CAP_PREFERRED_IR); 837b8e80941Smrg if (preferred_ir == PIPE_SHADER_IR_NIR) { 838b8e80941Smrg functions->ShaderCacheSerializeDriverBlob = st_serialise_nir_program; 839b8e80941Smrg functions->ProgramBinarySerializeDriverBlob = 840b8e80941Smrg st_serialise_nir_program_binary; 841b8e80941Smrg functions->ProgramBinaryDeserializeDriverBlob = 842b8e80941Smrg st_deserialise_nir_program; 843b8e80941Smrg } else { 844b8e80941Smrg functions->ShaderCacheSerializeDriverBlob = st_serialise_tgsi_program; 845b8e80941Smrg functions->ProgramBinarySerializeDriverBlob = 846b8e80941Smrg st_serialise_tgsi_program_binary; 847b8e80941Smrg functions->ProgramBinaryDeserializeDriverBlob = 848b8e80941Smrg st_deserialise_tgsi_program; 849b8e80941Smrg } 850848b8605Smrg} 851848b8605Smrg 852b8e80941Smrg 853b8e80941Smrgstruct st_context * 854b8e80941Smrgst_create_context(gl_api api, struct pipe_context *pipe, 855b8e80941Smrg const struct gl_config *visual, 856b8e80941Smrg struct st_context *share, 857b8e80941Smrg const struct st_config_options *options, 858b8e80941Smrg bool no_error) 859848b8605Smrg{ 860848b8605Smrg struct gl_context *ctx; 861848b8605Smrg struct gl_context *shareCtx = share ? share->ctx : NULL; 862848b8605Smrg struct dd_function_table funcs; 863b8e80941Smrg struct st_context *st; 864b8e80941Smrg 865b8e80941Smrg util_cpu_detect(); 866848b8605Smrg 867848b8605Smrg memset(&funcs, 0, sizeof(funcs)); 868b8e80941Smrg st_init_driver_functions(pipe->screen, &funcs); 869b8e80941Smrg 870b8e80941Smrg ctx = calloc(1, sizeof(struct gl_context)); 871b8e80941Smrg if (!ctx) 872b8e80941Smrg return NULL; 873848b8605Smrg 874b8e80941Smrg if (!_mesa_initialize_context(ctx, api, visual, shareCtx, &funcs)) { 875b8e80941Smrg free(ctx); 876848b8605Smrg return NULL; 877848b8605Smrg } 878848b8605Smrg 879b8e80941Smrg st_debug_init(); 880b8e80941Smrg 881b8e80941Smrg if (pipe->screen->get_disk_shader_cache && 882b8e80941Smrg !(ST_DEBUG & DEBUG_TGSI)) 883b8e80941Smrg ctx->Cache = pipe->screen->get_disk_shader_cache(pipe->screen); 884848b8605Smrg 885848b8605Smrg /* XXX: need a capability bit in gallium to query if the pipe 886848b8605Smrg * driver prefers DP4 or MUL/MAD for vertex transformation. 887848b8605Smrg */ 888848b8605Smrg if (debug_get_option_mesa_mvp_dp4()) 889848b8605Smrg ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS = GL_TRUE; 890848b8605Smrg 891b8e80941Smrg st = st_create_context_priv(ctx, pipe, options, no_error); 892b8e80941Smrg if (!st) { 893b8e80941Smrg _mesa_destroy_context(ctx); 894848b8605Smrg } 895848b8605Smrg 896b8e80941Smrg return st; 897848b8605Smrg} 898848b8605Smrg 899848b8605Smrg 900848b8605Smrg/** 901b8e80941Smrg * When we destroy a context, we must examine all texture objects to 902b8e80941Smrg * find/release any sampler views created by that context. 903b8e80941Smrg * 904b8e80941Smrg * This callback is called per-texture object. It releases all the 905b8e80941Smrg * texture's sampler views which belong to the context. 906848b8605Smrg */ 907848b8605Smrgstatic void 908848b8605Smrgdestroy_tex_sampler_cb(GLuint id, void *data, void *userData) 909848b8605Smrg{ 910848b8605Smrg struct gl_texture_object *texObj = (struct gl_texture_object *) data; 911848b8605Smrg struct st_context *st = (struct st_context *) userData; 912848b8605Smrg 913b8e80941Smrg st_texture_release_context_sampler_view(st, st_texture_object(texObj)); 914b8e80941Smrg} 915b8e80941Smrg 916b8e80941Smrgstatic void 917b8e80941Smrgdestroy_framebuffer_attachment_sampler_cb(GLuint id, void *data, void *userData) 918b8e80941Smrg{ 919b8e80941Smrg struct gl_framebuffer* glfb = (struct gl_framebuffer*) data; 920b8e80941Smrg struct st_context *st = (struct st_context *) userData; 921b8e80941Smrg 922b8e80941Smrg for (unsigned i = 0; i < BUFFER_COUNT; i++) { 923b8e80941Smrg struct gl_renderbuffer_attachment *att = &glfb->Attachment[i]; 924b8e80941Smrg if (att->Texture) { 925b8e80941Smrg st_texture_release_context_sampler_view(st, st_texture_object(att->Texture)); 926b8e80941Smrg } 927b8e80941Smrg } 928848b8605Smrg} 929b8e80941Smrg 930b8e80941Smrgvoid 931b8e80941Smrgst_destroy_context(struct st_context *st) 932848b8605Smrg{ 933848b8605Smrg struct gl_context *ctx = st->ctx; 934b8e80941Smrg struct st_framebuffer *stfb, *next; 935b8e80941Smrg struct gl_framebuffer *save_drawbuffer; 936b8e80941Smrg struct gl_framebuffer *save_readbuffer; 937b8e80941Smrg 938b8e80941Smrg /* Save the current context and draw/read buffers*/ 939b8e80941Smrg GET_CURRENT_CONTEXT(save_ctx); 940b8e80941Smrg if (save_ctx) { 941b8e80941Smrg save_drawbuffer = save_ctx->WinSysDrawBuffer; 942b8e80941Smrg save_readbuffer = save_ctx->WinSysReadBuffer; 943b8e80941Smrg } else { 944b8e80941Smrg save_drawbuffer = save_readbuffer = NULL; 945b8e80941Smrg } 946b8e80941Smrg 947b8e80941Smrg /* 948b8e80941Smrg * We need to bind the context we're deleting so that 949b8e80941Smrg * _mesa_reference_texobj_() uses this context when deleting textures. 950b8e80941Smrg * Similarly for framebuffer objects, etc. 951b8e80941Smrg */ 952b8e80941Smrg _mesa_make_current(ctx, NULL, NULL); 953b8e80941Smrg 954b8e80941Smrg /* This must be called first so that glthread has a chance to finish */ 955b8e80941Smrg _mesa_glthread_destroy(ctx); 956848b8605Smrg 957848b8605Smrg _mesa_HashWalk(ctx->Shared->TexObjects, destroy_tex_sampler_cb, st); 958848b8605Smrg 959b8e80941Smrg /* For the fallback textures, free any sampler views belonging to this 960b8e80941Smrg * context. 961b8e80941Smrg */ 962b8e80941Smrg for (unsigned i = 0; i < NUM_TEXTURE_TARGETS; i++) { 963b8e80941Smrg struct st_texture_object *stObj = 964b8e80941Smrg st_texture_object(ctx->Shared->FallbackTex[i]); 965b8e80941Smrg if (stObj) { 966b8e80941Smrg st_texture_release_context_sampler_view(st, stObj); 967b8e80941Smrg } 968b8e80941Smrg } 969b8e80941Smrg 970b8e80941Smrg st_context_free_zombie_objects(st); 971b8e80941Smrg 972b8e80941Smrg mtx_destroy(&st->zombie_sampler_views.mutex); 973b8e80941Smrg mtx_destroy(&st->zombie_shaders.mutex); 974848b8605Smrg 975848b8605Smrg st_reference_fragprog(st, &st->fp, NULL); 976b8e80941Smrg st_reference_prog(st, &st->gp, NULL); 977848b8605Smrg st_reference_vertprog(st, &st->vp, NULL); 978b8e80941Smrg st_reference_prog(st, &st->tcp, NULL); 979b8e80941Smrg st_reference_prog(st, &st->tep, NULL); 980b8e80941Smrg st_reference_compprog(st, &st->cp, NULL); 981848b8605Smrg 982b8e80941Smrg /* release framebuffer in the winsys buffers list */ 983b8e80941Smrg LIST_FOR_EACH_ENTRY_SAFE_REV(stfb, next, &st->winsys_buffers, head) { 984b8e80941Smrg st_framebuffer_reference(&stfb, NULL); 985848b8605Smrg } 986848b8605Smrg 987b8e80941Smrg _mesa_HashWalk(ctx->Shared->FrameBuffers, destroy_framebuffer_attachment_sampler_cb, st); 988848b8605Smrg 989b8e80941Smrg pipe_sampler_view_reference(&st->pixel_xfer.pixelmap_sampler_view, NULL); 990b8e80941Smrg pipe_resource_reference(&st->pixel_xfer.pixelmap_texture, NULL); 991848b8605Smrg 992b8e80941Smrg _vbo_DestroyContext(ctx); 993848b8605Smrg 994848b8605Smrg st_destroy_program_variants(st); 995848b8605Smrg 996b8e80941Smrg _mesa_free_context_data(ctx, false); 997848b8605Smrg 998848b8605Smrg /* This will free the st_context too, so 'st' must not be accessed 999848b8605Smrg * afterwards. */ 1000b8e80941Smrg st_destroy_context_priv(st, true); 1001848b8605Smrg st = NULL; 1002848b8605Smrg 1003b8e80941Smrg /* This must be called after st_destroy_context_priv() to avoid a race 1004b8e80941Smrg * condition between any shader compiler threads and context destruction. 1005b8e80941Smrg */ 1006b8e80941Smrg _mesa_destroy_shader_compiler_types(); 1007848b8605Smrg 1008848b8605Smrg free(ctx); 1009848b8605Smrg 1010b8e80941Smrg if (save_ctx == ctx) { 1011b8e80941Smrg /* unbind the context we just deleted */ 1012b8e80941Smrg _mesa_make_current(NULL, NULL, NULL); 1013b8e80941Smrg } else { 1014b8e80941Smrg /* Restore the current context and draw/read buffers (may be NULL) */ 1015b8e80941Smrg _mesa_make_current(save_ctx, save_drawbuffer, save_readbuffer); 1016b8e80941Smrg } 1017848b8605Smrg} 1018