i965: Generalize intel_upload.c to support multiple uploaders.
authorKenneth Graunke <kenneth@whitecape.org>
Tue, 27 Feb 2018 07:17:35 +0000 (23:17 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Fri, 2 Mar 2018 22:19:33 +0000 (14:19 -0800)
I'd like to reuse the upload logic for a new program cache, but the
buffers will need to have a different lifetime than the default
uploader, and also some address space restrictions.  So, we can't
use a single uploader for both situations - we'll need two of them.

This creates a public 'uploader' structure, and adjusts the interface
to take an uploader rather than always using brw->upload.  It should
have no functional change at the moment.

Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
src/mesa/drivers/dri/i965/brw_context.c
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_curbe.c
src/mesa/drivers/dri/i965/brw_draw_upload.c
src/mesa/drivers/dri/i965/brw_wm_surface_state.c
src/mesa/drivers/dri/i965/gen6_constant_state.c
src/mesa/drivers/dri/i965/intel_batchbuffer.c
src/mesa/drivers/dri/i965/intel_buffer_objects.h
src/mesa/drivers/dri/i965/intel_upload.c

index 8ab9063..fca5c8e 100644 (file)
@@ -1018,6 +1018,8 @@ brwCreateContext(gl_api api,
 
    }
 
+   brw_upload_init(&brw->upload, brw->bufmgr, 65536);
+
    brw_init_state(brw);
 
    intelInitExtensions(ctx);
index 050b656..d6e3c78 100644 (file)
@@ -718,6 +718,14 @@ struct brw_perf_query_info
    uint32_t n_b_counter_regs;
 };
 
+struct brw_uploader {
+   struct brw_bufmgr *bufmgr;
+   struct brw_bo *bo;
+   void *map;
+   uint32_t next_offset;
+   unsigned default_size;
+};
+
 /**
  * brw_context is derived from gl_context.
  */
@@ -786,11 +794,7 @@ struct brw_context
 
    struct intel_batchbuffer batch;
 
-   struct {
-      struct brw_bo *bo;
-      void *map;
-      uint32_t next_offset;
-   } upload;
+   struct brw_uploader upload;
 
    /**
     * Set if rendering has occurred to the drawable's front buffer.
index c747110..e4a2bd9 100644 (file)
@@ -214,8 +214,8 @@ brw_upload_constant_buffer(struct brw_context *brw)
       goto emit;
    }
 
-   buf = intel_upload_space(brw, bufsz, 64,
-                            &brw->curbe.curbe_bo, &brw->curbe.curbe_offset);
+   buf = brw_upload_space(&brw->upload, bufsz, 64,
+                          &brw->curbe.curbe_bo, &brw->curbe.curbe_offset);
 
    STATIC_ASSERT(sizeof(gl_constant_value) == sizeof(float));
 
index 9b81999..c058064 100644 (file)
@@ -412,10 +412,10 @@ copy_array_to_vbo_array(struct brw_context *brw,
     * to replicate it out.
     */
    if (src_stride == 0) {
-      intel_upload_data(brw, element->glarray->Ptr,
-                        element->glarray->_ElementSize,
-                        element->glarray->_ElementSize,
-                       &buffer->bo, &buffer->offset);
+      brw_upload_data(&brw->upload, element->glarray->Ptr,
+                      element->glarray->_ElementSize,
+                      element->glarray->_ElementSize,
+                      &buffer->bo, &buffer->offset);
 
       buffer->stride = 0;
       buffer->size = element->glarray->_ElementSize;
@@ -425,8 +425,8 @@ copy_array_to_vbo_array(struct brw_context *brw,
    const unsigned char *src = element->glarray->Ptr + min * src_stride;
    int count = max - min + 1;
    GLuint size = count * dst_stride;
-   uint8_t *dst = intel_upload_space(brw, size, dst_stride,
-                                     &buffer->bo, &buffer->offset);
+   uint8_t *dst = brw_upload_space(&brw->upload, size, dst_stride,
+                                   &buffer->bo, &buffer->offset);
 
    /* The GL 4.5 spec says:
     *      "If any enabled array’s buffer binding is zero when DrawArrays or
@@ -699,15 +699,17 @@ brw_prepare_shader_draw_parameters(struct brw_context *brw)
    /* For non-indirect draws, upload gl_BaseVertex. */
    if ((vs_prog_data->uses_basevertex || vs_prog_data->uses_baseinstance) &&
        brw->draw.draw_params_bo == NULL) {
-      intel_upload_data(brw, &brw->draw.params, sizeof(brw->draw.params), 4,
-                       &brw->draw.draw_params_bo,
-                        &brw->draw.draw_params_offset);
+      brw_upload_data(&brw->upload,
+                      &brw->draw.params, sizeof(brw->draw.params), 4,
+                      &brw->draw.draw_params_bo,
+                      &brw->draw.draw_params_offset);
    }
 
    if (vs_prog_data->uses_drawid) {
-      intel_upload_data(brw, &brw->draw.gl_drawid, sizeof(brw->draw.gl_drawid), 4,
-                        &brw->draw.draw_id_bo,
-                        &brw->draw.draw_id_offset);
+      brw_upload_data(&brw->upload,
+                      &brw->draw.gl_drawid, sizeof(brw->draw.gl_drawid), 4,
+                      &brw->draw.draw_id_bo,
+                      &brw->draw.draw_id_offset);
    }
 }
 
@@ -734,8 +736,8 @@ brw_upload_indices(struct brw_context *brw)
    if (!_mesa_is_bufferobj(bufferobj)) {
       /* Get new bufferobj, offset:
        */
-      intel_upload_data(brw, index_buffer->ptr, ib_size, ib_type_size,
-                       &brw->ib.bo, &offset);
+      brw_upload_data(&brw->upload, index_buffer->ptr, ib_size, ib_type_size,
+                      &brw->ib.bo, &offset);
       brw->ib.size = brw->ib.bo->size;
    } else {
       offset = (GLuint) (unsigned long) index_buffer->ptr;
index af2faea..caa92d7 100644 (file)
@@ -1630,12 +1630,12 @@ brw_upload_cs_work_groups_surface(struct brw_context *brw)
 
       if (brw->compute.num_work_groups_bo == NULL) {
          bo = NULL;
-         intel_upload_data(brw,
-                           (void *)brw->compute.num_work_groups,
-                           3 * sizeof(GLuint),
-                           sizeof(GLuint),
-                           &bo,
-                           &bo_offset);
+         brw_upload_data(&brw->upload,
+                         (void *)brw->compute.num_work_groups,
+                         3 * sizeof(GLuint),
+                         sizeof(GLuint),
+                         &bo,
+                         &bo_offset);
       } else {
          bo = brw->compute.num_work_groups_bo;
          bo_offset = brw->compute.num_work_groups_offset;
index 89b1202..afcd2be 100644 (file)
@@ -151,9 +151,9 @@ gen6_upload_push_constants(struct brw_context *brw,
       const int size = prog_data->nr_params * sizeof(gl_constant_value);
       gl_constant_value *param;
       if (devinfo->gen >= 8 || devinfo->is_haswell) {
-         param = intel_upload_space(brw, size, 32,
-                                    &stage_state->push_const_bo,
-                                    &stage_state->push_const_offset);
+         param = brw_upload_space(&brw->upload, size, 32,
+                                  &stage_state->push_const_bo,
+                                  &stage_state->push_const_offset);
       } else {
          param = brw_state_batch(brw, size, 32,
                                  &stage_state->push_const_offset);
@@ -249,8 +249,8 @@ brw_upload_pull_constants(struct brw_context *brw,
    uint32_t size = prog_data->nr_pull_params * 4;
    struct brw_bo *const_bo = NULL;
    uint32_t const_offset;
-   gl_constant_value *constants = intel_upload_space(brw, size, 64,
-                                                     &const_bo, &const_offset);
+   gl_constant_value *constants = brw_upload_space(&brw->upload, size, 64,
+                                                   &const_bo, &const_offset);
 
    STATIC_ASSERT(sizeof(gl_constant_value) == sizeof(float));
 
index aabe21b..d824ff2 100644 (file)
@@ -1017,7 +1017,7 @@ _intel_batchbuffer_flush_fence(struct brw_context *brw,
    assert(!brw->batch.no_wrap);
 
    brw_finish_batch(brw);
-   intel_upload_finish(brw);
+   brw_upload_finish(&brw->upload);
 
    finish_growing_bos(&brw->batch.batch);
    finish_growing_bos(&brw->batch.state);
index 3b46d5c..849b231 100644 (file)
@@ -99,20 +99,23 @@ struct brw_bo *intel_bufferobj_buffer(struct brw_context *brw,
                                       uint32_t size,
                                       bool write);
 
-void intel_upload_data(struct brw_context *brw,
-                       const void *data,
+void brw_upload_data(struct brw_uploader *upload,
+                     const void *data,
+                     uint32_t size,
+                     uint32_t alignment,
+                     struct brw_bo **out_bo,
+                     uint32_t *out_offset);
+
+void *brw_upload_space(struct brw_uploader *upload,
                        uint32_t size,
                        uint32_t alignment,
                        struct brw_bo **out_bo,
                        uint32_t *out_offset);
 
-void *intel_upload_space(struct brw_context *brw,
-                         uint32_t size,
-                         uint32_t alignment,
-                         struct brw_bo **out_bo,
-                         uint32_t *out_offset);
-
-void intel_upload_finish(struct brw_context *brw);
+void brw_upload_finish(struct brw_uploader *upload);
+void brw_upload_init(struct brw_uploader *upload,
+                     struct brw_bufmgr *bufmgr,
+                     unsigned default_size);
 
 /* Hook the bufferobject implementation into mesa:
  */
index 4b5d880..53dff55 100644 (file)
  */
 
 #include "main/imports.h"
-#include "main/mtypes.h"
 #include "main/macros.h"
-#include "main/bufferobj.h"
-
+#include "brw_bufmgr.h"
 #include "brw_context.h"
-#include "intel_blit.h"
 #include "intel_buffer_objects.h"
-#include "intel_batchbuffer.h"
-#include "intel_fbo.h"
-#include "intel_mipmap_tree.h"
-
-#include "brw_context.h"
-
-#define INTEL_UPLOAD_SIZE (64*1024)
 
 void
-intel_upload_finish(struct brw_context *brw)
+brw_upload_finish(struct brw_uploader *upload)
 {
-   assert((brw->upload.bo == NULL) == (brw->upload.map == NULL));
-   if (!brw->upload.bo)
+   assert((upload->bo == NULL) == (upload->map == NULL));
+   if (!upload->bo)
       return;
 
-   brw_bo_unmap(brw->upload.bo);
-   brw_bo_unreference(brw->upload.bo);
-   brw->upload.bo = NULL;
-   brw->upload.map = NULL;
-   brw->upload.next_offset = 0;
+   brw_bo_unmap(upload->bo);
+   brw_bo_unreference(upload->bo);
+   upload->bo = NULL;
+   upload->map = NULL;
+   upload->next_offset = 0;
 }
 
 /**
@@ -64,16 +54,13 @@ intel_upload_finish(struct brw_context *brw)
  * In most cases, streamed data (for GPU state structures, for example) is
  * uploaded through brw_state_batch(), since that interface allows relocations
  * from the streamed space returned to other BOs.  However, that interface has
- * the restriction that the amount of space allocated has to be "small" (see
- * estimated_max_prim_size in brw_draw.c).
+ * the restriction that the amount of space allocated has to be "small".
  *
  * This interface, on the other hand, is able to handle arbitrary sized
  * allocation requests, though it will batch small allocations into the same
  * BO for efficiency and reduced memory footprint.
  *
- * \note The returned pointer is valid only until intel_upload_finish(), which
- * will happen at batch flush or the next
- * intel_upload_space()/intel_upload_data().
+ * \note The returned pointer is valid only until brw_upload_finish().
  *
  * \param out_bo Pointer to a BO, which must point to a valid BO or NULL on
  * entry, and will have a reference to the new BO containing the state on
@@ -82,37 +69,37 @@ intel_upload_finish(struct brw_context *brw)
  * \param out_offset Offset within the buffer object that the data will land.
  */
 void *
-intel_upload_space(struct brw_context *brw,
-                   uint32_t size,
-                   uint32_t alignment,
-                   struct brw_bo **out_bo,
-                   uint32_t *out_offset)
+brw_upload_space(struct brw_uploader *upload,
+                 uint32_t size,
+                 uint32_t alignment,
+                 struct brw_bo **out_bo,
+                 uint32_t *out_offset)
 {
    uint32_t offset;
 
-   offset = ALIGN_NPOT(brw->upload.next_offset, alignment);
-   if (brw->upload.bo && offset + size > brw->upload.bo->size) {
-      intel_upload_finish(brw);
+   offset = ALIGN_NPOT(upload->next_offset, alignment);
+   if (upload->bo && offset + size > upload->bo->size) {
+      brw_upload_finish(upload);
       offset = 0;
    }
 
-   assert((brw->upload.bo == NULL) == (brw->upload.map == NULL));
-   if (!brw->upload.bo) {
-      brw->upload.bo = brw_bo_alloc(brw->bufmgr, "streamed data",
-                                    MAX2(INTEL_UPLOAD_SIZE, size), 4096);
-      brw->upload.map = brw_bo_map(brw, brw->upload.bo, MAP_READ | MAP_WRITE);
+   assert((upload->bo == NULL) == (upload->map == NULL));
+   if (!upload->bo) {
+      upload->bo = brw_bo_alloc(upload->bufmgr, "streamed data",
+                                MAX2(upload->default_size, size), 4096);
+      upload->map = brw_bo_map(NULL, upload->bo, MAP_READ | MAP_WRITE);
    }
 
-   brw->upload.next_offset = offset + size;
+   upload->next_offset = offset + size;
 
    *out_offset = offset;
-   if (*out_bo != brw->upload.bo) {
+   if (*out_bo != upload->bo) {
       brw_bo_unreference(*out_bo);
-      *out_bo = brw->upload.bo;
-      brw_bo_reference(brw->upload.bo);
+      *out_bo = upload->bo;
+      brw_bo_reference(upload->bo);
    }
 
-   return brw->upload.map + offset;
+   return upload->map + offset;
 }
 
 /**
@@ -121,13 +108,25 @@ intel_upload_space(struct brw_context *brw,
  * References to this memory should not be retained across batch flushes.
  */
 void
-intel_upload_data(struct brw_context *brw,
-                  const void *data,
-                  uint32_t size,
-                  uint32_t alignment,
-                  struct brw_bo **out_bo,
-                  uint32_t *out_offset)
+brw_upload_data(struct brw_uploader *upload,
+                const void *data,
+                uint32_t size,
+                uint32_t alignment,
+                struct brw_bo **out_bo,
+                uint32_t *out_offset)
 {
-   void *dst = intel_upload_space(brw, size, alignment, out_bo, out_offset);
+   void *dst = brw_upload_space(upload, size, alignment, out_bo, out_offset);
    memcpy(dst, data, size);
 }
+
+void
+brw_upload_init(struct brw_uploader *upload,
+                struct brw_bufmgr *bufmgr,
+                unsigned default_size)
+{
+   upload->bufmgr = bufmgr;
+   upload->bo = NULL;
+   upload->map = NULL;
+   upload->next_offset = 0;
+   upload->default_size = default_size;
+}