OpenGL: don't poll for errors, rely on KHR_debug

Errors are caught & reported by our GL debug callback. This gives us way more useful information than sporadic calls to glGetError.

I removed almost all use of glGetError, including our own GPU_ASSERT_NO_GL_ERRORS and GPU_CHECK_ERRORS_AROUND macros.

Still used in rna_Image_gl_load because it passes unvalidated input to OpenGL functions.

Still used in gpu_state_print_fl_ex as an exception handling hack -- will rewrite this soon.

The optimism embodied by this commit will not prevent OpenGL errors. We need to analyze what would cause GL to fail at certain points and proactively intercept these failures. Or guarantee they can't happen.
This commit is contained in:
Mike Erwin 2016-08-19 00:52:52 -04:00
parent d8f036efd6
commit 7e02d335c0
12 changed files with 47 additions and 260 deletions

View File

@ -757,11 +757,6 @@ static void init_internal_icons(void)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
if (glGetError() == GL_OUT_OF_MEMORY) {
glDeleteTextures(1, &icongltex.id);
icongltex.id = 0;
}
}
}
}

View File

@ -41,24 +41,9 @@ extern "C" {
/* prints something if debug mode is active only */
void GPU_print_error_debug(const char *str);
/* replacement for gluErrorString */
const char *gpuErrorString(GLenum err);
/* prints current OpenGL state */
void GPU_state_print(void);
void GPU_assert_no_gl_errors(const char *file, int line, const char *str);
# define GPU_ASSERT_NO_GL_ERRORS(str) GPU_assert_no_gl_errors(__FILE__, __LINE__, (str))
# define GPU_CHECK_ERRORS_AROUND(glProcCall) \
( \
GPU_ASSERT_NO_GL_ERRORS("Pre: " #glProcCall), \
(glProcCall), \
GPU_ASSERT_NO_GL_ERRORS("Post: " #glProcCall) \
)
/* inserts a debug marker message for the debug context messaging system */
void GPU_string_marker(const char *str);

View File

@ -50,7 +50,7 @@ struct GPUTexture;
void GPU_texture_bind_as_framebuffer(struct GPUTexture *tex);
GPUFrameBuffer *GPU_framebuffer_create(void);
int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, struct GPUTexture *tex, int slot, char err_out[256]);
bool GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, struct GPUTexture *tex, int slot);
void GPU_framebuffer_texture_detach(struct GPUTexture *tex);
void GPU_framebuffer_slots_bind(GPUFrameBuffer *fb, int slot);
void GPU_framebuffer_texture_unbind(GPUFrameBuffer *fb, struct GPUTexture *tex);

View File

@ -582,11 +582,8 @@ bool GPU_fx_compositor_initialize_passes(
/* bind the buffers */
/* first depth buffer, because system assumes read/write buffers */
if (!GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer, 0, err_out))
printf("%.256s\n", err_out);
if (!GPU_framebuffer_texture_attach(fx->gbuffer, fx->color_buffer, 0, err_out))
printf("%.256s\n", err_out);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer, 0);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->color_buffer, 0);
if (!GPU_framebuffer_check_valid(fx->gbuffer, err_out))
printf("%.256s\n", err_out);
@ -631,7 +628,7 @@ static void gpu_fx_bind_render_target(int *passes_left, GPUFX *fx, struct GPUOff
}
else {
/* bind the ping buffer to the color buffer */
GPU_framebuffer_texture_attach(fx->gbuffer, target, 0, NULL);
GPU_framebuffer_texture_attach(fx->gbuffer, target, 0);
}
}
@ -660,8 +657,7 @@ void GPU_fx_compositor_setup_XRay_pass(GPUFX *fx, bool do_xray)
GPU_framebuffer_texture_detach(fx->depth_buffer);
/* first depth buffer, because system assumes read/write buffers */
if (!GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer_xray, 0, err_out))
printf("%.256s\n", err_out);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer_xray, 0);
}
@ -671,7 +667,7 @@ void GPU_fx_compositor_XRay_resolve(GPUFX *fx)
GPU_framebuffer_texture_detach(fx->depth_buffer_xray);
/* attach regular framebuffer */
GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer, 0, NULL);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer, 0);
/* full screen quad where we will always write to depth buffer */
glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_SCISSOR_BIT);
@ -919,9 +915,9 @@ bool GPU_fx_do_composite_pass(
GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, src);
/* target is the downsampled coc buffer */
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_half_downsampled_near, 0, NULL);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_half_downsampled_far, 1, NULL);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_nearfar_coc, 2, NULL);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_half_downsampled_near, 0);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_half_downsampled_far, 1);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_nearfar_coc, 2);
/* binding takes care of setting the viewport to the downsampled size */
GPU_framebuffer_slots_bind(fx->gbuffer, 0);
@ -965,7 +961,7 @@ bool GPU_fx_do_composite_pass(
GPU_texture_filter_mode(fx->dof_half_downsampled_far, false, false);
/* target is the downsampled coc buffer */
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_far_blur, 0, NULL);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_far_blur, 0);
GPU_texture_bind_as_framebuffer(fx->dof_far_blur);
glDisable(GL_DEPTH_TEST);
@ -989,7 +985,7 @@ bool GPU_fx_do_composite_pass(
GPU_shader_uniform_vector(dof_shader_pass2, interface->select_uniform, 2, 1, selection);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_blur, 0, NULL);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_blur, 0);
/* have to clear the buffer unfortunately */
glClear(GL_COLOR_BUFFER_BIT);
/* the draw call we all waited for, draw a point per pixel, scaled per circle of confusion */
@ -1108,7 +1104,7 @@ bool GPU_fx_do_composite_pass(
GPU_shader_uniform_texture(dof_shader_pass1, interface->depth_uniform, fx->depth_buffer);
/* target is the downsampled coc buffer */
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_buffer, 0, NULL);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_buffer, 0);
/* binding takes care of setting the viewport to the downsampled size */
GPU_texture_bind_as_framebuffer(fx->dof_near_coc_buffer);
@ -1148,7 +1144,7 @@ bool GPU_fx_do_composite_pass(
GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_near_coc_buffer);
/* use final buffer as a temp here */
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_final_buffer, 0, NULL);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_final_buffer, 0);
/* Drawing quad */
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
@ -1165,7 +1161,7 @@ bool GPU_fx_do_composite_pass(
GPU_texture_bind(fx->dof_near_coc_final_buffer, numslots++);
GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_near_coc_final_buffer);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_blurred_buffer, 0, NULL);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_blurred_buffer, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
/* *unbind/detach */
@ -1192,7 +1188,7 @@ bool GPU_fx_do_composite_pass(
GPU_texture_bind(fx->dof_near_coc_blurred_buffer, numslots++);
GPU_shader_uniform_texture(dof_shader_pass3, interface->near_coc_blurred, fx->dof_near_coc_blurred_buffer);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_final_buffer, 0, NULL);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_final_buffer, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
/* disable bindings */
@ -1218,7 +1214,7 @@ bool GPU_fx_do_composite_pass(
GPU_shader_uniform_texture(dof_shader_pass4, interface->near_coc_downsampled, fx->dof_near_coc_final_buffer);
GPU_shader_uniform_vector(dof_shader_pass4, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_buffer, 0, NULL);
GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_buffer, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
/* disable bindings */

View File

@ -43,113 +43,6 @@
#include <stdlib.h>
#include <string.h>
#define CASE_CODE_RETURN_STR(code) case code: return #code;
static const char *gpu_gl_error_symbol(GLenum err)
{
switch (err) {
CASE_CODE_RETURN_STR(GL_NO_ERROR)
CASE_CODE_RETURN_STR(GL_INVALID_ENUM)
CASE_CODE_RETURN_STR(GL_INVALID_VALUE)
CASE_CODE_RETURN_STR(GL_INVALID_OPERATION)
CASE_CODE_RETURN_STR(GL_STACK_OVERFLOW)
CASE_CODE_RETURN_STR(GL_STACK_UNDERFLOW)
CASE_CODE_RETURN_STR(GL_OUT_OF_MEMORY)
#if GL_ARB_imaging
CASE_CODE_RETURN_STR(GL_TABLE_TOO_LARGE)
#endif
#if defined(WITH_GLU)
CASE_CODE_RETURN_STR(GLU_INVALID_ENUM)
CASE_CODE_RETURN_STR(GLU_INVALID_VALUE)
CASE_CODE_RETURN_STR(GLU_OUT_OF_MEMORY)
#endif
default:
return "<unknown error>";
}
}
#undef CASE_CODE_RETURN_STR
static bool gpu_report_gl_errors(const char *file, int line, const char *str)
{
GLenum gl_error = glGetError();
if (gl_error == GL_NO_ERROR) {
return true;
}
else {
/* glGetError should have cleared the error flag, so if we get the
* same flag twice that means glGetError itself probably triggered
* the error. This happens on Windows if the GL context is invalid.
*/
{
GLenum new_error = glGetError();
if (gl_error == new_error) {
fprintf(stderr, "GL: Possible context invalidation issue\n");
return false;
}
}
fprintf(stderr,
"%s:%d: ``%s'' -> GL Error (0x%04X - %s): %s\n",
file, line, str, gl_error,
gpu_gl_error_symbol(gl_error),
gpuErrorString(gl_error));
return false;
}
}
const char *gpuErrorString(GLenum err)
{
switch (err) {
case GL_NO_ERROR:
return "No Error";
case GL_INVALID_ENUM:
return "Invalid Enumeration";
case GL_INVALID_VALUE:
return "Invalid Value";
case GL_INVALID_OPERATION:
return "Invalid Operation";
case GL_STACK_OVERFLOW:
return "Stack Overflow";
case GL_STACK_UNDERFLOW:
return "Stack Underflow";
case GL_OUT_OF_MEMORY:
return "Out of Memory";
#if GL_ARB_imaging
case GL_TABLE_TOO_LARGE:
return "Table Too Large";
#endif
#if defined(WITH_GLU)
case GLU_INVALID_ENUM:
return "Invalid Enum (GLU)";
case GLU_INVALID_VALUE:
return "Invalid Value (GLU)";
case GLU_OUT_OF_MEMORY:
return "Out of Memory (GLU)";
#endif
default:
return "<unknown error>";
}
}
/* Debug callbacks need the same calling convention as OpenGL functions.
*/
@ -400,18 +293,6 @@ void GPU_print_error_debug(const char *str)
fprintf(stderr, "GPU: %s\n", str);
}
void GPU_assert_no_gl_errors(const char *file, int line, const char *str)
{
if (G.debug) {
GLboolean gl_ok = gpu_report_gl_errors(file, line, str);
BLI_assert(gl_ok);
(void) gl_ok;
}
}
static void gpu_state_print_fl_ex(const char *name, GLenum type)
{
const unsigned char err_mark[4] = {0xff, 0xff, 0xff, 0xff};
@ -438,7 +319,8 @@ static void gpu_state_print_fl_ex(const char *name, GLenum type)
void GPU_state_print(void)
{
GPU_ASSERT_NO_GL_ERRORS("GPU_state_print"); /* clear any errors */
/* clear any errors */
while (glGetError() != GL_NO_ERROR) {}
gpu_state_print_fl(GL_ACCUM_ALPHA_BITS);
gpu_state_print_fl(GL_ACCUM_BLUE_BITS);

View File

@ -98,8 +98,7 @@ GPUFrameBuffer *GPU_framebuffer_create(void)
glGenFramebuffers(1, &fb->object);
if (!fb->object) {
fprintf(stderr, "GPUFFrameBuffer: framebuffer gen failed. %d\n",
(int)glGetError());
fprintf(stderr, "GPUFFrameBuffer: framebuffer gen failed.\n");
GPU_framebuffer_free(fb);
return NULL;
}
@ -113,16 +112,15 @@ GPUFrameBuffer *GPU_framebuffer_create(void)
return fb;
}
int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, char err_out[256])
bool GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot)
{
GLenum attachment;
GLenum error;
if (slot >= GPU_FB_MAX_SLOTS) {
fprintf(stderr,
"Attaching to index %d framebuffer slot unsupported. "
"Use at most %d\n", slot, GPU_FB_MAX_SLOTS);
return 0;
return false;
}
if ((G.debug & G_DEBUG)) {
@ -141,20 +139,9 @@ int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot
glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
GG.currentfb = fb->object;
/* Clean glError buffer. */
while (glGetError() != GL_NO_ERROR) {}
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment,
GPU_texture_target(tex), GPU_texture_opengl_bindcode(tex), 0);
error = glGetError();
if (error == GL_INVALID_OPERATION) {
GPU_framebuffer_restore();
GPU_print_framebuffer_error(error, err_out);
return 0;
}
if (GPU_texture_depth(tex))
fb->depthtex = tex;
else
@ -162,7 +149,7 @@ int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot
GPU_texture_framebuffer_set(tex, fb, slot);
return 1;
return true;
}
void GPU_framebuffer_texture_detach(GPUTexture *tex)
@ -306,22 +293,17 @@ bool GPU_framebuffer_bound(GPUFrameBuffer *fb)
bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256])
{
GLenum status;
glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
GG.currentfb = fb->object;
/* Clean glError buffer. */
while (glGetError() != GL_NO_ERROR) {}
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
GPU_framebuffer_restore();
GPU_print_framebuffer_error(status, err_out);
return false;
}
return true;
}
@ -466,7 +448,7 @@ GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, char err_
return NULL;
}
if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, 0, err_out)) {
if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, 0)) {
GPU_offscreen_free(ofs);
return NULL;
}
@ -477,7 +459,7 @@ GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, char err_
return NULL;
}
if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->color, 0, err_out)) {
if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->color, 0)) {
GPU_offscreen_free(ofs);
return NULL;
}
@ -594,8 +576,6 @@ finally:
if (fbo_blit) {
glDeleteFramebuffers(1, &fbo_blit);
}
GPU_ASSERT_NO_GL_ERRORS("Read Multi-Sample Pixels");
}
else {
glReadPixels(0, 0, w, h, GL_RGBA, type, pixels);

View File

@ -2384,7 +2384,7 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
return lamp;
}
if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, 0, NULL)) {
if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, 0)) {
gpu_lamp_shadow_free(lamp);
return lamp;
}
@ -2396,7 +2396,7 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
return lamp;
}
if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0, NULL)) {
if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0)) {
gpu_lamp_shadow_free(lamp);
return lamp;
}
@ -2419,7 +2419,7 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
return lamp;
}
if (!GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, 0, NULL)) {
if (!GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, 0)) {
gpu_lamp_shadow_free(lamp);
return lamp;
}
@ -2441,7 +2441,7 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
return lamp;
}
if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0, NULL)) {
if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0)) {
gpu_lamp_shadow_free(lamp);
return lamp;
}

View File

@ -470,16 +470,12 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
void GPU_shader_bind(GPUShader *shader)
{
GPU_ASSERT_NO_GL_ERRORS("Pre Shader Bind");
glUseProgram(shader->program);
GPU_ASSERT_NO_GL_ERRORS("Post Shader Bind");
}
void GPU_shader_unbind(void)
{
GPU_ASSERT_NO_GL_ERRORS("Pre Shader Unbind");
glUseProgram(0);
GPU_ASSERT_NO_GL_ERRORS("Post Shader Unbind");
}
void GPU_shader_free(GPUShader *shader)
@ -519,16 +515,12 @@ void GPU_shader_uniform_vector(GPUShader *UNUSED(shader), int location, int leng
if (location == -1 || value == NULL)
return;
GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Vector");
if (length == 1) glUniform1fv(location, arraysize, value);
else if (length == 2) glUniform2fv(location, arraysize, value);
else if (length == 3) glUniform3fv(location, arraysize, value);
else if (length == 4) glUniform4fv(location, arraysize, value);
else if (length == 9) glUniformMatrix3fv(location, arraysize, 0, value);
else if (length == 16) glUniformMatrix4fv(location, arraysize, 0, value);
GPU_ASSERT_NO_GL_ERRORS("Post Uniform Vector");
}
void GPU_shader_uniform_vector_int(GPUShader *UNUSED(shader), int location, int length, int arraysize, const int *value)
@ -536,14 +528,10 @@ void GPU_shader_uniform_vector_int(GPUShader *UNUSED(shader), int location, int
if (location == -1)
return;
GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Vector");
if (length == 1) glUniform1iv(location, arraysize, value);
else if (length == 2) glUniform2iv(location, arraysize, value);
else if (length == 3) glUniform3iv(location, arraysize, value);
else if (length == 4) glUniform4iv(location, arraysize, value);
GPU_ASSERT_NO_GL_ERRORS("Post Uniform Vector");
}
void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value)
@ -551,7 +539,7 @@ void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value)
if (location == -1)
return;
GPU_CHECK_ERRORS_AROUND(glUniform1i(location, value));
glUniform1i(location, value);
}
void GPU_shader_geometry_stage_primitive_io(GPUShader *shader, int input, int output, int number)
@ -582,8 +570,6 @@ void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUText
if (location == -1)
return;
GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Texture");
arbnumber = (GLenum)((GLuint)GL_TEXTURE0 + number);
if (number != 0) glActiveTexture(arbnumber);
@ -594,17 +580,11 @@ void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUText
glUniform1i(location, number);
glEnable(target);
if (number != 0) glActiveTexture(GL_TEXTURE0);
GPU_ASSERT_NO_GL_ERRORS("Post Uniform Texture");
}
int GPU_shader_get_attribute(GPUShader *shader, const char *name)
{
int index;
GPU_CHECK_ERRORS_AROUND(index = glGetAttribLocation(shader->program, name));
return index;
return glGetAttribLocation(shader->program, name);
}
GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)

View File

@ -117,12 +117,10 @@ static GPUTexture *GPU_texture_create_nD(
if (!tex->bindcode) {
if (err_out) {
BLI_snprintf(err_out, 256, "GPUTexture: texture create failed: %d",
(int)glGetError());
BLI_snprintf(err_out, 256, "GPUTexture: texture create failed");
}
else {
fprintf(stderr, "GPUTexture: texture create failed: %d\n",
(int)glGetError());
fprintf(stderr, "GPUTexture: texture create failed");
}
GPU_texture_free(tex);
return NULL;
@ -260,8 +258,7 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, const f
glGenTextures(1, &tex->bindcode);
if (!tex->bindcode) {
fprintf(stderr, "GPUTexture: texture create failed: %d\n",
(int)glGetError());
fprintf(stderr, "GPUTexture: texture create failed");
GPU_texture_free(tex);
return NULL;
}
@ -269,8 +266,6 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, const f
tex->number = 0;
glBindTexture(tex->target, tex->bindcode);
GPU_ASSERT_NO_GL_ERRORS("3D glBindTexture");
type = GL_FLOAT;
if (channels == 4) {
format = GL_RGBA;
@ -308,8 +303,6 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, const f
pixels = GPU_texture_convert_pixels(w*h*depth, fpixels);
#endif
GPU_ASSERT_NO_GL_ERRORS("3D glTexImage3D");
/* hardcore stuff, 3D texture rescaling - warning, this is gonna hurt your performance a lot, but we need it
* for gooseberry */
if (rescale && fpixels) {
@ -346,14 +339,10 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, const f
MEM_freeN(tex3d);
}
else {
if (fpixels) {
glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, fpixels);
GPU_ASSERT_NO_GL_ERRORS("3D glTexSubImage3D");
}
else if (fpixels) {
glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, fpixels);
}
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@ -400,7 +389,7 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget
ima->gputexture[gputt] = tex;
if (!glIsTexture(tex->bindcode)) {
GPU_ASSERT_NO_GL_ERRORS("Blender Texture Not Loaded");
GPU_print_error_debug("Blender Texture Not Loaded");
}
else {
GLint w, h, border;
@ -454,7 +443,7 @@ GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
prv->gputexture[0] = tex;
if (!glIsTexture(tex->bindcode)) {
GPU_ASSERT_NO_GL_ERRORS("Blender Texture Not Loaded");
GPU_print_error_debug("Blender Texture Not Loaded");
}
else {
GLint w, h;
@ -625,8 +614,6 @@ void GPU_texture_bind(GPUTexture *tex, int number)
if (number < 0)
return;
GPU_ASSERT_NO_GL_ERRORS("Pre Texture Bind");
GLenum arbnumber = (GLenum)((GLuint)GL_TEXTURE0 + number);
if (number != 0) glActiveTexture(arbnumber);
if (tex->bindcode != 0) {
@ -638,8 +625,6 @@ void GPU_texture_bind(GPUTexture *tex, int number)
if (number != 0) glActiveTexture(GL_TEXTURE0);
tex->number = number;
GPU_ASSERT_NO_GL_ERRORS("Post Texture Bind");
}
void GPU_texture_unbind(GPUTexture *tex)
@ -651,8 +636,6 @@ void GPU_texture_unbind(GPUTexture *tex)
if (tex->number == -1)
return;
GPU_ASSERT_NO_GL_ERRORS("Pre Texture Unbind");
GLenum arbnumber = (GLenum)((GLuint)GL_TEXTURE0 + tex->number);
if (tex->number != 0) glActiveTexture(arbnumber);
@ -661,8 +644,6 @@ void GPU_texture_unbind(GPUTexture *tex)
if (tex->number != 0) glActiveTexture(GL_TEXTURE0);
tex->number = -1;
GPU_ASSERT_NO_GL_ERRORS("Post Texture Unbind");
}
int GPU_texture_bound_number(GPUTexture *tex)
@ -680,8 +661,6 @@ void GPU_texture_filter_mode(GPUTexture *tex, bool compare, bool use_filter)
if (tex->number == -1)
return;
GPU_ASSERT_NO_GL_ERRORS("Pre Texture Unbind");
GLenum arbnumber = (GLenum)((GLuint)GL_TEXTURE0 + tex->number);
if (tex->number != 0) glActiveTexture(arbnumber);
@ -701,8 +680,6 @@ void GPU_texture_filter_mode(GPUTexture *tex, bool compare, bool use_filter)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
if (tex->number != 0) glActiveTexture(GL_TEXTURE0);
GPU_ASSERT_NO_GL_ERRORS("Post Texture Unbind");
}
void GPU_texture_free(GPUTexture *tex)

View File

@ -251,6 +251,8 @@ static int rna_Image_gl_load(Image *image, ReportList *reports, int frame, int f
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLint)filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLint)mag);
/* TODO(merwin): validate input (dimensions, filter, mag) before calling OpenGL
* instead of trusting input & testing for error after */
error = glGetError();
if (error) {

View File

@ -376,7 +376,7 @@ static void wm_draw_triple_fail(bContext *C, wmWindow *win)
wm_method_draw_overlap_all(C, win, 0);
}
static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple)
static bool wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple)
{
const int winsize_x = WM_window_pixels_x(win);
const int winsize_y = WM_window_pixels_y(win);
@ -400,7 +400,7 @@ static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple)
if (!triple->bind) {
/* not the typical failure case but we handle it anyway */
printf("WM: failed to allocate texture for triple buffer drawing (glGenTextures).\n");
return 0;
return false;
}
/* proxy texture is only guaranteed to test for the cases that
@ -411,7 +411,7 @@ static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple)
glBindTexture(triple->target, 0);
printf("WM: failed to allocate texture for triple buffer drawing "
"(texture too large for graphics card).\n");
return 0;
return false;
}
/* setup actual texture */
@ -421,13 +421,7 @@ static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple)
glTexParameteri(triple->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(triple->target, 0);
/* not sure if this works everywhere .. */
if (glGetError() == GL_OUT_OF_MEMORY) {
printf("WM: failed to allocate texture for triple buffer drawing (out of memory).\n");
return 0;
}
return 1;
return true;
}
void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha)

View File

@ -68,8 +68,6 @@
#include "RNA_access.h"
#include "GPU_debug.h"
#include "UI_interface.h"
#include "PIL_time.h"
@ -2526,8 +2524,6 @@ void wm_event_do_handlers(bContext *C)
/* update key configuration after handling events */
WM_keyconfig_update(wm);
GPU_ASSERT_NO_GL_ERRORS("wm_event_do_handlers");
}
/* ********** filesector handling ************ */