1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009, VMware, Inc.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Author: Keith Whitwell <keithw@vmware.com>
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Author: Jakob Bornecrantz <wallbraker@gmail.com>
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "dri_screen.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "dri_context.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "dri_drawable.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_screen.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_format.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_inlines.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswap_fences_unref(struct dri_drawable *draw);
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            const enum st_attachment_type *statts,
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            unsigned count,
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            struct pipe_resource **out)
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_drawable *drawable =
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (struct dri_drawable *) stfbi->st_manager_private;
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_screen *screen = dri_screen(drawable->sPriv);
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned statt_mask, new_mask;
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean new_stamp;
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int lastStamp;
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   statt_mask = 0x0;
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < count; i++)
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      statt_mask |= (1 << statts[i]);
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* record newly allocated textures */
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   new_mask = (statt_mask & ~drawable->texture_mask);
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * dPriv->dri2.stamp is the server stamp.  dPriv->lastStamp is the
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * client stamp.  It has the value of the server stamp when last
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * checked.
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   do {
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lastStamp = drawable->dPriv->lastStamp;
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      new_stamp = (drawable->texture_stamp != lastStamp);
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (new_stamp || new_mask || screen->broken_invalidate) {
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (new_stamp && drawable->update_drawable_info)
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            drawable->update_drawable_info(drawable);
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         drawable->allocate_textures(drawable, statts, count);
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* add existing textures */
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (drawable->textures[i])
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               statt_mask |= (1 << i);
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         drawable->texture_stamp = lastStamp;
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         drawable->texture_mask = statt_mask;
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } while (lastStamp != drawable->dPriv->lastStamp);
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!out)
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return TRUE;
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < count; i++) {
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      out[i] = NULL;
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_resource_reference(&out[i], drawable->textures[statts[i]]);
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               enum st_attachment_type statt)
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_drawable *drawable =
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (struct dri_drawable *) stfbi->st_manager_private;
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* XXX remove this and just set the correct one on the framebuffer */
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drawable->flush_frontbuffer(drawable, statt);
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is called when we need to set up GL rendering to a new X window.
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgboolean
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri_create_buffer(__DRIscreen * sPriv,
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  __DRIdrawable * dPriv,
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  const struct gl_config * visual, boolean isPixmap)
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_screen *screen = sPriv->driverPrivate;
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_drawable *drawable = NULL;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (isPixmap)
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto fail;		       /* not implemented */
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drawable = CALLOC_STRUCT(dri_drawable);
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (drawable == NULL)
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto fail;
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri_fill_st_visual(&drawable->stvis, screen, visual);
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* setup the st_framebuffer_iface */
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drawable->base.visual = &drawable->stvis;
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drawable->base.flush_front = dri_st_framebuffer_flush_front;
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drawable->base.validate = dri_st_framebuffer_validate;
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drawable->base.st_manager_private = (void *) drawable;
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drawable->screen = screen;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drawable->sPriv = sPriv;
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drawable->dPriv = dPriv;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drawable->desired_fences = screen->default_throttle_frames;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (drawable->desired_fences > DRI_SWAP_FENCES_MAX)
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      drawable->desired_fences = DRI_SWAP_FENCES_MAX;
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dPriv->driverPrivate = (void *)drawable;
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   p_atomic_set(&drawable->base.stamp, 1);
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return GL_TRUE;
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfail:
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(drawable);
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return GL_FALSE;
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri_destroy_buffer(__DRIdrawable * dPriv)
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_drawable *drawable = dri_drawable(dPriv);
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_surface_reference(&drawable->drisw_surface, NULL);
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_resource_reference(&drawable->textures[i], NULL);
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   swap_fences_unref(drawable);
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(drawable);
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Validate the texture at an attachment.  Allocate the texture if it does not
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * exist.  Used by the TFP extension.
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri_drawable_validate_att(struct dri_drawable *drawable,
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          enum st_attachment_type statt)
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   enum st_attachment_type statts[ST_ATTACHMENT_COUNT];
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i, count = 0;
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* check if buffer already exists */
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (drawable->texture_mask & (1 << statt))
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* make sure DRI2 does not destroy existing buffers */
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (drawable->texture_mask & (1 << i)) {
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         statts[count++] = i;
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   statts[count++] = statt;
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drawable->texture_stamp = drawable->dPriv->lastStamp - 1;
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drawable->base.validate(&drawable->base, statts, count, NULL);
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * These are used for GLX_EXT_texture_from_pixmap
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    GLint format, __DRIdrawable *dPriv)
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_context *ctx = dri_context(pDRICtx);
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_drawable *drawable = dri_drawable(dPriv);
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_resource *pt;
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri_drawable_validate_att(drawable, ST_ATTACHMENT_FRONT_LEFT);
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Use the pipe resource associated with the X drawable */
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pt = drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pt) {
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      enum pipe_format internal_format = pt->format;
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (format == __DRI_TEXTURE_FORMAT_RGB)  {
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* only need to cover the formats recognized by dri_fill_st_visual */
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         switch (internal_format) {
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case PIPE_FORMAT_B8G8R8A8_UNORM:
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            internal_format = PIPE_FORMAT_B8G8R8X8_UNORM;
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case PIPE_FORMAT_A8R8G8B8_UNORM:
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            internal_format = PIPE_FORMAT_X8R8G8B8_UNORM;
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         default:
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      drawable->update_tex_buffer(drawable, ctx, pt);
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx->st->teximage(ctx->st,
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            (target == GL_TEXTURE_2D) ? ST_TEXTURE_2D : ST_TEXTURE_RECT,
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            0, internal_format, pt, FALSE);
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   __DRIdrawable *dPriv)
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri_set_tex_buffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst __DRItexBufferExtension driTexBufferExtension = {
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri_set_tex_buffer,
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri_set_tex_buffer2,
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   NULL,
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Get the format and binding of an attachment.
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri_drawable_get_format(struct dri_drawable *drawable,
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        enum st_attachment_type statt,
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        enum pipe_format *format,
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        unsigned *bind)
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (statt) {
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ST_ATTACHMENT_FRONT_LEFT:
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ST_ATTACHMENT_BACK_LEFT:
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ST_ATTACHMENT_FRONT_RIGHT:
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ST_ATTACHMENT_BACK_RIGHT:
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *format = drawable->stvis.color_format;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ST_ATTACHMENT_DEPTH_STENCIL:
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *format = drawable->stvis.depth_stencil_format;
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *bind = PIPE_BIND_DEPTH_STENCIL; /* XXX sampler? */
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *format = PIPE_FORMAT_NONE;
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *bind = 0;
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * swap_fences_pop_front - pull a fence from the throttle queue
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If the throttle queue is filled to the desired number of fences,
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * pull fences off the queue until the number is less than the desired
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * number of fences, and return the last fence pulled.
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pipe_fence_handle *
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswap_fences_pop_front(struct dri_drawable *draw)
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_screen *screen = draw->screen->base.screen;
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_fence_handle *fence = NULL;
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (draw->desired_fences == 0)
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (draw->cur_fences >= draw->desired_fences) {
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      screen->fence_reference(screen, &fence, draw->swap_fences[draw->tail]);
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      screen->fence_reference(screen, &draw->swap_fences[draw->tail++], NULL);
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      draw->tail &= DRI_SWAP_FENCES_MASK;
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      --draw->cur_fences;
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return fence;
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * swap_fences_push_back - push a fence onto the throttle queue
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * push a fence onto the throttle queue and pull fences of the queue
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * so that the desired number of fences are on the queue.
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswap_fences_push_back(struct dri_drawable *draw,
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      struct pipe_fence_handle *fence)
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_screen *screen = draw->screen->base.screen;
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!fence || draw->desired_fences == 0)
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while(draw->cur_fences == draw->desired_fences)
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swap_fences_pop_front(draw);
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   draw->cur_fences++;
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   screen->fence_reference(screen, &draw->swap_fences[draw->head++],
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   fence);
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   draw->head &= DRI_SWAP_FENCES_MASK;
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * swap_fences_unref - empty the throttle queue
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * pulls fences of the throttle queue until it is empty.
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswap_fences_unref(struct dri_drawable *draw)
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_screen *screen = draw->screen->base.screen;
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while(draw->cur_fences) {
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      screen->fence_reference(screen, &draw->swap_fences[draw->tail++], NULL);
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      draw->tail &= DRI_SWAP_FENCES_MASK;
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      --draw->cur_fences;
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * dri_throttle - A DRI2ThrottleExtension throttling function.
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * pulls a fence off the throttling queue and waits for it if the
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * number of fences on the throttling queue has reached the desired
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * number.
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Then flushes to insert a fence at the current rendering position, and
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * pushes that fence on the queue. This requires that the st_context_iface
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * flush method returns a fence even if there are no commands to flush.
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri_throttle(__DRIcontext *driCtx, __DRIdrawable *dPriv,
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     enum __DRI2throttleReason reason)
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct dri_drawable *draw = dri_drawable(dPriv);
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct st_context_iface *ctxi;
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct pipe_screen *screen = draw->screen->base.screen;
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct pipe_fence_handle *fence;
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (reason != __DRI2_THROTTLE_SWAPBUFFER &&
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	reason != __DRI2_THROTTLE_FLUSHFRONT)
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return;
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    fence = swap_fences_pop_front(draw);
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (fence) {
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	(void) screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	screen->fence_reference(screen, &fence, NULL);
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (driCtx == NULL)
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return;
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ctxi = dri_context(driCtx)->st;
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ctxi->flush(ctxi, 0, &fence);
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (fence) {
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	swap_fences_push_back(draw, fence);
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	screen->fence_reference(screen, &fence, NULL);
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst __DRI2throttleExtension dri2ThrottleExtension = {
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    .base = { __DRI2_THROTTLE, __DRI2_THROTTLE_VERSION },
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    .throttle = dri_throttle,
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* vim: set sw=3 ts=8 sts=3 expandtab: */
403