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 "xm_api.h" 29bf215546Sopenharmony_ci#include "xm_st.h" 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#include "util/u_inlines.h" 32bf215546Sopenharmony_ci#include "util/u_atomic.h" 33bf215546Sopenharmony_ci#include "util/u_memory.h" 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_cistruct xmesa_st_framebuffer { 36bf215546Sopenharmony_ci XMesaDisplay display; 37bf215546Sopenharmony_ci XMesaBuffer buffer; 38bf215546Sopenharmony_ci struct pipe_screen *screen; 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci struct st_visual stvis; 41bf215546Sopenharmony_ci enum pipe_texture_target target; 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci unsigned texture_width, texture_height, texture_mask; 44bf215546Sopenharmony_ci struct pipe_resource *textures[ST_ATTACHMENT_COUNT]; 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci struct pipe_resource *display_resource; 47bf215546Sopenharmony_ci}; 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_cistatic inline struct xmesa_st_framebuffer * 51bf215546Sopenharmony_cixmesa_st_framebuffer(struct st_framebuffer_iface *stfbi) 52bf215546Sopenharmony_ci{ 53bf215546Sopenharmony_ci return (struct xmesa_st_framebuffer *) stfbi->st_manager_private; 54bf215546Sopenharmony_ci} 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci/** 58bf215546Sopenharmony_ci * Display (present) an attachment to the xlib_drawable of the framebuffer. 59bf215546Sopenharmony_ci */ 60bf215546Sopenharmony_cistatic bool 61bf215546Sopenharmony_cixmesa_st_framebuffer_display(struct st_framebuffer_iface *stfbi, 62bf215546Sopenharmony_ci struct st_context_iface *stctx, 63bf215546Sopenharmony_ci enum st_attachment_type statt, 64bf215546Sopenharmony_ci struct pipe_box *box) 65bf215546Sopenharmony_ci{ 66bf215546Sopenharmony_ci struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi); 67bf215546Sopenharmony_ci struct pipe_resource *ptex = xstfb->textures[statt]; 68bf215546Sopenharmony_ci struct pipe_resource *pres; 69bf215546Sopenharmony_ci struct pipe_context *pctx = stctx ? stctx->pipe : NULL; 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci if (!ptex) 72bf215546Sopenharmony_ci return true; 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci pres = xstfb->display_resource; 75bf215546Sopenharmony_ci /* (re)allocate the surface for the texture to be displayed */ 76bf215546Sopenharmony_ci if (!pres || pres != ptex) { 77bf215546Sopenharmony_ci pipe_resource_reference(&xstfb->display_resource, ptex); 78bf215546Sopenharmony_ci pres = xstfb->display_resource; 79bf215546Sopenharmony_ci } 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci xstfb->screen->flush_frontbuffer(xstfb->screen, pctx, pres, 0, 0, &xstfb->buffer->ws, box); 82bf215546Sopenharmony_ci return true; 83bf215546Sopenharmony_ci} 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci/** 87bf215546Sopenharmony_ci * Copy the contents between the attachments. 88bf215546Sopenharmony_ci */ 89bf215546Sopenharmony_cistatic void 90bf215546Sopenharmony_cixmesa_st_framebuffer_copy_textures(struct st_framebuffer_iface *stfbi, 91bf215546Sopenharmony_ci enum st_attachment_type src_statt, 92bf215546Sopenharmony_ci enum st_attachment_type dst_statt, 93bf215546Sopenharmony_ci unsigned x, unsigned y, 94bf215546Sopenharmony_ci unsigned width, unsigned height) 95bf215546Sopenharmony_ci{ 96bf215546Sopenharmony_ci struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi); 97bf215546Sopenharmony_ci struct pipe_resource *src_ptex = xstfb->textures[src_statt]; 98bf215546Sopenharmony_ci struct pipe_resource *dst_ptex = xstfb->textures[dst_statt]; 99bf215546Sopenharmony_ci struct pipe_box src_box; 100bf215546Sopenharmony_ci struct pipe_context *pipe; 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci if (!src_ptex || !dst_ptex) 103bf215546Sopenharmony_ci return; 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci pipe = xmesa_get_context(stfbi); 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci u_box_2d(x, y, width, height, &src_box); 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci if (src_ptex && dst_ptex) 110bf215546Sopenharmony_ci pipe->resource_copy_region(pipe, dst_ptex, 0, x, y, 0, 111bf215546Sopenharmony_ci src_ptex, 0, &src_box); 112bf215546Sopenharmony_ci} 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci/** 116bf215546Sopenharmony_ci * Remove outdated textures and create the requested ones. 117bf215546Sopenharmony_ci * This is a helper used during framebuffer validation. 118bf215546Sopenharmony_ci */ 119bf215546Sopenharmony_cibool 120bf215546Sopenharmony_cixmesa_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi, 121bf215546Sopenharmony_ci unsigned width, unsigned height, 122bf215546Sopenharmony_ci unsigned mask) 123bf215546Sopenharmony_ci{ 124bf215546Sopenharmony_ci struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi); 125bf215546Sopenharmony_ci struct pipe_resource templ; 126bf215546Sopenharmony_ci enum st_attachment_type i; 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci /* remove outdated textures */ 129bf215546Sopenharmony_ci if (xstfb->texture_width != width || xstfb->texture_height != height) { 130bf215546Sopenharmony_ci for (i = 0; i < ST_ATTACHMENT_COUNT; i++) 131bf215546Sopenharmony_ci pipe_resource_reference(&xstfb->textures[i], NULL); 132bf215546Sopenharmony_ci } 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_ci memset(&templ, 0, sizeof(templ)); 135bf215546Sopenharmony_ci templ.target = xstfb->target; 136bf215546Sopenharmony_ci templ.width0 = width; 137bf215546Sopenharmony_ci templ.height0 = height; 138bf215546Sopenharmony_ci templ.depth0 = 1; 139bf215546Sopenharmony_ci templ.array_size = 1; 140bf215546Sopenharmony_ci templ.last_level = 0; 141bf215546Sopenharmony_ci templ.nr_samples = xstfb->stvis.samples; 142bf215546Sopenharmony_ci templ.nr_storage_samples = xstfb->stvis.samples; 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci for (i = 0; i < ST_ATTACHMENT_COUNT; i++) { 145bf215546Sopenharmony_ci enum pipe_format format; 146bf215546Sopenharmony_ci unsigned bind; 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci /* the texture already exists or not requested */ 149bf215546Sopenharmony_ci if (xstfb->textures[i] || !(mask & (1 << i))) { 150bf215546Sopenharmony_ci /* remember the texture */ 151bf215546Sopenharmony_ci if (xstfb->textures[i]) 152bf215546Sopenharmony_ci mask |= (1 << i); 153bf215546Sopenharmony_ci continue; 154bf215546Sopenharmony_ci } 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci switch (i) { 157bf215546Sopenharmony_ci case ST_ATTACHMENT_FRONT_LEFT: 158bf215546Sopenharmony_ci case ST_ATTACHMENT_BACK_LEFT: 159bf215546Sopenharmony_ci case ST_ATTACHMENT_FRONT_RIGHT: 160bf215546Sopenharmony_ci case ST_ATTACHMENT_BACK_RIGHT: 161bf215546Sopenharmony_ci format = xstfb->stvis.color_format; 162bf215546Sopenharmony_ci bind = PIPE_BIND_DISPLAY_TARGET | 163bf215546Sopenharmony_ci PIPE_BIND_RENDER_TARGET; 164bf215546Sopenharmony_ci break; 165bf215546Sopenharmony_ci case ST_ATTACHMENT_DEPTH_STENCIL: 166bf215546Sopenharmony_ci format = xstfb->stvis.depth_stencil_format; 167bf215546Sopenharmony_ci bind = PIPE_BIND_DEPTH_STENCIL; 168bf215546Sopenharmony_ci break; 169bf215546Sopenharmony_ci default: 170bf215546Sopenharmony_ci format = PIPE_FORMAT_NONE; 171bf215546Sopenharmony_ci break; 172bf215546Sopenharmony_ci } 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci if (format != PIPE_FORMAT_NONE) { 175bf215546Sopenharmony_ci templ.format = format; 176bf215546Sopenharmony_ci templ.bind = bind; 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci xstfb->textures[i] = 179bf215546Sopenharmony_ci xstfb->screen->resource_create(xstfb->screen, &templ); 180bf215546Sopenharmony_ci if (!xstfb->textures[i]) 181bf215546Sopenharmony_ci return FALSE; 182bf215546Sopenharmony_ci } 183bf215546Sopenharmony_ci } 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci xstfb->texture_width = width; 186bf215546Sopenharmony_ci xstfb->texture_height = height; 187bf215546Sopenharmony_ci xstfb->texture_mask = mask; 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci return true; 190bf215546Sopenharmony_ci} 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci/** 194bf215546Sopenharmony_ci * Check that a framebuffer's attachments match the window's size. 195bf215546Sopenharmony_ci * 196bf215546Sopenharmony_ci * Called via st_framebuffer_iface::validate() 197bf215546Sopenharmony_ci * 198bf215546Sopenharmony_ci * \param statts array of framebuffer attachments 199bf215546Sopenharmony_ci * \param count number of framebuffer attachments in statts[] 200bf215546Sopenharmony_ci * \param out returns resources for each of the attachments 201bf215546Sopenharmony_ci */ 202bf215546Sopenharmony_cistatic bool 203bf215546Sopenharmony_cixmesa_st_framebuffer_validate(struct st_context_iface *stctx, 204bf215546Sopenharmony_ci struct st_framebuffer_iface *stfbi, 205bf215546Sopenharmony_ci const enum st_attachment_type *statts, 206bf215546Sopenharmony_ci unsigned count, 207bf215546Sopenharmony_ci struct pipe_resource **out) 208bf215546Sopenharmony_ci{ 209bf215546Sopenharmony_ci struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi); 210bf215546Sopenharmony_ci unsigned statt_mask, new_mask, i; 211bf215546Sopenharmony_ci bool resized; 212bf215546Sopenharmony_ci bool ret; 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci /* build mask of ST_ATTACHMENT bits */ 215bf215546Sopenharmony_ci statt_mask = 0x0; 216bf215546Sopenharmony_ci for (i = 0; i < count; i++) 217bf215546Sopenharmony_ci statt_mask |= 1 << statts[i]; 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci /* record newly allocated textures */ 220bf215546Sopenharmony_ci new_mask = statt_mask & ~xstfb->texture_mask; 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_ci /* If xmesa_strict_invalidate is not set, we will not yet have 223bf215546Sopenharmony_ci * called XGetGeometry(). Do so here: 224bf215546Sopenharmony_ci */ 225bf215546Sopenharmony_ci if (!xmesa_strict_invalidate) 226bf215546Sopenharmony_ci xmesa_check_buffer_size(xstfb->buffer); 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci resized = (xstfb->buffer->width != xstfb->texture_width || 229bf215546Sopenharmony_ci xstfb->buffer->height != xstfb->texture_height); 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci /* revalidate textures */ 232bf215546Sopenharmony_ci if (resized || new_mask) { 233bf215546Sopenharmony_ci ret = xmesa_st_framebuffer_validate_textures(stfbi, 234bf215546Sopenharmony_ci xstfb->buffer->width, xstfb->buffer->height, statt_mask); 235bf215546Sopenharmony_ci if (!ret) 236bf215546Sopenharmony_ci return ret; 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_ci if (!resized) { 239bf215546Sopenharmony_ci enum st_attachment_type back, front; 240bf215546Sopenharmony_ci 241bf215546Sopenharmony_ci back = ST_ATTACHMENT_BACK_LEFT; 242bf215546Sopenharmony_ci front = ST_ATTACHMENT_FRONT_LEFT; 243bf215546Sopenharmony_ci /* copy the contents if front is newly allocated and back is not */ 244bf215546Sopenharmony_ci if ((statt_mask & (1 << back)) && 245bf215546Sopenharmony_ci (new_mask & (1 << front)) && 246bf215546Sopenharmony_ci !(new_mask & (1 << back))) { 247bf215546Sopenharmony_ci xmesa_st_framebuffer_copy_textures(stfbi, back, front, 248bf215546Sopenharmony_ci 0, 0, xstfb->texture_width, xstfb->texture_height); 249bf215546Sopenharmony_ci } 250bf215546Sopenharmony_ci } 251bf215546Sopenharmony_ci } 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_ci for (i = 0; i < count; i++) 254bf215546Sopenharmony_ci pipe_resource_reference(&out[i], xstfb->textures[statts[i]]); 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci return true; 257bf215546Sopenharmony_ci} 258bf215546Sopenharmony_ci 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci/** 261bf215546Sopenharmony_ci * Called via st_framebuffer_iface::flush_front() 262bf215546Sopenharmony_ci */ 263bf215546Sopenharmony_cistatic bool 264bf215546Sopenharmony_cixmesa_st_framebuffer_flush_front(struct st_context_iface *stctx, 265bf215546Sopenharmony_ci struct st_framebuffer_iface *stfbi, 266bf215546Sopenharmony_ci enum st_attachment_type statt) 267bf215546Sopenharmony_ci{ 268bf215546Sopenharmony_ci struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi); 269bf215546Sopenharmony_ci bool ret; 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci if (statt != ST_ATTACHMENT_FRONT_LEFT) 272bf215546Sopenharmony_ci return false; 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci ret = xmesa_st_framebuffer_display(stfbi, stctx, statt, NULL); 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_ci if (ret && xmesa_strict_invalidate) 277bf215546Sopenharmony_ci xmesa_check_buffer_size(xstfb->buffer); 278bf215546Sopenharmony_ci 279bf215546Sopenharmony_ci return ret; 280bf215546Sopenharmony_ci} 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_cistatic uint32_t xmesa_stfbi_ID = 0; 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_cistruct st_framebuffer_iface * 285bf215546Sopenharmony_cixmesa_create_st_framebuffer(XMesaDisplay xmdpy, XMesaBuffer b) 286bf215546Sopenharmony_ci{ 287bf215546Sopenharmony_ci struct st_framebuffer_iface *stfbi; 288bf215546Sopenharmony_ci struct xmesa_st_framebuffer *xstfb; 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_ci assert(xmdpy->display == b->xm_visual->display); 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci stfbi = CALLOC_STRUCT(st_framebuffer_iface); 293bf215546Sopenharmony_ci xstfb = CALLOC_STRUCT(xmesa_st_framebuffer); 294bf215546Sopenharmony_ci if (!stfbi || !xstfb) { 295bf215546Sopenharmony_ci free(stfbi); 296bf215546Sopenharmony_ci free(xstfb); 297bf215546Sopenharmony_ci return NULL; 298bf215546Sopenharmony_ci } 299bf215546Sopenharmony_ci 300bf215546Sopenharmony_ci xstfb->display = xmdpy; 301bf215546Sopenharmony_ci xstfb->buffer = b; 302bf215546Sopenharmony_ci xstfb->screen = xmdpy->screen; 303bf215546Sopenharmony_ci xstfb->stvis = b->xm_visual->stvis; 304bf215546Sopenharmony_ci if (xstfb->screen->get_param(xstfb->screen, PIPE_CAP_NPOT_TEXTURES)) 305bf215546Sopenharmony_ci xstfb->target = PIPE_TEXTURE_2D; 306bf215546Sopenharmony_ci else 307bf215546Sopenharmony_ci xstfb->target = PIPE_TEXTURE_RECT; 308bf215546Sopenharmony_ci 309bf215546Sopenharmony_ci stfbi->visual = &xstfb->stvis; 310bf215546Sopenharmony_ci stfbi->flush_front = xmesa_st_framebuffer_flush_front; 311bf215546Sopenharmony_ci stfbi->validate = xmesa_st_framebuffer_validate; 312bf215546Sopenharmony_ci stfbi->ID = p_atomic_inc_return(&xmesa_stfbi_ID); 313bf215546Sopenharmony_ci stfbi->state_manager = xmdpy->smapi; 314bf215546Sopenharmony_ci p_atomic_set(&stfbi->stamp, 1); 315bf215546Sopenharmony_ci stfbi->st_manager_private = (void *) xstfb; 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci return stfbi; 318bf215546Sopenharmony_ci} 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_civoid 322bf215546Sopenharmony_cixmesa_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi) 323bf215546Sopenharmony_ci{ 324bf215546Sopenharmony_ci struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi); 325bf215546Sopenharmony_ci int i; 326bf215546Sopenharmony_ci 327bf215546Sopenharmony_ci pipe_resource_reference(&xstfb->display_resource, NULL); 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci for (i = 0; i < ST_ATTACHMENT_COUNT; i++) 330bf215546Sopenharmony_ci pipe_resource_reference(&xstfb->textures[i], NULL); 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_ci free(xstfb); 333bf215546Sopenharmony_ci free(stfbi); 334bf215546Sopenharmony_ci} 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_ci/** 338bf215546Sopenharmony_ci * Return the pipe_surface which corresponds to the given 339bf215546Sopenharmony_ci * framebuffer attachment. 340bf215546Sopenharmony_ci */ 341bf215546Sopenharmony_cistruct pipe_resource * 342bf215546Sopenharmony_cixmesa_get_framebuffer_resource(struct st_framebuffer_iface *stfbi, 343bf215546Sopenharmony_ci enum st_attachment_type att) 344bf215546Sopenharmony_ci{ 345bf215546Sopenharmony_ci struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi); 346bf215546Sopenharmony_ci return xstfb->textures[att]; 347bf215546Sopenharmony_ci} 348bf215546Sopenharmony_ci 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_civoid 351bf215546Sopenharmony_cixmesa_swap_st_framebuffer(struct st_framebuffer_iface *stfbi) 352bf215546Sopenharmony_ci{ 353bf215546Sopenharmony_ci struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi); 354bf215546Sopenharmony_ci bool ret; 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_ci ret = xmesa_st_framebuffer_display(stfbi, NULL, ST_ATTACHMENT_BACK_LEFT, NULL); 357bf215546Sopenharmony_ci if (ret) { 358bf215546Sopenharmony_ci struct pipe_resource **front, **back, *tmp; 359bf215546Sopenharmony_ci 360bf215546Sopenharmony_ci front = &xstfb->textures[ST_ATTACHMENT_FRONT_LEFT]; 361bf215546Sopenharmony_ci back = &xstfb->textures[ST_ATTACHMENT_BACK_LEFT]; 362bf215546Sopenharmony_ci /* swap textures only if the front texture has been allocated */ 363bf215546Sopenharmony_ci if (*front) { 364bf215546Sopenharmony_ci tmp = *front; 365bf215546Sopenharmony_ci *front = *back; 366bf215546Sopenharmony_ci *back = tmp; 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_ci /* the current context should validate the buffer after swapping */ 369bf215546Sopenharmony_ci if (!xmesa_strict_invalidate) 370bf215546Sopenharmony_ci xmesa_notify_invalid_buffer(xstfb->buffer); 371bf215546Sopenharmony_ci } 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_ci if (xmesa_strict_invalidate) 374bf215546Sopenharmony_ci xmesa_check_buffer_size(xstfb->buffer); 375bf215546Sopenharmony_ci } 376bf215546Sopenharmony_ci} 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_civoid 380bf215546Sopenharmony_cixmesa_copy_st_framebuffer(struct st_framebuffer_iface *stfbi, 381bf215546Sopenharmony_ci enum st_attachment_type src, 382bf215546Sopenharmony_ci enum st_attachment_type dst, 383bf215546Sopenharmony_ci int x, int y, int w, int h) 384bf215546Sopenharmony_ci{ 385bf215546Sopenharmony_ci xmesa_st_framebuffer_copy_textures(stfbi, src, dst, x, y, w, h); 386bf215546Sopenharmony_ci if (dst == ST_ATTACHMENT_FRONT_LEFT) { 387bf215546Sopenharmony_ci struct pipe_box box = {}; 388bf215546Sopenharmony_ci 389bf215546Sopenharmony_ci box.x = x; 390bf215546Sopenharmony_ci box.y = y; 391bf215546Sopenharmony_ci box.width = w; 392bf215546Sopenharmony_ci box.height = h; 393bf215546Sopenharmony_ci xmesa_st_framebuffer_display(stfbi, NULL, src, &box); 394bf215546Sopenharmony_ci } 395bf215546Sopenharmony_ci} 396bf215546Sopenharmony_ci 397bf215546Sopenharmony_ci 398bf215546Sopenharmony_cistruct pipe_resource* 399bf215546Sopenharmony_cixmesa_get_attachment(struct st_framebuffer_iface *stfbi, 400bf215546Sopenharmony_ci enum st_attachment_type st_attachment) 401bf215546Sopenharmony_ci{ 402bf215546Sopenharmony_ci struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi); 403bf215546Sopenharmony_ci struct pipe_resource *res; 404bf215546Sopenharmony_ci 405bf215546Sopenharmony_ci res = xstfb->textures[st_attachment]; 406bf215546Sopenharmony_ci return res; 407bf215546Sopenharmony_ci} 408bf215546Sopenharmony_ci 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_cistruct pipe_context* 411bf215546Sopenharmony_cixmesa_get_context(struct st_framebuffer_iface *stfbi) 412bf215546Sopenharmony_ci{ 413bf215546Sopenharmony_ci struct pipe_context *pipe; 414bf215546Sopenharmony_ci struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi); 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_ci pipe = xstfb->display->pipe; 417bf215546Sopenharmony_ci if (!pipe) { 418bf215546Sopenharmony_ci pipe = xstfb->screen->context_create(xstfb->screen, NULL, 0); 419bf215546Sopenharmony_ci if (!pipe) 420bf215546Sopenharmony_ci return NULL; 421bf215546Sopenharmony_ci xstfb->display->pipe = pipe; 422bf215546Sopenharmony_ci } 423bf215546Sopenharmony_ci return pipe; 424bf215546Sopenharmony_ci} 425