⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 indirect_vertex_array.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 4 页
字号:
    else {	arrays->DrawArrays = emit_DrawArrays_none;	arrays->DrawElements = emit_DrawElements_none;    }    arrays->array_info_cache_valid = GL_TRUE;}/** * Emit a \c glDrawArrays command using the "none" protocol.  That is, * emit immediate-mode commands that are equivalent to the requiested * \c glDrawArrays command.  This is used with servers that don't support * the OpenGL 1.1 / EXT_vertex_arrays DrawArrays protocol or in cases where * vertex state is enabled that is not compatible with that protocol. */voidemit_DrawArrays_none( GLenum mode, GLint first, GLsizei count ){    __GLXcontext *gc = __glXGetCurrentContext();    const __GLXattribute * state =        (const __GLXattribute *)(gc->client_state_private);    struct array_state_vector * arrays = state->array_state;    size_t single_vertex_size;    GLubyte * pc;    unsigned  i;    static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };    static const uint16_t end_cmd[2]   = { 4, X_GLrop_End };    single_vertex_size = calculate_single_vertex_size_none( arrays );    pc = gc->pc;    (void) memcpy( pc, begin_cmd, 4 );    *(int *)(pc +  4) = mode;    pc += 8;    for ( i = 0 ; i < count ; i++ ) {	if ( (pc + single_vertex_size) >= gc->bufEnd ) {	    pc = __glXFlushRenderBuffer(gc, pc);	}	pc = emit_element_none( pc, arrays, first + i );    }    if ( (pc + 4) >= gc->bufEnd ) {	pc = __glXFlushRenderBuffer(gc, pc);    }    (void) memcpy( pc, end_cmd, 4 );    pc += 4;    gc->pc = pc;    if ( gc->pc > gc->limit ) {	(void) __glXFlushRenderBuffer(gc, gc->pc);    }}/** * Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays * protocol. *  * \param gc                    GLX context. * \param arrays                Array state. * \param elements_per_request  Location to store the number of elements that *                              can fit in a single Render / RenderLarge *                              command. * \param total_request         Total number of requests for a RenderLarge *                              command.  If a Render command is used, this *                              will be zero. * \param mode                  Drawing mode. * \param count                 Number of vertices. *  * \returns * A pointer to the buffer for array data. */static GLubyte *emit_DrawArrays_header_old( __GLXcontext * gc,			    struct array_state_vector * arrays,			    size_t * elements_per_request,			    unsigned int * total_requests,			    GLenum mode, GLsizei count ){    size_t command_size;    size_t single_vertex_size;    const unsigned header_size = 16;    unsigned  i;    GLubyte * pc;    /* Determine the size of the whole command.  This includes the header,     * the ARRAY_INFO data and the array data.  Once this size is calculated,     * it will be known whether a Render or RenderLarge command is needed.     */    single_vertex_size = 0;    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {	if ( arrays->arrays[i].enabled ) {	    single_vertex_size += __GLX_PAD( arrays->arrays[i].element_size );	}    }    command_size = arrays->array_info_cache_size + header_size       + (single_vertex_size * count);    /* Write the header for either a Render command or a RenderLarge     * command.  After the header is written, write the ARRAY_INFO data.     */    if ( command_size > gc->maxSmallRenderCommandSize ) {	/* maxSize is the maximum amount of data can be stuffed into a single	 * packet.  sz_xGLXRenderReq is added because bufSize is the maximum	 * packet size minus sz_xGLXRenderReq.	 */	const size_t maxSize = (gc->bufSize + sz_xGLXRenderReq)	  - sz_xGLXRenderLargeReq;	unsigned vertex_requests;	/* Calculate the number of data packets that will be required to send	 * the whole command.  To do this, the number of verticies that	 * will fit in a single buffer must be calculated.	 * 	 * The important value here is elements_per_request.  This is the	 * number of complete array elements that will fit in a single	 * buffer.  There may be some wasted space at the end of the buffer,	 * but splitting elements across buffer boundries would be painful.	 */	elements_per_request[0] = maxSize / single_vertex_size;	vertex_requests = (count + elements_per_request[0] - 1)	  / elements_per_request[0];	  	*total_requests = vertex_requests + 1;	__glXFlushRenderBuffer(gc, gc->pc);	command_size += 4;	pc = ((GLubyte *) arrays->array_info_cache) - (header_size + 4);	*(uint32_t *)(pc +  0) = command_size;	*(uint32_t *)(pc +  4) = X_GLrop_DrawArrays;	*(uint32_t *)(pc +  8) = count;	*(uint32_t *)(pc + 12) = arrays->enabled_client_array_count;	*(uint32_t *)(pc + 16) = mode;	__glXSendLargeChunk( gc, 1, *total_requests, pc,			     header_size + 4 + arrays->array_info_cache_size );	pc = gc->pc;    }    else {	if ( (gc->pc + command_size) >= gc->bufEnd ) {	    (void) __glXFlushRenderBuffer(gc, gc->pc);	}	pc = gc->pc;	*(uint16_t *)(pc +  0) = command_size;	*(uint16_t *)(pc +  2) = X_GLrop_DrawArrays;	*(uint32_t *)(pc +  4) = count;	*(uint32_t *)(pc +  8) = arrays->enabled_client_array_count;	*(uint32_t *)(pc + 12) = mode;	pc += header_size;	(void) memcpy( pc, arrays->array_info_cache,		       arrays->array_info_cache_size );	pc += arrays->array_info_cache_size;	*elements_per_request = count;	*total_requests = 0;    }    return pc;}/** */voidemit_DrawArrays_old( GLenum mode, GLint first, GLsizei count ){    __GLXcontext *gc = __glXGetCurrentContext();    const __GLXattribute * state =        (const __GLXattribute *)(gc->client_state_private);    struct array_state_vector * arrays = state->array_state;    GLubyte * pc;    size_t elements_per_request;    unsigned total_requests = 0;    unsigned i;    size_t total_sent = 0;    pc = emit_DrawArrays_header_old( gc, arrays, & elements_per_request,				     & total_requests, mode, count);        /* Write the arrays.     */    if ( total_requests == 0 ) {	assert( elements_per_request >= count );	for ( i = 0 ; i < count ; i++ ) {	    pc = emit_element_old( pc, arrays, i + first );	}	assert( pc <= gc->bufEnd );	gc->pc = pc;	if ( gc->pc > gc->limit ) {	    (void) __glXFlushRenderBuffer(gc, gc->pc);	}    }    else {	unsigned req;	for ( req = 2 ; req <= total_requests ; req++ ) {	    if ( count < elements_per_request ) {		elements_per_request = count;	    }	    pc = gc->pc;	    for ( i = 0 ; i < elements_per_request ; i++ ) {		pc = emit_element_old( pc, arrays, i + first );	    }	    first += elements_per_request;	    total_sent += (size_t) (pc - gc->pc);	    __glXSendLargeChunk( gc, req, total_requests, gc->pc,				 pc - gc->pc );	    count -= elements_per_request;	}    }}voidemit_DrawElements_none( GLenum mode, GLsizei count, GLenum type,			const GLvoid *indices ){    __GLXcontext *gc = __glXGetCurrentContext();    const __GLXattribute * state =        (const __GLXattribute *)(gc->client_state_private);    struct array_state_vector * arrays = state->array_state;    static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };    static const uint16_t end_cmd[2]   = { 4, X_GLrop_End };    GLubyte * pc;    size_t single_vertex_size;    unsigned  i;    single_vertex_size = calculate_single_vertex_size_none( arrays );    if ( (gc->pc + single_vertex_size) >= gc->bufEnd ) {	gc->pc = __glXFlushRenderBuffer(gc, gc->pc);    }    pc = gc->pc;    (void) memcpy( pc, begin_cmd, 4 );    *(int *)(pc +  4) = mode;    pc += 8;    for ( i = 0 ; i < count ; i++ ) {	unsigned  index = 0;	if ( (pc + single_vertex_size) >= gc->bufEnd ) {	    pc = __glXFlushRenderBuffer(gc, pc);	}	switch( type ) {	case GL_UNSIGNED_INT:	    index = (unsigned) (((GLuint *) indices)[i]);	    break;	case GL_UNSIGNED_SHORT:	    index = (unsigned) (((GLushort *) indices)[i]);	    break;	case GL_UNSIGNED_BYTE:	    index = (unsigned) (((GLubyte *) indices)[i]);	    break;	}	pc = emit_element_none( pc, arrays, index );    }    if ( (pc + 4) >= gc->bufEnd ) {	pc = __glXFlushRenderBuffer(gc, pc);    }    (void) memcpy( pc, end_cmd, 4 );    pc += 4;    gc->pc = pc;    if ( gc->pc > gc->limit ) {	(void) __glXFlushRenderBuffer(gc, gc->pc);    }}/** */voidemit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,		       const GLvoid *indices ){    __GLXcontext *gc = __glXGetCurrentContext();    const __GLXattribute * state =        (const __GLXattribute *)(gc->client_state_private);    struct array_state_vector * arrays = state->array_state;    GLubyte * pc;    size_t elements_per_request;    unsigned total_requests = 0;    unsigned i;    unsigned req;    unsigned req_element=0;    pc = emit_DrawArrays_header_old( gc, arrays, & elements_per_request,				     & total_requests, mode, count);        /* Write the arrays.     */    req = 2;    while ( count > 0 ) {	if ( count < elements_per_request ) {	    elements_per_request = count;	}	switch( type ) {	case GL_UNSIGNED_INT: {	    const GLuint   * ui_ptr = (const GLuint   *) indices + req_element;	    for ( i = 0 ; i < elements_per_request ; i++ ) {		const GLint index = (GLint) *(ui_ptr++);		pc = emit_element_old( pc, arrays, index );	    }	    break;	}	case GL_UNSIGNED_SHORT: {	    const GLushort * us_ptr = (const GLushort *) indices + req_element;	    for ( i = 0 ; i < elements_per_request ; i++ ) {		const GLint index = (GLint) *(us_ptr++);		pc = emit_element_old( pc, arrays, index );	    }	    break;	}	case GL_UNSIGNED_BYTE: {	    const GLubyte  * ub_ptr = (const GLubyte  *) indices + req_element;	    for ( i = 0 ; i < elements_per_request ; i++ ) {		const GLint index = (GLint) *(ub_ptr++);		pc = emit_element_old( pc, arrays, index );	    }	    break;	}	}	if ( total_requests != 0 ) {	    __glXSendLargeChunk( gc, req, total_requests, gc->pc,				 pc - gc->pc );	    pc = gc->pc;	    req++;	}	count -= elements_per_request;	req_element += elements_per_request;    }    assert( (total_requests == 0) || ((req - 1) == total_requests) );    if ( total_requests == 0 ) {	assert( pc <= gc->bufEnd );	gc->pc = pc;	if ( gc->pc > gc->limit ) {	    (void) __glXFlushRenderBuffer(gc, gc->pc);	}    }}/** * Validate that the \c mode parameter to \c glDrawArrays, et. al. is valid. * If it is not valid, then an error code is set in the GLX context. *  * \returns * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not. */static GLbooleanvalidate_mode(__GLXcontext *gc, GLenum mode){    switch(mode) {      case GL_POINTS:      case GL_LINE_STRIP:      case GL_LINE_LOOP:      case GL_LINES:      case GL_TRIANGLE_STRIP:      case GL_TRIANGLE_FAN:      case GL_TRIANGLES:      case GL_QUAD_STRIP:      case GL_QUADS:      case GL_POLYGON:	break;      default:        __glXSetError(gc, GL_INVALID_ENUM);        return GL_FALSE;    }        return GL_TRUE;}/** * Validate that the \c count parameter to \c glDrawArrays, et. al. is valid. * A value less than zero is invalid and will result in \c GL_INVALID_VALUE * being set.  A value of zero will not result in an error being set, but * will result in \c GL_FALSE being returned. *  * \returns * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not. */static GLbooleanvalidate_count(__GLXcontext *gc, GLsizei count){    if (count < 0) {	__glXSetError(gc, GL_INVALID_VALUE);    }    return (count > 0);}/** * Validate that the \c type parameter to \c glDrawElements, et. al. is * valid.  Only \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, and * \c GL_UNSIGNED_INT are valid. * * \returns * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not. */static GLboolean validate_type(__GLXcontext *gc, GLenum type){    switch( type ) {    case GL_UNSIGNED_INT:    case GL_UNSIGNED_SHORT:    case GL_UNSIGNED_BYTE:	return GL_TRUE;     default:	__glXSetError(gc, GL_INVALID_ENUM);	return GL_FALSE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -