gallium: remove TGSI opcode DPH
[mesa.git] / src / gallium / drivers / r300 / r300_render_translate.c
index 0ea11e5bfc2ea19c72910bcabfc22aac20d0aeb0..7dc49d35298335441c1eec62e28ac0c016dca0a0 100644 (file)
  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
 
-/**
- * The functions below translate vertex and index buffers to the layout
- * compatible with the hardware, so that all vertex and index fetches are
- * DWORD-aligned and all used vertex and index formats are supported.
- * For indices, an optional index offset is added to each index.
- */
-
 #include "r300_context.h"
-#include "translate/translate.h"
-
-void r300_begin_vertex_translate(struct r300_context *r300)
-{
-    struct pipe_context *pipe = &r300->context;
-    struct translate_key key = {0};
-    struct translate_element *te;
-    unsigned tr_elem_index[PIPE_MAX_ATTRIBS] = {0};
-    struct translate *tr;
-    struct r300_vertex_element_state *ve = r300->velems;
-    boolean vb_translated[PIPE_MAX_ATTRIBS] = {0};
-    void *vb_map[PIPE_MAX_ATTRIBS] = {0}, *out_map;
-    struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0}, *out_transfer;
-    struct pipe_resource *out_buffer;
-    unsigned i, num_verts;
-
-    /* Initialize the translate key, i.e. the recipe how vertices should be
-     * translated. */
-    for (i = 0; i < ve->count; i++) {
-        struct pipe_vertex_buffer *vb =
-                &r300->vertex_buffer[ve->velem[i].vertex_buffer_index];
-        enum pipe_format output_format = ve->hw_format[i];
-        unsigned output_format_size = ve->hw_format_size[i];
-
-        /* Check for support. */
-        if (ve->velem[i].src_format == ve->hw_format[i] &&
-            (vb->buffer_offset + ve->velem[i].src_offset) % 4 == 0 &&
-            vb->stride % 4 == 0) {
-            continue;
-        }
-
-        /* Workaround for translate: output floats instead of halfs. */
-        switch (output_format) {
-            case PIPE_FORMAT_R16_FLOAT:
-                output_format = PIPE_FORMAT_R32_FLOAT;
-                output_format_size = 4;
-                break;
-            case PIPE_FORMAT_R16G16_FLOAT:
-                output_format = PIPE_FORMAT_R32G32_FLOAT;
-                output_format_size = 8;
-                break;
-            case PIPE_FORMAT_R16G16B16_FLOAT:
-                output_format = PIPE_FORMAT_R32G32B32_FLOAT;
-                output_format_size = 12;
-                break;
-            case PIPE_FORMAT_R16G16B16A16_FLOAT:
-                output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
-                output_format_size = 16;
-                break;
-            default:;
-        }
-
-        /* Add this vertex element. */
-        te = &key.element[key.nr_elements];
-        /*te->type;
-        te->instance_divisor;*/
-        te->input_buffer = ve->velem[i].vertex_buffer_index;
-        te->input_format = ve->velem[i].src_format;
-        te->input_offset = vb->buffer_offset + ve->velem[i].src_offset;
-        te->output_format = output_format;
-        te->output_offset = key.output_stride;
-
-        key.output_stride += output_format_size;
-        vb_translated[ve->velem[i].vertex_buffer_index] = TRUE;
-        tr_elem_index[i] = key.nr_elements;
-        key.nr_elements++;
-    }
-
-    /* Get a translate object. */
-    tr = translate_cache_find(r300->tran.translate_cache, &key);
-
-    /* Map buffers we want to translate. */
-    for (i = 0; i < r300->vertex_buffer_count; i++) {
-        if (vb_translated[i]) {
-            struct pipe_vertex_buffer *vb = &r300->vertex_buffer[i];
-
-            vb_map[i] = pipe_buffer_map(pipe, vb->buffer,
-                                        PIPE_TRANSFER_READ, &vb_transfer[i]);
-
-            tr->set_buffer(tr, i, vb_map[i], vb->stride, vb->max_index);
-        }
-    }
-
-    /* Create and map the output buffer. */
-    num_verts = r300->vertex_buffer_max_index + 1;
-
-    out_buffer = pipe_buffer_create(&r300->screen->screen,
-                                    PIPE_BIND_VERTEX_BUFFER,
-                                    key.output_stride * num_verts);
+#include "util/u_index_modify.h"
+#include "util/u_upload_mgr.h"
 
-    out_map = pipe_buffer_map(pipe, out_buffer, PIPE_TRANSFER_WRITE,
-                              &out_transfer);
-
-    /* Translate. */
-    tr->run(tr, 0, num_verts, 0, out_map);
-
-    /* Unmap all buffers. */
-    for (i = 0; i < r300->vertex_buffer_count; i++) {
-        if (vb_translated[i]) {
-            pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer,
-                              vb_transfer[i]);
-        }
-    }
-
-    pipe_buffer_unmap(pipe, out_buffer, out_transfer);
-
-    /* Setup the new vertex buffer in the first free slot. */
-    for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
-        struct pipe_vertex_buffer *vb = &r300->vertex_buffer[i];
-
-        if (!vb->buffer) {
-            pipe_resource_reference(&vb->buffer, out_buffer);
-            vb->buffer_offset = 0;
-            vb->max_index = num_verts - 1;
-            vb->stride = key.output_stride;
-            r300->tran.vb_slot = i;
-            break;
-        }
-    }
-
-    /* Save and replace vertex elements. */
-    {
-        struct pipe_vertex_element new_velems[PIPE_MAX_ATTRIBS];
-
-        r300->tran.saved_velems = r300->velems;
-
-        for (i = 0; i < ve->count; i++) {
-            if (vb_translated[ve->velem[i].vertex_buffer_index]) {
-                te = &key.element[tr_elem_index[i]];
-                new_velems[i].instance_divisor = ve->velem[i].instance_divisor;
-                new_velems[i].src_format = te->output_format;
-                new_velems[i].src_offset = te->output_offset;
-                new_velems[i].vertex_buffer_index = r300->tran.vb_slot;
-            } else {
-                memcpy(&new_velems[i], &ve->velem[i],
-                       sizeof(struct pipe_vertex_element));
-            }
-        }
-
-        r300->tran.new_velems =
-            pipe->create_vertex_elements_state(pipe, ve->count, new_velems);
-        pipe->bind_vertex_elements_state(pipe, r300->tran.new_velems);
-    }
-
-    pipe_resource_reference(&out_buffer, NULL);
-}
-
-void r300_end_vertex_translate(struct r300_context *r300)
-{
-    struct pipe_context *pipe = &r300->context;
-
-    /* Restore vertex elements. */
-    pipe->bind_vertex_elements_state(pipe, r300->tran.saved_velems);
-    pipe->delete_vertex_elements_state(pipe, r300->tran.new_velems);
-
-    /* Delete the now-unused VBO. */
-    pipe_resource_reference(&r300->vertex_buffer[r300->tran.vb_slot].buffer,
-                            NULL);
-}
-
-static void r300_shorten_ubyte_elts(struct r300_context* r300,
-                                    struct pipe_resource** elts,
-                                    int index_bias,
-                                    unsigned start,
-                                    unsigned count)
-{
-    struct pipe_context* context = &r300->context;
-    struct pipe_screen* screen = r300->context.screen;
-    struct pipe_resource* new_elts;
-    unsigned char *in_map;
-    unsigned short *out_map;
-    struct pipe_transfer *src_transfer, *dst_transfer;
-    unsigned i;
-
-    new_elts = pipe_buffer_create(screen,
-                                  PIPE_BIND_INDEX_BUFFER,
-                                  2 * count);
-
-    in_map = pipe_buffer_map(context, *elts, PIPE_TRANSFER_READ, &src_transfer);
-    out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE, &dst_transfer);
-
-    in_map += start;
-
-    for (i = 0; i < count; i++) {
-        *out_map = (unsigned short)(*in_map + index_bias);
-        in_map++;
-        out_map++;
-    }
-
-    pipe_buffer_unmap(context, *elts, src_transfer);
-    pipe_buffer_unmap(context, new_elts, dst_transfer);
-
-    *elts = new_elts;
-}
-
-static void r300_rebuild_ushort_elts(struct r300_context *r300,
-                                     struct pipe_resource **elts,
-                                     int index_bias,
-                                     unsigned start, unsigned count)
-{
-    struct pipe_context *context = &r300->context;
-    struct pipe_transfer *in_transfer = NULL;
-    struct pipe_transfer *out_transfer = NULL;
-    struct pipe_resource *new_elts;
-    unsigned short *in_map;
-    unsigned short *out_map;
-    unsigned i;
-
-    new_elts = pipe_buffer_create(context->screen,
-                                  PIPE_BIND_INDEX_BUFFER,
-                                  2 * count);
-
-    in_map = pipe_buffer_map(context, *elts,
-                             PIPE_TRANSFER_READ, &in_transfer);
-    out_map = pipe_buffer_map(context, new_elts,
-                              PIPE_TRANSFER_WRITE, &out_transfer);
-
-    in_map += start;
-    for (i = 0; i < count; i++) {
-        *out_map = (unsigned short)(*in_map + index_bias);
-        in_map++;
-        out_map++;
-    }
-
-    pipe_buffer_unmap(context, *elts, in_transfer);
-    pipe_buffer_unmap(context, new_elts, out_transfer);
-
-    *elts = new_elts;
-}
-
-static void r300_rebuild_uint_elts(struct r300_context *r300,
-                                   struct pipe_resource **elts,
-                                   int index_bias,
-                                   unsigned start, unsigned count)
-{
-    struct pipe_context *context = &r300->context;
-    struct pipe_transfer *in_transfer = NULL;
-    struct pipe_transfer *out_transfer = NULL;
-    struct pipe_resource *new_elts;
-    unsigned int *in_map;
-    unsigned int *out_map;
-    unsigned i;
-
-    new_elts = pipe_buffer_create(context->screen,
-                                  PIPE_BIND_INDEX_BUFFER,
-                                  2 * count);
-
-    in_map = pipe_buffer_map(context, *elts,
-                             PIPE_TRANSFER_READ, &in_transfer);
-    out_map = pipe_buffer_map(context, new_elts,
-                              PIPE_TRANSFER_WRITE, &out_transfer);
-
-    in_map += start;
-    for (i = 0; i < count; i++) {
-        *out_map = (unsigned int)(*in_map + index_bias);
-        in_map++;
-        out_map++;
-    }
-
-    pipe_buffer_unmap(context, *elts, in_transfer);
-    pipe_buffer_unmap(context, new_elts, out_transfer);
-
-    *elts = new_elts;
-}
 
 void r300_translate_index_buffer(struct r300_context *r300,
-                                 struct pipe_resource **index_buffer,
+                                 const struct pipe_draw_info *info,
+                                 struct pipe_resource **out_buffer,
                                  unsigned *index_size, unsigned index_offset,
                                  unsigned *start, unsigned count)
 {
+    unsigned out_offset;
+    void *ptr;
+
     switch (*index_size) {
-        case 1:
-            r300_shorten_ubyte_elts(r300, index_buffer, index_offset, *start, count);
-            *index_size = 2;
-            *start = 0;
-            break;
+    case 1:
+        *out_buffer = NULL;
+        u_upload_alloc(r300->uploader, 0, count * 2, 4,
+                       &out_offset, out_buffer, &ptr);
+
+        util_shorten_ubyte_elts_to_userptr(
+                &r300->context, info, PIPE_TRANSFER_UNSYNCHRONIZED, index_offset,
+                *start, count, ptr);
+
+        *index_size = 2;
+        *start = out_offset / 2;
+        break;
+
+    case 2:
+        if (index_offset) {
+            *out_buffer = NULL;
+            u_upload_alloc(r300->uploader, 0, count * 2, 4,
+                           &out_offset, out_buffer, &ptr);
+
+            util_rebuild_ushort_elts_to_userptr(&r300->context, info,
+                                                PIPE_TRANSFER_UNSYNCHRONIZED,
+                                                index_offset, *start,
+                                                count, ptr);
+
+            *start = out_offset / 2;
+        }
+        break;
 
-        case 2:
-            if (*start % 2 != 0 || index_offset) {
-                r300_rebuild_ushort_elts(r300, index_buffer, index_offset, *start, count);
-                *start = 0;
-            }
-            break;
+    case 4:
+        if (index_offset) {
+            *out_buffer = NULL;
+            u_upload_alloc(r300->uploader, 0, count * 4, 4,
+                           &out_offset, out_buffer, &ptr);
 
-        case 4:
-            if (index_offset) {
-                r300_rebuild_uint_elts(r300, index_buffer, index_offset, *start, count);
-                *start = 0;
-            }
-            break;
+            util_rebuild_uint_elts_to_userptr(&r300->context, info,
+                                              PIPE_TRANSFER_UNSYNCHRONIZED,
+                                              index_offset, *start,
+                                              count, ptr);
+
+            *start = out_offset / 4;
+        }
+        break;
     }
 }