diff --git a/src/gallium/drivers/ilo/Makefile.sources b/src/gallium/drivers/ilo/Makefile.sources index f1a7ef522f2..fbb33b4e10a 100644 --- a/src/gallium/drivers/ilo/Makefile.sources +++ b/src/gallium/drivers/ilo/Makefile.sources @@ -1,4 +1,5 @@ C_SOURCES := \ + core/ilo_buffer.h \ core/ilo_core.h \ core/ilo_debug.c \ core/ilo_debug.h \ diff --git a/src/gallium/drivers/ilo/core/ilo_buffer.h b/src/gallium/drivers/ilo/core/ilo_buffer.h new file mode 100644 index 00000000000..50f97d10bd7 --- /dev/null +++ b/src/gallium/drivers/ilo/core/ilo_buffer.h @@ -0,0 +1,90 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2012-2013 LunarG, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Chia-I Wu + */ + +#ifndef ILO_BUFFER_H +#define ILO_BUFFER_H + +#include "intel_winsys.h" + +#include "ilo_core.h" +#include "ilo_dev.h" + +struct ilo_buffer { + unsigned bo_size; + + struct intel_bo *bo; +}; + +static inline void +ilo_buffer_init(struct ilo_buffer *buf, const struct ilo_dev *dev, + unsigned size, uint32_t bind, uint32_t flags) +{ + buf->bo_size = size; + + /* + * From the Sandy Bridge PRM, volume 1 part 1, page 118: + * + * "For buffers, which have no inherent "height," padding requirements + * are different. A buffer must be padded to the next multiple of 256 + * array elements, with an additional 16 bytes added beyond that to + * account for the L1 cache line." + */ + if (bind & PIPE_BIND_SAMPLER_VIEW) + buf->bo_size = align(buf->bo_size, 256) + 16; + + if ((bind & PIPE_BIND_VERTEX_BUFFER) && ilo_dev_gen(dev) < ILO_GEN(7.5)) { + /* + * As noted in ilo_format_translate(), we treat some 3-component formats + * as 4-component formats to work around hardware limitations. Imagine + * the case where the vertex buffer holds a single + * PIPE_FORMAT_R16G16B16_FLOAT vertex, and buf->bo_size is 6. The + * hardware would fail to fetch it at boundary check because the vertex + * buffer is expected to hold a PIPE_FORMAT_R16G16B16A16_FLOAT vertex + * and that takes at least 8 bytes. + * + * For the workaround to work, we should add 2 to the bo size. But that + * would waste a page when the bo size is already page aligned. Let's + * round it to page size for now and revisit this when needed. + */ + buf->bo_size = align(buf->bo_size, 4096); + } +} + +static inline void +ilo_buffer_cleanup(struct ilo_buffer *buf) +{ + intel_bo_unref(buf->bo); +} + +static inline void +ilo_buffer_set_bo(struct ilo_buffer *buf, struct intel_bo *bo) +{ + intel_bo_unref(buf->bo); + buf->bo = intel_bo_ref(bo); +} + +#endif /* ILO_BUFFER_H */ diff --git a/src/gallium/drivers/ilo/ilo_resource.c b/src/gallium/drivers/ilo/ilo_resource.c index 7e8d70083cb..ae4ae59f7ef 100644 --- a/src/gallium/drivers/ilo/ilo_resource.c +++ b/src/gallium/drivers/ilo/ilo_resource.c @@ -414,21 +414,28 @@ tex_get_handle(struct ilo_texture *tex, struct winsys_handle *handle) } static bool -buf_create_bo(struct ilo_buffer *buf) +buf_create_bo(struct ilo_buffer_resource *buf) { struct ilo_screen *is = ilo_screen(buf->base.screen); const char *name = resource_get_bo_name(&buf->base); const bool cpu_init = resource_get_cpu_init(&buf->base); + struct intel_bo *bo; - buf->bo = intel_winsys_alloc_bo(is->dev.winsys, name, buf->bo_size, cpu_init); + bo = intel_winsys_alloc_bo(is->dev.winsys, name, + buf->buffer.bo_size, cpu_init); + if (!bo) + return false; - return (buf->bo != NULL); + ilo_buffer_set_bo(&buf->buffer, bo); + intel_bo_unref(bo); + + return true; } static void -buf_destroy(struct ilo_buffer *buf) +buf_destroy(struct ilo_buffer_resource *buf) { - intel_bo_unref(buf->bo); + ilo_buffer_cleanup(&buf->buffer); FREE(buf); } @@ -436,9 +443,9 @@ static struct pipe_resource * buf_create(struct pipe_screen *screen, const struct pipe_resource *templ) { const struct ilo_screen *is = ilo_screen(screen); - struct ilo_buffer *buf; + struct ilo_buffer_resource *buf; - buf = CALLOC_STRUCT(ilo_buffer); + buf = CALLOC_STRUCT(ilo_buffer_resource); if (!buf) return NULL; @@ -446,39 +453,11 @@ buf_create(struct pipe_screen *screen, const struct pipe_resource *templ) buf->base.screen = screen; pipe_reference_init(&buf->base.reference, 1); - buf->bo_size = templ->width0; + ilo_buffer_init(&buf->buffer, &is->dev, + templ->width0, templ->bind, templ->flags); - /* - * From the Sandy Bridge PRM, volume 1 part 1, page 118: - * - * "For buffers, which have no inherent "height," padding requirements - * are different. A buffer must be padded to the next multiple of 256 - * array elements, with an additional 16 bytes added beyond that to - * account for the L1 cache line." - */ - if (templ->bind & PIPE_BIND_SAMPLER_VIEW) - buf->bo_size = align(buf->bo_size, 256) + 16; - - if ((templ->bind & PIPE_BIND_VERTEX_BUFFER) && - ilo_dev_gen(&is->dev) < ILO_GEN(7.5)) { - /* - * As noted in ilo_format_translate(), we treat some 3-component formats - * as 4-component formats to work around hardware limitations. Imagine - * the case where the vertex buffer holds a single - * PIPE_FORMAT_R16G16B16_FLOAT vertex, and buf->bo_size is 6. The - * hardware would fail to fetch it at boundary check because the vertex - * buffer is expected to hold a PIPE_FORMAT_R16G16B16A16_FLOAT vertex - * and that takes at least 8 bytes. - * - * For the workaround to work, we should add 2 to the bo size. But that - * would waste a page when the bo size is already page aligned. Let's - * round it to page size for now and revisit this when needed. - */ - buf->bo_size = align(buf->bo_size, 4096); - } - - if (buf->bo_size < templ->width0 || - buf->bo_size > ilo_max_resource_size || + if (buf->buffer.bo_size < templ->width0 || + buf->buffer.bo_size > ilo_max_resource_size || !buf_create_bo(buf)) { FREE(buf); return NULL; @@ -540,7 +519,7 @@ ilo_resource_destroy(struct pipe_screen *screen, struct pipe_resource *res) { if (res->target == PIPE_BUFFER) - buf_destroy(ilo_buffer(res)); + buf_destroy((struct ilo_buffer_resource *) res); else tex_destroy(ilo_texture(res)); } @@ -559,26 +538,17 @@ ilo_init_resource_functions(struct ilo_screen *is) } bool -ilo_buffer_rename_bo(struct ilo_buffer *buf) +ilo_resource_rename_bo(struct pipe_resource *res) { - struct intel_bo *old_bo = buf->bo; + if (res->target == PIPE_BUFFER) { + return buf_create_bo((struct ilo_buffer_resource *) res); + } else { + struct ilo_texture *tex = ilo_texture(res); - if (buf_create_bo(buf)) { - intel_bo_unref(old_bo); - return true; - } - else { - buf->bo = old_bo; - return false; + /* an imported texture cannot be renamed */ + if (tex->imported) + return false; + + return tex_create_bo(tex); } } - -bool -ilo_texture_rename_bo(struct ilo_texture *tex) -{ - /* an imported texture cannot be renamed */ - if (tex->imported) - return false; - - return tex_create_bo(tex); -} diff --git a/src/gallium/drivers/ilo/ilo_resource.h b/src/gallium/drivers/ilo/ilo_resource.h index b5be9b5300d..f78f9495233 100644 --- a/src/gallium/drivers/ilo/ilo_resource.h +++ b/src/gallium/drivers/ilo/ilo_resource.h @@ -29,6 +29,7 @@ #define ILO_RESOURCE_H #include "core/intel_winsys.h" +#include "core/ilo_buffer.h" #include "core/ilo_image.h" #include "ilo_common.h" @@ -77,13 +78,6 @@ enum ilo_texture_flags { ILO_TEXTURE_HIZ = 1 << 7, }; -struct ilo_buffer { - struct pipe_resource base; - - struct intel_bo *bo; - unsigned bo_size; -}; - /** * A 3D image slice, cube face, or array layer. */ @@ -116,11 +110,17 @@ struct ilo_texture { struct ilo_texture *separate_s8; }; +struct ilo_buffer_resource { + struct pipe_resource base; + + struct ilo_buffer buffer; +}; + static inline struct ilo_buffer * ilo_buffer(struct pipe_resource *res) { - return (struct ilo_buffer *) - ((res && res->target == PIPE_BUFFER) ? res : NULL); + return (res && res->target == PIPE_BUFFER) ? + &((struct ilo_buffer_resource *) res)->buffer : NULL; } static inline struct ilo_texture * @@ -134,10 +134,7 @@ void ilo_init_resource_functions(struct ilo_screen *is); bool -ilo_buffer_rename_bo(struct ilo_buffer *buf); - -bool -ilo_texture_rename_bo(struct ilo_texture *tex); +ilo_resource_rename_bo(struct pipe_resource *res); /** * Return the bo of the resource. diff --git a/src/gallium/drivers/ilo/ilo_transfer.c b/src/gallium/drivers/ilo/ilo_transfer.c index 4ee33523753..56e67870881 100644 --- a/src/gallium/drivers/ilo/ilo_transfer.c +++ b/src/gallium/drivers/ilo/ilo_transfer.c @@ -133,17 +133,6 @@ resource_get_transfer_method(struct pipe_resource *res, return true; } -/** - * Rename the bo of the resource. - */ -static bool -resource_rename_bo(struct pipe_resource *res) -{ - return (res->target == PIPE_BUFFER) ? - ilo_buffer_rename_bo(ilo_buffer(res)) : - ilo_texture_rename_bo(ilo_texture(res)); -} - /** * Return true if usage allows the use of staging bo to avoid blocking. */ @@ -227,7 +216,7 @@ xfer_unblock(struct ilo_transfer *xfer, bool *resource_renamed) unblocked = true; } else if ((xfer->base.usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) && - resource_rename_bo(res)) { + ilo_resource_rename_bo(res)) { renamed = true; unblocked = true; } @@ -1087,9 +1076,10 @@ choose_transfer_method(struct ilo_context *ilo, struct ilo_transfer *xfer) } static void -buf_pwrite(struct ilo_context *ilo, struct ilo_buffer *buf, +buf_pwrite(struct ilo_context *ilo, struct pipe_resource *res, unsigned usage, int offset, int size, const void *data) { + struct ilo_buffer *buf = ilo_buffer(res); bool need_submit; /* see if we can avoid blocking */ @@ -1097,8 +1087,8 @@ buf_pwrite(struct ilo_context *ilo, struct ilo_buffer *buf, bool unblocked = false; if ((usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) && - ilo_buffer_rename_bo(buf)) { - ilo_state_vector_resource_renamed(&ilo->state_vector, &buf->base); + ilo_resource_rename_bo(res)) { + ilo_state_vector_resource_renamed(&ilo->state_vector, res); unblocked = true; } else { @@ -1108,7 +1098,7 @@ buf_pwrite(struct ilo_context *ilo, struct ilo_buffer *buf, * allocate a staging buffer to hold the data and pipelined copy it * over */ - templ = buf->base; + templ = *res; templ.width0 = size; templ.usage = PIPE_USAGE_STAGING; templ.bind = PIPE_BIND_TRANSFER_WRITE; @@ -1120,7 +1110,7 @@ buf_pwrite(struct ilo_context *ilo, struct ilo_buffer *buf, u_box_1d(0, size, &staging_box); ilo_blitter_blt_copy_resource(ilo->blitter, - &buf->base, 0, offset, 0, 0, + res, 0, offset, 0, 0, staging, 0, &staging_box); pipe_resource_reference(&staging, NULL); @@ -1251,7 +1241,7 @@ ilo_transfer_inline_write(struct pipe_context *pipe, assert(box->height == 1); assert(box->depth == 1); - buf_pwrite(ilo_context(pipe), ilo_buffer(res), + buf_pwrite(ilo_context(pipe), res, usage, box->x, box->width, data); } else {