On Mon, Jan 2, 2017 at 12:45 AM, Pohjolainen, Topi <topi.pohjolai...@gmail.com> wrote: > On Thu, Dec 29, 2016 at 11:55:37AM -0800, Anuj Phogat wrote: >> On Tue, Dec 20, 2016 at 6:45 AM, Topi Pohjolainen >> <topi.pohjolai...@gmail.com> wrote: >> > Signed-off-by: Topi Pohjolainen <topi.pohjolai...@intel.com> >> > --- >> > src/mesa/drivers/dri/i965/intel_tex.h | 8 + >> > src/mesa/drivers/dri/i965/intel_tex_subimage.c | 194 >> > +++++++++++++++++++++++++ >> > 2 files changed, 202 insertions(+) >> > >> > diff --git a/src/mesa/drivers/dri/i965/intel_tex.h >> > b/src/mesa/drivers/dri/i965/intel_tex.h >> > index 376f075..c7d0937 100644 >> > --- a/src/mesa/drivers/dri/i965/intel_tex.h >> > +++ b/src/mesa/drivers/dri/i965/intel_tex.h >> > @@ -65,6 +65,14 @@ intel_texsubimage_tiled_memcpy(struct gl_context *ctx, >> > bool for_glTexImage); >> > >> > bool >> > +intel_texsubimage_gpu_copy(struct brw_context *brw, GLuint dims, >> > + struct gl_texture_image *tex_image, >> > + unsigned x, unsigned y, unsigned z, >> > + unsigned w, unsigned h, unsigned d, >> > + GLenum format, GLenum type, const void *pixels, >> > + const struct gl_pixelstore_attrib *packing); >> > + >> > +bool >> > intel_gettexsubimage_tiled_memcpy(struct gl_context *ctx, >> > struct gl_texture_image *texImage, >> > GLint xoffset, GLint yofset, >> > diff --git a/src/mesa/drivers/dri/i965/intel_tex_subimage.c >> > b/src/mesa/drivers/dri/i965/intel_tex_subimage.c >> > index b7e52bc..f999a93 100644 >> > --- a/src/mesa/drivers/dri/i965/intel_tex_subimage.c >> > +++ b/src/mesa/drivers/dri/i965/intel_tex_subimage.c >> > @@ -24,6 +24,7 @@ >> > */ >> > >> > #include "main/bufferobj.h" >> > +#include "main/glformats.h" >> > #include "main/image.h" >> > #include "main/macros.h" >> > #include "main/mtypes.h" >> > @@ -34,8 +35,10 @@ >> > #include "main/enums.h" >> > #include "drivers/common/meta.h" >> > >> > +#include "brw_blorp.h" >> > #include "brw_context.h" >> > #include "intel_batchbuffer.h" >> > +#include "intel_buffer_objects.h" >> > #include "intel_tex.h" >> > #include "intel_mipmap_tree.h" >> > #include "intel_blit.h" >> > @@ -43,6 +46,197 @@ >> > >> > #define FILE_DEBUG_FLAG DEBUG_TEXTURE >> > >> > +static drm_intel_bo * >> > +intel_texsubimage_get_src_as_bo(struct brw_context *brw, unsigned dims, >> > + struct gl_texture_image *tex_image, >> > + unsigned w, unsigned h, unsigned d, >> > + GLenum format, GLenum type, const void >> > *pixels, >> > + const struct gl_pixelstore_attrib >> > *packing) >> > +{ >> > + /* Account for SKIP_PIXELS, SKIP_ROWS, ALIGNMENT, and SKIP_IMAGES */ >> > + const uint32_t first_pixel = _mesa_image_offset(dims, packing, w, h, >> > + format, type, 0, 0, 0); >> > + const uint32_t last_pixel = _mesa_image_offset(dims, packing, w, h, >> > + format, type, >> > + d - 1, h - 1, w); >> > + const uint32_t size = last_pixel - first_pixel; >> > + >> > + drm_intel_bo * const bo = >> > + drm_intel_bo_alloc(brw->bufmgr, "tmp_tex_subimage_src", size, 64); >> > + >> > + if (bo == NULL) { >> > + perf_debug("intel_texsubimage: temp bo creation failed: size = >> > %u\n", >> > + size); >> > + return false; >> > + } >> > + >> > + if (drm_intel_bo_subdata(bo, 0, size, pixels + first_pixel)) { >> > + perf_debug("intel_texsubimage: temp bo upload failed\n"); >> > + drm_intel_bo_unreference(bo); >> > + return NULL; >> > + } >> > + >> > + return bo; >> > +} >> > + >> > +static uint32_t >> > +intel_texsubimage_get_src_offset(unsigned dims, unsigned w, unsigned h, >> > + GLenum format, GLenum type, >> > + const void *pixels, >> > + const struct gl_pixelstore_attrib >> > *packing) >> > +{ >> > + /* Account for SKIP_PIXELS, SKIP_ROWS, ALIGNMENT, and SKIP_IMAGES */ >> > + const uint32_t first_pixel = _mesa_image_offset(dims, packing, w, h, >> > + format, type, 0, 0, 0); >> > + >> > + /* In case of buffer object source 'pixels' represents offset in >> > bytes. */ >> > + return first_pixel + (intptr_t)pixels; >> > +} >> > + >> > +/* Consider all the restrictions and determine the format of the source. >> > */ >> > +static mesa_format >> > +intel_texsubimage_check_upload(struct brw_context *brw, >> > + const struct gl_texture_image *tex_image, >> > + unsigned h, GLenum format, GLenum type, >> > + const struct gl_pixelstore_attrib *packing) >> > +{ >> > + /* TODO: Add support for buffer object upload 1D alignment or perhaps >> > use >> > + * flat 2D source. >> > + */ >> > + if (tex_image->TexObject->Target == GL_TEXTURE_1D_ARRAY) { >> > + perf_debug("intel_texsubimage: 1D_ARRAY not supported\n"); >> > + return MESA_FORMAT_NONE; >> > + } >> > + >> > + if (brw->ctx._ImageTransferState) >> > + return MESA_FORMAT_NONE; >> > + >> > + if (packing->SwapBytes || packing->LsbFirst || packing->Invert) { >> > + perf_debug("intel_texsubimage: unsupported gl_pixelstore_attrib\n"); >> > + return MESA_FORMAT_NONE; >> > + } >> > + >> > + /* TODO: This can be easily supported as blit manually offsets miptree >> > + * for each slice. >> > + */ >> > + if (packing->ImageHeight != 0) { >> > + perf_debug("intel_texsubimage: _attrib::ImageHeight not >> > supported\n"); >> > + return MESA_FORMAT_NONE; >> > + } >> > + >> > + if (packing->RowLength != 0) { >> > + perf_debug("intel_texsubimage: _attrib::RowLength not supported\n"); >> > + return MESA_FORMAT_NONE; >> > + } >> > + >> > + if (format != GL_RED && >> > + format != GL_RG && >> > + format != GL_RGB && >> > + format != GL_RGBA && >> > + format != GL_ALPHA) { >> > + perf_debug("intel_texsubimage: %s not supported", >> > + _mesa_enum_to_string(format)); >> > + return MESA_FORMAT_NONE; >> > + } >> > + >> > + const mesa_format src_mesa_format = >> > + _mesa_tex_format_from_format_and_type(&brw->ctx, format, type); >> > + if (src_mesa_format == MESA_FORMAT_NONE) >> > + return MESA_FORMAT_NONE; >> Above if check is not required if you move the src_mesa_format >> computation after the below if block. > > That makes it simpler, will do. > >> > + >> > + if (!brw->format_supported_as_render_target[tex_image->TexFormat]) { >> > + perf_debug("intel_texsubimage: can't use %s as render target\n", >> > + _mesa_get_format_name(tex_image->TexFormat)); >> > + return MESA_FORMAT_NONE; >> > + } >> > + >> > + return src_mesa_format; >> > +} >> > + >> > +bool >> > +intel_texsubimage_gpu_copy(struct brw_context *brw, GLuint dims, >> > + struct gl_texture_image *tex_image, >> > + unsigned x, unsigned y, unsigned z, >> > + unsigned w, unsigned h, unsigned d, >> > + GLenum format, GLenum type, const void *pixels, >> > + const struct gl_pixelstore_attrib *packing) >> > +{ >> > + const bool is_src_bo = _mesa_is_bufferobj(packing->BufferObj); >> > + struct intel_texture_image *intel_image = >> > intel_texture_image(tex_image); >> > + >> > + /* Make sure there is something to upload. */ >> > + if (pixels == NULL && !is_src_bo) >> > + return false; >> > + >> > + const mesa_format src_mesa_format = intel_texsubimage_check_upload( >> > + brw, tex_image, h, format, type, packing); >> > + if (src_mesa_format == MESA_FORMAT_NONE) >> > + return MESA_FORMAT_NONE; >> return false ? > > Oops, good catch! > >> > + >> > + const uint32_t offset = is_src_bo ? >> > + intel_texsubimage_get_src_offset(dims, w, h, format, type, pixels, >> > + packing) : 0; >> > + const uint32_t stride = _mesa_image_row_stride(packing, w, format, >> > type); >> > + const unsigned level = tex_image->Level + >> > tex_image->TexObject->MinLevel; >> > + const unsigned start_layer = >> > + tex_image->TexObject->MinLayer + tex_image->Face + z; >> > + >> > + assert(level <= intel_image->mt->last_level); >> > + assert(start_layer + d <= intel_image->mt->level[level].depth); >> > + >> > + drm_intel_bo * const src_bo = is_src_bo ? >> > + intel_buffer_object(packing->BufferObj)->buffer : >> > + intel_texsubimage_get_src_as_bo(brw, dims, tex_image, w, h, d, >> > + format, type, pixels, packing); >> > + if (src_bo == NULL) >> > + return false; >> > + >> > + bool result = false; >> > + >> > + /* Blit slice-by-slice creating a single-slice miptree for each layer. >> > This >> > + * way the alignment in the source buffer object does not need to meet >> > the >> > + * hw requirements. >> > + */ >> Can you explain this hw alignment requirement? This is for my understanding. > > Good question. Even for linear (non-tiled) buffers I noticed by experimenting > that hardware wants to have individual slices of arrayed textures vertically > aligned by 4. However, for single slice the starting address doesn't need to > be aligned, and therefore offsetting to individual slices manually works. > It'll be nice to put this information in a comment here. So, nobody will get confused later which hw alignment requirement you are talking about. >> >> > + for (unsigned i = 0; i < d; ++i) { >> > + /* Wrap the source buffer object with a miptree. */ >> > + struct intel_mipmap_tree *src_mt = intel_miptree_create_for_bo( >> > + brw, src_bo, src_mesa_format, >> > + offset + i * h * stride, >> > + w, h, 1, stride, 0); >> > + if (!src_mt) { >> > + perf_debug("intel_texsubimage: miptree creation for src >> > failed\n"); >> > + goto err; >> > + } >> > + >> > + /* In case exact match is needed, copy using equivalent UINT formats >> > + * preventing hardware from changing presentation for SNORM -1. >> > + */ >> > + if (src_mt->format == intel_image->mt->format) { >> > + brw_blorp_copy_miptrees(brw, src_mt, 0, 0, >> > + intel_image->mt, level, start_layer + i, >> > + 0, 0, x, y, w, h); >> > + } else { >> > + brw_blorp_blit_miptrees(brw, src_mt, 0, 0, >> > + src_mesa_format, SWIZZLE_XYZW, >> > + intel_image->mt, level, start_layer + i, >> > + intel_image->mt->format, >> > + 0, 0, w, h, >> > + x, y, x + w, y + h, >> > + GL_NEAREST, false, false, false, false); >> > + } >> > + >> > + intel_miptree_release(&src_mt); >> > + } >> > + >> > + result = true; >> > + >> > +err: >> > + if (!is_src_bo) >> > + drm_intel_bo_unreference(src_bo); >> > + >> > + return result; >> > +} >> > + >> > /** >> > * \brief A fast path for glTexImage and glTexSubImage. >> > * >> > -- >> > 2.5.5 >> > >> > _______________________________________________ >> > mesa-dev mailing list >> > mesa-dev@lists.freedesktop.org >> > https://lists.freedesktop.org/mailman/listinfo/mesa-dev
With suggested changes paches 6-8 are: Reviewed-by: Anuj Phogat <anuj.pho...@gmail.com> _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev