static void incomplete_type_error(expression e, type t) { /* Avoid duplicate error message. */ if (t == error_type) return; if (e && is_identifier(e)) error("`%s' has an incomplete type", CAST(identifier, e)->cstring.data); else { while (type_array(t) && type_array_size(t)) t = type_array_of(t); if (type_struct(t)) error("invalid use of undefined type `struct %s'", type_tag(t)->name); else if (type_union(t)) error("invalid use of undefined type `union %s'", type_tag(t)->name); else if (type_enum(t)) error("invalid use of undefined type `enum %s'", type_tag(t)->name); else if (type_void(t)) error("invalid use of void expression"); else if (type_array(t)) error("invalid use of array with unspecified bounds"); else assert(0); /* XXX: Missing special message for typedef's */ } }
/* build an array in reverse order i.e: given values = array< 10, array< 3, int > > and size = 42 (42 must be wrapped inside an expression) return array< 10, array< 3, array< 42, int > > > --> it nest the newly created array inside the one it is given keeping the same basic type */ const struct type * type_new_array_type_reversed(const struct type *values, const struct expression *array_size) { struct type *ty = type_new(TYPE_ARRAY); if (!type_is_array(values)) { ty->array_type.values = values; ty->array_type.array_size = array_size; return ty; } ty->array_type.array_size = type_array_size(values); ty->array_type.values = type_new_array_type(type_array_values(values), array_size); return ty; }
static void dump_fields(region r, const char *prefix, field_declaration fields) { while (fields) { if (fields->name) /* skip anon fields */ { type t = fields->type; printf(" %s%s ", prefix, fields->name); while (type_array(t)) { type base = type_array_of(t); expression size = type_array_size(t); printf("[%lu]", (unsigned long)constant_uint_value(size->cst)); t = base; } dump_type(t); assert(cval_isinteger(fields->offset)); printf(" %lu %lu\n", (unsigned long)cval_uint_value(fields->offset), (unsigned long) (!cval_istop(fields->bitwidth) ? cval_uint_value(fields->bitwidth) : BITSPERBYTE * cval_uint_value(type_size(t)))); if (type_aggregate(t)) { tag_declaration tdecl = type_tag(t); char *newprefix = rarrayalloc(r, strlen(prefix) + strlen(fields->name) + 2, char); sprintf(newprefix, "%s%s.", prefix, fields->name); dump_fields(r, newprefix, tdecl->fieldlist); printf(" %s%s AX\n", prefix, fields->name); } } fields = fields->next; }
/** * Test glDrawElements() with glPrimitiveRestartIndexNV(). */ static bool test_draw_by_index(VBO_CFG vbo_cfg, bool one_by_one, GLenum primMode, GLenum indexType) { #define NUM_VERTS 48 #define NUM_ELEMS (NUM_VERTS * 5 / 4) GLfloat verts[NUM_VERTS+2][2]; GLubyte indices[sizeof(GLuint) * NUM_ELEMS]; GLfloat x, dx; GLuint restart_index; GLuint num_elems; bool pass = true; const char *typeStr = NULL, *primStr = NULL; GLuint vbo1, vbo2; bool create_vbo1 = false; bool create_vbo2 = false; uintptr_t index_offset = 0; uintptr_t vbo_data_size = sizeof(verts) + sizeof(indices); GLuint i, j; if ((vbo_cfg != DISABLE_VBO) && (vbo_cfg != VBO_INDEX_ONLY)) { create_vbo1 = true; } if ((vbo_cfg == VBO_INDEX_ONLY) || (vbo_cfg == VBO_SEPARATE_VERTEX_AND_INDEX)) { create_vbo2 = true; } if ((vbo_cfg == DISABLE_VBO) || (vbo_cfg == VBO_VERTEX_ONLY)) { index_offset = (uintptr_t) indices; } else if (vbo_cfg == VBO_COMBINED_VERTEX_AND_INDEX) { index_offset = sizeof(verts); } else { index_offset = 0; } switch (indexType) { case GL_UNSIGNED_BYTE: restart_index = 255; typeStr = "GL_UNSIGNED_BYTE"; break; case GL_UNSIGNED_SHORT: restart_index = 1000; typeStr = "GL_UNSIGNED_SHORT"; break; case GL_UNSIGNED_INT: restart_index = 1000 * 1000; typeStr = "GL_UNSIGNED_INT"; break; default: assert(0); restart_index = 0; } x = 0.0; dx = 20.0; if (primMode == GL_TRIANGLE_STRIP) { const GLfloat y = 0.5 * piglit_height - 10.0, dy = 20.0; for (i = 0; i < NUM_VERTS / 2; i++) { verts[i*2+0][0] = x; verts[i*2+0][1] = y; verts[i*2+1][0] = x; verts[i*2+1][1] = y + dy; x += dx; } /* setup elements to draw series of squares w/ tri strip */ for (i = j = 0; i < NUM_VERTS; i++) { write_index_value(indices, indexType, j, i); j++; if (i > 0 && i % 4 == 3) { write_index_value(indices, indexType, j, restart_index); j++; } } num_elems = j; primStr = "GL_TRIANGLE_STRIP"; } else { const GLfloat y = 0.5 * piglit_height; assert(primMode == GL_LINE_STRIP); glLineWidth(5.0); for (i = 0; i < NUM_VERTS; i++) { verts[i][0] = x; verts[i][1] = y; x += dx; } /* setup elements to draw series of disjoint lines w/ line strip */ for (i = j = 0; i < NUM_VERTS / 2; i++) { write_index_value(indices, indexType, j, i); j++; if (i > 0 && i % 2 == 1) { write_index_value(indices, indexType, j, restart_index); j++; } } num_elems = j; primStr = "GL_LINE_STRIP"; } assert(num_elems <= NUM_ELEMS); /* debug */ if (0) { for (i = 0; i < num_elems; i++) printf("%2d: %d\n", i, read_index_value(indices, indexType, i)); } piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); glClear(GL_COLOR_BUFFER_BIT); glColor4fv(green); if (create_vbo1) { glGenBuffers(1, &vbo1); glBindBuffer(GL_ARRAY_BUFFER, vbo1); glBufferData(GL_ARRAY_BUFFER, vbo_data_size, NULL, GL_STATIC_DRAW); } if (create_vbo2) { glGenBuffers(1, &vbo2); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo2); glBufferData(GL_ELEMENT_ARRAY_BUFFER, vbo_data_size, NULL, GL_STATIC_DRAW); } else { vbo2 = vbo1; } if (create_vbo1) { /* Load vertex data into VBO */ glBindBuffer(GL_ARRAY_BUFFER, vbo1); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(verts), verts); glVertexPointer(2, GL_FLOAT, 0, (void *)0); } else { glVertexPointer(2, GL_FLOAT, 0, (void *)verts); } if ((vbo_cfg != DISABLE_VBO) && (vbo_cfg != VBO_VERTEX_ONLY)) { /* Load index data into VBO */ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo2); glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, index_offset, type_array_size(indexType, num_elems), indices); } glEnableClientState(GL_VERTEX_ARRAY); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; enable_restart(restart_index); /* Draw */ if (one_by_one) { do_ArrayElement(primMode, num_elems, indexType, indices); } else { glDrawElements(primMode, num_elems, indexType, (void*) index_offset); } disable_restart(); glDisableClientState(GL_VERTEX_ARRAY); if (vbo_cfg != DISABLE_VBO) { glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } if (create_vbo1) { glDeleteBuffers(1, &vbo1); } if (create_vbo2) { glDeleteBuffers(1, &vbo2); } if (!check_rendering()) { fprintf(stderr, "%s: failure drawing with %s(%s, %s), %s\n", TestName, one_by_one ? "glArrayElement" : "glDrawElements", primStr, typeStr, vbo_cfg_names[vbo_cfg]); pass = false; } piglit_present_results(); return pass; #undef NUM_VERTS }