diff options
Diffstat (limited to 'src/gallium/drivers/nvfx/nvfx_vbo.c')
-rw-r--r-- | src/gallium/drivers/nvfx/nvfx_vbo.c | 637 |
1 files changed, 0 insertions, 637 deletions
diff --git a/src/gallium/drivers/nvfx/nvfx_vbo.c b/src/gallium/drivers/nvfx/nvfx_vbo.c deleted file mode 100644 index b72379d6536..00000000000 --- a/src/gallium/drivers/nvfx/nvfx_vbo.c +++ /dev/null @@ -1,637 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_state.h" -#include "util/u_inlines.h" -#include "util/u_format.h" -#include "util/u_transfer.h" -#include "translate/translate.h" - -#include "nvfx_context.h" -#include "nvfx_state.h" -#include "nvfx_resource.h" - -#include "nouveau/nouveau_channel.h" -#include "nouveau/nv04_pushbuf.h" - -static inline unsigned -util_guess_unique_indices_count(unsigned mode, unsigned indices) -{ - /* Euler's formula gives V = - * = E - F + 2 = - * = F * (polygon_edges / 2 - 1) + 2 = - * = F * (polygon_edges - 2) / 2 + 2 = - * = indices * (polygon_edges - 2) / (2 * indices_per_face) + 2 - * = indices * (1 / 2 - 1 / polygon_edges) + 2 - */ - switch(mode) - { - case PIPE_PRIM_LINES: - return indices >> 1; - case PIPE_PRIM_TRIANGLES: - { - // avoid an expensive division by 3 using the multiplicative inverse mod 2^32 - unsigned q; - unsigned inv3 = 2863311531; - indices >>= 1; - q = indices * inv3; - if(unlikely(q >= indices)) - { - q += inv3; - if(q >= indices) - q += inv3; - } - return indices + 2; - //return indices / 6 + 2; - } - // guess that indexed quads are created by successive connections, since a closed mesh seems unlikely - case PIPE_PRIM_QUADS: - return (indices >> 1) + 2; - // return (indices >> 2) + 2; // if it is a closed mesh - default: - return indices; - } -} - -static unsigned nvfx_decide_upload_mode(struct pipe_context *pipe, const struct pipe_draw_info *info) -{ - struct nvfx_context* nvfx = nvfx_context(pipe); - unsigned hardware_cost = 0; - unsigned inline_cost = 0; - unsigned unique_vertices; - unsigned upload_mode; - float best_index_cost_for_hardware_vertices_as_inline_cost; - boolean prefer_hardware_indices; - unsigned index_inline_cost; - unsigned index_hardware_cost; - if (info->indexed) - unique_vertices = util_guess_unique_indices_count(info->mode, info->count); - else - unique_vertices = info->count; - - /* Here we try to figure out if we are better off writing vertex data directly on the FIFO, - * or create hardware buffer objects and pointing the hardware to them. - * - * This is done by computing the total memcpy cost of each option, ignoring uploads - * if we think that the buffer is static and thus the upload cost will be amortized over - * future draw calls. - * - * For instance, if everything looks static, we will always create buffer objects, while if - * everything is a user buffer and we are not doing indexed drawing, we never do. - * - * Other interesting cases are where a small user vertex buffer, but a huge user index buffer, - * where we will upload the vertex buffer, so that we can use hardware index lookup, and - * the opposite case, where we instead do index lookup in software to avoid uploading - * a huge amount of vertex data that is not going to be used. - * - * Otherwise, we generally move to the GPU the after it has been pushed - * NVFX_STATIC_BUFFER_MIN_REUSE_TIMES times to the GPU without having - * been updated with a transfer (or just the buffer having been destroyed). - * - * There is no special handling for user buffers, since applications can use - * OpenGL VBOs in a one-shot fashion. OpenGL 3/4 core profile forces this - * by the way. - * - * Note that currently we don't support only putting some data on the FIFO, and - * some on vertex buffers (constant and instanced data is independent from this). - * - * nVidia doesn't seem to do this either, even though it should be at least - * doable with VTX_ATTR and possibly with VERTEX_DATA too if not indexed. - */ - - for (unsigned i = 0; i < nvfx->vtxelt->num_per_vertex_buffer_infos; i++) - { - struct nvfx_per_vertex_buffer_info* vbi = &nvfx->vtxelt->per_vertex_buffer_info[i]; - struct pipe_vertex_buffer *vb = &nvfx->vtxbuf[vbi->vertex_buffer_index]; - struct nvfx_buffer* buffer = nvfx_buffer(vb->buffer); - buffer->bytes_to_draw_until_static -= vbi->per_vertex_size * unique_vertices; - if (!nvfx_buffer_seems_static(buffer)) - { - hardware_cost += buffer->dirty_end - buffer->dirty_begin; - if (!buffer->base.bo) - hardware_cost += nvfx->screen->buffer_allocation_cost; - } - inline_cost += vbi->per_vertex_size * info->count; - } - - best_index_cost_for_hardware_vertices_as_inline_cost = 0.0f; - prefer_hardware_indices = FALSE; - index_inline_cost = 0; - index_hardware_cost = 0; - - if (info->indexed) - { - index_inline_cost = nvfx->idxbuf.index_size * info->count; - if (nvfx->screen->index_buffer_reloc_flags - && (nvfx->idxbuf.index_size == 2 || nvfx->idxbuf.index_size == 4) - && !(nvfx->idxbuf.offset & (nvfx->idxbuf.index_size - 1))) - { - struct nvfx_buffer* buffer = nvfx_buffer(nvfx->idxbuf.buffer); - buffer->bytes_to_draw_until_static -= index_inline_cost; - - prefer_hardware_indices = TRUE; - - if (!nvfx_buffer_seems_static(buffer)) - { - index_hardware_cost = buffer->dirty_end - buffer->dirty_begin; - if (!buffer->base.bo) - index_hardware_cost += nvfx->screen->buffer_allocation_cost; - } - - if ((float) index_inline_cost < (float) index_hardware_cost * nvfx->screen->inline_cost_per_hardware_cost) - { - best_index_cost_for_hardware_vertices_as_inline_cost = (float) index_inline_cost; - } - else - { - best_index_cost_for_hardware_vertices_as_inline_cost = (float) index_hardware_cost * nvfx->screen->inline_cost_per_hardware_cost; - prefer_hardware_indices = TRUE; - } - } - } - - /* let's finally figure out which of the 3 paths we want to take */ - if ((float) (inline_cost + index_inline_cost) > ((float) hardware_cost * nvfx->screen->inline_cost_per_hardware_cost + best_index_cost_for_hardware_vertices_as_inline_cost)) - upload_mode = 1 + prefer_hardware_indices; - else - upload_mode = 0; - -#ifdef DEBUG - if (unlikely(nvfx->screen->trace_draw)) - { - fprintf(stderr, "DRAW"); - if (info->indexed) - { - fprintf(stderr, "_IDX%u", nvfx->idxbuf.index_size); - if (info->index_bias) - fprintf(stderr, " biased %u", info->index_bias); - fprintf(stderr, " idxrange %u -> %u", info->min_index, info->max_index); - } - if (info->instance_count > 1) - fprintf(stderr, " %u instances from %u", info->instance_count, info->indexed); - fprintf(stderr, " start %u count %u prim %u", info->start, info->count, info->mode); - if (!upload_mode) - fprintf(stderr, " -> inline vertex data"); - else if (upload_mode == 2 || !info->indexed) - fprintf(stderr, " -> buffer range"); - else - fprintf(stderr, " -> inline indices"); - fprintf(stderr, " [ivtx %u hvtx %u iidx %u hidx %u bidx %f] <", inline_cost, hardware_cost, index_inline_cost, index_hardware_cost, best_index_cost_for_hardware_vertices_as_inline_cost); - for (unsigned i = 0; i < nvfx->vtxelt->num_per_vertex_buffer_infos; ++i) - { - struct nvfx_per_vertex_buffer_info* vbi = &nvfx->vtxelt->per_vertex_buffer_info[i]; - struct pipe_vertex_buffer *vb = &nvfx->vtxbuf[vbi->vertex_buffer_index]; - struct nvfx_buffer* buffer = nvfx_buffer(vb->buffer); - if (i) - fprintf(stderr, ", "); - fprintf(stderr, "%p%s left %Li", buffer, buffer->last_update_static ? " static" : "", buffer->bytes_to_draw_until_static); - } - fprintf(stderr, ">\n"); - } -#endif - - return upload_mode; -} - -void nvfx_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) -{ - struct nvfx_context *nvfx = nvfx_context(pipe); - unsigned upload_mode = 0; - - if (!nvfx->vtxelt->needs_translate) - upload_mode = nvfx_decide_upload_mode(pipe, info); - - nvfx->use_index_buffer = upload_mode > 1; - - if ((upload_mode > 0) != nvfx->use_vertex_buffers) - { - nvfx->use_vertex_buffers = (upload_mode > 0); - nvfx->dirty |= NVFX_NEW_ARRAYS; - nvfx->draw_dirty |= NVFX_NEW_ARRAYS; - } - - if (upload_mode > 0) - { - for (unsigned i = 0; i < nvfx->vtxelt->num_per_vertex_buffer_infos; i++) - { - struct nvfx_per_vertex_buffer_info* vbi = &nvfx->vtxelt->per_vertex_buffer_info[i]; - struct pipe_vertex_buffer *vb = &nvfx->vtxbuf[vbi->vertex_buffer_index]; - nvfx_buffer_upload(nvfx_buffer(vb->buffer)); - } - - if (upload_mode > 1) - { - nvfx_buffer_upload(nvfx_buffer(nvfx->idxbuf.buffer)); - - if (unlikely(info->index_bias != nvfx->base_vertex)) - { - nvfx->base_vertex = info->index_bias; - nvfx->dirty |= NVFX_NEW_ARRAYS; - } - } - else - { - if (unlikely(info->start < nvfx->base_vertex && nvfx->base_vertex)) - { - nvfx->base_vertex = 0; - nvfx->dirty |= NVFX_NEW_ARRAYS; - } - } - } - - if (nvfx->screen->force_swtnl || !nvfx_state_validate(nvfx)) - nvfx_draw_vbo_swtnl(pipe, info); - else - nvfx_push_vbo(pipe, info); -} - -boolean -nvfx_vbo_validate(struct nvfx_context *nvfx) -{ - struct nouveau_channel* chan = nvfx->screen->base.channel; - struct nouveau_grobj *eng3d = nvfx->screen->eng3d; - int i; - int elements = MAX2(nvfx->vtxelt->num_elements, nvfx->hw_vtxelt_nr); - unsigned vb_flags = nvfx->screen->vertex_buffer_reloc_flags | NOUVEAU_BO_RD; - - if (!elements) - return TRUE; - - MARK_RING(chan, (5 + 2) * 16 + 2 + 11, 16 + 2); - for(unsigned i = 0; i < nvfx->vtxelt->num_constant; ++i) - { - struct nvfx_low_frequency_element *ve = &nvfx->vtxelt->constant[i]; - struct pipe_vertex_buffer *vb = &nvfx->vtxbuf[ve->vertex_buffer_index]; - struct nvfx_buffer* buffer = nvfx_buffer(vb->buffer); - float v[4]; - ve->fetch_rgba_float(v, buffer->data + vb->buffer_offset + ve->src_offset, 0, 0); - nvfx_emit_vtx_attr(chan, eng3d, ve->idx, v, ve->ncomp); - } - - - BEGIN_RING(chan, eng3d, NV30_3D_VTXFMT(0), elements); - if(nvfx->use_vertex_buffers) - { - unsigned idx = 0; - for (i = 0; i < nvfx->vtxelt->num_per_vertex; i++) { - struct nvfx_per_vertex_element *ve = &nvfx->vtxelt->per_vertex[i]; - struct pipe_vertex_buffer *vb = &nvfx->vtxbuf[ve->vertex_buffer_index]; - - if(idx != ve->idx) - { - assert(idx < ve->idx); - OUT_RINGp(chan, &nvfx->vtxelt->vtxfmt[idx], ve->idx - idx); - idx = ve->idx; - } - - OUT_RING(chan, nvfx->vtxelt->vtxfmt[idx] | (vb->stride << NV30_3D_VTXFMT_STRIDE__SHIFT)); - ++idx; - } - if(idx != nvfx->vtxelt->num_elements) - OUT_RINGp(chan, &nvfx->vtxelt->vtxfmt[idx], nvfx->vtxelt->num_elements - idx); - } - else - OUT_RINGp(chan, nvfx->vtxelt->vtxfmt, nvfx->vtxelt->num_elements); - - for(i = nvfx->vtxelt->num_elements; i < elements; ++i) - OUT_RING(chan, NV30_3D_VTXFMT_TYPE_V32_FLOAT); - - if(nvfx->is_nv4x) { - unsigned i; - /* seems to be some kind of cache flushing */ - for(i = 0; i < 3; ++i) { - BEGIN_RING(chan, eng3d, 0x1718, 1); - OUT_RING(chan, 0); - } - } - - BEGIN_RING(chan, eng3d, NV30_3D_VTXBUF(0), elements); - if(nvfx->use_vertex_buffers) - { - unsigned idx = 0; - for (i = 0; i < nvfx->vtxelt->num_per_vertex; i++) { - struct nvfx_per_vertex_element *ve = &nvfx->vtxelt->per_vertex[i]; - struct pipe_vertex_buffer *vb = &nvfx->vtxbuf[ve->vertex_buffer_index]; - struct nouveau_bo* bo = nvfx_resource(vb->buffer)->bo; - - for(; idx < ve->idx; ++idx) - OUT_RING(chan, 0); - - OUT_RELOC(chan, bo, - vb->buffer_offset + ve->src_offset + nvfx->base_vertex * vb->stride, - vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, - 0, NV30_3D_VTXBUF_DMA1); - ++idx; - } - - for(; idx < elements; ++idx) - OUT_RING(chan, 0); - } - else - { - for (i = 0; i < elements; i++) - OUT_RING(chan, 0); - } - - BEGIN_RING(chan, eng3d, 0x1710, 1); - OUT_RING(chan, 0); - - nvfx->hw_vtxelt_nr = nvfx->vtxelt->num_elements; - nvfx->relocs_needed &=~ NVFX_RELOCATE_VTXBUF; - return TRUE; -} - -void -nvfx_vbo_swtnl_validate(struct nvfx_context *nvfx) -{ - struct nouveau_channel* chan = nvfx->screen->base.channel; - struct nouveau_grobj *eng3d = nvfx->screen->eng3d; - unsigned num_outputs = nvfx->vertprog->draw_elements; - int elements = MAX2(num_outputs, nvfx->hw_vtxelt_nr); - - if (!elements) - return; - - BEGIN_RING(chan, eng3d, NV30_3D_VTXFMT(0), elements); - for(unsigned i = 0; i < num_outputs; ++i) - OUT_RING(chan, (4 << NV30_3D_VTXFMT_SIZE__SHIFT) | NV30_3D_VTXFMT_TYPE_V32_FLOAT); - for(unsigned i = num_outputs; i < elements; ++i) - OUT_RING(chan, NV30_3D_VTXFMT_TYPE_V32_FLOAT); - - if(nvfx->is_nv4x) { - unsigned i; - /* seems to be some kind of cache flushing */ - for(i = 0; i < 3; ++i) { - BEGIN_RING(chan, eng3d, 0x1718, 1); - OUT_RING(chan, 0); - } - } - - BEGIN_RING(chan, eng3d, NV30_3D_VTXBUF(0), elements); - for (unsigned i = 0; i < elements; i++) - OUT_RING(chan, 0); - - BEGIN_RING(chan, eng3d, 0x1710, 1); - OUT_RING(chan, 0); - - nvfx->hw_vtxelt_nr = num_outputs; - nvfx->relocs_needed &=~ NVFX_RELOCATE_VTXBUF; -} - -void -nvfx_vbo_relocate(struct nvfx_context *nvfx) -{ - struct nouveau_channel* chan; - unsigned vb_flags; - int i; - - if(!nvfx->use_vertex_buffers) - return; - - chan = nvfx->screen->base.channel; - vb_flags = nvfx->screen->vertex_buffer_reloc_flags | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY; - - MARK_RING(chan, 2 * 16 + 3, 2 * 16 + 3); - for (i = 0; i < nvfx->vtxelt->num_per_vertex; i++) { - struct nvfx_per_vertex_element *ve = &nvfx->vtxelt->per_vertex[i]; - struct pipe_vertex_buffer *vb = &nvfx->vtxbuf[ve->vertex_buffer_index]; - struct nouveau_bo* bo = nvfx_resource(vb->buffer)->bo; - - OUT_RELOC(chan, bo, RING_3D(NV30_3D_VTXBUF(ve->idx), 1), - vb_flags, 0, 0); - OUT_RELOC(chan, bo, vb->buffer_offset + ve->src_offset + nvfx->base_vertex * vb->stride, - vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, - 0, NV30_3D_VTXBUF_DMA1); - } - nvfx->relocs_needed &=~ NVFX_RELOCATE_VTXBUF; -} - -static void -nvfx_idxbuf_emit(struct nvfx_context* nvfx, unsigned ib_flags) -{ - struct nouveau_channel* chan = nvfx->screen->base.channel; - unsigned ib_format = (nvfx->idxbuf.index_size == 2) ? NV30_3D_IDXBUF_FORMAT_TYPE_U16 : NV30_3D_IDXBUF_FORMAT_TYPE_U32; - struct nouveau_bo* bo = nvfx_resource(nvfx->idxbuf.buffer)->bo; - ib_flags |= nvfx->screen->index_buffer_reloc_flags | NOUVEAU_BO_RD; - - assert(nvfx->screen->index_buffer_reloc_flags); - - MARK_RING(chan, 3, 3); - if(ib_flags & NOUVEAU_BO_DUMMY) - OUT_RELOC(chan, bo, RING_3D(NV30_3D_IDXBUF_OFFSET, 2), ib_flags, 0, 0); - else - OUT_RING(chan, RING_3D(NV30_3D_IDXBUF_OFFSET, 2)); - OUT_RELOC(chan, bo, nvfx->idxbuf.offset + 1, ib_flags | NOUVEAU_BO_LOW, 0, 0); - OUT_RELOC(chan, bo, ib_format, ib_flags | NOUVEAU_BO_OR, - 0, NV30_3D_IDXBUF_FORMAT_DMA1); - nvfx->relocs_needed &=~ NVFX_RELOCATE_IDXBUF; -} - -void -nvfx_idxbuf_validate(struct nvfx_context* nvfx) -{ - nvfx_idxbuf_emit(nvfx, 0); -} - -void -nvfx_idxbuf_relocate(struct nvfx_context* nvfx) -{ - nvfx_idxbuf_emit(nvfx, NOUVEAU_BO_DUMMY); -} - -unsigned nvfx_vertex_formats[PIPE_FORMAT_COUNT] = -{ - [PIPE_FORMAT_R32_FLOAT] = NV30_3D_VTXFMT_TYPE_V32_FLOAT, - [PIPE_FORMAT_R32G32_FLOAT] = NV30_3D_VTXFMT_TYPE_V32_FLOAT, - [PIPE_FORMAT_R32G32B32_FLOAT] = NV30_3D_VTXFMT_TYPE_V32_FLOAT, - [PIPE_FORMAT_R32G32B32A32_FLOAT] = NV30_3D_VTXFMT_TYPE_V32_FLOAT, - [PIPE_FORMAT_R16_FLOAT] = NV30_3D_VTXFMT_TYPE_V16_FLOAT, - [PIPE_FORMAT_R16G16_FLOAT] = NV30_3D_VTXFMT_TYPE_V16_FLOAT, - [PIPE_FORMAT_R16G16B16_FLOAT] = NV30_3D_VTXFMT_TYPE_V16_FLOAT, - [PIPE_FORMAT_R16G16B16A16_FLOAT] = NV30_3D_VTXFMT_TYPE_V16_FLOAT, - [PIPE_FORMAT_R8_UNORM] = NV30_3D_VTXFMT_TYPE_U8_UNORM, - [PIPE_FORMAT_R8G8_UNORM] = NV30_3D_VTXFMT_TYPE_U8_UNORM, - [PIPE_FORMAT_R8G8B8_UNORM] = NV30_3D_VTXFMT_TYPE_U8_UNORM, - [PIPE_FORMAT_R8G8B8A8_UNORM] = NV30_3D_VTXFMT_TYPE_U8_UNORM, - [PIPE_FORMAT_R8G8B8A8_USCALED] = NV30_3D_VTXFMT_TYPE_U8_USCALED, - [PIPE_FORMAT_R16_SNORM] = NV30_3D_VTXFMT_TYPE_V16_SNORM, - [PIPE_FORMAT_R16G16_SNORM] = NV30_3D_VTXFMT_TYPE_V16_SNORM, - [PIPE_FORMAT_R16G16B16_SNORM] = NV30_3D_VTXFMT_TYPE_V16_SNORM, - [PIPE_FORMAT_R16G16B16A16_SNORM] = NV30_3D_VTXFMT_TYPE_V16_SNORM, - [PIPE_FORMAT_R16_SSCALED] = NV30_3D_VTXFMT_TYPE_V16_SSCALED, - [PIPE_FORMAT_R16G16_SSCALED] = NV30_3D_VTXFMT_TYPE_V16_SSCALED, - [PIPE_FORMAT_R16G16B16_SSCALED] = NV30_3D_VTXFMT_TYPE_V16_SSCALED, - [PIPE_FORMAT_R16G16B16A16_SSCALED] = NV30_3D_VTXFMT_TYPE_V16_SSCALED, -}; - -static void * -nvfx_vtxelts_state_create(struct pipe_context *pipe, - unsigned num_elements, - const struct pipe_vertex_element *elements) -{ - struct nvfx_vtxelt_state *cso = CALLOC_STRUCT(nvfx_vtxelt_state); - struct translate_key transkey; - unsigned per_vertex_size[16]; - unsigned vb_compacted_index[16]; - - if(num_elements > 16) - { - _debug_printf("Error: application attempted to use %u vertex elements, but only 16 are supported: ignoring the rest\n", num_elements); - num_elements = 16; - } - - memset(per_vertex_size, 0, sizeof(per_vertex_size)); - memcpy(cso->pipe, elements, num_elements * sizeof(elements[0])); - cso->num_elements = num_elements; - cso->needs_translate = FALSE; - - transkey.nr_elements = 0; - transkey.output_stride = 0; - - for(unsigned i = 0; i < num_elements; ++i) - { - const struct pipe_vertex_element* ve = &elements[i]; - if(!ve->instance_divisor) - per_vertex_size[ve->vertex_buffer_index] += util_format_get_stride(ve->src_format, 1); - } - - for(unsigned i = 0; i < 16; ++i) - { - if(per_vertex_size[i]) - { - unsigned idx = cso->num_per_vertex_buffer_infos++; - cso->per_vertex_buffer_info[idx].vertex_buffer_index = i; - cso->per_vertex_buffer_info[idx].per_vertex_size = per_vertex_size[i]; - vb_compacted_index[i] = idx; - } - } - - for(unsigned i = 0; i < num_elements; ++i) - { - const struct pipe_vertex_element* ve = &elements[i]; - unsigned type = nvfx_vertex_formats[ve->src_format]; - unsigned ncomp = util_format_get_nr_components(ve->src_format); - - //if(ve->frequency != PIPE_ELEMENT_FREQUENCY_PER_VERTEX) - if(ve->instance_divisor) - { - struct nvfx_low_frequency_element* lfve; - cso->vtxfmt[i] = NV30_3D_VTXFMT_TYPE_V32_FLOAT; - - //if(ve->frequency == PIPE_ELEMENT_FREQUENCY_CONSTANT) - if(0) - lfve = &cso->constant[cso->num_constant++]; - else - { - lfve = &cso->per_instance[cso->num_per_instance++].base; - ((struct nvfx_per_instance_element*)lfve)->instance_divisor = ve->instance_divisor; - } - - lfve->idx = i; - lfve->vertex_buffer_index = ve->vertex_buffer_index; - lfve->src_offset = ve->src_offset; - lfve->fetch_rgba_float = util_format_description(ve->src_format)->fetch_rgba_float; - lfve->ncomp = ncomp; - } - else - { - unsigned idx; - - idx = cso->num_per_vertex++; - cso->per_vertex[idx].idx = i; - cso->per_vertex[idx].vertex_buffer_index = ve->vertex_buffer_index; - cso->per_vertex[idx].src_offset = ve->src_offset; - - idx = transkey.nr_elements++; - transkey.element[idx].input_format = ve->src_format; - transkey.element[idx].input_buffer = vb_compacted_index[ve->vertex_buffer_index]; - transkey.element[idx].input_offset = ve->src_offset; - transkey.element[idx].instance_divisor = 0; - transkey.element[idx].type = TRANSLATE_ELEMENT_NORMAL; - if(type) - { - transkey.element[idx].output_format = ve->src_format; - cso->vtxfmt[i] = (ncomp << NV30_3D_VTXFMT_SIZE__SHIFT) | type; - } - else - { - unsigned float32[4] = {PIPE_FORMAT_R32_FLOAT, PIPE_FORMAT_R32G32_FLOAT, PIPE_FORMAT_R32G32B32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT}; - transkey.element[idx].output_format = float32[ncomp - 1]; - cso->needs_translate = TRUE; - cso->vtxfmt[i] = (ncomp << NV30_3D_VTXFMT_SIZE__SHIFT) | NV30_3D_VTXFMT_TYPE_V32_FLOAT; - } - transkey.element[idx].output_offset = transkey.output_stride; - transkey.output_stride += (util_format_get_stride(transkey.element[idx].output_format, 1) + 3) & ~3; - } - } - - cso->translate = translate_create(&transkey); - cso->vertex_length = transkey.output_stride >> 2; - cso->max_vertices_per_packet = 2047 / MAX2(cso->vertex_length, 1); - - return (void *)cso; -} - -static void -nvfx_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso) -{ - FREE(hwcso); -} - -static void -nvfx_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso) -{ - struct nvfx_context *nvfx = nvfx_context(pipe); - - nvfx->vtxelt = hwcso; - nvfx->use_vertex_buffers = -1; - nvfx->draw_dirty |= NVFX_NEW_ARRAYS; -} - -static void -nvfx_set_vertex_buffers(struct pipe_context *pipe, unsigned count, - const struct pipe_vertex_buffer *vb) -{ - struct nvfx_context *nvfx = nvfx_context(pipe); - - util_copy_vertex_buffers(nvfx->vtxbuf, - &nvfx->vtxbuf_nr, - vb, count); - - nvfx->use_vertex_buffers = -1; - nvfx->draw_dirty |= NVFX_NEW_ARRAYS; -} - -static void -nvfx_set_index_buffer(struct pipe_context *pipe, - const struct pipe_index_buffer *ib) -{ - struct nvfx_context *nvfx = nvfx_context(pipe); - - if(ib) - { - pipe_resource_reference(&nvfx->idxbuf.buffer, ib->buffer); - nvfx->idxbuf.index_size = ib->index_size; - nvfx->idxbuf.offset = ib->offset; - } - else - { - pipe_resource_reference(&nvfx->idxbuf.buffer, 0); - nvfx->idxbuf.index_size = 0; - nvfx->idxbuf.offset = 0; - } - - nvfx->dirty |= NVFX_NEW_INDEX; - nvfx->draw_dirty |= NVFX_NEW_INDEX; -} - -void -nvfx_init_vbo_functions(struct nvfx_context *nvfx) -{ - nvfx->pipe.set_vertex_buffers = nvfx_set_vertex_buffers; - nvfx->pipe.set_index_buffer = nvfx_set_index_buffer; - - nvfx->pipe.create_vertex_elements_state = nvfx_vtxelts_state_create; - nvfx->pipe.delete_vertex_elements_state = nvfx_vtxelts_state_delete; - nvfx->pipe.bind_vertex_elements_state = nvfx_vtxelts_state_bind; - - nvfx->pipe.redefine_user_buffer = u_default_redefine_user_buffer; -} |