glx-multithread-texture: Avoid front-buffer rendering.
[piglit.git] / tests / util / piglit-fbo.cpp
blobdf403d7177cacf11f3c4a3c7419fdbe4cede453c
1 /*
2 * Copyright © 2013 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
24 /**
25 * \file piglit-fbo.cpp
27 * This file defines the functions which can be utilized to develop
28 * new piglit test cases. These functions initialize a framebuffer
29 * object based on paramaters passed.
31 #include "piglit-fbo.h"
32 using namespace piglit_util_fbo;
34 FboConfig::FboConfig(int num_samples, int width, int height)
35 : num_samples(num_samples),
36 num_rb_attachments(1),
37 num_tex_attachments(0),
38 width(width),
39 height(height),
40 layers(0),
41 use_rect(num_samples == 0),
42 attachment_layer(0),
43 combine_depth_stencil(true),
44 color_format(GL_RGBA),
45 color_internalformat(GL_RGBA),
46 depth_internalformat(GL_DEPTH_COMPONENT24),
47 stencil_internalformat(GL_STENCIL_INDEX8)
49 memset(rb_attachment, 0, PIGLIT_MAX_COLOR_ATTACHMENTS * sizeof(GLuint));
50 memset(tex_attachment, 0, PIGLIT_MAX_COLOR_ATTACHMENTS * sizeof(GLuint));
52 /* Set default values for single renderbuffer and texture attachment. */
53 rb_attachment[0] = GL_COLOR_ATTACHMENT0;
54 tex_attachment[0] = GL_COLOR_ATTACHMENT0;
57 Fbo::Fbo()
58 : config(0, 0, 0), /* will be overwritten on first call to setup() */
59 handle(0),
60 depth_rb(0),
61 stencil_rb(0),
62 gl_objects_generated(false)
64 memset(color_tex, 0, PIGLIT_MAX_COLOR_ATTACHMENTS * sizeof(GLuint));
65 memset(color_rb, 0, PIGLIT_MAX_COLOR_ATTACHMENTS * sizeof(GLuint));
68 void
69 Fbo::generate_gl_objects(void)
71 GLint max_color_attachments;
72 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
73 glGenFramebuffers(1, &handle);
74 glGenTextures(max_color_attachments, color_tex);
75 glGenRenderbuffers(max_color_attachments, color_rb);
76 glGenRenderbuffers(1, &depth_rb);
77 glGenRenderbuffers(1, &stencil_rb);
78 gl_objects_generated = true;
81 void
82 Fbo::attach_color_renderbuffer(const FboConfig &config, int index)
84 glBindRenderbuffer(GL_RENDERBUFFER, color_rb[index]);
85 glRenderbufferStorageMultisample(GL_RENDERBUFFER,
86 config.num_samples,
87 config.color_internalformat,
88 config.width,
89 config.height);
90 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
91 config.rb_attachment[index],
92 GL_RENDERBUFFER, color_rb[index]);
95 void
96 Fbo::attach_color_texture(const FboConfig &config, int index)
98 GLenum target = config.use_rect ? GL_TEXTURE_RECTANGLE : GL_TEXTURE_2D;
99 glBindTexture(target, color_tex[index]);
100 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
101 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
102 glTexImage2D(target,
103 0 /* level */,
104 config.color_internalformat,
105 config.width,
106 config.height,
107 0 /* border */,
108 config.color_format /* format */,
109 GL_BYTE /* type */,
110 NULL /* data */);
111 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
112 config.tex_attachment[index],
113 target,
114 color_tex[index],
115 0 /* level */);
118 void
119 Fbo::attach_multisample_color_texture(const FboConfig &config, int index)
121 if (config.layers == 0) {
122 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, color_tex[index]);
123 glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE,
124 config.num_samples,
125 config.color_internalformat,
126 config.width,
127 config.height,
128 GL_TRUE /* fixed sample locations */);
129 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
130 config.tex_attachment[index],
131 GL_TEXTURE_2D_MULTISAMPLE,
132 color_tex[index],
133 0 /* level */);
134 } else {
135 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, color_tex[index]);
136 glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
137 config.num_samples,
138 config.color_internalformat,
139 config.width,
140 config.height,
141 config.layers,
142 GL_TRUE /* fixed sample locations */);
143 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER,
144 config.tex_attachment[index],
145 color_tex[index],
146 0 /* level */,
147 config.attachment_layer);
151 void
152 Fbo::set_samples(int num_samples)
154 FboConfig new_config = this->config;
155 new_config.num_samples = num_samples;
156 setup(new_config);
160 * Modify the state of the framebuffer object to reflect the state in
161 * new_config. if the resulting framebuffer is incomplete, terminate
162 * the test.
164 void
165 Fbo::setup(const FboConfig &new_config)
167 GLint max_attachments;
168 GLint requested_attachments = new_config.num_rb_attachments +
169 new_config.num_tex_attachments;
170 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_attachments);
172 if (requested_attachments > max_attachments) {
173 printf("Number of color attachments are not supported by the"
174 " implementation.\nattachments requested = %d,"
175 " max attachments supported = %d\n",
176 requested_attachments, max_attachments);
177 piglit_report_result(PIGLIT_SKIP);
180 if (!try_setup(new_config)) {
181 printf("Framebuffer not complete\n");
182 piglit_report_result(PIGLIT_SKIP);
187 * Modify the state of the framebuffer object to reflect the state in
188 * config. Return true if the resulting framebuffer is complete,
189 * false otherwise.
191 bool
192 Fbo::try_setup(const FboConfig &new_config)
194 this->config = new_config;
196 if (!gl_objects_generated)
197 generate_gl_objects();
199 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, handle);
201 /* Color buffer */
202 if (config.color_internalformat != GL_NONE) {
204 /* Attach renderbuffers as color attachments */
205 for (int i = 0; i < config.num_rb_attachments; i++)
206 attach_color_renderbuffer(new_config, i);
208 if (config.num_samples == 0) {
210 /* Attach textures as color attachments */
211 piglit_require_extension("GL_ARB_texture_rectangle");
212 for (int i = 0; i < config.num_tex_attachments; i++)
213 attach_color_texture(new_config, i);
215 } else {
217 /* Attach multisample textures as color attachments */
218 piglit_require_extension("GL_ARB_texture_multisample");
219 for (int i = 0; i < config.num_tex_attachments; i++)
220 attach_multisample_color_texture(new_config, i);
224 /* Depth/stencil buffer(s) */
225 if (config.combine_depth_stencil) {
226 glBindRenderbuffer(GL_RENDERBUFFER, depth_rb);
227 glRenderbufferStorageMultisample(GL_RENDERBUFFER,
228 config.num_samples,
229 GL_DEPTH_STENCIL,
230 config.width,
231 config.height);
232 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
233 GL_DEPTH_STENCIL_ATTACHMENT,
234 GL_RENDERBUFFER, depth_rb);
235 } else {
236 if (config.stencil_internalformat != GL_NONE) {
237 glBindRenderbuffer(GL_RENDERBUFFER, stencil_rb);
238 glRenderbufferStorageMultisample(GL_RENDERBUFFER,
239 config.num_samples,
240 config.stencil_internalformat,
241 config.width,
242 config.height);
243 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
244 GL_STENCIL_ATTACHMENT,
245 GL_RENDERBUFFER, stencil_rb);
248 if (config.depth_internalformat != GL_NONE) {
249 glBindRenderbuffer(GL_RENDERBUFFER, depth_rb);
250 glRenderbufferStorageMultisample(GL_RENDERBUFFER,
251 config.num_samples,
252 config.depth_internalformat,
253 config.width,
254 config.height);
255 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
256 GL_DEPTH_ATTACHMENT,
257 GL_RENDERBUFFER, depth_rb);
261 bool success = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)
262 == GL_FRAMEBUFFER_COMPLETE;
264 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, piglit_winsys_fbo);
266 return success;
269 void
270 Fbo::set_viewport()
272 glViewport(0, 0, config.width, config.height);