From eb99bf8abe367aaf01ccf50347b510d8cfb87688 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Mon, 26 Feb 2018 23:17:35 -0800 Subject: [PATCH] i965: Generalize intel_upload.c to support multiple uploaders. 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 --- src/mesa/drivers/dri/i965/brw_context.c | 2 + src/mesa/drivers/dri/i965/brw_context.h | 14 ++-- src/mesa/drivers/dri/i965/brw_curbe.c | 4 +- src/mesa/drivers/dri/i965/brw_draw_upload.c | 30 ++++---- src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 12 +-- src/mesa/drivers/dri/i965/gen6_constant_state.c | 10 +-- src/mesa/drivers/dri/i965/intel_batchbuffer.c | 2 +- src/mesa/drivers/dri/i965/intel_buffer_objects.h | 21 ++--- src/mesa/drivers/dri/i965/intel_upload.c | 97 ++++++++++++------------ 9 files changed, 101 insertions(+), 91 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index 8ab9063d214..fca5c8e3072 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -1018,6 +1018,8 @@ brwCreateContext(gl_api api, } + brw_upload_init(&brw->upload, brw->bufmgr, 65536); + brw_init_state(brw); intelInitExtensions(ctx); diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 050b656e3da..d6e3c7807f7 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -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. diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index c747110e310..e4a2bd9c891 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -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)); diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 9b81999ea05..c058064403e 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -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; diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index af2faea3bfe..caa92d7d878 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -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; diff --git a/src/mesa/drivers/dri/i965/gen6_constant_state.c b/src/mesa/drivers/dri/i965/gen6_constant_state.c index 89b1202dd65..afcd2bebd76 100644 --- a/src/mesa/drivers/dri/i965/gen6_constant_state.c +++ b/src/mesa/drivers/dri/i965/gen6_constant_state.c @@ -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)); diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c index aabe21b7c8e..d824ff272ec 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c @@ -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); diff --git a/src/mesa/drivers/dri/i965/intel_buffer_objects.h b/src/mesa/drivers/dri/i965/intel_buffer_objects.h index 3b46d5c9c81..849b231c8c0 100644 --- a/src/mesa/drivers/dri/i965/intel_buffer_objects.h +++ b/src/mesa/drivers/dri/i965/intel_buffer_objects.h @@ -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: */ diff --git a/src/mesa/drivers/dri/i965/intel_upload.c b/src/mesa/drivers/dri/i965/intel_upload.c index 4b5d880a5fe..53dff556873 100644 --- a/src/mesa/drivers/dri/i965/intel_upload.c +++ b/src/mesa/drivers/dri/i965/intel_upload.c @@ -29,33 +29,23 @@ */ #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; +} -- 2.11.0