static void r200_emit_vecfog(GLcontext *ctx, struct radeon_aos *aos, GLvoid *data, int stride, int count) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); uint32_t *out; int i; int size = 1; if (stride == 0) { radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32); count = 1; aos->stride = 0; } else { radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32); aos->stride = size; } aos->components = size; aos->count = count; out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); for (i = 0; i < count; i++) { out[0] = r200ComputeFogBlendFactor( ctx, *(GLfloat *)data ); out++; data += stride; } }
static void emit_tex_vector( GLcontext *ctx, struct radeon_dma_region *rvb, char *data, int size, int stride, int count ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); int emitsize; if (RADEON_DEBUG & DEBUG_VERTS) fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size); assert (!rvb->buf); switch (size) { case 4: emitsize = 3; break; default: emitsize = 2; break; } if (stride == 0) { radeonAllocDmaRegion( rmesa, rvb, 4 * emitsize, 4 ); count = 1; rvb->aos_start = GET_START(rvb); rvb->aos_stride = 0; rvb->aos_size = emitsize; } else { radeonAllocDmaRegion( rmesa, rvb, 4 * emitsize * count, 4 ); rvb->aos_start = GET_START(rvb); rvb->aos_stride = emitsize; rvb->aos_size = emitsize; } /* Emit the data */ switch (size) { case 1: emit_s0_vec( ctx, rvb, data, stride, count ); break; case 2: emit_vec8( ctx, rvb, data, stride, count ); break; case 3: emit_vec8( ctx, rvb, data, stride, count ); break; case 4: emit_stq_vec( ctx, rvb, data, stride, count ); break; default: assert(0); exit(1); break; } }
GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa, GLuint primitive, GLuint min_nr ) { GLushort *retval; radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive); assert((primitive & R200_VF_PRIM_WALK_IND)); radeonEmitState(&rmesa->radeon); radeonAllocDmaRegion(&rmesa->radeon, &rmesa->radeon.tcl.elt_dma_bo, &rmesa->radeon.tcl.elt_dma_offset, R200_ELT_BUF_SZ, 4); rmesa->tcl.elt_used = min_nr * 2; radeon_bo_map(rmesa->radeon.tcl.elt_dma_bo, 1); retval = rmesa->radeon.tcl.elt_dma_bo->ptr + rmesa->radeon.tcl.elt_dma_offset; assert(!rmesa->radeon.dma.flush); rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; rmesa->radeon.dma.flush = r200FlushElts; return retval; }
static void emit_ubyte_rgba( GLcontext *ctx, struct radeon_dma_region *rvb, char *data, int size, int stride, int count ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); if (RADEON_DEBUG & DEBUG_VERTS) fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size); assert (!rvb->buf); if (stride == 0) { radeonAllocDmaRegion( rmesa, rvb, 4, 4 ); count = 1; rvb->aos_start = GET_START(rvb); rvb->aos_stride = 0; rvb->aos_size = 1; } else { radeonAllocDmaRegion( rmesa, rvb, 4 * count, 4 ); /* alignment? */ rvb->aos_start = GET_START(rvb); rvb->aos_stride = 1; rvb->aos_size = 1; } /* Emit the data */ switch (size) { case 3: emit_ubyte_rgba3( ctx, rvb, data, stride, count ); break; case 4: emit_ubyte_rgba4( ctx, rvb, data, stride, count ); break; default: assert(0); exit(1); break; } }
static void evergreenSetupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf) { context_t *context = EVERGREEN_CONTEXT(ctx); if (!mesa_ind_buf) { context->ind_buf.bo = NULL; return; } #if MESA_BIG_ENDIAN if (mesa_ind_buf->type == GL_UNSIGNED_INT) #else if (mesa_ind_buf->type != GL_UNSIGNED_BYTE) #endif { const GLvoid *src_ptr; GLvoid *dst_ptr; GLboolean mapped_named_bo = GL_FALSE; if (mesa_ind_buf->obj->Name && !mesa_ind_buf->obj->Pointer) { ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY_ARB, mesa_ind_buf->obj); assert(mesa_ind_buf->obj->Pointer != NULL); mapped_named_bo = GL_TRUE; } src_ptr = ADD_POINTERS(mesa_ind_buf->obj->Pointer, mesa_ind_buf->ptr); const GLuint size = mesa_ind_buf->count * getTypeSize(mesa_ind_buf->type); radeonAllocDmaRegion(&context->radeon, &context->ind_buf.bo, &context->ind_buf.bo_offset, size, 4); radeon_bo_map(context->ind_buf.bo, 1); assert(context->ind_buf.bo->ptr != NULL); dst_ptr = ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset); memcpy(dst_ptr, src_ptr, size); radeon_bo_unmap(context->ind_buf.bo); context->ind_buf.is_32bit = (mesa_ind_buf->type == GL_UNSIGNED_INT); context->ind_buf.count = mesa_ind_buf->count; if (mapped_named_bo) { ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, mesa_ind_buf->obj); } } else { evergreenFixupIndexBuffer(ctx, mesa_ind_buf); } }
static void evergreenAlignDataToDword(GLcontext *ctx, const struct gl_client_array *input, int count, struct StreamDesc *attr) { context_t *context = EVERGREEN_CONTEXT(ctx); const int dst_stride = (input->StrideB + 3) & ~3; const int size = getTypeSize(input->Type) * input->Size * count; GLboolean mapped_named_bo = GL_FALSE; radeonAllocDmaRegion(&context->radeon, &attr->bo, &attr->bo_offset, size, 32); radeon_bo_map(attr->bo, 1); if (!input->BufferObj->Pointer) { ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, input->BufferObj); mapped_named_bo = GL_TRUE; } { GLvoid *src_ptr = ADD_POINTERS(input->BufferObj->Pointer, input->Ptr); GLvoid *dst_ptr = ADD_POINTERS(attr->bo->ptr, attr->bo_offset); int i; for (i = 0; i < count; ++i) { memcpy(dst_ptr, src_ptr, input->StrideB); src_ptr += input->StrideB; dst_ptr += dst_stride; } } radeon_bo_unmap(attr->bo); if (mapped_named_bo) { ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj); } attr->stride = dst_stride; }
static void r300AlignDataToDword(GLcontext *ctx, const struct gl_client_array *input, int count, struct vertex_attribute *attr) { r300ContextPtr r300 = R300_CONTEXT(ctx); const int dst_stride = (input->StrideB + 3) & ~3; const int size = getTypeSize(input->Type) * input->Size * count; GLboolean mapped_named_bo = GL_FALSE; radeonAllocDmaRegion(&r300->radeon, &attr->bo, &attr->bo_offset, size, 32); radeon_bo_map(attr->bo, 1); if (!input->BufferObj->Pointer) { ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, input->BufferObj); mapped_named_bo = GL_TRUE; } radeon_print(RADEON_FALLBACKS, RADEON_IMPORTANT, "%s. Vertex alignment doesn't match hw requirements.\n", __func__); { GLvoid *src_ptr = ADD_POINTERS(input->BufferObj->Pointer, input->Ptr); GLvoid *dst_ptr = ADD_POINTERS(attr->bo->ptr, attr->bo_offset); int i; for (i = 0; i < count; ++i) { memcpy(dst_ptr, src_ptr, input->StrideB); src_ptr += input->StrideB; dst_ptr += dst_stride; } } if (mapped_named_bo) { ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj); } radeon_bo_unmap(attr->bo); attr->stride = dst_stride; }
GLboolean evergreenSetupVPconstants(struct gl_context * ctx) { context_t *context = EVERGREEN_CONTEXT(ctx); EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context); struct evergreen_vertex_program *vp = (struct evergreen_vertex_program *) context->selected_vp; struct gl_program_parameter_list *paramList; unsigned int unNumParamData; unsigned int ui; int alloc_size; /* sent out shader constants. */ paramList = vp->mesa_program->Base.Parameters; if(NULL != paramList) { /* vp->mesa_program was cloned, not updated by glsl shader api. */ /* _mesa_reference_program has already checked glsl shProg is ok and set ctx->VertexProgem._Current */ /* so, use ctx->VertexProgem._Current */ struct gl_program_parameter_list *paramListOrginal = ctx->VertexProgram._Current->Base.Parameters; _mesa_load_state_parameters(ctx, paramList); if (paramList->NumParameters > EVERGREEN_MAX_DX9_CONSTS) return GL_FALSE; EVERGREEN_STATECHANGE(context, vs); evergreen->vs.num_consts = paramList->NumParameters; unNumParamData = paramList->NumParameters; /* alloc multiple of 16 constants */ alloc_size = ((unNumParamData * 4 * 4) + 255) & ~255; for(ui=0; ui<unNumParamData; ui++) { if(paramList->Parameters[ui].Type == PROGRAM_UNIFORM) { evergreen->vs.consts[ui][0].f32All = paramListOrginal->ParameterValues[ui][0].f; evergreen->vs.consts[ui][1].f32All = paramListOrginal->ParameterValues[ui][1].f; evergreen->vs.consts[ui][2].f32All = paramListOrginal->ParameterValues[ui][2].f; evergreen->vs.consts[ui][3].f32All = paramListOrginal->ParameterValues[ui][3].f; } else { evergreen->vs.consts[ui][0].f32All = paramList->ParameterValues[ui][0].f; evergreen->vs.consts[ui][1].f32All = paramList->ParameterValues[ui][1].f; evergreen->vs.consts[ui][2].f32All = paramList->ParameterValues[ui][2].f; evergreen->vs.consts[ui][3].f32All = paramList->ParameterValues[ui][3].f; } } radeonAllocDmaRegion(&context->radeon, &context->vp_Constbo, &context->vp_bo_offset, alloc_size, 256); r600EmitShaderConsts(ctx, context->vp_Constbo, context->vp_bo_offset, (GLvoid *)&(evergreen->vs.consts[0][0]), unNumParamData * 4 * 4); } else evergreen->vs.num_consts = 0; COMPILED_SUB * pCompiledSub; GLuint uj; GLuint unConstOffset = evergreen->vs.num_consts; for(ui=0; ui<vp->r700AsmCode.unNumPresub; ui++) { pCompiledSub = vp->r700AsmCode.presubs[ui].pCompiledSub; evergreen->vs.num_consts += pCompiledSub->NumParameters; for(uj=0; uj<pCompiledSub->NumParameters; uj++) { evergreen->vs.consts[uj + unConstOffset][0].f32All = pCompiledSub->ParameterValues[uj][0]; evergreen->vs.consts[uj + unConstOffset][1].f32All = pCompiledSub->ParameterValues[uj][1]; evergreen->vs.consts[uj + unConstOffset][2].f32All = pCompiledSub->ParameterValues[uj][2]; evergreen->vs.consts[uj + unConstOffset][3].f32All = pCompiledSub->ParameterValues[uj][3]; } unConstOffset += pCompiledSub->NumParameters; } return GL_TRUE; }
static void evergreenSetupStreams(GLcontext *ctx, const struct gl_client_array *input[], int count) { context_t *context = EVERGREEN_CONTEXT(ctx); GLuint stride; int ret; int i, index; EVERGREEN_STATECHANGE(context, vtx); for(index = 0; index < context->nNumActiveAos; index++) { struct radeon_aos *aos = &context->radeon.tcl.aos[index]; i = context->stream_desc[index].element; stride = (input[i]->StrideB == 0) ? getTypeSize(input[i]->Type) * input[i]->Size : input[i]->StrideB; if (input[i]->Type == GL_DOUBLE || input[i]->Type == GL_UNSIGNED_INT || input[i]->Type == GL_INT #if MESA_BIG_ENDIAN || getTypeSize(input[i]->Type) != 4 #endif ) { evergreenConvertAttrib(ctx, count, input[i], &context->stream_desc[index]); } else { if (input[i]->BufferObj->Name) { context->stream_desc[index].stride = input[i]->StrideB; context->stream_desc[index].bo_offset = (intptr_t) input[i]->Ptr; context->stream_desc[index].bo = get_radeon_buffer_object(input[i]->BufferObj)->bo; context->stream_desc[index].is_named_bo = GL_TRUE; } else { int size; int local_count = count; uint32_t *dst; if (input[i]->StrideB == 0) { size = getTypeSize(input[i]->Type) * input[i]->Size; local_count = 1; } else { size = getTypeSize(input[i]->Type) * input[i]->Size * local_count; } radeonAllocDmaRegion(&context->radeon, &context->stream_desc[index].bo, &context->stream_desc[index].bo_offset, size, 32); radeon_bo_map(context->stream_desc[index].bo, 1); assert(context->stream_desc[index].bo->ptr != NULL); dst = (uint32_t *)ADD_POINTERS(context->stream_desc[index].bo->ptr, context->stream_desc[index].bo_offset); switch (context->stream_desc[index].dwords) { case 1: radeonEmitVec4(dst, input[i]->Ptr, input[i]->StrideB, local_count); break; case 2: radeonEmitVec8(dst, input[i]->Ptr, input[i]->StrideB, local_count); break; case 3: radeonEmitVec12(dst, input[i]->Ptr, input[i]->StrideB, local_count); break; case 4: radeonEmitVec16(dst, input[i]->Ptr, input[i]->StrideB, local_count); break; default: assert(0); break; } radeon_bo_unmap(context->stream_desc[index].bo); } } aos->count = context->stream_desc[index].stride == 0 ? 1 : count; aos->stride = context->stream_desc[index].stride / sizeof(float); aos->components = context->stream_desc[index].dwords; aos->bo = context->stream_desc[index].bo; aos->offset = context->stream_desc[index].bo_offset; if(context->stream_desc[index].is_named_bo) { radeon_cs_space_add_persistent_bo(context->radeon.cmdbuf.cs, context->stream_desc[index].bo, RADEON_GEM_DOMAIN_GTT, 0); } } ret = radeon_cs_space_check_with_bo(context->radeon.cmdbuf.cs, first_elem(&context->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0); }
static void evergreenFixupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf) { context_t *context = EVERGREEN_CONTEXT(ctx); GLvoid *src_ptr; GLuint *out; int i; GLboolean mapped_named_bo = GL_FALSE; if (mesa_ind_buf->obj->Name && !mesa_ind_buf->obj->Pointer) { ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY_ARB, mesa_ind_buf->obj); mapped_named_bo = GL_TRUE; assert(mesa_ind_buf->obj->Pointer != NULL); } src_ptr = ADD_POINTERS(mesa_ind_buf->obj->Pointer, mesa_ind_buf->ptr); if (mesa_ind_buf->type == GL_UNSIGNED_BYTE) { GLuint size = sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1); GLubyte *in = (GLubyte *)src_ptr; radeonAllocDmaRegion(&context->radeon, &context->ind_buf.bo, &context->ind_buf.bo_offset, size, 4); radeon_bo_map(context->ind_buf.bo, 1); assert(context->ind_buf.bo->ptr != NULL); out = (GLuint *)ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset); for (i = 0; i + 1 < mesa_ind_buf->count; i += 2) { *out++ = in[i] | in[i + 1] << 16; } if (i < mesa_ind_buf->count) { *out++ = in[i]; } radeon_bo_unmap(context->ind_buf.bo); #if MESA_BIG_ENDIAN } else { /* if (mesa_ind_buf->type == GL_UNSIGNED_SHORT) */ GLushort *in = (GLushort *)src_ptr; GLuint size = sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1); radeonAllocDmaRegion(&context->radeon, &context->ind_buf.bo, &context->ind_buf.bo_offset, size, 4); radeon_bo_map(context->ind_buf.bo, 1); assert(context->ind_buf.bo->ptr != NULL); out = (GLuint *)ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset); for (i = 0; i + 1 < mesa_ind_buf->count; i += 2) { *out++ = in[i] | in[i + 1] << 16; } if (i < mesa_ind_buf->count) { *out++ = in[i]; } radeon_bo_unmap(context->ind_buf.bo); #endif } context->ind_buf.is_32bit = GL_FALSE; context->ind_buf.count = mesa_ind_buf->count; if (mapped_named_bo) { ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, mesa_ind_buf->obj); } }
/** * Convert attribute data type to float * If the attribute uses named buffer object replace the bo with newly allocated bo */ static void evergreenConvertAttrib(GLcontext *ctx, int count, const struct gl_client_array *input, struct StreamDesc *attr) { context_t *context = R700_CONTEXT(ctx); const GLvoid *src_ptr; GLboolean mapped_named_bo = GL_FALSE; GLfloat *dst_ptr; GLuint stride; stride = (input->StrideB == 0) ? evergreen_getTypeSize(input->Type) * input->Size : input->StrideB; /* Convert value for first element only */ if (input->StrideB == 0) { count = 1; } if (input->BufferObj->Name) { if (!input->BufferObj->Pointer) { ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, input->BufferObj); mapped_named_bo = GL_TRUE; } src_ptr = ADD_POINTERS(input->BufferObj->Pointer, input->Ptr); } else { src_ptr = input->Ptr; } radeonAllocDmaRegion(&context->radeon, &attr->bo, &attr->bo_offset, sizeof(GLfloat) * input->Size * count, 32); radeon_bo_map(attr->bo, 1); dst_ptr = (GLfloat *)ADD_POINTERS(attr->bo->ptr, attr->bo_offset); assert(src_ptr != NULL); switch (input->Type) { case GL_DOUBLE: CONVERT(GLdouble, (GLfloat)); break; case GL_UNSIGNED_INT: CONVERT(GLuint, UINT_TO_FLOAT); break; case GL_INT: CONVERT(GLint, INT_TO_FLOAT); break; case GL_UNSIGNED_SHORT: CONVERT(GLushort, USHORT_TO_FLOAT); break; case GL_SHORT: CONVERT(GLshort, SHORT_TO_FLOAT); break; case GL_UNSIGNED_BYTE: assert(input->Format != GL_BGRA); CONVERT(GLubyte, UBYTE_TO_FLOAT); break; case GL_BYTE: CONVERT(GLbyte, BYTE_TO_FLOAT); break; default: assert(0); break; } radeon_bo_unmap(attr->bo); if (mapped_named_bo) { ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj); } }
static void radeonUploadRectSubImage( radeonContextPtr rmesa, radeonTexObjPtr t, struct gl_texture_image *texImage, GLint x, GLint y, GLint width, GLint height ) { const struct gl_texture_format *texFormat = texImage->TexFormat; int blit_format, dstPitch, done; switch ( texFormat->TexelBytes ) { case 1: blit_format = RADEON_GMC_DST_8BPP_CI; break; case 2: blit_format = RADEON_GMC_DST_16BPP; break; case 4: blit_format = RADEON_GMC_DST_32BPP; break; default: fprintf( stderr, "radeonUploadRectSubImage: unknown blit_format (texelbytes=%d)\n", texFormat->TexelBytes); return; } t->image[0][0].data = texImage->Data; /* Currently don't need to cope with small pitches. */ width = texImage->Width; height = texImage->Height; dstPitch = t->pp_txpitch + 32; { /* FIXME: prefer GART-texturing if possible */ /* Data not in GART memory, or bad pitch. */ for (done = 0; done < height ; ) { struct radeon_dma_region region; int lines = MIN2( height - done, RADEON_BUFFER_SIZE / dstPitch ); int src_pitch; char *tex; src_pitch = texImage->RowStride * texFormat->TexelBytes; tex = (char *)texImage->Data + done * src_pitch; memset(®ion, 0, sizeof(region)); radeonAllocDmaRegion( rmesa, ®ion, lines * dstPitch, 1024 ); /* Copy texdata to dma: */ if (0) fprintf(stderr, "%s: src_pitch %d dst_pitch %d\n", __FUNCTION__, src_pitch, dstPitch); if (src_pitch == dstPitch) { memcpy( region.address + region.start, tex, lines * src_pitch ); } else { char *buf = region.address + region.start; int i; for (i = 0 ; i < lines ; i++) { memcpy( buf, tex, src_pitch ); buf += dstPitch; tex += src_pitch; } } radeonEmitWait( rmesa, RADEON_WAIT_3D ); /* Blit to framebuffer */ radeonEmitBlit( rmesa, blit_format, dstPitch, GET_START( ®ion ), dstPitch, t->bufAddr, 0, 0, 0, done, width, lines ); radeonEmitWait( rmesa, RADEON_WAIT_2D ); radeonReleaseDmaRegion( rmesa, ®ion, __FUNCTION__ ); done += lines; } } }
static void r300FixupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf) { r300ContextPtr r300 = R300_CONTEXT(ctx); GLvoid *src_ptr; GLuint *out; int i; GLboolean mapped_named_bo = GL_FALSE; if (mesa_ind_buf->obj->Name && !mesa_ind_buf->obj->Pointer) { ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY_ARB, mesa_ind_buf->obj); mapped_named_bo = GL_TRUE; assert(mesa_ind_buf->obj->Pointer != NULL); } src_ptr = ADD_POINTERS(mesa_ind_buf->obj->Pointer, mesa_ind_buf->ptr); radeon_print(RADEON_FALLBACKS, RADEON_IMPORTANT, "%s: Fixing index buffer format. type %d\n", __func__, mesa_ind_buf->type); if (mesa_ind_buf->type == GL_UNSIGNED_BYTE) { GLuint size = sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1); GLubyte *in = (GLubyte *)src_ptr; radeonAllocDmaRegion(&r300->radeon, &r300->ind_buf.bo, &r300->ind_buf.bo_offset, size, 4); radeon_bo_map(r300->ind_buf.bo, 1); assert(r300->ind_buf.bo->ptr != NULL); out = (GLuint *)ADD_POINTERS(r300->ind_buf.bo->ptr, r300->ind_buf.bo_offset); for (i = 0; i + 1 < mesa_ind_buf->count; i += 2) { *out++ = in[i] | in[i + 1] << 16; } if (i < mesa_ind_buf->count) { *out++ = in[i]; } radeon_bo_unmap(r300->ind_buf.bo); #if MESA_BIG_ENDIAN } else { /* if (mesa_ind_buf->type == GL_UNSIGNED_SHORT) */ GLushort *in = (GLushort *)src_ptr; GLuint size = sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1); radeonAllocDmaRegion(&r300->radeon, &r300->ind_buf.bo, &r300->ind_buf.bo_offset, size, 4); radeon_bo_map(r300->ind_buf.bo, 1); assert(r300->ind_buf.bo->ptr != NULL); out = (GLuint *)ADD_POINTERS(r300->ind_buf.bo->ptr, r300->ind_buf.bo_offset); for (i = 0; i + 1 < mesa_ind_buf->count; i += 2) { *out++ = in[i] | in[i + 1] << 16; } if (i < mesa_ind_buf->count) { *out++ = in[i]; } radeon_bo_unmap(r300->ind_buf.bo); #endif } r300->ind_buf.is_32bit = GL_FALSE; r300->ind_buf.count = mesa_ind_buf->count; if (mapped_named_bo) { ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, mesa_ind_buf->obj); } }
static void r300AllocDmaRegions(GLcontext *ctx, const struct gl_client_array *input[], int count) { r300ContextPtr r300 = R300_CONTEXT(ctx); struct r300_vertex_buffer *vbuf = &r300->vbuf; GLuint stride; int ret; int i, index; radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s: count %d num_attribs %d\n", __func__, count, vbuf->num_attribs); for (index = 0; index < vbuf->num_attribs; index++) { struct radeon_aos *aos = &r300->radeon.tcl.aos[index]; i = vbuf->attribs[index].element; stride = (input[i]->StrideB == 0) ? getTypeSize(input[i]->Type) * input[i]->Size : input[i]->StrideB; if (input[i]->Type == GL_DOUBLE || input[i]->Type == GL_UNSIGNED_INT || input[i]->Type == GL_INT || #if MESA_BIG_ENDIAN getTypeSize(input[i]->Type) != 4 || #endif stride < 4) { r300ConvertAttrib(ctx, count, input[i], &vbuf->attribs[index]); } else { if (input[i]->BufferObj->Name) { if (stride % 4 != 0 || (intptr_t)input[i]->Ptr % 4 != 0) { r300AlignDataToDword(ctx, input[i], count, &vbuf->attribs[index]); vbuf->attribs[index].is_named_bo = GL_FALSE; } else { vbuf->attribs[index].stride = input[i]->StrideB; vbuf->attribs[index].bo_offset = (intptr_t) input[i]->Ptr; vbuf->attribs[index].bo = get_radeon_buffer_object(input[i]->BufferObj)->bo; vbuf->attribs[index].is_named_bo = GL_TRUE; } } else { int size; int local_count = count; uint32_t *dst; if (input[i]->StrideB == 0) { size = getTypeSize(input[i]->Type) * input[i]->Size; local_count = 1; } else { size = getTypeSize(input[i]->Type) * input[i]->Size * local_count; } radeonAllocDmaRegion(&r300->radeon, &vbuf->attribs[index].bo, &vbuf->attribs[index].bo_offset, size, 32); radeon_bo_map(vbuf->attribs[index].bo, 1); assert(vbuf->attribs[index].bo->ptr != NULL); dst = (uint32_t *)ADD_POINTERS(vbuf->attribs[index].bo->ptr, vbuf->attribs[index].bo_offset); switch (vbuf->attribs[index].dwords) { case 1: radeonEmitVec4(dst, input[i]->Ptr, input[i]->StrideB, local_count); break; case 2: radeonEmitVec8(dst, input[i]->Ptr, input[i]->StrideB, local_count); break; case 3: radeonEmitVec12(dst, input[i]->Ptr, input[i]->StrideB, local_count); break; case 4: radeonEmitVec16(dst, input[i]->Ptr, input[i]->StrideB, local_count); break; default: assert(0); break; } radeon_bo_unmap(vbuf->attribs[index].bo); } } aos->count = vbuf->attribs[index].stride == 0 ? 1 : count; aos->stride = vbuf->attribs[index].stride / sizeof(float); aos->components = vbuf->attribs[index].dwords; aos->bo = vbuf->attribs[index].bo; aos->offset = vbuf->attribs[index].bo_offset; if (vbuf->attribs[index].is_named_bo) { radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs, r300->vbuf.attribs[index].bo, RADEON_GEM_DOMAIN_GTT, 0); } } r300->radeon.tcl.aos_count = vbuf->num_attribs; ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs, first_elem(&r300->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0); r300SwitchFallback(ctx, R300_FALLBACK_INVALID_BUFFERS, ret); }
static void r300SetupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf) { r300ContextPtr r300 = R300_CONTEXT(ctx); if (!mesa_ind_buf) { r300->ind_buf.bo = NULL; return; } radeon_print(RADEON_RENDER, RADEON_TRACE, "%s\n", __func__); #if MESA_BIG_ENDIAN if (mesa_ind_buf->type == GL_UNSIGNED_INT) { #else if (mesa_ind_buf->type != GL_UNSIGNED_BYTE) { #endif const GLvoid *src_ptr; GLvoid *dst_ptr; GLboolean mapped_named_bo = GL_FALSE; if (mesa_ind_buf->obj->Name && !mesa_ind_buf->obj->Pointer) { ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY_ARB, mesa_ind_buf->obj); assert(mesa_ind_buf->obj->Pointer != NULL); mapped_named_bo = GL_TRUE; } src_ptr = ADD_POINTERS(mesa_ind_buf->obj->Pointer, mesa_ind_buf->ptr); const GLuint size = mesa_ind_buf->count * getTypeSize(mesa_ind_buf->type); radeonAllocDmaRegion(&r300->radeon, &r300->ind_buf.bo, &r300->ind_buf.bo_offset, size, 4); radeon_bo_map(r300->ind_buf.bo, 1); assert(r300->ind_buf.bo->ptr != NULL); dst_ptr = ADD_POINTERS(r300->ind_buf.bo->ptr, r300->ind_buf.bo_offset); memcpy(dst_ptr, src_ptr, size); radeon_bo_unmap(r300->ind_buf.bo); r300->ind_buf.is_32bit = (mesa_ind_buf->type == GL_UNSIGNED_INT); r300->ind_buf.count = mesa_ind_buf->count; if (mapped_named_bo) { ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, mesa_ind_buf->obj); } } else { r300FixupIndexBuffer(ctx, mesa_ind_buf); } } #define CONVERT( TYPE, MACRO ) do { \ GLuint i, j, sz; \ sz = input->Size; \ if (input->Normalized) { \ for (i = 0; i < count; i++) { \ const TYPE *in = (TYPE *)src_ptr; \ for (j = 0; j < sz; j++) { \ *dst_ptr++ = MACRO(*in); \ in++; \ } \ src_ptr += stride; \ } \ } else { \ for (i = 0; i < count; i++) { \ const TYPE *in = (TYPE *)src_ptr; \ for (j = 0; j < sz; j++) { \ *dst_ptr++ = (GLfloat)(*in); \ in++; \ } \ src_ptr += stride; \ } \ } \ } while (0) /** * Convert attribute data type to float * If the attribute uses named buffer object replace the bo with newly allocated bo */ static void r300ConvertAttrib(GLcontext *ctx, int count, const struct gl_client_array *input, struct vertex_attribute *attr) { r300ContextPtr r300 = R300_CONTEXT(ctx); const GLvoid *src_ptr; GLboolean mapped_named_bo = GL_FALSE; GLfloat *dst_ptr; GLuint stride; stride = (input->StrideB == 0) ? getTypeSize(input->Type) * input->Size : input->StrideB; /* Convert value for first element only */ if (input->StrideB == 0) count = 1; if (input->BufferObj->Name) { if (!input->BufferObj->Pointer) { ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, input->BufferObj); mapped_named_bo = GL_TRUE; } src_ptr = ADD_POINTERS(input->BufferObj->Pointer, input->Ptr); } else { src_ptr = input->Ptr; } radeonAllocDmaRegion(&r300->radeon, &attr->bo, &attr->bo_offset, sizeof(GLfloat) * input->Size * count, 32); radeon_bo_map(attr->bo, 1); dst_ptr = (GLfloat *)ADD_POINTERS(attr->bo->ptr, attr->bo_offset); radeon_print(RADEON_FALLBACKS, RADEON_IMPORTANT, "%s: Converting vertex attributes, attribute data format %x," "stride %d, components %d\n" , __FUNCTION__, input->Type , stride, input->Size); assert(src_ptr != NULL); switch (input->Type) { case GL_DOUBLE: CONVERT(GLdouble, (GLfloat)); break; case GL_UNSIGNED_INT: CONVERT(GLuint, UINT_TO_FLOAT); break; case GL_INT: CONVERT(GLint, INT_TO_FLOAT); break; case GL_UNSIGNED_SHORT: CONVERT(GLushort, USHORT_TO_FLOAT); break; case GL_SHORT: CONVERT(GLshort, SHORT_TO_FLOAT); break; case GL_UNSIGNED_BYTE: assert(input->Format != GL_BGRA); CONVERT(GLubyte, UBYTE_TO_FLOAT); break; case GL_BYTE: CONVERT(GLbyte, BYTE_TO_FLOAT); break; default: assert(0); break; } radeon_bo_unmap(attr->bo); if (mapped_named_bo) { ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj); } }