1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Mesa 3-D graphics library 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Copyright (C) 2010 LunarG Inc. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 8bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 9bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 11bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 12bf215546Sopenharmony_ci * 13bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 14bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci * Authors: 25bf215546Sopenharmony_ci * Chia-I Wu <olv@lunarg.com> 26bf215546Sopenharmony_ci */ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "main/mtypes.h" 29bf215546Sopenharmony_ci#include "main/extensions.h" 30bf215546Sopenharmony_ci#include "main/context.h" 31bf215546Sopenharmony_ci#include "main/debug_output.h" 32bf215546Sopenharmony_ci#include "main/framebuffer.h" 33bf215546Sopenharmony_ci#include "main/glthread.h" 34bf215546Sopenharmony_ci#include "main/texobj.h" 35bf215546Sopenharmony_ci#include "main/teximage.h" 36bf215546Sopenharmony_ci#include "main/texstate.h" 37bf215546Sopenharmony_ci#include "main/errors.h" 38bf215546Sopenharmony_ci#include "main/framebuffer.h" 39bf215546Sopenharmony_ci#include "main/fbobject.h" 40bf215546Sopenharmony_ci#include "main/renderbuffer.h" 41bf215546Sopenharmony_ci#include "main/version.h" 42bf215546Sopenharmony_ci#include "util/hash_table.h" 43bf215546Sopenharmony_ci#include "st_texture.h" 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci#include "st_context.h" 46bf215546Sopenharmony_ci#include "st_debug.h" 47bf215546Sopenharmony_ci#include "st_extensions.h" 48bf215546Sopenharmony_ci#include "st_format.h" 49bf215546Sopenharmony_ci#include "st_cb_bitmap.h" 50bf215546Sopenharmony_ci#include "st_cb_flush.h" 51bf215546Sopenharmony_ci#include "st_manager.h" 52bf215546Sopenharmony_ci#include "st_sampler_view.h" 53bf215546Sopenharmony_ci#include "st_util.h" 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci#include "state_tracker/st_gl_api.h" 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci#include "pipe/p_context.h" 58bf215546Sopenharmony_ci#include "pipe/p_screen.h" 59bf215546Sopenharmony_ci#include "util/format/u_format.h" 60bf215546Sopenharmony_ci#include "util/u_helpers.h" 61bf215546Sopenharmony_ci#include "util/u_pointer.h" 62bf215546Sopenharmony_ci#include "util/u_inlines.h" 63bf215546Sopenharmony_ci#include "util/u_atomic.h" 64bf215546Sopenharmony_ci#include "util/u_surface.h" 65bf215546Sopenharmony_ci#include "util/list.h" 66bf215546Sopenharmony_ci#include "util/u_memory.h" 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_cistruct hash_table; 69bf215546Sopenharmony_cistruct st_manager_private 70bf215546Sopenharmony_ci{ 71bf215546Sopenharmony_ci struct hash_table *stfbi_ht; /* framebuffer iface objects hash table */ 72bf215546Sopenharmony_ci simple_mtx_t st_mutex; 73bf215546Sopenharmony_ci}; 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci/** 76bf215546Sopenharmony_ci * Cast wrapper to convert a struct gl_framebuffer to an gl_framebuffer. 77bf215546Sopenharmony_ci * Return NULL if the struct gl_framebuffer is a user-created framebuffer. 78bf215546Sopenharmony_ci * We'll only return non-null for window system framebuffers. 79bf215546Sopenharmony_ci * Note that this function may fail. 80bf215546Sopenharmony_ci */ 81bf215546Sopenharmony_cistatic inline struct gl_framebuffer * 82bf215546Sopenharmony_cist_ws_framebuffer(struct gl_framebuffer *fb) 83bf215546Sopenharmony_ci{ 84bf215546Sopenharmony_ci /* FBO cannot be casted. See st_new_framebuffer */ 85bf215546Sopenharmony_ci if (fb && _mesa_is_winsys_fbo(fb) && 86bf215546Sopenharmony_ci fb != _mesa_get_incomplete_framebuffer()) 87bf215546Sopenharmony_ci return fb; 88bf215546Sopenharmony_ci return NULL; 89bf215546Sopenharmony_ci} 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci/** 92bf215546Sopenharmony_ci * Map an attachment to a buffer index. 93bf215546Sopenharmony_ci */ 94bf215546Sopenharmony_cistatic inline gl_buffer_index 95bf215546Sopenharmony_ciattachment_to_buffer_index(enum st_attachment_type statt) 96bf215546Sopenharmony_ci{ 97bf215546Sopenharmony_ci gl_buffer_index index; 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci switch (statt) { 100bf215546Sopenharmony_ci case ST_ATTACHMENT_FRONT_LEFT: 101bf215546Sopenharmony_ci index = BUFFER_FRONT_LEFT; 102bf215546Sopenharmony_ci break; 103bf215546Sopenharmony_ci case ST_ATTACHMENT_BACK_LEFT: 104bf215546Sopenharmony_ci index = BUFFER_BACK_LEFT; 105bf215546Sopenharmony_ci break; 106bf215546Sopenharmony_ci case ST_ATTACHMENT_FRONT_RIGHT: 107bf215546Sopenharmony_ci index = BUFFER_FRONT_RIGHT; 108bf215546Sopenharmony_ci break; 109bf215546Sopenharmony_ci case ST_ATTACHMENT_BACK_RIGHT: 110bf215546Sopenharmony_ci index = BUFFER_BACK_RIGHT; 111bf215546Sopenharmony_ci break; 112bf215546Sopenharmony_ci case ST_ATTACHMENT_DEPTH_STENCIL: 113bf215546Sopenharmony_ci index = BUFFER_DEPTH; 114bf215546Sopenharmony_ci break; 115bf215546Sopenharmony_ci case ST_ATTACHMENT_ACCUM: 116bf215546Sopenharmony_ci index = BUFFER_ACCUM; 117bf215546Sopenharmony_ci break; 118bf215546Sopenharmony_ci default: 119bf215546Sopenharmony_ci index = BUFFER_COUNT; 120bf215546Sopenharmony_ci break; 121bf215546Sopenharmony_ci } 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci return index; 124bf215546Sopenharmony_ci} 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_ci/** 128bf215546Sopenharmony_ci * Map a buffer index to an attachment. 129bf215546Sopenharmony_ci */ 130bf215546Sopenharmony_cistatic inline enum st_attachment_type 131bf215546Sopenharmony_cibuffer_index_to_attachment(gl_buffer_index index) 132bf215546Sopenharmony_ci{ 133bf215546Sopenharmony_ci enum st_attachment_type statt; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci switch (index) { 136bf215546Sopenharmony_ci case BUFFER_FRONT_LEFT: 137bf215546Sopenharmony_ci statt = ST_ATTACHMENT_FRONT_LEFT; 138bf215546Sopenharmony_ci break; 139bf215546Sopenharmony_ci case BUFFER_BACK_LEFT: 140bf215546Sopenharmony_ci statt = ST_ATTACHMENT_BACK_LEFT; 141bf215546Sopenharmony_ci break; 142bf215546Sopenharmony_ci case BUFFER_FRONT_RIGHT: 143bf215546Sopenharmony_ci statt = ST_ATTACHMENT_FRONT_RIGHT; 144bf215546Sopenharmony_ci break; 145bf215546Sopenharmony_ci case BUFFER_BACK_RIGHT: 146bf215546Sopenharmony_ci statt = ST_ATTACHMENT_BACK_RIGHT; 147bf215546Sopenharmony_ci break; 148bf215546Sopenharmony_ci case BUFFER_DEPTH: 149bf215546Sopenharmony_ci statt = ST_ATTACHMENT_DEPTH_STENCIL; 150bf215546Sopenharmony_ci break; 151bf215546Sopenharmony_ci case BUFFER_ACCUM: 152bf215546Sopenharmony_ci statt = ST_ATTACHMENT_ACCUM; 153bf215546Sopenharmony_ci break; 154bf215546Sopenharmony_ci default: 155bf215546Sopenharmony_ci statt = ST_ATTACHMENT_INVALID; 156bf215546Sopenharmony_ci break; 157bf215546Sopenharmony_ci } 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci return statt; 160bf215546Sopenharmony_ci} 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_ci/** 164bf215546Sopenharmony_ci * Make sure a context picks up the latest cached state of the 165bf215546Sopenharmony_ci * drawables it binds to. 166bf215546Sopenharmony_ci */ 167bf215546Sopenharmony_cistatic void 168bf215546Sopenharmony_cist_context_validate(struct st_context *st, 169bf215546Sopenharmony_ci struct gl_framebuffer *stdraw, 170bf215546Sopenharmony_ci struct gl_framebuffer *stread) 171bf215546Sopenharmony_ci{ 172bf215546Sopenharmony_ci if (stdraw && stdraw->stamp != st->draw_stamp) { 173bf215546Sopenharmony_ci st->dirty |= ST_NEW_FRAMEBUFFER; 174bf215546Sopenharmony_ci _mesa_resize_framebuffer(st->ctx, stdraw, 175bf215546Sopenharmony_ci stdraw->Width, 176bf215546Sopenharmony_ci stdraw->Height); 177bf215546Sopenharmony_ci st->draw_stamp = stdraw->stamp; 178bf215546Sopenharmony_ci } 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci if (stread && stread->stamp != st->read_stamp) { 181bf215546Sopenharmony_ci if (stread != stdraw) { 182bf215546Sopenharmony_ci st->dirty |= ST_NEW_FRAMEBUFFER; 183bf215546Sopenharmony_ci _mesa_resize_framebuffer(st->ctx, stread, 184bf215546Sopenharmony_ci stread->Width, 185bf215546Sopenharmony_ci stread->Height); 186bf215546Sopenharmony_ci } 187bf215546Sopenharmony_ci st->read_stamp = stread->stamp; 188bf215546Sopenharmony_ci } 189bf215546Sopenharmony_ci} 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_civoid 193bf215546Sopenharmony_cist_set_ws_renderbuffer_surface(struct gl_renderbuffer *rb, 194bf215546Sopenharmony_ci struct pipe_surface *surf) 195bf215546Sopenharmony_ci{ 196bf215546Sopenharmony_ci pipe_surface_reference(&rb->surface_srgb, NULL); 197bf215546Sopenharmony_ci pipe_surface_reference(&rb->surface_linear, NULL); 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci if (util_format_is_srgb(surf->format)) 200bf215546Sopenharmony_ci pipe_surface_reference(&rb->surface_srgb, surf); 201bf215546Sopenharmony_ci else 202bf215546Sopenharmony_ci pipe_surface_reference(&rb->surface_linear, surf); 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci rb->surface = surf; /* just assign, don't ref */ 205bf215546Sopenharmony_ci pipe_resource_reference(&rb->texture, surf->texture); 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_ci rb->Width = surf->width; 208bf215546Sopenharmony_ci rb->Height = surf->height; 209bf215546Sopenharmony_ci} 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_ci/** 213bf215546Sopenharmony_ci * Validate a framebuffer to make sure up-to-date pipe_textures are used. 214bf215546Sopenharmony_ci * The context is only used for creating pipe surfaces and for calling 215bf215546Sopenharmony_ci * _mesa_resize_framebuffer(). 216bf215546Sopenharmony_ci * (That should probably be rethought, since those surfaces become 217bf215546Sopenharmony_ci * drawable state, not context state, and can be freed by another pipe 218bf215546Sopenharmony_ci * context). 219bf215546Sopenharmony_ci */ 220bf215546Sopenharmony_cistatic void 221bf215546Sopenharmony_cist_framebuffer_validate(struct gl_framebuffer *stfb, 222bf215546Sopenharmony_ci struct st_context *st) 223bf215546Sopenharmony_ci{ 224bf215546Sopenharmony_ci struct pipe_resource *textures[ST_ATTACHMENT_COUNT]; 225bf215546Sopenharmony_ci uint width, height; 226bf215546Sopenharmony_ci unsigned i; 227bf215546Sopenharmony_ci bool changed = false; 228bf215546Sopenharmony_ci int32_t new_stamp; 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci new_stamp = p_atomic_read(&stfb->iface->stamp); 231bf215546Sopenharmony_ci if (stfb->iface_stamp == new_stamp) 232bf215546Sopenharmony_ci return; 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci memset(textures, 0, stfb->num_statts * sizeof(textures[0])); 235bf215546Sopenharmony_ci 236bf215546Sopenharmony_ci /* validate the fb */ 237bf215546Sopenharmony_ci do { 238bf215546Sopenharmony_ci if (!stfb->iface->validate(&st->iface, stfb->iface, stfb->statts, 239bf215546Sopenharmony_ci stfb->num_statts, textures)) 240bf215546Sopenharmony_ci return; 241bf215546Sopenharmony_ci 242bf215546Sopenharmony_ci stfb->iface_stamp = new_stamp; 243bf215546Sopenharmony_ci new_stamp = p_atomic_read(&stfb->iface->stamp); 244bf215546Sopenharmony_ci } while(stfb->iface_stamp != new_stamp); 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci width = stfb->Width; 247bf215546Sopenharmony_ci height = stfb->Height; 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci for (i = 0; i < stfb->num_statts; i++) { 250bf215546Sopenharmony_ci struct gl_renderbuffer *rb; 251bf215546Sopenharmony_ci struct pipe_surface *ps, surf_tmpl; 252bf215546Sopenharmony_ci gl_buffer_index idx; 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci if (!textures[i]) 255bf215546Sopenharmony_ci continue; 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_ci idx = attachment_to_buffer_index(stfb->statts[i]); 258bf215546Sopenharmony_ci if (idx >= BUFFER_COUNT) { 259bf215546Sopenharmony_ci pipe_resource_reference(&textures[i], NULL); 260bf215546Sopenharmony_ci continue; 261bf215546Sopenharmony_ci } 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci rb = stfb->Attachment[idx].Renderbuffer; 264bf215546Sopenharmony_ci assert(rb); 265bf215546Sopenharmony_ci if (rb->texture == textures[i] && 266bf215546Sopenharmony_ci rb->Width == textures[i]->width0 && 267bf215546Sopenharmony_ci rb->Height == textures[i]->height0) { 268bf215546Sopenharmony_ci pipe_resource_reference(&textures[i], NULL); 269bf215546Sopenharmony_ci continue; 270bf215546Sopenharmony_ci } 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci u_surface_default_template(&surf_tmpl, textures[i]); 273bf215546Sopenharmony_ci ps = st->pipe->create_surface(st->pipe, textures[i], &surf_tmpl); 274bf215546Sopenharmony_ci if (ps) { 275bf215546Sopenharmony_ci st_set_ws_renderbuffer_surface(rb, ps); 276bf215546Sopenharmony_ci pipe_surface_reference(&ps, NULL); 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci changed = true; 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci width = rb->Width; 281bf215546Sopenharmony_ci height = rb->Height; 282bf215546Sopenharmony_ci } 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci pipe_resource_reference(&textures[i], NULL); 285bf215546Sopenharmony_ci } 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_ci if (changed) { 288bf215546Sopenharmony_ci ++stfb->stamp; 289bf215546Sopenharmony_ci _mesa_resize_framebuffer(st->ctx, stfb, width, height); 290bf215546Sopenharmony_ci } 291bf215546Sopenharmony_ci} 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci/** 295bf215546Sopenharmony_ci * Update the attachments to validate by looping the existing renderbuffers. 296bf215546Sopenharmony_ci */ 297bf215546Sopenharmony_cistatic void 298bf215546Sopenharmony_cist_framebuffer_update_attachments(struct gl_framebuffer *stfb) 299bf215546Sopenharmony_ci{ 300bf215546Sopenharmony_ci gl_buffer_index idx; 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci stfb->num_statts = 0; 303bf215546Sopenharmony_ci 304bf215546Sopenharmony_ci for (enum st_attachment_type i = 0; i < ST_ATTACHMENT_COUNT; i++) 305bf215546Sopenharmony_ci stfb->statts[i] = ST_ATTACHMENT_INVALID; 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_ci for (idx = 0; idx < BUFFER_COUNT; idx++) { 308bf215546Sopenharmony_ci struct gl_renderbuffer *rb; 309bf215546Sopenharmony_ci enum st_attachment_type statt; 310bf215546Sopenharmony_ci 311bf215546Sopenharmony_ci rb = stfb->Attachment[idx].Renderbuffer; 312bf215546Sopenharmony_ci if (!rb || rb->software) 313bf215546Sopenharmony_ci continue; 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci statt = buffer_index_to_attachment(idx); 316bf215546Sopenharmony_ci if (statt != ST_ATTACHMENT_INVALID && 317bf215546Sopenharmony_ci st_visual_have_buffers(stfb->iface->visual, 1 << statt)) 318bf215546Sopenharmony_ci stfb->statts[stfb->num_statts++] = statt; 319bf215546Sopenharmony_ci } 320bf215546Sopenharmony_ci stfb->stamp++; 321bf215546Sopenharmony_ci} 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci/** 324bf215546Sopenharmony_ci * Allocate a renderbuffer for an on-screen window (not a user-created 325bf215546Sopenharmony_ci * renderbuffer). The window system code determines the format. 326bf215546Sopenharmony_ci */ 327bf215546Sopenharmony_cistatic struct gl_renderbuffer * 328bf215546Sopenharmony_cist_new_renderbuffer_fb(enum pipe_format format, unsigned samples, boolean sw) 329bf215546Sopenharmony_ci{ 330bf215546Sopenharmony_ci struct gl_renderbuffer *rb; 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_ci rb = CALLOC_STRUCT(gl_renderbuffer); 333bf215546Sopenharmony_ci if (!rb) { 334bf215546Sopenharmony_ci _mesa_error(NULL, GL_OUT_OF_MEMORY, "creating renderbuffer"); 335bf215546Sopenharmony_ci return NULL; 336bf215546Sopenharmony_ci } 337bf215546Sopenharmony_ci 338bf215546Sopenharmony_ci _mesa_init_renderbuffer(rb, 0); 339bf215546Sopenharmony_ci rb->ClassID = 0x4242; /* just a unique value */ 340bf215546Sopenharmony_ci rb->NumSamples = samples; 341bf215546Sopenharmony_ci rb->NumStorageSamples = samples; 342bf215546Sopenharmony_ci rb->Format = st_pipe_format_to_mesa_format(format); 343bf215546Sopenharmony_ci rb->_BaseFormat = _mesa_get_format_base_format(rb->Format); 344bf215546Sopenharmony_ci rb->software = sw; 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci switch (format) { 347bf215546Sopenharmony_ci case PIPE_FORMAT_B10G10R10A2_UNORM: 348bf215546Sopenharmony_ci case PIPE_FORMAT_R10G10B10A2_UNORM: 349bf215546Sopenharmony_ci rb->InternalFormat = GL_RGB10_A2; 350bf215546Sopenharmony_ci break; 351bf215546Sopenharmony_ci case PIPE_FORMAT_R10G10B10X2_UNORM: 352bf215546Sopenharmony_ci case PIPE_FORMAT_B10G10R10X2_UNORM: 353bf215546Sopenharmony_ci rb->InternalFormat = GL_RGB10; 354bf215546Sopenharmony_ci break; 355bf215546Sopenharmony_ci case PIPE_FORMAT_R8G8B8A8_UNORM: 356bf215546Sopenharmony_ci case PIPE_FORMAT_B8G8R8A8_UNORM: 357bf215546Sopenharmony_ci case PIPE_FORMAT_A8R8G8B8_UNORM: 358bf215546Sopenharmony_ci rb->InternalFormat = GL_RGBA8; 359bf215546Sopenharmony_ci break; 360bf215546Sopenharmony_ci case PIPE_FORMAT_R8G8B8X8_UNORM: 361bf215546Sopenharmony_ci case PIPE_FORMAT_B8G8R8X8_UNORM: 362bf215546Sopenharmony_ci case PIPE_FORMAT_X8R8G8B8_UNORM: 363bf215546Sopenharmony_ci case PIPE_FORMAT_R8G8B8_UNORM: 364bf215546Sopenharmony_ci rb->InternalFormat = GL_RGB8; 365bf215546Sopenharmony_ci break; 366bf215546Sopenharmony_ci case PIPE_FORMAT_R8G8B8A8_SRGB: 367bf215546Sopenharmony_ci case PIPE_FORMAT_B8G8R8A8_SRGB: 368bf215546Sopenharmony_ci case PIPE_FORMAT_A8R8G8B8_SRGB: 369bf215546Sopenharmony_ci rb->InternalFormat = GL_SRGB8_ALPHA8; 370bf215546Sopenharmony_ci break; 371bf215546Sopenharmony_ci case PIPE_FORMAT_R8G8B8X8_SRGB: 372bf215546Sopenharmony_ci case PIPE_FORMAT_B8G8R8X8_SRGB: 373bf215546Sopenharmony_ci case PIPE_FORMAT_X8R8G8B8_SRGB: 374bf215546Sopenharmony_ci rb->InternalFormat = GL_SRGB8; 375bf215546Sopenharmony_ci break; 376bf215546Sopenharmony_ci case PIPE_FORMAT_B5G5R5A1_UNORM: 377bf215546Sopenharmony_ci rb->InternalFormat = GL_RGB5_A1; 378bf215546Sopenharmony_ci break; 379bf215546Sopenharmony_ci case PIPE_FORMAT_B4G4R4A4_UNORM: 380bf215546Sopenharmony_ci rb->InternalFormat = GL_RGBA4; 381bf215546Sopenharmony_ci break; 382bf215546Sopenharmony_ci case PIPE_FORMAT_B5G6R5_UNORM: 383bf215546Sopenharmony_ci rb->InternalFormat = GL_RGB565; 384bf215546Sopenharmony_ci break; 385bf215546Sopenharmony_ci case PIPE_FORMAT_Z16_UNORM: 386bf215546Sopenharmony_ci rb->InternalFormat = GL_DEPTH_COMPONENT16; 387bf215546Sopenharmony_ci break; 388bf215546Sopenharmony_ci case PIPE_FORMAT_Z32_UNORM: 389bf215546Sopenharmony_ci rb->InternalFormat = GL_DEPTH_COMPONENT32; 390bf215546Sopenharmony_ci break; 391bf215546Sopenharmony_ci case PIPE_FORMAT_Z24_UNORM_S8_UINT: 392bf215546Sopenharmony_ci case PIPE_FORMAT_S8_UINT_Z24_UNORM: 393bf215546Sopenharmony_ci rb->InternalFormat = GL_DEPTH24_STENCIL8_EXT; 394bf215546Sopenharmony_ci break; 395bf215546Sopenharmony_ci case PIPE_FORMAT_Z24X8_UNORM: 396bf215546Sopenharmony_ci case PIPE_FORMAT_X8Z24_UNORM: 397bf215546Sopenharmony_ci rb->InternalFormat = GL_DEPTH_COMPONENT24; 398bf215546Sopenharmony_ci break; 399bf215546Sopenharmony_ci case PIPE_FORMAT_S8_UINT: 400bf215546Sopenharmony_ci rb->InternalFormat = GL_STENCIL_INDEX8_EXT; 401bf215546Sopenharmony_ci break; 402bf215546Sopenharmony_ci case PIPE_FORMAT_R16G16B16A16_SNORM: 403bf215546Sopenharmony_ci /* accum buffer */ 404bf215546Sopenharmony_ci rb->InternalFormat = GL_RGBA16_SNORM; 405bf215546Sopenharmony_ci break; 406bf215546Sopenharmony_ci case PIPE_FORMAT_R16G16B16A16_UNORM: 407bf215546Sopenharmony_ci rb->InternalFormat = GL_RGBA16; 408bf215546Sopenharmony_ci break; 409bf215546Sopenharmony_ci case PIPE_FORMAT_R16G16B16_UNORM: 410bf215546Sopenharmony_ci rb->InternalFormat = GL_RGB16; 411bf215546Sopenharmony_ci break; 412bf215546Sopenharmony_ci case PIPE_FORMAT_R8_UNORM: 413bf215546Sopenharmony_ci rb->InternalFormat = GL_R8; 414bf215546Sopenharmony_ci break; 415bf215546Sopenharmony_ci case PIPE_FORMAT_R8G8_UNORM: 416bf215546Sopenharmony_ci rb->InternalFormat = GL_RG8; 417bf215546Sopenharmony_ci break; 418bf215546Sopenharmony_ci case PIPE_FORMAT_R16_UNORM: 419bf215546Sopenharmony_ci rb->InternalFormat = GL_R16; 420bf215546Sopenharmony_ci break; 421bf215546Sopenharmony_ci case PIPE_FORMAT_R16G16_UNORM: 422bf215546Sopenharmony_ci rb->InternalFormat = GL_RG16; 423bf215546Sopenharmony_ci break; 424bf215546Sopenharmony_ci case PIPE_FORMAT_R32G32B32A32_FLOAT: 425bf215546Sopenharmony_ci rb->InternalFormat = GL_RGBA32F; 426bf215546Sopenharmony_ci break; 427bf215546Sopenharmony_ci case PIPE_FORMAT_R32G32B32X32_FLOAT: 428bf215546Sopenharmony_ci case PIPE_FORMAT_R32G32B32_FLOAT: 429bf215546Sopenharmony_ci rb->InternalFormat = GL_RGB32F; 430bf215546Sopenharmony_ci break; 431bf215546Sopenharmony_ci case PIPE_FORMAT_R16G16B16A16_FLOAT: 432bf215546Sopenharmony_ci rb->InternalFormat = GL_RGBA16F; 433bf215546Sopenharmony_ci break; 434bf215546Sopenharmony_ci case PIPE_FORMAT_R16G16B16X16_FLOAT: 435bf215546Sopenharmony_ci rb->InternalFormat = GL_RGB16F; 436bf215546Sopenharmony_ci break; 437bf215546Sopenharmony_ci default: 438bf215546Sopenharmony_ci _mesa_problem(NULL, 439bf215546Sopenharmony_ci "Unexpected format %s in st_new_renderbuffer_fb", 440bf215546Sopenharmony_ci util_format_name(format)); 441bf215546Sopenharmony_ci FREE(rb); 442bf215546Sopenharmony_ci return NULL; 443bf215546Sopenharmony_ci } 444bf215546Sopenharmony_ci 445bf215546Sopenharmony_ci rb->surface = NULL; 446bf215546Sopenharmony_ci 447bf215546Sopenharmony_ci return rb; 448bf215546Sopenharmony_ci} 449bf215546Sopenharmony_ci 450bf215546Sopenharmony_ci/** 451bf215546Sopenharmony_ci * Add a renderbuffer to the framebuffer. The framebuffer is one that 452bf215546Sopenharmony_ci * corresponds to a window and is not a user-created FBO. 453bf215546Sopenharmony_ci */ 454bf215546Sopenharmony_cistatic bool 455bf215546Sopenharmony_cist_framebuffer_add_renderbuffer(struct gl_framebuffer *stfb, 456bf215546Sopenharmony_ci gl_buffer_index idx, bool prefer_srgb) 457bf215546Sopenharmony_ci{ 458bf215546Sopenharmony_ci struct gl_renderbuffer *rb; 459bf215546Sopenharmony_ci enum pipe_format format; 460bf215546Sopenharmony_ci bool sw; 461bf215546Sopenharmony_ci 462bf215546Sopenharmony_ci assert(_mesa_is_winsys_fbo(stfb)); 463bf215546Sopenharmony_ci 464bf215546Sopenharmony_ci /* do not distinguish depth/stencil buffers */ 465bf215546Sopenharmony_ci if (idx == BUFFER_STENCIL) 466bf215546Sopenharmony_ci idx = BUFFER_DEPTH; 467bf215546Sopenharmony_ci 468bf215546Sopenharmony_ci switch (idx) { 469bf215546Sopenharmony_ci case BUFFER_DEPTH: 470bf215546Sopenharmony_ci format = stfb->iface->visual->depth_stencil_format; 471bf215546Sopenharmony_ci sw = false; 472bf215546Sopenharmony_ci break; 473bf215546Sopenharmony_ci case BUFFER_ACCUM: 474bf215546Sopenharmony_ci format = stfb->iface->visual->accum_format; 475bf215546Sopenharmony_ci sw = true; 476bf215546Sopenharmony_ci break; 477bf215546Sopenharmony_ci default: 478bf215546Sopenharmony_ci format = stfb->iface->visual->color_format; 479bf215546Sopenharmony_ci if (prefer_srgb) 480bf215546Sopenharmony_ci format = util_format_srgb(format); 481bf215546Sopenharmony_ci sw = false; 482bf215546Sopenharmony_ci break; 483bf215546Sopenharmony_ci } 484bf215546Sopenharmony_ci 485bf215546Sopenharmony_ci if (format == PIPE_FORMAT_NONE) 486bf215546Sopenharmony_ci return false; 487bf215546Sopenharmony_ci 488bf215546Sopenharmony_ci rb = st_new_renderbuffer_fb(format, stfb->iface->visual->samples, sw); 489bf215546Sopenharmony_ci if (!rb) 490bf215546Sopenharmony_ci return false; 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci if (idx != BUFFER_DEPTH) { 493bf215546Sopenharmony_ci _mesa_attach_and_own_rb(stfb, idx, rb); 494bf215546Sopenharmony_ci return true; 495bf215546Sopenharmony_ci } 496bf215546Sopenharmony_ci 497bf215546Sopenharmony_ci bool rb_ownership_taken = false; 498bf215546Sopenharmony_ci if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0)) { 499bf215546Sopenharmony_ci _mesa_attach_and_own_rb(stfb, BUFFER_DEPTH, rb); 500bf215546Sopenharmony_ci rb_ownership_taken = true; 501bf215546Sopenharmony_ci } 502bf215546Sopenharmony_ci 503bf215546Sopenharmony_ci if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) { 504bf215546Sopenharmony_ci if (rb_ownership_taken) 505bf215546Sopenharmony_ci _mesa_attach_and_reference_rb(stfb, BUFFER_STENCIL, rb); 506bf215546Sopenharmony_ci else 507bf215546Sopenharmony_ci _mesa_attach_and_own_rb(stfb, BUFFER_STENCIL, rb); 508bf215546Sopenharmony_ci } 509bf215546Sopenharmony_ci 510bf215546Sopenharmony_ci return true; 511bf215546Sopenharmony_ci} 512bf215546Sopenharmony_ci 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_ci/** 515bf215546Sopenharmony_ci * Intialize a struct gl_config from a visual. 516bf215546Sopenharmony_ci */ 517bf215546Sopenharmony_cistatic void 518bf215546Sopenharmony_cist_visual_to_context_mode(const struct st_visual *visual, 519bf215546Sopenharmony_ci struct gl_config *mode) 520bf215546Sopenharmony_ci{ 521bf215546Sopenharmony_ci memset(mode, 0, sizeof(*mode)); 522bf215546Sopenharmony_ci 523bf215546Sopenharmony_ci if (st_visual_have_buffers(visual, ST_ATTACHMENT_BACK_LEFT_MASK)) 524bf215546Sopenharmony_ci mode->doubleBufferMode = GL_TRUE; 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci if (st_visual_have_buffers(visual, 527bf215546Sopenharmony_ci ST_ATTACHMENT_FRONT_RIGHT_MASK | ST_ATTACHMENT_BACK_RIGHT_MASK)) 528bf215546Sopenharmony_ci mode->stereoMode = GL_TRUE; 529bf215546Sopenharmony_ci 530bf215546Sopenharmony_ci if (visual->color_format != PIPE_FORMAT_NONE) { 531bf215546Sopenharmony_ci mode->redBits = 532bf215546Sopenharmony_ci util_format_get_component_bits(visual->color_format, 533bf215546Sopenharmony_ci UTIL_FORMAT_COLORSPACE_RGB, 0); 534bf215546Sopenharmony_ci mode->greenBits = 535bf215546Sopenharmony_ci util_format_get_component_bits(visual->color_format, 536bf215546Sopenharmony_ci UTIL_FORMAT_COLORSPACE_RGB, 1); 537bf215546Sopenharmony_ci mode->blueBits = 538bf215546Sopenharmony_ci util_format_get_component_bits(visual->color_format, 539bf215546Sopenharmony_ci UTIL_FORMAT_COLORSPACE_RGB, 2); 540bf215546Sopenharmony_ci mode->alphaBits = 541bf215546Sopenharmony_ci util_format_get_component_bits(visual->color_format, 542bf215546Sopenharmony_ci UTIL_FORMAT_COLORSPACE_RGB, 3); 543bf215546Sopenharmony_ci 544bf215546Sopenharmony_ci mode->rgbBits = mode->redBits + 545bf215546Sopenharmony_ci mode->greenBits + mode->blueBits + mode->alphaBits; 546bf215546Sopenharmony_ci mode->sRGBCapable = util_format_is_srgb(visual->color_format); 547bf215546Sopenharmony_ci } 548bf215546Sopenharmony_ci 549bf215546Sopenharmony_ci if (visual->depth_stencil_format != PIPE_FORMAT_NONE) { 550bf215546Sopenharmony_ci mode->depthBits = 551bf215546Sopenharmony_ci util_format_get_component_bits(visual->depth_stencil_format, 552bf215546Sopenharmony_ci UTIL_FORMAT_COLORSPACE_ZS, 0); 553bf215546Sopenharmony_ci mode->stencilBits = 554bf215546Sopenharmony_ci util_format_get_component_bits(visual->depth_stencil_format, 555bf215546Sopenharmony_ci UTIL_FORMAT_COLORSPACE_ZS, 1); 556bf215546Sopenharmony_ci } 557bf215546Sopenharmony_ci 558bf215546Sopenharmony_ci if (visual->accum_format != PIPE_FORMAT_NONE) { 559bf215546Sopenharmony_ci mode->accumRedBits = 560bf215546Sopenharmony_ci util_format_get_component_bits(visual->accum_format, 561bf215546Sopenharmony_ci UTIL_FORMAT_COLORSPACE_RGB, 0); 562bf215546Sopenharmony_ci mode->accumGreenBits = 563bf215546Sopenharmony_ci util_format_get_component_bits(visual->accum_format, 564bf215546Sopenharmony_ci UTIL_FORMAT_COLORSPACE_RGB, 1); 565bf215546Sopenharmony_ci mode->accumBlueBits = 566bf215546Sopenharmony_ci util_format_get_component_bits(visual->accum_format, 567bf215546Sopenharmony_ci UTIL_FORMAT_COLORSPACE_RGB, 2); 568bf215546Sopenharmony_ci mode->accumAlphaBits = 569bf215546Sopenharmony_ci util_format_get_component_bits(visual->accum_format, 570bf215546Sopenharmony_ci UTIL_FORMAT_COLORSPACE_RGB, 3); 571bf215546Sopenharmony_ci } 572bf215546Sopenharmony_ci 573bf215546Sopenharmony_ci if (visual->samples > 1) { 574bf215546Sopenharmony_ci mode->samples = visual->samples; 575bf215546Sopenharmony_ci } 576bf215546Sopenharmony_ci} 577bf215546Sopenharmony_ci 578bf215546Sopenharmony_ci 579bf215546Sopenharmony_ci/** 580bf215546Sopenharmony_ci * Create a framebuffer from a manager interface. 581bf215546Sopenharmony_ci */ 582bf215546Sopenharmony_cistatic struct gl_framebuffer * 583bf215546Sopenharmony_cist_framebuffer_create(struct st_context *st, 584bf215546Sopenharmony_ci struct st_framebuffer_iface *stfbi) 585bf215546Sopenharmony_ci{ 586bf215546Sopenharmony_ci struct gl_framebuffer *stfb; 587bf215546Sopenharmony_ci struct gl_config mode; 588bf215546Sopenharmony_ci gl_buffer_index idx; 589bf215546Sopenharmony_ci bool prefer_srgb = false; 590bf215546Sopenharmony_ci 591bf215546Sopenharmony_ci if (!stfbi) 592bf215546Sopenharmony_ci return NULL; 593bf215546Sopenharmony_ci 594bf215546Sopenharmony_ci stfb = CALLOC_STRUCT(gl_framebuffer); 595bf215546Sopenharmony_ci if (!stfb) 596bf215546Sopenharmony_ci return NULL; 597bf215546Sopenharmony_ci 598bf215546Sopenharmony_ci st_visual_to_context_mode(stfbi->visual, &mode); 599bf215546Sopenharmony_ci 600bf215546Sopenharmony_ci /* 601bf215546Sopenharmony_ci * For desktop GL, sRGB framebuffer write is controlled by both the 602bf215546Sopenharmony_ci * capability of the framebuffer and GL_FRAMEBUFFER_SRGB. We should 603bf215546Sopenharmony_ci * advertise the capability when the pipe driver (and core Mesa) supports 604bf215546Sopenharmony_ci * it so that applications can enable sRGB write when they want to. 605bf215546Sopenharmony_ci * 606bf215546Sopenharmony_ci * This is not to be confused with GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB. When 607bf215546Sopenharmony_ci * the attribute is GLX_TRUE, it tells the st manager to pick a color 608bf215546Sopenharmony_ci * format such that util_format_srgb(visual->color_format) can be supported 609bf215546Sopenharmony_ci * by the pipe driver. We still need to advertise the capability here. 610bf215546Sopenharmony_ci * 611bf215546Sopenharmony_ci * For GLES, however, sRGB framebuffer write is initially only controlled 612bf215546Sopenharmony_ci * by the capability of the framebuffer, with GL_EXT_sRGB_write_control 613bf215546Sopenharmony_ci * control is given back to the applications, but GL_FRAMEBUFFER_SRGB is 614bf215546Sopenharmony_ci * still enabled by default since this is the behaviour when 615bf215546Sopenharmony_ci * EXT_sRGB_write_control is not available. Since GL_EXT_sRGB_write_control 616bf215546Sopenharmony_ci * brings GLES on par with desktop GLs EXT_framebuffer_sRGB, in mesa this 617bf215546Sopenharmony_ci * is also expressed by using the same extension flag 618bf215546Sopenharmony_ci */ 619bf215546Sopenharmony_ci if (_mesa_has_EXT_framebuffer_sRGB(st->ctx)) { 620bf215546Sopenharmony_ci struct pipe_screen *screen = st->screen; 621bf215546Sopenharmony_ci const enum pipe_format srgb_format = 622bf215546Sopenharmony_ci util_format_srgb(stfbi->visual->color_format); 623bf215546Sopenharmony_ci 624bf215546Sopenharmony_ci if (srgb_format != PIPE_FORMAT_NONE && 625bf215546Sopenharmony_ci st_pipe_format_to_mesa_format(srgb_format) != MESA_FORMAT_NONE && 626bf215546Sopenharmony_ci screen->is_format_supported(screen, srgb_format, 627bf215546Sopenharmony_ci PIPE_TEXTURE_2D, stfbi->visual->samples, 628bf215546Sopenharmony_ci stfbi->visual->samples, 629bf215546Sopenharmony_ci (PIPE_BIND_DISPLAY_TARGET | 630bf215546Sopenharmony_ci PIPE_BIND_RENDER_TARGET))) { 631bf215546Sopenharmony_ci mode.sRGBCapable = GL_TRUE; 632bf215546Sopenharmony_ci /* Since GL_FRAMEBUFFER_SRGB is enabled by default on GLES we must not 633bf215546Sopenharmony_ci * create renderbuffers with an sRGB format derived from the 634bf215546Sopenharmony_ci * visual->color_format, but we still want sRGB for desktop GL. 635bf215546Sopenharmony_ci */ 636bf215546Sopenharmony_ci prefer_srgb = _mesa_is_desktop_gl(st->ctx); 637bf215546Sopenharmony_ci } 638bf215546Sopenharmony_ci } 639bf215546Sopenharmony_ci 640bf215546Sopenharmony_ci _mesa_initialize_window_framebuffer(stfb, &mode); 641bf215546Sopenharmony_ci 642bf215546Sopenharmony_ci stfb->iface = stfbi; 643bf215546Sopenharmony_ci stfb->iface_ID = stfbi->ID; 644bf215546Sopenharmony_ci stfb->iface_stamp = p_atomic_read(&stfbi->stamp) - 1; 645bf215546Sopenharmony_ci 646bf215546Sopenharmony_ci /* add the color buffer */ 647bf215546Sopenharmony_ci idx = stfb->_ColorDrawBufferIndexes[0]; 648bf215546Sopenharmony_ci if (!st_framebuffer_add_renderbuffer(stfb, idx, prefer_srgb)) { 649bf215546Sopenharmony_ci FREE(stfb); 650bf215546Sopenharmony_ci return NULL; 651bf215546Sopenharmony_ci } 652bf215546Sopenharmony_ci 653bf215546Sopenharmony_ci st_framebuffer_add_renderbuffer(stfb, BUFFER_DEPTH, false); 654bf215546Sopenharmony_ci st_framebuffer_add_renderbuffer(stfb, BUFFER_ACCUM, false); 655bf215546Sopenharmony_ci 656bf215546Sopenharmony_ci stfb->stamp = 0; 657bf215546Sopenharmony_ci st_framebuffer_update_attachments(stfb); 658bf215546Sopenharmony_ci 659bf215546Sopenharmony_ci return stfb; 660bf215546Sopenharmony_ci} 661bf215546Sopenharmony_ci 662bf215546Sopenharmony_ci 663bf215546Sopenharmony_cistatic uint32_t 664bf215546Sopenharmony_cist_framebuffer_iface_hash(const void *key) 665bf215546Sopenharmony_ci{ 666bf215546Sopenharmony_ci return (uintptr_t)key; 667bf215546Sopenharmony_ci} 668bf215546Sopenharmony_ci 669bf215546Sopenharmony_ci 670bf215546Sopenharmony_cistatic bool 671bf215546Sopenharmony_cist_framebuffer_iface_equal(const void *a, const void *b) 672bf215546Sopenharmony_ci{ 673bf215546Sopenharmony_ci return (struct st_framebuffer_iface *)a == (struct st_framebuffer_iface *)b; 674bf215546Sopenharmony_ci} 675bf215546Sopenharmony_ci 676bf215546Sopenharmony_ci 677bf215546Sopenharmony_cistatic bool 678bf215546Sopenharmony_cist_framebuffer_iface_lookup(struct st_manager *smapi, 679bf215546Sopenharmony_ci const struct st_framebuffer_iface *stfbi) 680bf215546Sopenharmony_ci{ 681bf215546Sopenharmony_ci struct st_manager_private *smPriv = 682bf215546Sopenharmony_ci (struct st_manager_private *)smapi->st_manager_private; 683bf215546Sopenharmony_ci struct hash_entry *entry; 684bf215546Sopenharmony_ci 685bf215546Sopenharmony_ci assert(smPriv); 686bf215546Sopenharmony_ci assert(smPriv->stfbi_ht); 687bf215546Sopenharmony_ci 688bf215546Sopenharmony_ci simple_mtx_lock(&smPriv->st_mutex); 689bf215546Sopenharmony_ci entry = _mesa_hash_table_search(smPriv->stfbi_ht, stfbi); 690bf215546Sopenharmony_ci simple_mtx_unlock(&smPriv->st_mutex); 691bf215546Sopenharmony_ci 692bf215546Sopenharmony_ci return entry != NULL; 693bf215546Sopenharmony_ci} 694bf215546Sopenharmony_ci 695bf215546Sopenharmony_ci 696bf215546Sopenharmony_cistatic bool 697bf215546Sopenharmony_cist_framebuffer_iface_insert(struct st_manager *smapi, 698bf215546Sopenharmony_ci struct st_framebuffer_iface *stfbi) 699bf215546Sopenharmony_ci{ 700bf215546Sopenharmony_ci struct st_manager_private *smPriv = 701bf215546Sopenharmony_ci (struct st_manager_private *)smapi->st_manager_private; 702bf215546Sopenharmony_ci struct hash_entry *entry; 703bf215546Sopenharmony_ci 704bf215546Sopenharmony_ci assert(smPriv); 705bf215546Sopenharmony_ci assert(smPriv->stfbi_ht); 706bf215546Sopenharmony_ci 707bf215546Sopenharmony_ci simple_mtx_lock(&smPriv->st_mutex); 708bf215546Sopenharmony_ci entry = _mesa_hash_table_insert(smPriv->stfbi_ht, stfbi, stfbi); 709bf215546Sopenharmony_ci simple_mtx_unlock(&smPriv->st_mutex); 710bf215546Sopenharmony_ci 711bf215546Sopenharmony_ci return entry != NULL; 712bf215546Sopenharmony_ci} 713bf215546Sopenharmony_ci 714bf215546Sopenharmony_ci 715bf215546Sopenharmony_cistatic void 716bf215546Sopenharmony_cist_framebuffer_iface_remove(struct st_manager *smapi, 717bf215546Sopenharmony_ci struct st_framebuffer_iface *stfbi) 718bf215546Sopenharmony_ci{ 719bf215546Sopenharmony_ci struct st_manager_private *smPriv = 720bf215546Sopenharmony_ci (struct st_manager_private *)smapi->st_manager_private; 721bf215546Sopenharmony_ci struct hash_entry *entry; 722bf215546Sopenharmony_ci 723bf215546Sopenharmony_ci if (!smPriv || !smPriv->stfbi_ht) 724bf215546Sopenharmony_ci return; 725bf215546Sopenharmony_ci 726bf215546Sopenharmony_ci simple_mtx_lock(&smPriv->st_mutex); 727bf215546Sopenharmony_ci entry = _mesa_hash_table_search(smPriv->stfbi_ht, stfbi); 728bf215546Sopenharmony_ci if (!entry) 729bf215546Sopenharmony_ci goto unlock; 730bf215546Sopenharmony_ci 731bf215546Sopenharmony_ci _mesa_hash_table_remove(smPriv->stfbi_ht, entry); 732bf215546Sopenharmony_ci 733bf215546Sopenharmony_ciunlock: 734bf215546Sopenharmony_ci simple_mtx_unlock(&smPriv->st_mutex); 735bf215546Sopenharmony_ci} 736bf215546Sopenharmony_ci 737bf215546Sopenharmony_ci 738bf215546Sopenharmony_ci/** 739bf215546Sopenharmony_ci * The framebuffer interface object is no longer valid. 740bf215546Sopenharmony_ci * Remove the object from the framebuffer interface hash table. 741bf215546Sopenharmony_ci */ 742bf215546Sopenharmony_cistatic void 743bf215546Sopenharmony_cist_api_destroy_drawable(struct st_api *stapi, 744bf215546Sopenharmony_ci struct st_framebuffer_iface *stfbi) 745bf215546Sopenharmony_ci{ 746bf215546Sopenharmony_ci if (!stfbi) 747bf215546Sopenharmony_ci return; 748bf215546Sopenharmony_ci 749bf215546Sopenharmony_ci st_framebuffer_iface_remove(stfbi->state_manager, stfbi); 750bf215546Sopenharmony_ci} 751bf215546Sopenharmony_ci 752bf215546Sopenharmony_ci 753bf215546Sopenharmony_ci/** 754bf215546Sopenharmony_ci * Purge the winsys buffers list to remove any references to 755bf215546Sopenharmony_ci * non-existing framebuffer interface objects. 756bf215546Sopenharmony_ci */ 757bf215546Sopenharmony_cistatic void 758bf215546Sopenharmony_cist_framebuffers_purge(struct st_context *st) 759bf215546Sopenharmony_ci{ 760bf215546Sopenharmony_ci struct st_context_iface *st_iface = &st->iface; 761bf215546Sopenharmony_ci struct st_manager *smapi = st_iface->state_manager; 762bf215546Sopenharmony_ci struct gl_framebuffer *stfb, *next; 763bf215546Sopenharmony_ci 764bf215546Sopenharmony_ci assert(smapi); 765bf215546Sopenharmony_ci 766bf215546Sopenharmony_ci LIST_FOR_EACH_ENTRY_SAFE_REV(stfb, next, &st->winsys_buffers, head) { 767bf215546Sopenharmony_ci struct st_framebuffer_iface *stfbi = stfb->iface; 768bf215546Sopenharmony_ci 769bf215546Sopenharmony_ci assert(stfbi); 770bf215546Sopenharmony_ci 771bf215546Sopenharmony_ci /** 772bf215546Sopenharmony_ci * If the corresponding framebuffer interface object no longer exists, 773bf215546Sopenharmony_ci * remove the framebuffer object from the context's winsys buffers list, 774bf215546Sopenharmony_ci * and unreference the framebuffer object, so its resources can be 775bf215546Sopenharmony_ci * deleted. 776bf215546Sopenharmony_ci */ 777bf215546Sopenharmony_ci if (!st_framebuffer_iface_lookup(smapi, stfbi)) { 778bf215546Sopenharmony_ci list_del(&stfb->head); 779bf215546Sopenharmony_ci _mesa_reference_framebuffer(&stfb, NULL); 780bf215546Sopenharmony_ci } 781bf215546Sopenharmony_ci } 782bf215546Sopenharmony_ci} 783bf215546Sopenharmony_ci 784bf215546Sopenharmony_ci 785bf215546Sopenharmony_cistatic void 786bf215546Sopenharmony_cist_context_flush(struct st_context_iface *stctxi, unsigned flags, 787bf215546Sopenharmony_ci struct pipe_fence_handle **fence, 788bf215546Sopenharmony_ci void (*before_flush_cb) (void*), 789bf215546Sopenharmony_ci void* args) 790bf215546Sopenharmony_ci{ 791bf215546Sopenharmony_ci struct st_context *st = (struct st_context *) stctxi; 792bf215546Sopenharmony_ci unsigned pipe_flags = 0; 793bf215546Sopenharmony_ci 794bf215546Sopenharmony_ci if (flags & ST_FLUSH_END_OF_FRAME) 795bf215546Sopenharmony_ci pipe_flags |= PIPE_FLUSH_END_OF_FRAME; 796bf215546Sopenharmony_ci if (flags & ST_FLUSH_FENCE_FD) 797bf215546Sopenharmony_ci pipe_flags |= PIPE_FLUSH_FENCE_FD; 798bf215546Sopenharmony_ci 799bf215546Sopenharmony_ci /* We can do these in any order because FLUSH_VERTICES will also flush 800bf215546Sopenharmony_ci * the bitmap cache if there are any unflushed vertices. 801bf215546Sopenharmony_ci */ 802bf215546Sopenharmony_ci st_flush_bitmap_cache(st); 803bf215546Sopenharmony_ci FLUSH_VERTICES(st->ctx, 0, 0); 804bf215546Sopenharmony_ci 805bf215546Sopenharmony_ci /* Notify the caller that we're ready to flush */ 806bf215546Sopenharmony_ci if (before_flush_cb) 807bf215546Sopenharmony_ci before_flush_cb(args); 808bf215546Sopenharmony_ci st_flush(st, fence, pipe_flags); 809bf215546Sopenharmony_ci 810bf215546Sopenharmony_ci if ((flags & ST_FLUSH_WAIT) && fence && *fence) { 811bf215546Sopenharmony_ci st->screen->fence_finish(st->screen, NULL, *fence, 812bf215546Sopenharmony_ci PIPE_TIMEOUT_INFINITE); 813bf215546Sopenharmony_ci st->screen->fence_reference(st->screen, fence, NULL); 814bf215546Sopenharmony_ci } 815bf215546Sopenharmony_ci 816bf215546Sopenharmony_ci if (flags & ST_FLUSH_FRONT) 817bf215546Sopenharmony_ci st_manager_flush_frontbuffer(st); 818bf215546Sopenharmony_ci 819bf215546Sopenharmony_ci /* DRI3 changes the framebuffer after SwapBuffers, but we need to invoke 820bf215546Sopenharmony_ci * st_manager_validate_framebuffers to notice that. 821bf215546Sopenharmony_ci * 822bf215546Sopenharmony_ci * Set gfx_shaders_may_be_dirty to invoke st_validate_state in the next 823bf215546Sopenharmony_ci * draw call, which will invoke st_manager_validate_framebuffers, but it 824bf215546Sopenharmony_ci * won't dirty states if there is no change. 825bf215546Sopenharmony_ci */ 826bf215546Sopenharmony_ci if (flags & ST_FLUSH_END_OF_FRAME) 827bf215546Sopenharmony_ci st->gfx_shaders_may_be_dirty = true; 828bf215546Sopenharmony_ci} 829bf215546Sopenharmony_ci 830bf215546Sopenharmony_cistatic bool 831bf215546Sopenharmony_cist_context_teximage(struct st_context_iface *stctxi, 832bf215546Sopenharmony_ci enum st_texture_type tex_type, 833bf215546Sopenharmony_ci int level, enum pipe_format pipe_format, 834bf215546Sopenharmony_ci struct pipe_resource *tex, bool mipmap) 835bf215546Sopenharmony_ci{ 836bf215546Sopenharmony_ci struct st_context *st = (struct st_context *) stctxi; 837bf215546Sopenharmony_ci struct gl_context *ctx = st->ctx; 838bf215546Sopenharmony_ci struct gl_texture_object *texObj; 839bf215546Sopenharmony_ci struct gl_texture_image *texImage; 840bf215546Sopenharmony_ci GLenum internalFormat; 841bf215546Sopenharmony_ci GLuint width, height, depth; 842bf215546Sopenharmony_ci GLenum target; 843bf215546Sopenharmony_ci 844bf215546Sopenharmony_ci switch (tex_type) { 845bf215546Sopenharmony_ci case ST_TEXTURE_1D: 846bf215546Sopenharmony_ci target = GL_TEXTURE_1D; 847bf215546Sopenharmony_ci break; 848bf215546Sopenharmony_ci case ST_TEXTURE_2D: 849bf215546Sopenharmony_ci target = GL_TEXTURE_2D; 850bf215546Sopenharmony_ci break; 851bf215546Sopenharmony_ci case ST_TEXTURE_3D: 852bf215546Sopenharmony_ci target = GL_TEXTURE_3D; 853bf215546Sopenharmony_ci break; 854bf215546Sopenharmony_ci case ST_TEXTURE_RECT: 855bf215546Sopenharmony_ci target = GL_TEXTURE_RECTANGLE_ARB; 856bf215546Sopenharmony_ci break; 857bf215546Sopenharmony_ci default: 858bf215546Sopenharmony_ci return FALSE; 859bf215546Sopenharmony_ci } 860bf215546Sopenharmony_ci 861bf215546Sopenharmony_ci texObj = _mesa_get_current_tex_object(ctx, target); 862bf215546Sopenharmony_ci 863bf215546Sopenharmony_ci _mesa_lock_texture(ctx, texObj); 864bf215546Sopenharmony_ci 865bf215546Sopenharmony_ci /* switch to surface based */ 866bf215546Sopenharmony_ci if (!texObj->surface_based) { 867bf215546Sopenharmony_ci _mesa_clear_texture_object(ctx, texObj, NULL); 868bf215546Sopenharmony_ci texObj->surface_based = GL_TRUE; 869bf215546Sopenharmony_ci } 870bf215546Sopenharmony_ci 871bf215546Sopenharmony_ci texImage = _mesa_get_tex_image(ctx, texObj, target, level); 872bf215546Sopenharmony_ci if (tex) { 873bf215546Sopenharmony_ci mesa_format texFormat = st_pipe_format_to_mesa_format(pipe_format); 874bf215546Sopenharmony_ci 875bf215546Sopenharmony_ci if (util_format_has_alpha(tex->format)) 876bf215546Sopenharmony_ci internalFormat = GL_RGBA; 877bf215546Sopenharmony_ci else 878bf215546Sopenharmony_ci internalFormat = GL_RGB; 879bf215546Sopenharmony_ci 880bf215546Sopenharmony_ci _mesa_init_teximage_fields(ctx, texImage, 881bf215546Sopenharmony_ci tex->width0, tex->height0, 1, 0, 882bf215546Sopenharmony_ci internalFormat, texFormat); 883bf215546Sopenharmony_ci 884bf215546Sopenharmony_ci width = tex->width0; 885bf215546Sopenharmony_ci height = tex->height0; 886bf215546Sopenharmony_ci depth = tex->depth0; 887bf215546Sopenharmony_ci 888bf215546Sopenharmony_ci /* grow the image size until we hit level = 0 */ 889bf215546Sopenharmony_ci while (level > 0) { 890bf215546Sopenharmony_ci if (width != 1) 891bf215546Sopenharmony_ci width <<= 1; 892bf215546Sopenharmony_ci if (height != 1) 893bf215546Sopenharmony_ci height <<= 1; 894bf215546Sopenharmony_ci if (depth != 1) 895bf215546Sopenharmony_ci depth <<= 1; 896bf215546Sopenharmony_ci level--; 897bf215546Sopenharmony_ci } 898bf215546Sopenharmony_ci } 899bf215546Sopenharmony_ci else { 900bf215546Sopenharmony_ci _mesa_clear_texture_image(ctx, texImage); 901bf215546Sopenharmony_ci width = height = depth = 0; 902bf215546Sopenharmony_ci } 903bf215546Sopenharmony_ci 904bf215546Sopenharmony_ci pipe_resource_reference(&texObj->pt, tex); 905bf215546Sopenharmony_ci st_texture_release_all_sampler_views(st, texObj); 906bf215546Sopenharmony_ci pipe_resource_reference(&texImage->pt, tex); 907bf215546Sopenharmony_ci texObj->surface_format = pipe_format; 908bf215546Sopenharmony_ci 909bf215546Sopenharmony_ci texObj->needs_validation = true; 910bf215546Sopenharmony_ci 911bf215546Sopenharmony_ci _mesa_dirty_texobj(ctx, texObj); 912bf215546Sopenharmony_ci _mesa_unlock_texture(ctx, texObj); 913bf215546Sopenharmony_ci 914bf215546Sopenharmony_ci return true; 915bf215546Sopenharmony_ci} 916bf215546Sopenharmony_ci 917bf215546Sopenharmony_ci 918bf215546Sopenharmony_cistatic void 919bf215546Sopenharmony_cist_context_copy(struct st_context_iface *stctxi, 920bf215546Sopenharmony_ci struct st_context_iface *stsrci, unsigned mask) 921bf215546Sopenharmony_ci{ 922bf215546Sopenharmony_ci struct st_context *st = (struct st_context *) stctxi; 923bf215546Sopenharmony_ci struct st_context *src = (struct st_context *) stsrci; 924bf215546Sopenharmony_ci 925bf215546Sopenharmony_ci _mesa_copy_context(src->ctx, st->ctx, mask); 926bf215546Sopenharmony_ci} 927bf215546Sopenharmony_ci 928bf215546Sopenharmony_ci 929bf215546Sopenharmony_cistatic bool 930bf215546Sopenharmony_cist_context_share(struct st_context_iface *stctxi, 931bf215546Sopenharmony_ci struct st_context_iface *stsrci) 932bf215546Sopenharmony_ci{ 933bf215546Sopenharmony_ci struct st_context *st = (struct st_context *) stctxi; 934bf215546Sopenharmony_ci struct st_context *src = (struct st_context *) stsrci; 935bf215546Sopenharmony_ci 936bf215546Sopenharmony_ci return _mesa_share_state(st->ctx, src->ctx); 937bf215546Sopenharmony_ci} 938bf215546Sopenharmony_ci 939bf215546Sopenharmony_ci 940bf215546Sopenharmony_cistatic void 941bf215546Sopenharmony_cist_context_destroy(struct st_context_iface *stctxi) 942bf215546Sopenharmony_ci{ 943bf215546Sopenharmony_ci struct st_context *st = (struct st_context *) stctxi; 944bf215546Sopenharmony_ci st_destroy_context(st); 945bf215546Sopenharmony_ci} 946bf215546Sopenharmony_ci 947bf215546Sopenharmony_ci 948bf215546Sopenharmony_cistatic void 949bf215546Sopenharmony_cist_start_thread(struct st_context_iface *stctxi) 950bf215546Sopenharmony_ci{ 951bf215546Sopenharmony_ci struct st_context *st = (struct st_context *) stctxi; 952bf215546Sopenharmony_ci 953bf215546Sopenharmony_ci _mesa_glthread_init(st->ctx); 954bf215546Sopenharmony_ci} 955bf215546Sopenharmony_ci 956bf215546Sopenharmony_ci 957bf215546Sopenharmony_cistatic void 958bf215546Sopenharmony_cist_thread_finish(struct st_context_iface *stctxi) 959bf215546Sopenharmony_ci{ 960bf215546Sopenharmony_ci struct st_context *st = (struct st_context *) stctxi; 961bf215546Sopenharmony_ci 962bf215546Sopenharmony_ci _mesa_glthread_finish(st->ctx); 963bf215546Sopenharmony_ci} 964bf215546Sopenharmony_ci 965bf215546Sopenharmony_ci 966bf215546Sopenharmony_cistatic void 967bf215546Sopenharmony_cist_context_invalidate_state(struct st_context_iface *stctxi, 968bf215546Sopenharmony_ci unsigned flags) 969bf215546Sopenharmony_ci{ 970bf215546Sopenharmony_ci struct st_context *st = (struct st_context *) stctxi; 971bf215546Sopenharmony_ci 972bf215546Sopenharmony_ci if (flags & ST_INVALIDATE_FS_SAMPLER_VIEWS) 973bf215546Sopenharmony_ci st->dirty |= ST_NEW_FS_SAMPLER_VIEWS; 974bf215546Sopenharmony_ci if (flags & ST_INVALIDATE_FS_CONSTBUF0) 975bf215546Sopenharmony_ci st->dirty |= ST_NEW_FS_CONSTANTS; 976bf215546Sopenharmony_ci if (flags & ST_INVALIDATE_VS_CONSTBUF0) 977bf215546Sopenharmony_ci st->dirty |= ST_NEW_VS_CONSTANTS; 978bf215546Sopenharmony_ci if (flags & ST_INVALIDATE_VERTEX_BUFFERS) { 979bf215546Sopenharmony_ci st->ctx->Array.NewVertexElements = true; 980bf215546Sopenharmony_ci st->dirty |= ST_NEW_VERTEX_ARRAYS; 981bf215546Sopenharmony_ci } 982bf215546Sopenharmony_ci} 983bf215546Sopenharmony_ci 984bf215546Sopenharmony_ci 985bf215546Sopenharmony_cistatic void 986bf215546Sopenharmony_cist_manager_destroy(struct st_manager *smapi) 987bf215546Sopenharmony_ci{ 988bf215546Sopenharmony_ci struct st_manager_private *smPriv = smapi->st_manager_private; 989bf215546Sopenharmony_ci 990bf215546Sopenharmony_ci if (smPriv && smPriv->stfbi_ht) { 991bf215546Sopenharmony_ci _mesa_hash_table_destroy(smPriv->stfbi_ht, NULL); 992bf215546Sopenharmony_ci simple_mtx_destroy(&smPriv->st_mutex); 993bf215546Sopenharmony_ci FREE(smPriv); 994bf215546Sopenharmony_ci smapi->st_manager_private = NULL; 995bf215546Sopenharmony_ci } 996bf215546Sopenharmony_ci} 997bf215546Sopenharmony_ci 998bf215546Sopenharmony_ci 999bf215546Sopenharmony_cistatic struct st_context_iface * 1000bf215546Sopenharmony_cist_api_create_context(struct st_api *stapi, struct st_manager *smapi, 1001bf215546Sopenharmony_ci const struct st_context_attribs *attribs, 1002bf215546Sopenharmony_ci enum st_context_error *error, 1003bf215546Sopenharmony_ci struct st_context_iface *shared_stctxi) 1004bf215546Sopenharmony_ci{ 1005bf215546Sopenharmony_ci struct st_context *shared_ctx = (struct st_context *) shared_stctxi; 1006bf215546Sopenharmony_ci struct st_context *st; 1007bf215546Sopenharmony_ci struct pipe_context *pipe; 1008bf215546Sopenharmony_ci struct gl_config mode, *mode_ptr = &mode; 1009bf215546Sopenharmony_ci gl_api api; 1010bf215546Sopenharmony_ci bool no_error = false; 1011bf215546Sopenharmony_ci unsigned ctx_flags = PIPE_CONTEXT_PREFER_THREADED; 1012bf215546Sopenharmony_ci 1013bf215546Sopenharmony_ci if (!(stapi->profile_mask & (1 << attribs->profile))) 1014bf215546Sopenharmony_ci return NULL; 1015bf215546Sopenharmony_ci 1016bf215546Sopenharmony_ci switch (attribs->profile) { 1017bf215546Sopenharmony_ci case ST_PROFILE_DEFAULT: 1018bf215546Sopenharmony_ci api = API_OPENGL_COMPAT; 1019bf215546Sopenharmony_ci break; 1020bf215546Sopenharmony_ci case ST_PROFILE_OPENGL_ES1: 1021bf215546Sopenharmony_ci api = API_OPENGLES; 1022bf215546Sopenharmony_ci break; 1023bf215546Sopenharmony_ci case ST_PROFILE_OPENGL_ES2: 1024bf215546Sopenharmony_ci api = API_OPENGLES2; 1025bf215546Sopenharmony_ci break; 1026bf215546Sopenharmony_ci case ST_PROFILE_OPENGL_CORE: 1027bf215546Sopenharmony_ci api = API_OPENGL_CORE; 1028bf215546Sopenharmony_ci break; 1029bf215546Sopenharmony_ci default: 1030bf215546Sopenharmony_ci *error = ST_CONTEXT_ERROR_BAD_API; 1031bf215546Sopenharmony_ci return NULL; 1032bf215546Sopenharmony_ci } 1033bf215546Sopenharmony_ci 1034bf215546Sopenharmony_ci _mesa_initialize(attribs->options.mesa_extension_override); 1035bf215546Sopenharmony_ci 1036bf215546Sopenharmony_ci /* Create a hash table for the framebuffer interface objects 1037bf215546Sopenharmony_ci * if it has not been created for this st manager. 1038bf215546Sopenharmony_ci */ 1039bf215546Sopenharmony_ci if (smapi->st_manager_private == NULL) { 1040bf215546Sopenharmony_ci struct st_manager_private *smPriv; 1041bf215546Sopenharmony_ci 1042bf215546Sopenharmony_ci smPriv = CALLOC_STRUCT(st_manager_private); 1043bf215546Sopenharmony_ci simple_mtx_init(&smPriv->st_mutex, mtx_plain); 1044bf215546Sopenharmony_ci smPriv->stfbi_ht = _mesa_hash_table_create(NULL, 1045bf215546Sopenharmony_ci st_framebuffer_iface_hash, 1046bf215546Sopenharmony_ci st_framebuffer_iface_equal); 1047bf215546Sopenharmony_ci smapi->st_manager_private = smPriv; 1048bf215546Sopenharmony_ci smapi->destroy = st_manager_destroy; 1049bf215546Sopenharmony_ci } 1050bf215546Sopenharmony_ci 1051bf215546Sopenharmony_ci if (attribs->flags & ST_CONTEXT_FLAG_ROBUST_ACCESS) 1052bf215546Sopenharmony_ci ctx_flags |= PIPE_CONTEXT_ROBUST_BUFFER_ACCESS; 1053bf215546Sopenharmony_ci 1054bf215546Sopenharmony_ci if (attribs->flags & ST_CONTEXT_FLAG_NO_ERROR) 1055bf215546Sopenharmony_ci no_error = true; 1056bf215546Sopenharmony_ci 1057bf215546Sopenharmony_ci if (attribs->flags & ST_CONTEXT_FLAG_LOW_PRIORITY) 1058bf215546Sopenharmony_ci ctx_flags |= PIPE_CONTEXT_LOW_PRIORITY; 1059bf215546Sopenharmony_ci else if (attribs->flags & ST_CONTEXT_FLAG_HIGH_PRIORITY) 1060bf215546Sopenharmony_ci ctx_flags |= PIPE_CONTEXT_HIGH_PRIORITY; 1061bf215546Sopenharmony_ci 1062bf215546Sopenharmony_ci if (attribs->flags & ST_CONTEXT_FLAG_RESET_NOTIFICATION_ENABLED) 1063bf215546Sopenharmony_ci ctx_flags |= PIPE_CONTEXT_LOSE_CONTEXT_ON_RESET; 1064bf215546Sopenharmony_ci 1065bf215546Sopenharmony_ci pipe = smapi->screen->context_create(smapi->screen, NULL, ctx_flags); 1066bf215546Sopenharmony_ci if (!pipe) { 1067bf215546Sopenharmony_ci *error = ST_CONTEXT_ERROR_NO_MEMORY; 1068bf215546Sopenharmony_ci return NULL; 1069bf215546Sopenharmony_ci } 1070bf215546Sopenharmony_ci 1071bf215546Sopenharmony_ci st_visual_to_context_mode(&attribs->visual, &mode); 1072bf215546Sopenharmony_ci if (attribs->visual.color_format == PIPE_FORMAT_NONE) 1073bf215546Sopenharmony_ci mode_ptr = NULL; 1074bf215546Sopenharmony_ci st = st_create_context(api, pipe, mode_ptr, shared_ctx, 1075bf215546Sopenharmony_ci &attribs->options, no_error, 1076bf215546Sopenharmony_ci !!smapi->validate_egl_image); 1077bf215546Sopenharmony_ci if (!st) { 1078bf215546Sopenharmony_ci *error = ST_CONTEXT_ERROR_NO_MEMORY; 1079bf215546Sopenharmony_ci pipe->destroy(pipe); 1080bf215546Sopenharmony_ci return NULL; 1081bf215546Sopenharmony_ci } 1082bf215546Sopenharmony_ci 1083bf215546Sopenharmony_ci if (attribs->flags & ST_CONTEXT_FLAG_DEBUG) { 1084bf215546Sopenharmony_ci if (!_mesa_set_debug_state_int(st->ctx, GL_DEBUG_OUTPUT, GL_TRUE)) { 1085bf215546Sopenharmony_ci *error = ST_CONTEXT_ERROR_NO_MEMORY; 1086bf215546Sopenharmony_ci return NULL; 1087bf215546Sopenharmony_ci } 1088bf215546Sopenharmony_ci 1089bf215546Sopenharmony_ci st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT; 1090bf215546Sopenharmony_ci } 1091bf215546Sopenharmony_ci 1092bf215546Sopenharmony_ci if (st->ctx->Const.ContextFlags & GL_CONTEXT_FLAG_DEBUG_BIT) { 1093bf215546Sopenharmony_ci _mesa_update_debug_callback(st->ctx); 1094bf215546Sopenharmony_ci } 1095bf215546Sopenharmony_ci 1096bf215546Sopenharmony_ci if (attribs->flags & ST_CONTEXT_FLAG_FORWARD_COMPATIBLE) 1097bf215546Sopenharmony_ci st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT; 1098bf215546Sopenharmony_ci if (attribs->flags & ST_CONTEXT_FLAG_ROBUST_ACCESS) { 1099bf215546Sopenharmony_ci st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB; 1100bf215546Sopenharmony_ci st->ctx->Const.RobustAccess = GL_TRUE; 1101bf215546Sopenharmony_ci } 1102bf215546Sopenharmony_ci if (attribs->flags & ST_CONTEXT_FLAG_RESET_NOTIFICATION_ENABLED) { 1103bf215546Sopenharmony_ci st->ctx->Const.ResetStrategy = GL_LOSE_CONTEXT_ON_RESET_ARB; 1104bf215546Sopenharmony_ci st_install_device_reset_callback(st); 1105bf215546Sopenharmony_ci } 1106bf215546Sopenharmony_ci 1107bf215546Sopenharmony_ci if (attribs->flags & ST_CONTEXT_FLAG_RELEASE_NONE) 1108bf215546Sopenharmony_ci st->ctx->Const.ContextReleaseBehavior = GL_NONE; 1109bf215546Sopenharmony_ci 1110bf215546Sopenharmony_ci /* need to perform version check */ 1111bf215546Sopenharmony_ci if (attribs->major > 1 || attribs->minor > 0) { 1112bf215546Sopenharmony_ci /* Is the actual version less than the requested version? 1113bf215546Sopenharmony_ci */ 1114bf215546Sopenharmony_ci if (st->ctx->Version < attribs->major * 10U + attribs->minor) { 1115bf215546Sopenharmony_ci *error = ST_CONTEXT_ERROR_BAD_VERSION; 1116bf215546Sopenharmony_ci st_destroy_context(st); 1117bf215546Sopenharmony_ci return NULL; 1118bf215546Sopenharmony_ci } 1119bf215546Sopenharmony_ci } 1120bf215546Sopenharmony_ci 1121bf215546Sopenharmony_ci st->can_scissor_clear = !!st->screen->get_param(st->screen, PIPE_CAP_CLEAR_SCISSORED); 1122bf215546Sopenharmony_ci 1123bf215546Sopenharmony_ci st->ctx->invalidate_on_gl_viewport = 1124bf215546Sopenharmony_ci smapi->get_param(smapi, ST_MANAGER_BROKEN_INVALIDATE); 1125bf215546Sopenharmony_ci 1126bf215546Sopenharmony_ci st->iface.destroy = st_context_destroy; 1127bf215546Sopenharmony_ci st->iface.flush = st_context_flush; 1128bf215546Sopenharmony_ci st->iface.teximage = st_context_teximage; 1129bf215546Sopenharmony_ci st->iface.copy = st_context_copy; 1130bf215546Sopenharmony_ci st->iface.share = st_context_share; 1131bf215546Sopenharmony_ci st->iface.start_thread = st_start_thread; 1132bf215546Sopenharmony_ci st->iface.thread_finish = st_thread_finish; 1133bf215546Sopenharmony_ci st->iface.invalidate_state = st_context_invalidate_state; 1134bf215546Sopenharmony_ci st->iface.st_context_private = (void *) smapi; 1135bf215546Sopenharmony_ci st->iface.cso_context = st->cso_context; 1136bf215546Sopenharmony_ci st->iface.pipe = st->pipe; 1137bf215546Sopenharmony_ci st->iface.state_manager = smapi; 1138bf215546Sopenharmony_ci 1139bf215546Sopenharmony_ci if (st->ctx->IntelBlackholeRender && 1140bf215546Sopenharmony_ci st->screen->get_param(st->screen, PIPE_CAP_FRONTEND_NOOP)) 1141bf215546Sopenharmony_ci st->pipe->set_frontend_noop(st->pipe, st->ctx->IntelBlackholeRender); 1142bf215546Sopenharmony_ci 1143bf215546Sopenharmony_ci *error = ST_CONTEXT_SUCCESS; 1144bf215546Sopenharmony_ci return &st->iface; 1145bf215546Sopenharmony_ci} 1146bf215546Sopenharmony_ci 1147bf215546Sopenharmony_ci 1148bf215546Sopenharmony_cistatic struct st_context_iface * 1149bf215546Sopenharmony_cist_api_get_current(struct st_api *stapi) 1150bf215546Sopenharmony_ci{ 1151bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 1152bf215546Sopenharmony_ci struct st_context *st = ctx ? ctx->st : NULL; 1153bf215546Sopenharmony_ci 1154bf215546Sopenharmony_ci return st ? &st->iface : NULL; 1155bf215546Sopenharmony_ci} 1156bf215546Sopenharmony_ci 1157bf215546Sopenharmony_ci 1158bf215546Sopenharmony_cistatic struct gl_framebuffer * 1159bf215546Sopenharmony_cist_framebuffer_reuse_or_create(struct st_context *st, 1160bf215546Sopenharmony_ci struct gl_framebuffer *fb, 1161bf215546Sopenharmony_ci struct st_framebuffer_iface *stfbi) 1162bf215546Sopenharmony_ci{ 1163bf215546Sopenharmony_ci struct gl_framebuffer *cur = NULL, *stfb = NULL; 1164bf215546Sopenharmony_ci 1165bf215546Sopenharmony_ci if (!stfbi) 1166bf215546Sopenharmony_ci return NULL; 1167bf215546Sopenharmony_ci 1168bf215546Sopenharmony_ci /* Check if there is already a framebuffer object for the specified 1169bf215546Sopenharmony_ci * framebuffer interface in this context. If there is one, use it. 1170bf215546Sopenharmony_ci */ 1171bf215546Sopenharmony_ci LIST_FOR_EACH_ENTRY(cur, &st->winsys_buffers, head) { 1172bf215546Sopenharmony_ci if (cur->iface_ID == stfbi->ID) { 1173bf215546Sopenharmony_ci _mesa_reference_framebuffer(&stfb, cur); 1174bf215546Sopenharmony_ci break; 1175bf215546Sopenharmony_ci } 1176bf215546Sopenharmony_ci } 1177bf215546Sopenharmony_ci 1178bf215546Sopenharmony_ci /* If there is not already a framebuffer object, create one */ 1179bf215546Sopenharmony_ci if (stfb == NULL) { 1180bf215546Sopenharmony_ci cur = st_framebuffer_create(st, stfbi); 1181bf215546Sopenharmony_ci 1182bf215546Sopenharmony_ci if (cur) { 1183bf215546Sopenharmony_ci /* add the referenced framebuffer interface object to 1184bf215546Sopenharmony_ci * the framebuffer interface object hash table. 1185bf215546Sopenharmony_ci */ 1186bf215546Sopenharmony_ci if (!st_framebuffer_iface_insert(stfbi->state_manager, stfbi)) { 1187bf215546Sopenharmony_ci _mesa_reference_framebuffer(&cur, NULL); 1188bf215546Sopenharmony_ci return NULL; 1189bf215546Sopenharmony_ci } 1190bf215546Sopenharmony_ci 1191bf215546Sopenharmony_ci /* add to the context's winsys buffers list */ 1192bf215546Sopenharmony_ci list_add(&cur->head, &st->winsys_buffers); 1193bf215546Sopenharmony_ci 1194bf215546Sopenharmony_ci _mesa_reference_framebuffer(&stfb, cur); 1195bf215546Sopenharmony_ci } 1196bf215546Sopenharmony_ci } 1197bf215546Sopenharmony_ci 1198bf215546Sopenharmony_ci return stfb; 1199bf215546Sopenharmony_ci} 1200bf215546Sopenharmony_ci 1201bf215546Sopenharmony_ci 1202bf215546Sopenharmony_cistatic bool 1203bf215546Sopenharmony_cist_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi, 1204bf215546Sopenharmony_ci struct st_framebuffer_iface *stdrawi, 1205bf215546Sopenharmony_ci struct st_framebuffer_iface *streadi) 1206bf215546Sopenharmony_ci{ 1207bf215546Sopenharmony_ci struct st_context *st = (struct st_context *) stctxi; 1208bf215546Sopenharmony_ci struct gl_framebuffer *stdraw, *stread; 1209bf215546Sopenharmony_ci bool ret; 1210bf215546Sopenharmony_ci 1211bf215546Sopenharmony_ci if (st) { 1212bf215546Sopenharmony_ci /* reuse or create the draw fb */ 1213bf215546Sopenharmony_ci stdraw = st_framebuffer_reuse_or_create(st, 1214bf215546Sopenharmony_ci st->ctx->WinSysDrawBuffer, stdrawi); 1215bf215546Sopenharmony_ci if (streadi != stdrawi) { 1216bf215546Sopenharmony_ci /* do the same for the read fb */ 1217bf215546Sopenharmony_ci stread = st_framebuffer_reuse_or_create(st, 1218bf215546Sopenharmony_ci st->ctx->WinSysReadBuffer, streadi); 1219bf215546Sopenharmony_ci } 1220bf215546Sopenharmony_ci else { 1221bf215546Sopenharmony_ci stread = NULL; 1222bf215546Sopenharmony_ci /* reuse the draw fb for the read fb */ 1223bf215546Sopenharmony_ci if (stdraw) 1224bf215546Sopenharmony_ci _mesa_reference_framebuffer(&stread, stdraw); 1225bf215546Sopenharmony_ci } 1226bf215546Sopenharmony_ci 1227bf215546Sopenharmony_ci /* If framebuffers were asked for, we'd better have allocated them */ 1228bf215546Sopenharmony_ci if ((stdrawi && !stdraw) || (streadi && !stread)) 1229bf215546Sopenharmony_ci return false; 1230bf215546Sopenharmony_ci 1231bf215546Sopenharmony_ci if (stdraw && stread) { 1232bf215546Sopenharmony_ci st_framebuffer_validate(stdraw, st); 1233bf215546Sopenharmony_ci if (stread != stdraw) 1234bf215546Sopenharmony_ci st_framebuffer_validate(stread, st); 1235bf215546Sopenharmony_ci 1236bf215546Sopenharmony_ci ret = _mesa_make_current(st->ctx, stdraw, stread); 1237bf215546Sopenharmony_ci 1238bf215546Sopenharmony_ci st->draw_stamp = stdraw->stamp - 1; 1239bf215546Sopenharmony_ci st->read_stamp = stread->stamp - 1; 1240bf215546Sopenharmony_ci st_context_validate(st, stdraw, stread); 1241bf215546Sopenharmony_ci } 1242bf215546Sopenharmony_ci else { 1243bf215546Sopenharmony_ci struct gl_framebuffer *incomplete = _mesa_get_incomplete_framebuffer(); 1244bf215546Sopenharmony_ci ret = _mesa_make_current(st->ctx, incomplete, incomplete); 1245bf215546Sopenharmony_ci } 1246bf215546Sopenharmony_ci 1247bf215546Sopenharmony_ci _mesa_reference_framebuffer(&stdraw, NULL); 1248bf215546Sopenharmony_ci _mesa_reference_framebuffer(&stread, NULL); 1249bf215546Sopenharmony_ci 1250bf215546Sopenharmony_ci /* Purge the context's winsys_buffers list in case any 1251bf215546Sopenharmony_ci * of the referenced drawables no longer exist. 1252bf215546Sopenharmony_ci */ 1253bf215546Sopenharmony_ci st_framebuffers_purge(st); 1254bf215546Sopenharmony_ci } 1255bf215546Sopenharmony_ci else { 1256bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 1257bf215546Sopenharmony_ci 1258bf215546Sopenharmony_ci if (ctx) { 1259bf215546Sopenharmony_ci /* Before releasing the context, release its associated 1260bf215546Sopenharmony_ci * winsys buffers first. Then purge the context's winsys buffers list 1261bf215546Sopenharmony_ci * to free the resources of any winsys buffers that no longer have 1262bf215546Sopenharmony_ci * an existing drawable. 1263bf215546Sopenharmony_ci */ 1264bf215546Sopenharmony_ci ret = _mesa_make_current(ctx, NULL, NULL); 1265bf215546Sopenharmony_ci st_framebuffers_purge(ctx->st); 1266bf215546Sopenharmony_ci } 1267bf215546Sopenharmony_ci 1268bf215546Sopenharmony_ci ret = _mesa_make_current(NULL, NULL, NULL); 1269bf215546Sopenharmony_ci } 1270bf215546Sopenharmony_ci 1271bf215546Sopenharmony_ci return ret; 1272bf215546Sopenharmony_ci} 1273bf215546Sopenharmony_ci 1274bf215546Sopenharmony_ci 1275bf215546Sopenharmony_cistatic void 1276bf215546Sopenharmony_cist_api_destroy(struct st_api *stapi) 1277bf215546Sopenharmony_ci{ 1278bf215546Sopenharmony_ci} 1279bf215546Sopenharmony_ci 1280bf215546Sopenharmony_ci 1281bf215546Sopenharmony_ci/** 1282bf215546Sopenharmony_ci * Flush the front buffer if the current context renders to the front buffer. 1283bf215546Sopenharmony_ci */ 1284bf215546Sopenharmony_civoid 1285bf215546Sopenharmony_cist_manager_flush_frontbuffer(struct st_context *st) 1286bf215546Sopenharmony_ci{ 1287bf215546Sopenharmony_ci struct gl_framebuffer *stfb = st_ws_framebuffer(st->ctx->DrawBuffer); 1288bf215546Sopenharmony_ci struct gl_renderbuffer *rb = NULL; 1289bf215546Sopenharmony_ci 1290bf215546Sopenharmony_ci if (!stfb) 1291bf215546Sopenharmony_ci return; 1292bf215546Sopenharmony_ci 1293bf215546Sopenharmony_ci /* If the context uses a doublebuffered visual, but the buffer is 1294bf215546Sopenharmony_ci * single-buffered, guess that it's a pbuffer, which doesn't need 1295bf215546Sopenharmony_ci * flushing. 1296bf215546Sopenharmony_ci */ 1297bf215546Sopenharmony_ci if (st->ctx->Visual.doubleBufferMode && 1298bf215546Sopenharmony_ci !stfb->Visual.doubleBufferMode) 1299bf215546Sopenharmony_ci return; 1300bf215546Sopenharmony_ci 1301bf215546Sopenharmony_ci /* Check front buffer used at the GL API level. */ 1302bf215546Sopenharmony_ci enum st_attachment_type statt = ST_ATTACHMENT_FRONT_LEFT; 1303bf215546Sopenharmony_ci rb = stfb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; 1304bf215546Sopenharmony_ci if (!rb) { 1305bf215546Sopenharmony_ci /* Check back buffer redirected by EGL_KHR_mutable_render_buffer. */ 1306bf215546Sopenharmony_ci statt = ST_ATTACHMENT_BACK_LEFT; 1307bf215546Sopenharmony_ci rb = stfb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; 1308bf215546Sopenharmony_ci } 1309bf215546Sopenharmony_ci 1310bf215546Sopenharmony_ci /* Do we have a front color buffer and has it been drawn to since last 1311bf215546Sopenharmony_ci * frontbuffer flush? 1312bf215546Sopenharmony_ci */ 1313bf215546Sopenharmony_ci if (rb && rb->defined && 1314bf215546Sopenharmony_ci stfb->iface->flush_front(&st->iface, stfb->iface, statt)) { 1315bf215546Sopenharmony_ci rb->defined = GL_FALSE; 1316bf215546Sopenharmony_ci 1317bf215546Sopenharmony_ci /* Trigger an update of rb->defined on next draw */ 1318bf215546Sopenharmony_ci st->dirty |= ST_NEW_FB_STATE; 1319bf215546Sopenharmony_ci } 1320bf215546Sopenharmony_ci} 1321bf215546Sopenharmony_ci 1322bf215546Sopenharmony_ci 1323bf215546Sopenharmony_ci/** 1324bf215546Sopenharmony_ci * Re-validate the framebuffers. 1325bf215546Sopenharmony_ci */ 1326bf215546Sopenharmony_civoid 1327bf215546Sopenharmony_cist_manager_validate_framebuffers(struct st_context *st) 1328bf215546Sopenharmony_ci{ 1329bf215546Sopenharmony_ci struct gl_framebuffer *stdraw = st_ws_framebuffer(st->ctx->DrawBuffer); 1330bf215546Sopenharmony_ci struct gl_framebuffer *stread = st_ws_framebuffer(st->ctx->ReadBuffer); 1331bf215546Sopenharmony_ci 1332bf215546Sopenharmony_ci if (stdraw) 1333bf215546Sopenharmony_ci st_framebuffer_validate(stdraw, st); 1334bf215546Sopenharmony_ci if (stread && stread != stdraw) 1335bf215546Sopenharmony_ci st_framebuffer_validate(stread, st); 1336bf215546Sopenharmony_ci 1337bf215546Sopenharmony_ci st_context_validate(st, stdraw, stread); 1338bf215546Sopenharmony_ci} 1339bf215546Sopenharmony_ci 1340bf215546Sopenharmony_ci 1341bf215546Sopenharmony_ci/** 1342bf215546Sopenharmony_ci * Flush any outstanding swapbuffers on the current draw framebuffer. 1343bf215546Sopenharmony_ci */ 1344bf215546Sopenharmony_civoid 1345bf215546Sopenharmony_cist_manager_flush_swapbuffers(void) 1346bf215546Sopenharmony_ci{ 1347bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 1348bf215546Sopenharmony_ci struct st_context *st = (ctx) ? ctx->st : NULL; 1349bf215546Sopenharmony_ci struct gl_framebuffer *stfb; 1350bf215546Sopenharmony_ci 1351bf215546Sopenharmony_ci if (!st) 1352bf215546Sopenharmony_ci return; 1353bf215546Sopenharmony_ci 1354bf215546Sopenharmony_ci stfb = st_ws_framebuffer(ctx->DrawBuffer); 1355bf215546Sopenharmony_ci if (!stfb || !stfb->iface->flush_swapbuffers) 1356bf215546Sopenharmony_ci return; 1357bf215546Sopenharmony_ci 1358bf215546Sopenharmony_ci stfb->iface->flush_swapbuffers(&st->iface, stfb->iface); 1359bf215546Sopenharmony_ci} 1360bf215546Sopenharmony_ci 1361bf215546Sopenharmony_ci 1362bf215546Sopenharmony_ci/** 1363bf215546Sopenharmony_ci * Add a color renderbuffer on demand. The FBO must correspond to a window, 1364bf215546Sopenharmony_ci * not a user-created FBO. 1365bf215546Sopenharmony_ci */ 1366bf215546Sopenharmony_cibool 1367bf215546Sopenharmony_cist_manager_add_color_renderbuffer(struct gl_context *ctx, 1368bf215546Sopenharmony_ci struct gl_framebuffer *fb, 1369bf215546Sopenharmony_ci gl_buffer_index idx) 1370bf215546Sopenharmony_ci{ 1371bf215546Sopenharmony_ci struct gl_framebuffer *stfb = st_ws_framebuffer(fb); 1372bf215546Sopenharmony_ci 1373bf215546Sopenharmony_ci /* FBO */ 1374bf215546Sopenharmony_ci if (!stfb) 1375bf215546Sopenharmony_ci return false; 1376bf215546Sopenharmony_ci 1377bf215546Sopenharmony_ci assert(_mesa_is_winsys_fbo(fb)); 1378bf215546Sopenharmony_ci 1379bf215546Sopenharmony_ci if (stfb->Attachment[idx].Renderbuffer) 1380bf215546Sopenharmony_ci return true; 1381bf215546Sopenharmony_ci 1382bf215546Sopenharmony_ci switch (idx) { 1383bf215546Sopenharmony_ci case BUFFER_FRONT_LEFT: 1384bf215546Sopenharmony_ci case BUFFER_BACK_LEFT: 1385bf215546Sopenharmony_ci case BUFFER_FRONT_RIGHT: 1386bf215546Sopenharmony_ci case BUFFER_BACK_RIGHT: 1387bf215546Sopenharmony_ci break; 1388bf215546Sopenharmony_ci default: 1389bf215546Sopenharmony_ci return false; 1390bf215546Sopenharmony_ci } 1391bf215546Sopenharmony_ci 1392bf215546Sopenharmony_ci if (!st_framebuffer_add_renderbuffer(stfb, idx, 1393bf215546Sopenharmony_ci stfb->Visual.sRGBCapable)) 1394bf215546Sopenharmony_ci return false; 1395bf215546Sopenharmony_ci 1396bf215546Sopenharmony_ci st_framebuffer_update_attachments(stfb); 1397bf215546Sopenharmony_ci 1398bf215546Sopenharmony_ci /* 1399bf215546Sopenharmony_ci * Force a call to the frontend manager to validate the 1400bf215546Sopenharmony_ci * new renderbuffer. It might be that there is a window system 1401bf215546Sopenharmony_ci * renderbuffer available. 1402bf215546Sopenharmony_ci */ 1403bf215546Sopenharmony_ci if (stfb->iface) 1404bf215546Sopenharmony_ci stfb->iface_stamp = p_atomic_read(&stfb->iface->stamp) - 1; 1405bf215546Sopenharmony_ci 1406bf215546Sopenharmony_ci st_invalidate_buffers(st_context(ctx)); 1407bf215546Sopenharmony_ci 1408bf215546Sopenharmony_ci return true; 1409bf215546Sopenharmony_ci} 1410bf215546Sopenharmony_ci 1411bf215546Sopenharmony_ci 1412bf215546Sopenharmony_cistatic unsigned 1413bf215546Sopenharmony_ciget_version(struct pipe_screen *screen, 1414bf215546Sopenharmony_ci struct st_config_options *options, gl_api api) 1415bf215546Sopenharmony_ci{ 1416bf215546Sopenharmony_ci struct gl_constants consts = {0}; 1417bf215546Sopenharmony_ci struct gl_extensions extensions = {0}; 1418bf215546Sopenharmony_ci GLuint version; 1419bf215546Sopenharmony_ci 1420bf215546Sopenharmony_ci if (_mesa_override_gl_version_contextless(&consts, &api, &version)) { 1421bf215546Sopenharmony_ci return version; 1422bf215546Sopenharmony_ci } 1423bf215546Sopenharmony_ci 1424bf215546Sopenharmony_ci _mesa_init_constants(&consts, api); 1425bf215546Sopenharmony_ci _mesa_init_extensions(&extensions); 1426bf215546Sopenharmony_ci 1427bf215546Sopenharmony_ci st_init_limits(screen, &consts, &extensions); 1428bf215546Sopenharmony_ci st_init_extensions(screen, &consts, &extensions, options, api); 1429bf215546Sopenharmony_ci version = _mesa_get_version(&extensions, &consts, api); 1430bf215546Sopenharmony_ci free(consts.SpirVExtensions); 1431bf215546Sopenharmony_ci return version; 1432bf215546Sopenharmony_ci} 1433bf215546Sopenharmony_ci 1434bf215546Sopenharmony_ci 1435bf215546Sopenharmony_cistatic void 1436bf215546Sopenharmony_cist_api_query_versions(struct st_api *stapi, struct st_manager *sm, 1437bf215546Sopenharmony_ci struct st_config_options *options, 1438bf215546Sopenharmony_ci int *gl_core_version, 1439bf215546Sopenharmony_ci int *gl_compat_version, 1440bf215546Sopenharmony_ci int *gl_es1_version, 1441bf215546Sopenharmony_ci int *gl_es2_version) 1442bf215546Sopenharmony_ci{ 1443bf215546Sopenharmony_ci *gl_core_version = get_version(sm->screen, options, API_OPENGL_CORE); 1444bf215546Sopenharmony_ci *gl_compat_version = get_version(sm->screen, options, API_OPENGL_COMPAT); 1445bf215546Sopenharmony_ci *gl_es1_version = get_version(sm->screen, options, API_OPENGLES); 1446bf215546Sopenharmony_ci *gl_es2_version = get_version(sm->screen, options, API_OPENGLES2); 1447bf215546Sopenharmony_ci} 1448bf215546Sopenharmony_ci 1449bf215546Sopenharmony_ci 1450bf215546Sopenharmony_cistatic const struct st_api st_gl_api = { 1451bf215546Sopenharmony_ci .name = "Mesa " PACKAGE_VERSION, 1452bf215546Sopenharmony_ci .api = ST_API_OPENGL, 1453bf215546Sopenharmony_ci .profile_mask = ST_PROFILE_DEFAULT_MASK | 1454bf215546Sopenharmony_ci ST_PROFILE_OPENGL_CORE_MASK | 1455bf215546Sopenharmony_ci ST_PROFILE_OPENGL_ES1_MASK | 1456bf215546Sopenharmony_ci ST_PROFILE_OPENGL_ES2_MASK | 1457bf215546Sopenharmony_ci 0, 1458bf215546Sopenharmony_ci .feature_mask = ST_API_FEATURE_MS_VISUALS_MASK, 1459bf215546Sopenharmony_ci .destroy = st_api_destroy, 1460bf215546Sopenharmony_ci .query_versions = st_api_query_versions, 1461bf215546Sopenharmony_ci .create_context = st_api_create_context, 1462bf215546Sopenharmony_ci .make_current = st_api_make_current, 1463bf215546Sopenharmony_ci .get_current = st_api_get_current, 1464bf215546Sopenharmony_ci .destroy_drawable = st_api_destroy_drawable, 1465bf215546Sopenharmony_ci}; 1466bf215546Sopenharmony_ci 1467bf215546Sopenharmony_ci 1468bf215546Sopenharmony_cistruct st_api * 1469bf215546Sopenharmony_cist_gl_api_create(void) 1470bf215546Sopenharmony_ci{ 1471bf215546Sopenharmony_ci return (struct st_api *) &st_gl_api; 1472bf215546Sopenharmony_ci} 1473bf215546Sopenharmony_ci 1474bf215546Sopenharmony_civoid 1475bf215546Sopenharmony_cist_manager_invalidate_drawables(struct gl_context *ctx) 1476bf215546Sopenharmony_ci{ 1477bf215546Sopenharmony_ci struct gl_framebuffer *stdraw; 1478bf215546Sopenharmony_ci struct gl_framebuffer *stread; 1479bf215546Sopenharmony_ci 1480bf215546Sopenharmony_ci /* 1481bf215546Sopenharmony_ci * Normally we'd want the frontend manager to mark the drawables 1482bf215546Sopenharmony_ci * invalid only when needed. This will force the frontend manager 1483bf215546Sopenharmony_ci * to revalidate the drawable, rather than just update the context with 1484bf215546Sopenharmony_ci * the latest cached drawable info. 1485bf215546Sopenharmony_ci */ 1486bf215546Sopenharmony_ci 1487bf215546Sopenharmony_ci stdraw = st_ws_framebuffer(ctx->DrawBuffer); 1488bf215546Sopenharmony_ci stread = st_ws_framebuffer(ctx->ReadBuffer); 1489bf215546Sopenharmony_ci 1490bf215546Sopenharmony_ci if (stdraw) 1491bf215546Sopenharmony_ci stdraw->iface_stamp = p_atomic_read(&stdraw->iface->stamp) - 1; 1492bf215546Sopenharmony_ci if (stread && stread != stdraw) 1493bf215546Sopenharmony_ci stread->iface_stamp = p_atomic_read(&stread->iface->stamp) - 1; 1494bf215546Sopenharmony_ci} 1495