intel: only enable occlusion query if the drm has defines.
[mesa.git] / src / mesa / drivers / dri / intel / intel_depthstencil.c
1 /**************************************************************************
2 *
3 * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include "glheader.h"
29 #include "imports.h"
30 #include "context.h"
31 #include "depthstencil.h"
32 #include "fbobject.h"
33 #include "framebuffer.h"
34 #include "hash.h"
35 #include "mtypes.h"
36 #include "renderbuffer.h"
37
38 #include "intel_context.h"
39 #include "intel_fbo.h"
40 #include "intel_depthstencil.h"
41 #include "intel_regions.h"
42 #include "intel_span.h"
43
44 /**
45 * The GL_EXT_framebuffer_object allows the user to create their own
46 * framebuffer objects consisting of color renderbuffers (0 or more),
47 * depth renderbuffers (0 or 1) and stencil renderbuffers (0 or 1).
48 *
49 * The spec considers depth and stencil renderbuffers to be totally independent
50 * buffers. In reality, most graphics hardware today uses a combined
51 * depth+stencil buffer (one 32-bit pixel = 24 bits of Z + 8 bits of stencil).
52 *
53 * This causes difficulty because the user may create some number of depth
54 * renderbuffers and some number of stencil renderbuffers and bind them
55 * together in framebuffers in any combination.
56 *
57 * This code manages all that.
58 *
59 * 1. Depth renderbuffers are always allocated in hardware as 32bpp
60 * GL_DEPTH24_STENCIL8 buffers.
61 *
62 * 2. Stencil renderbuffers are initially allocated in software as 8bpp
63 * GL_STENCIL_INDEX8 buffers.
64 *
65 * 3. Depth and Stencil renderbuffers use the PairedStencil and PairedDepth
66 * fields (respectively) to indicate if the buffer's currently paired
67 * with another stencil or depth buffer (respectively).
68 *
69 * 4. When a depth and stencil buffer are initially both attached to the
70 * current framebuffer, we merge the stencil buffer values into the
71 * depth buffer (really a depth+stencil buffer). The then hardware uses
72 * the combined buffer.
73 *
74 * 5. Whenever a depth or stencil buffer is reallocated (with
75 * glRenderbufferStorage) we undo the pairing and copy the stencil values
76 * from the combined depth/stencil buffer back to the stencil-only buffer.
77 *
78 * 6. We also undo the pairing when we find a change in buffer bindings.
79 *
80 * 7. If a framebuffer is only using a depth renderbuffer (no stencil), we
81 * just use the combined depth/stencil buffer and ignore the stencil values.
82 *
83 * 8. If a framebuffer is only using a stencil renderbuffer (no depth) we have
84 * to promote the 8bpp software stencil buffer to a 32bpp hardware
85 * depth+stencil buffer.
86 *
87 */
88
89 /**
90 * Undo the pairing/interleaving between depth and stencil buffers.
91 * irb should be a depth/stencil or stencil renderbuffer.
92 */
93 void
94 intel_unpair_depth_stencil(GLcontext *ctx, struct intel_renderbuffer *irb)
95 {
96 struct intel_context *intel = intel_context(ctx);
97 struct gl_renderbuffer *rb = &irb->Base;
98
99 if (irb->PairedStencil) {
100 /* irb is a depth/stencil buffer */
101 struct gl_renderbuffer *stencilRb;
102 struct intel_renderbuffer *stencilIrb;
103
104 ASSERT(rb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
105
106 stencilRb = _mesa_lookup_renderbuffer(ctx, irb->PairedStencil);
107 stencilIrb = intel_renderbuffer(stencilRb);
108 if (stencilIrb) {
109 /* need to extract stencil values from the depth buffer */
110 ASSERT(stencilIrb->PairedDepth == rb->Name);
111 intel_renderbuffer_map(intel, rb);
112 intel_renderbuffer_map(intel, stencilRb);
113 _mesa_extract_stencil(ctx, rb, stencilRb);
114 intel_renderbuffer_unmap(intel, stencilRb);
115 intel_renderbuffer_unmap(intel, rb);
116 stencilIrb->PairedDepth = 0;
117 }
118 irb->PairedStencil = 0;
119 }
120 else if (irb->PairedDepth) {
121 /* irb is a stencil buffer */
122 struct gl_renderbuffer *depthRb;
123 struct intel_renderbuffer *depthIrb;
124
125 ASSERT(rb->_ActualFormat == GL_STENCIL_INDEX8_EXT ||
126 rb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT);
127
128 depthRb = _mesa_lookup_renderbuffer(ctx, irb->PairedDepth);
129 depthIrb = intel_renderbuffer(depthRb);
130 if (depthIrb) {
131 /* need to extract stencil values from the depth buffer */
132 ASSERT(depthIrb->PairedStencil == rb->Name);
133 intel_renderbuffer_map(intel, rb);
134 intel_renderbuffer_map(intel, depthRb);
135 _mesa_extract_stencil(ctx, depthRb, rb);
136 intel_renderbuffer_unmap(intel, depthRb);
137 intel_renderbuffer_unmap(intel, rb);
138 depthIrb->PairedStencil = 0;
139 }
140 irb->PairedDepth = 0;
141 }
142 else {
143 _mesa_problem(ctx, "Problem in undo_depth_stencil_pairing");
144 }
145
146 ASSERT(irb->PairedStencil == 0);
147 ASSERT(irb->PairedDepth == 0);
148 }
149
150
151 /**
152 * Examine the depth and stencil renderbuffers which are attached to the
153 * framebuffer. If both depth and stencil are attached, make sure that the
154 * renderbuffers are 'paired' (combined). If only depth or only stencil is
155 * attached, undo any previous pairing.
156 *
157 * Must be called if NewState & _NEW_BUFFER (when renderbuffer attachments
158 * change, for example).
159 */
160 void
161 intel_validate_paired_depth_stencil(GLcontext * ctx,
162 struct gl_framebuffer *fb)
163 {
164 struct intel_context *intel = intel_context(ctx);
165 struct intel_renderbuffer *depthRb, *stencilRb;
166
167 depthRb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
168 stencilRb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
169
170 if (depthRb && stencilRb) {
171 if (depthRb == stencilRb) {
172 /* Using a user-created combined depth/stencil buffer.
173 * Nothing to do.
174 */
175 ASSERT(depthRb->Base._BaseFormat == GL_DEPTH_STENCIL_EXT);
176 ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT);
177 }
178 else {
179 /* Separate depth/stencil buffers, need to interleave now */
180 ASSERT(depthRb->Base._BaseFormat == GL_DEPTH_COMPONENT);
181 ASSERT(stencilRb->Base._BaseFormat == GL_STENCIL_INDEX);
182 /* may need to interleave depth/stencil now */
183 if (depthRb->PairedStencil == stencilRb->Base.Name) {
184 /* OK, the depth and stencil buffers are already interleaved */
185 ASSERT(stencilRb->PairedDepth == depthRb->Base.Name);
186 }
187 else {
188 /* need to setup new pairing/interleaving */
189 if (depthRb->PairedStencil) {
190 intel_unpair_depth_stencil(ctx, depthRb);
191 }
192 if (stencilRb->PairedDepth) {
193 intel_unpair_depth_stencil(ctx, stencilRb);
194 }
195
196 ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT);
197 ASSERT(stencilRb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT ||
198 stencilRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT);
199
200 /* establish new pairing: interleave stencil into depth buffer */
201 intel_renderbuffer_map(intel, &depthRb->Base);
202 intel_renderbuffer_map(intel, &stencilRb->Base);
203 _mesa_insert_stencil(ctx, &depthRb->Base, &stencilRb->Base);
204 intel_renderbuffer_unmap(intel, &stencilRb->Base);
205 intel_renderbuffer_unmap(intel, &depthRb->Base);
206 depthRb->PairedStencil = stencilRb->Base.Name;
207 stencilRb->PairedDepth = depthRb->Base.Name;
208 }
209
210 }
211 }
212 else if (depthRb) {
213 /* Depth buffer but no stencil buffer.
214 * We'll use a GL_DEPTH24_STENCIL8 buffer and ignore the stencil bits.
215 */
216 /* can't assert this until storage is allocated:
217 ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT);
218 */
219 /* intel_undo any previous pairing */
220 if (depthRb->PairedStencil) {
221 intel_unpair_depth_stencil(ctx, depthRb);
222 }
223 }
224 else if (stencilRb) {
225 /* Stencil buffer but no depth buffer.
226 * Since h/w doesn't typically support just 8bpp stencil w/out Z,
227 * we'll use a GL_DEPTH24_STENCIL8 buffer and ignore the depth bits.
228 */
229 /* undo any previous pairing */
230 if (stencilRb->PairedDepth) {
231 intel_unpair_depth_stencil(ctx, stencilRb);
232 }
233 if (stencilRb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT) {
234 /* promote buffer to GL_DEPTH24_STENCIL8 for hw rendering */
235 _mesa_promote_stencil(ctx, &stencilRb->Base);
236 ASSERT(stencilRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT);
237 }
238 }
239
240 /* Finally, update the fb->_DepthBuffer and fb->_StencilBuffer fields */
241 _mesa_update_depth_buffer(ctx, fb, BUFFER_DEPTH);
242 if (depthRb && depthRb->PairedStencil)
243 _mesa_update_stencil_buffer(ctx, fb, BUFFER_DEPTH);
244 else
245 _mesa_update_stencil_buffer(ctx, fb, BUFFER_STENCIL);
246
247
248 /* The hardware should use fb->Attachment[BUFFER_DEPTH].Renderbuffer
249 * first, if present, then fb->Attachment[BUFFER_STENCIL].Renderbuffer
250 * if present.
251 */
252 }