struct u_vbuf_elements * u_vbuf_create_vertex_elements(struct u_vbuf *mgrb, unsigned count, const struct pipe_vertex_element *attribs, struct pipe_vertex_element *native_attribs) { struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb; unsigned i; struct u_vbuf_elements *ve = CALLOC_STRUCT(u_vbuf_elements); ve->count = count; if (!count) { return ve; } memcpy(ve->ve, attribs, sizeof(struct pipe_vertex_element) * count); memcpy(native_attribs, attribs, sizeof(struct pipe_vertex_element) * count); /* Set the best native format in case the original format is not * supported. */ for (i = 0; i < count; i++) { enum pipe_format format = ve->ve[i].src_format; ve->src_format_size[i] = util_format_get_blocksize(format); /* Choose a native format. * For now we don't care about the alignment, that's going to * be sorted out later. */ if (!mgr->b.caps.format_fixed32) { switch (format) { FORMAT_REPLACE(R32_FIXED, R32_FLOAT); FORMAT_REPLACE(R32G32_FIXED, R32G32_FLOAT); FORMAT_REPLACE(R32G32B32_FIXED, R32G32B32_FLOAT); FORMAT_REPLACE(R32G32B32A32_FIXED, R32G32B32A32_FLOAT); default:; } } if (!mgr->b.caps.format_float16) { switch (format) { FORMAT_REPLACE(R16_FLOAT, R32_FLOAT); FORMAT_REPLACE(R16G16_FLOAT, R32G32_FLOAT); FORMAT_REPLACE(R16G16B16_FLOAT, R32G32B32_FLOAT); FORMAT_REPLACE(R16G16B16A16_FLOAT, R32G32B32A32_FLOAT); default:; } } if (!mgr->b.caps.format_float64) { switch (format) { FORMAT_REPLACE(R64_FLOAT, R32_FLOAT); FORMAT_REPLACE(R64G64_FLOAT, R32G32_FLOAT); FORMAT_REPLACE(R64G64B64_FLOAT, R32G32B32_FLOAT); FORMAT_REPLACE(R64G64B64A64_FLOAT, R32G32B32A32_FLOAT); default:; } } if (!mgr->b.caps.format_norm32) { switch (format) { FORMAT_REPLACE(R32_UNORM, R32_FLOAT); FORMAT_REPLACE(R32G32_UNORM, R32G32_FLOAT); FORMAT_REPLACE(R32G32B32_UNORM, R32G32B32_FLOAT); FORMAT_REPLACE(R32G32B32A32_UNORM, R32G32B32A32_FLOAT); FORMAT_REPLACE(R32_SNORM, R32_FLOAT); FORMAT_REPLACE(R32G32_SNORM, R32G32_FLOAT); FORMAT_REPLACE(R32G32B32_SNORM, R32G32B32_FLOAT); FORMAT_REPLACE(R32G32B32A32_SNORM, R32G32B32A32_FLOAT); default:; } } if (!mgr->b.caps.format_scaled32) { switch (format) { FORMAT_REPLACE(R32_USCALED, R32_FLOAT); FORMAT_REPLACE(R32G32_USCALED, R32G32_FLOAT); FORMAT_REPLACE(R32G32B32_USCALED, R32G32B32_FLOAT); FORMAT_REPLACE(R32G32B32A32_USCALED,R32G32B32A32_FLOAT); FORMAT_REPLACE(R32_SSCALED, R32_FLOAT); FORMAT_REPLACE(R32G32_SSCALED, R32G32_FLOAT); FORMAT_REPLACE(R32G32B32_SSCALED, R32G32B32_FLOAT); FORMAT_REPLACE(R32G32B32A32_SSCALED,R32G32B32A32_FLOAT); default:; } } native_attribs[i].src_format = format; ve->native_format[i] = format; ve->native_format_size[i] = util_format_get_blocksize(ve->native_format[i]); ve->incompatible_layout_elem[i] = ve->ve[i].src_format != ve->native_format[i] || (!mgr->b.caps.fetch_dword_unaligned && ve->ve[i].src_offset % 4 != 0); ve->incompatible_layout = ve->incompatible_layout || ve->incompatible_layout_elem[i]; } /* Align the formats to the size of DWORD if needed. */ if (!mgr->b.caps.fetch_dword_unaligned) { for (i = 0; i < count; i++) { ve->native_format_size[i] = align(ve->native_format_size[i], 4); } } return ve; }
static void * u_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count, const struct pipe_vertex_element *attribs) { struct pipe_context *pipe = mgr->pipe; unsigned i; struct pipe_vertex_element driver_attribs[PIPE_MAX_ATTRIBS]; struct u_vbuf_elements *ve = CALLOC_STRUCT(u_vbuf_elements); uint32_t used_buffers = 0; ve->count = count; memcpy(ve->ve, attribs, sizeof(struct pipe_vertex_element) * count); memcpy(driver_attribs, attribs, sizeof(struct pipe_vertex_element) * count); /* Set the best native format in case the original format is not * supported. */ for (i = 0; i < count; i++) { enum pipe_format format = ve->ve[i].src_format; ve->src_format_size[i] = util_format_get_blocksize(format); used_buffers |= 1 << ve->ve[i].vertex_buffer_index; if (!ve->ve[i].instance_divisor) { ve->noninstance_vb_mask_any |= 1 << ve->ve[i].vertex_buffer_index; } /* Choose a native format. * For now we don't care about the alignment, that's going to * be sorted out later. */ if (!mgr->caps.format_fixed32) { switch (format) { FORMAT_REPLACE(R32_FIXED, R32_FLOAT); FORMAT_REPLACE(R32G32_FIXED, R32G32_FLOAT); FORMAT_REPLACE(R32G32B32_FIXED, R32G32B32_FLOAT); FORMAT_REPLACE(R32G32B32A32_FIXED, R32G32B32A32_FLOAT); default:; } } if (!mgr->caps.format_float16) { switch (format) { FORMAT_REPLACE(R16_FLOAT, R32_FLOAT); FORMAT_REPLACE(R16G16_FLOAT, R32G32_FLOAT); FORMAT_REPLACE(R16G16B16_FLOAT, R32G32B32_FLOAT); FORMAT_REPLACE(R16G16B16A16_FLOAT, R32G32B32A32_FLOAT); default:; } } if (!mgr->caps.format_float64) { switch (format) { FORMAT_REPLACE(R64_FLOAT, R32_FLOAT); FORMAT_REPLACE(R64G64_FLOAT, R32G32_FLOAT); FORMAT_REPLACE(R64G64B64_FLOAT, R32G32B32_FLOAT); FORMAT_REPLACE(R64G64B64A64_FLOAT, R32G32B32A32_FLOAT); default:; } } if (!mgr->caps.format_norm32) { switch (format) { FORMAT_REPLACE(R32_UNORM, R32_FLOAT); FORMAT_REPLACE(R32G32_UNORM, R32G32_FLOAT); FORMAT_REPLACE(R32G32B32_UNORM, R32G32B32_FLOAT); FORMAT_REPLACE(R32G32B32A32_UNORM, R32G32B32A32_FLOAT); FORMAT_REPLACE(R32_SNORM, R32_FLOAT); FORMAT_REPLACE(R32G32_SNORM, R32G32_FLOAT); FORMAT_REPLACE(R32G32B32_SNORM, R32G32B32_FLOAT); FORMAT_REPLACE(R32G32B32A32_SNORM, R32G32B32A32_FLOAT); default:; } } if (!mgr->caps.format_scaled32) { switch (format) { FORMAT_REPLACE(R32_USCALED, R32_FLOAT); FORMAT_REPLACE(R32G32_USCALED, R32G32_FLOAT); FORMAT_REPLACE(R32G32B32_USCALED, R32G32B32_FLOAT); FORMAT_REPLACE(R32G32B32A32_USCALED,R32G32B32A32_FLOAT); FORMAT_REPLACE(R32_SSCALED, R32_FLOAT); FORMAT_REPLACE(R32G32_SSCALED, R32G32_FLOAT); FORMAT_REPLACE(R32G32B32_SSCALED, R32G32B32_FLOAT); FORMAT_REPLACE(R32G32B32A32_SSCALED,R32G32B32A32_FLOAT); default:; } } driver_attribs[i].src_format = format; ve->native_format[i] = format; ve->native_format_size[i] = util_format_get_blocksize(ve->native_format[i]); if (ve->ve[i].src_format != format || (!mgr->caps.velem_src_offset_unaligned && ve->ve[i].src_offset % 4 != 0)) { ve->incompatible_elem_mask |= 1 << i; ve->incompatible_vb_mask_any |= 1 << ve->ve[i].vertex_buffer_index; } else { ve->compatible_vb_mask_any |= 1 << ve->ve[i].vertex_buffer_index; } } ve->compatible_vb_mask_all = ~ve->incompatible_vb_mask_any & used_buffers; ve->incompatible_vb_mask_all = ~ve->compatible_vb_mask_any & used_buffers; /* Align the formats to the size of DWORD if needed. */ if (!mgr->caps.velem_src_offset_unaligned) { for (i = 0; i < count; i++) { ve->native_format_size[i] = align(ve->native_format_size[i], 4); } } ve->driver_cso = pipe->create_vertex_elements_state(pipe, count, driver_attribs); return ve; }