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
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
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 parameters 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),
41 use_rect(num_samples
== 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
;
58 : config(0, 0, 0), /* will be overwritten on first call to setup() */
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
));
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;
82 Fbo::attach_color_renderbuffer(const FboConfig
&config
, int index
)
84 glBindRenderbuffer(GL_RENDERBUFFER
, color_rb
[index
]);
85 glRenderbufferStorageMultisample(GL_RENDERBUFFER
,
87 config
.color_internalformat
,
90 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER
,
91 config
.rb_attachment
[index
],
92 GL_RENDERBUFFER
, color_rb
[index
]);
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
);
104 config
.color_internalformat
,
108 config
.color_format
/* format */,
111 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER
,
112 config
.tex_attachment
[index
],
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
,
125 config
.color_internalformat
,
128 GL_TRUE
/* fixed sample locations */);
129 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER
,
130 config
.tex_attachment
[index
],
131 GL_TEXTURE_2D_MULTISAMPLE
,
135 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY
, color_tex
[index
]);
136 glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY
,
138 config
.color_internalformat
,
142 GL_TRUE
/* fixed sample locations */);
143 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER
,
144 config
.tex_attachment
[index
],
147 config
.attachment_layer
);
152 Fbo::set_samples(int num_samples
)
154 FboConfig new_config
= this->config
;
155 new_config
.num_samples
= num_samples
;
160 * Modify the state of the framebuffer object to reflect the state in
161 * new_config. if the resulting framebuffer is incomplete, terminate
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,
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
);
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
);
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
,
232 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER
,
233 GL_DEPTH_STENCIL_ATTACHMENT
,
234 GL_RENDERBUFFER
, depth_rb
);
236 if (config
.stencil_internalformat
!= GL_NONE
) {
237 glBindRenderbuffer(GL_RENDERBUFFER
, stencil_rb
);
238 glRenderbufferStorageMultisample(GL_RENDERBUFFER
,
240 config
.stencil_internalformat
,
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
,
252 config
.depth_internalformat
,
255 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER
,
257 GL_RENDERBUFFER
, depth_rb
);
261 bool success
= glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER
)
262 == GL_FRAMEBUFFER_COMPLETE
;
264 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, piglit_winsys_fbo
);
272 glViewport(0, 0, config
.width
, config
.height
);