enum piglit_result piglit_display(void) { GLuint vs, fs; bool pass = true; GLuint prog; float green[] = {0.0, 1.0, 0.0, 0.0}; GLint status; /* Initial buffer clear. */ glClearColor(1.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source); prog = piglit_link_simple_program(vs, fs); if (!vs || !fs || !prog) piglit_report_result(PIGLIT_FAIL); piglit_DeleteShader(vs); piglit_DeleteShader(fs); piglit_UseProgram(prog); piglit_DeleteProgram(prog); /* Try to blow out the refcount */ piglit_DeleteProgram(prog); piglit_DeleteProgram(prog); piglit_DeleteProgram(prog); /* Sanity check: deleting didn't already unbind our shader program. */ piglit_draw_rect(-1, -1, 2, 2); pass = piglit_probe_rect_rgba(0, 0, piglit_width, piglit_height, green) && pass; /* The program should still report being deleted. */ piglit_GetProgramiv(prog, GL_DELETE_STATUS, &status); if (!piglit_check_gl_error(0)) piglit_report_result(PIGLIT_FAIL); if (status != GL_TRUE) { fprintf(stderr, "GL_DELETE_STATUS after a clear reported non-true %d\n", status); pass = false; } /* Now, disable the program and it should be finally deleted. */ piglit_UseProgram(0); piglit_GetProgramiv(prog, GL_DELETE_STATUS, &status); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; piglit_present_results(); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
bool do_test(const struct test *tests, unsigned num_tests) { bool pass = true; unsigned i; for (i = 0; i < num_tests; i++) { GLint vert = piglit_compile_shader_text(GL_VERTEX_SHADER, tests[i].code); GLint prog = piglit_link_simple_program(vert, 0); GLint num_attr; unsigned visited_count[64]; unsigned j; bool shader_dumped = false; memset(visited_count, 0, sizeof(visited_count)); /* From page 93 (page 109 of the PDF) says: * * "An attribute variable (either conventional or generic) * is considered active if it is determined by the * compiler and linker that the attribute may be accessed * when the shader is executed. Attribute variables that * are declared in a vertex shader but never used will not * count against the limit. In cases where the compiler * and linker cannot make a conclusive determination, an * attribute will be considered active." * * Compare the set of active attributes against the list of * expected active attributes. */ piglit_GetProgramiv(prog, GL_ACTIVE_ATTRIBUTES, &num_attr); for (j = 0; j < num_attr; j++) { const struct attribute *attr; char name_buf[256]; int attr_idx; GLsizei name_len; GLint size; GLenum type; glGetActiveAttrib(prog, j, sizeof(name_buf), &name_len, &size, &type, name_buf); attr_idx = find_attrib(tests[i].attributes, name_buf); /* If the named attribute is not in the list for the * test, then it must not be active. */ if (attr_idx < 0) { DUMP_SHADER(tests[i].code); fprintf(stderr, "Attribute `%s' should not be active " "but is.\n", name_buf); pass = false; continue; } attr = &tests[i].attributes[attr_idx]; if (visited_count[attr_idx] != 0) { DUMP_SHADER(tests[i].code); fprintf(stderr, "Attribute `%s' listed multiple times " "in active list.\n", name_buf); pass = false; } else if (attr->size != size) { DUMP_SHADER(tests[i].code); fprintf(stderr, "Attribute `%s' should have size %d, " "but had size %d.\n", name_buf, attr->size, size); pass = false; } else if (attr->type != type) { DUMP_SHADER(tests[i].code); fprintf(stderr, "Attribute `%s' should have type " "0x%04x, but had type 0x%04x.\n", name_buf, attr->type, type); pass = false; } visited_count[attr_idx]++; } for (j = 0; tests[i].attributes[j].name != NULL; j++) { if (tests[i].attributes[j].must_be_active && visited_count[j] == 0) { DUMP_SHADER(tests[i].code); fprintf(stderr, "Attribute `%s' should have been " "active but wasn't.\n", tests[i].attributes[j].name); pass = false; } } } return pass; }