X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fintel_mipmap_tree.h;h=2f1b8ebf0e1e86e3d829dd5d21ee78605f6437cb;hb=ed65e6ef49e17e9cae93a8f98e2968346de2bc6e;hp=d7181255edb4587f92b359293ab083de5f1f2201;hpb=814a0405048f96f0427f29316a86bfdfb6c8f1ce;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h index d7181255edb..2f1b8ebf0e1 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h @@ -1,75 +1,73 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. +/* + * Copyright 2006 VMware, Inc. * All Rights Reserved. - * + * * 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, sub license, and/or sell copies of the Software, and to + * 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 (including the * next paragraph) 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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. - * - **************************************************************************/ + */ + +/** @file intel_mipmap_tree.h + * + * This file defines the structure that wraps a BO and describes how the + * mipmap levels and slices of a texture are laid out. + * + * The hardware has a fixed layout of a texture depending on parameters such + * as the target/type (2D, 3D, CUBE), width, height, pitch, and number of + * mipmap levels. The individual level/layer slices are each 2D rectangles of + * pixels at some x/y offset from the start of the drm_intel_bo. + * + * Original OpenGL allowed texture miplevels to be specified in arbitrary + * order, and a texture may change size over time. Thus, each + * intel_texture_image has a reference to a miptree that contains the pixel + * data sized appropriately for it, which will later be referenced by/copied + * to the intel_texture_object at draw time (intel_finalize_mipmap_tree()) so + * that there's a single miptree for the complete texture. + */ #ifndef INTEL_MIPMAP_TREE_H #define INTEL_MIPMAP_TREE_H #include -#include "intel_regions.h" +#include "main/mtypes.h" +#include "isl/isl.h" +#include "intel_bufmgr.h" #include "intel_resolve_map.h" +#include #ifdef __cplusplus extern "C" { #endif -/* A layer on top of the intel_regions code which adds: - * - * - Code to size and layout a region to hold a set of mipmaps. - * - Query to determine if a new image fits in an existing tree. - * - More refcounting - * - maybe able to remove refcounting from intel_region? - * - ? - * - * The fixed mipmap layout of intel hardware where one offset - * specifies the position of all images in a mipmap hierachy - * complicates the implementation of GL texture image commands, - * compared to hardware where each image is specified with an - * independent offset. - * - * In an ideal world, each texture object would be associated with a - * single bufmgr buffer or 2d intel_region, and all the images within - * the texture object would slot into the tree as they arrive. The - * reality can be a little messier, as images can arrive from the user - * with sizes that don't fit in the existing tree, or in an order - * where the tree layout cannot be guessed immediately. - * - * This structure encodes an idealized mipmap tree. The GL image - * commands build these where possible, otherwise store the images in - * temporary system buffers. - */ +struct brw_context; +struct intel_renderbuffer; struct intel_resolve_map; struct intel_texture_image; /** + * This bit extends the set of GL_MAP_*_BIT enums. + * * When calling intel_miptree_map() on an ETC-transcoded-to-RGB miptree or a * depthstencil-split-to-separate-stencil miptree, we'll normally make a - * tmeporary and recreate the kind of data requested by Mesa core, since we're + * temporary and recreate the kind of data requested by Mesa core, since we're * satisfying some glGetTexImage() request or something. * * However, occasionally you want to actually map the miptree's current data @@ -78,28 +76,22 @@ struct intel_texture_image; #define BRW_MAP_DIRECT_BIT 0x80000000 struct intel_miptree_map { - /** Bitfield of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_BIT */ + /** Bitfield of GL_MAP_*_BIT and BRW_MAP_*_BIT. */ GLbitfield mode; /** Region of interest for the map. */ int x, y, w, h; /** Possibly malloced temporary buffer for the mapping. */ void *buffer; /** Possible pointer to a temporary linear miptree for the mapping. */ - struct intel_mipmap_tree *mt; + struct intel_mipmap_tree *linear_mt; /** Pointer to the start of (map_x, map_y) returned by the mapping. */ void *ptr; /** Stride of the mapping. */ int stride; - - /** - * intel_mipmap_tree::singlesample_mt is temporary storage that persists - * only for the duration of the map. - */ - bool singlesample_mt_is_tmp; }; /** - * Describes the location of each texture image within a texture region. + * Describes the location of each texture image within a miptree. */ struct intel_mipmap_level { @@ -107,8 +99,6 @@ struct intel_mipmap_level GLuint level_x; /** Offset to this miptree level, used in computing y_offset. */ GLuint level_y; - GLuint width; - GLuint height; /** * \brief Number of 2D slices in this miplevel. @@ -120,9 +110,20 @@ struct intel_mipmap_level * - For GL_TEXTURE_3D, it is the texture's depth at this miplevel. Its * value, like width and height, varies with miplevel. * - For other texture types, depth is 1. + * - Additionally, for UMS and CMS miptrees, depth is multiplied by + * sample count. */ GLuint depth; + /** + * \brief Is HiZ enabled for this level? + * + * If \c mt->level[l].has_hiz is set, then (1) \c mt->hiz_mt has been + * allocated and (2) the HiZ memory for the slices in this level reside at + * \c mt->hiz_mt->level[l]. + */ + bool has_hiz; + /** * \brief List of 2D images in this mipmap level. * @@ -142,6 +143,9 @@ struct intel_mipmap_level * \code * x = mt->level[l].slice[s].x_offset * y = mt->level[l].slice[s].y_offset + * + * On some hardware generations, we program these offsets into + * RENDER_SURFACE_STATE.XOffset and RENDER_SURFACE_STATE.YOffset. */ GLuint x_offset; GLuint y_offset; @@ -152,15 +156,6 @@ struct intel_mipmap_level * intel_miptree_map/unmap on this slice. */ struct intel_miptree_map *map; - - /** - * \brief Is HiZ enabled for this slice? - * - * If \c mt->level[l].slice[s].has_hiz is set, then (1) \c mt->hiz_mt - * has been allocated and (2) the HiZ memory corresponding to this slice - * resides at \c mt->hiz_mt->level[l].slice[s]. - */ - bool has_hiz; } *slice; }; @@ -179,12 +174,16 @@ enum intel_msaa_layout * accommodated by scaling up the width and the height of the surface so * that all the samples corresponding to a pixel are located at nearby * memory locations. + * + * @see PRM section "Interleaved Multisampled Surfaces" */ INTEL_MSAA_LAYOUT_IMS, /** * Uncompressed Multisample Surface. The surface is stored as a 2D array, * with array slice n containing all pixel data for sample n. + * + * @see PRM section "Uncompressed Multisampled Surfaces" */ INTEL_MSAA_LAYOUT_UMS, @@ -196,14 +195,16 @@ enum intel_msaa_layout * the common case (where all samples constituting a pixel have the same * color value) to be stored efficiently by just using a single array * slice. + * + * @see PRM section "Compressed Multisampled Surfaces" */ INTEL_MSAA_LAYOUT_CMS, }; /** - * Enum for keeping track of the state of an MCS buffer associated with a - * miptree. This determines when fast clear related operations are needed. + * Enum for keeping track of the fast clear state of a buffer associated with + * a miptree. * * Fast clear works by deferring the memory writes that would be used to clear * the buffer, so that instead of performing them at the time of the clear @@ -211,23 +212,18 @@ enum intel_msaa_layout * buffer is later accessed for rendering. The MCS buffer keeps track of * which regions of the buffer still have pending clear writes. * - * This enum keeps track of the driver's knowledge of the state of the MCS - * buffer. + * This enum keeps track of the driver's knowledge of pending fast clears in + * the MCS buffer. * * MCS buffers only exist on Gen7+. */ -enum intel_mcs_state +enum intel_fast_clear_state { /** * There is no MCS buffer for this miptree, and one should never be * allocated. */ - INTEL_MCS_STATE_NONE, - - /** - * An MCS buffer exists for this miptree, and it is used for MSAA purposes. - */ - INTEL_MCS_STATE_MSAA, + INTEL_FAST_CLEAR_STATE_NO_MCS, /** * No deferred clears are pending for this miptree, and the contents of the @@ -238,8 +234,11 @@ enum intel_mcs_state * * In this state, the color buffer can be used for purposes other than * rendering without needing a render target resolve. + * + * Since there is no such thing as a "fast color clear resolve" for MSAA + * buffers, an MSAA buffer will never be in this state. */ - INTEL_MCS_STATE_RESOLVED, + INTEL_FAST_CLEAR_STATE_RESOLVED, /** * An MCS buffer exists for this miptree, and deferred clears are pending @@ -247,28 +246,172 @@ enum intel_mcs_state * The contents of the color buffer are only correct for the regions where * the MCS buffer doesn't indicate a deferred clear. * - * In this state, a render target resolve must be performed before the - * color buffer can be used for purposes other than rendering. + * If a single-sample buffer is in this state, a render target resolve must + * be performed before it can be used for purposes other than rendering. */ - INTEL_MCS_STATE_UNRESOLVED, + INTEL_FAST_CLEAR_STATE_UNRESOLVED, /** * An MCS buffer exists for this miptree, and deferred clears are pending * for the entire color buffer, and the contents of the MCS buffer reflect * this. The contents of the color buffer are undefined. * - * In this state, a render target resolve must be performed before the - * color buffer can be used for purposes other than rendering. + * If a single-sample buffer is in this state, a render target resolve must + * be performed before it can be used for purposes other than rendering. * * If the client attempts to clear a buffer which is already in this state, * the clear can be safely skipped, since the buffer is already clear. */ - INTEL_MCS_STATE_CLEAR, + INTEL_FAST_CLEAR_STATE_CLEAR, +}; + +enum miptree_array_layout { + /* Each array slice contains all miplevels packed together. + * + * Gen hardware usually wants multilevel miptrees configured this way. + * + * A 2D Array texture with 2 slices and multiple LODs using + * ALL_LOD_IN_EACH_SLICE would look somewhat like this: + * + * +----------+ + * | | + * | | + * +----------+ + * +---+ +-+ + * | | +-+ + * +---+ * + * +----------+ + * | | + * | | + * +----------+ + * +---+ +-+ + * | | +-+ + * +---+ * + */ + ALL_LOD_IN_EACH_SLICE, + + /* Each LOD contains all slices of that LOD packed together. + * + * In some situations, Gen7+ hardware can use the array_spacing_lod0 + * feature to save space when the surface only contains LOD 0. + * + * Gen6 uses this for separate stencil and hiz since gen6 does not support + * multiple LODs for separate stencil and hiz. + * + * A 2D Array texture with 2 slices and multiple LODs using + * ALL_SLICES_AT_EACH_LOD would look somewhat like this: + * + * +----------+ + * | | + * | | + * +----------+ + * | | + * | | + * +----------+ + * +---+ +-+ + * | | +-+ + * +---+ +-+ + * | | : + * +---+ + */ + ALL_SLICES_AT_EACH_LOD, +}; + +/** + * Miptree aux buffer. These buffers are associated with a miptree, but the + * format is managed by the hardware. + * + * For Gen7+, we always give the hardware the start of the buffer, and let it + * handle all accesses to the buffer. Therefore we don't need the full miptree + * layout structure for this buffer. + * + * For Gen6, we need a hiz miptree structure for this buffer so we can program + * offsets to slices & miplevels. + */ +struct intel_miptree_aux_buffer +{ + /** + * Buffer object containing the pixel data. + * + * @see RENDER_SURFACE_STATE.AuxiliarySurfaceBaseAddress + * @see 3DSTATE_HIER_DEPTH_BUFFER.AuxiliarySurfaceBaseAddress + */ + drm_intel_bo *bo; + + /** + * Pitch in bytes. + * + * @see RENDER_SURFACE_STATE.AuxiliarySurfacePitch + * @see 3DSTATE_HIER_DEPTH_BUFFER.SurfacePitch + */ + uint32_t pitch; + + /** + * The distance in rows between array slices. + * + * @see RENDER_SURFACE_STATE.AuxiliarySurfaceQPitch + * @see 3DSTATE_HIER_DEPTH_BUFFER.SurfaceQPitch + */ + uint32_t qpitch; + + /** + * Hiz miptree. Used only by Gen6. + */ + struct intel_mipmap_tree *mt; +}; + +/* Tile resource modes */ +enum intel_miptree_tr_mode { + INTEL_MIPTREE_TRMODE_NONE, + INTEL_MIPTREE_TRMODE_YF, + INTEL_MIPTREE_TRMODE_YS }; struct intel_mipmap_tree { - /* Effectively the key: + /** + * Buffer object containing the surface. + * + * @see intel_mipmap_tree::offset + * @see RENDER_SURFACE_STATE.SurfaceBaseAddress + * @see RENDER_SURFACE_STATE.AuxiliarySurfaceBaseAddress + * @see 3DSTATE_DEPTH_BUFFER.SurfaceBaseAddress + * @see 3DSTATE_HIER_DEPTH_BUFFER.SurfaceBaseAddress + * @see 3DSTATE_STENCIL_BUFFER.SurfaceBaseAddress + */ + drm_intel_bo *bo; + + /** + * Pitch in bytes. + * + * @see RENDER_SURFACE_STATE.SurfacePitch + * @see RENDER_SURFACE_STATE.AuxiliarySurfacePitch + * @see 3DSTATE_DEPTH_BUFFER.SurfacePitch + * @see 3DSTATE_HIER_DEPTH_BUFFER.SurfacePitch + * @see 3DSTATE_STENCIL_BUFFER.SurfacePitch + */ + uint32_t pitch; + + /** + * One of the I915_TILING_* flags. + * + * @see RENDER_SURFACE_STATE.TileMode + * @see 3DSTATE_DEPTH_BUFFER.TileMode + */ + uint32_t tiling; + + /** + * @see RENDER_SURFACE_STATE.TiledResourceMode + * @see 3DSTATE_DEPTH_BUFFER.TiledResourceMode + */ + enum intel_miptree_tr_mode tr_mode; + + /** + * @brief One of GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY, etc. + * + * @see RENDER_SURFACE_STATE.SurfaceType + * @see RENDER_SURFACE_STATE.SurfaceArray + * @see 3DSTATE_DEPTH_BUFFER.SurfaceType */ GLenum target; @@ -279,24 +422,49 @@ struct intel_mipmap_tree * However, for textures and renderbuffers with packed depth/stencil formats * on hardware where we want or need to use separate stencil, there will be * two miptrees for storing the data. If the depthstencil texture or rb is - * MESA_FORMAT_Z32_FLOAT_X24S8, then mt->format will be - * MESA_FORMAT_Z32_FLOAT, otherwise for MESA_FORMAT_S8_Z24 objects it will be - * MESA_FORMAT_X8_Z24. + * MESA_FORMAT_Z32_FLOAT_S8X24_UINT, then mt->format will be + * MESA_FORMAT_Z_FLOAT32, otherwise for MESA_FORMAT_Z24_UNORM_S8_UINT objects it will be + * MESA_FORMAT_Z24_UNORM_X8_UINT. * * For ETC1/ETC2 textures, this is one of the uncompressed mesa texture - * formats if the hardware lacks support for ETC1/ETC2. See @ref wraps_etc. + * formats if the hardware lacks support for ETC1/ETC2. See @ref etc_format. + * + * @see RENDER_SURFACE_STATE.SurfaceFormat + * @see 3DSTATE_DEPTH_BUFFER.SurfaceFormat */ - gl_format format; + mesa_format format; - /** This variable stores the value of ETC compressed texture format */ - gl_format etc_format; + /** + * This variable stores the value of ETC compressed texture format + * + * @see RENDER_SURFACE_STATE.SurfaceFormat + */ + mesa_format etc_format; /** - * The X offset of each image in the miptree must be aligned to this. - * See the comments in brw_tex_layout.c. + * @name Surface Alignment + * @{ + * + * This defines the alignment of the upperleft pixel of each "slice" in the + * surface. The alignment is in pixel coordinates relative to the surface's + * most upperleft pixel, which is the pixel at (x=0, y=0, layer=0, + * level=0). + * + * The hardware docs do not use the term "slice". We use "slice" to mean + * the pixels at a given miplevel and layer. For 2D surfaces, the layer is + * the array slice; for 3D surfaces, the layer is the z offset. + * + * In the surface layout equations found in the hardware docs, the + * horizontal and vertical surface alignments often appear as variables 'i' + * and 'j'. */ - unsigned int align_w; - unsigned int align_h; /**< \see align_w */ + + /** @see RENDER_SURFACE_STATE.SurfaceHorizontalAlignment */ + uint32_t halign; + + /** @see RENDER_SURFACE_STATE.SurfaceVerticalAlignment */ + uint32_t valign; + /** @} */ GLuint first_level; GLuint last_level; @@ -311,31 +479,75 @@ struct intel_mipmap_tree */ GLuint physical_width0, physical_height0, physical_depth0; + /** Bytes per pixel (or bytes per block if compressed) */ GLuint cpp; + + /** + * @see RENDER_SURFACE_STATE.NumberOfMultisamples + * @see 3DSTATE_MULTISAMPLE.NumberOfMultisamples + */ GLuint num_samples; + bool compressed; /** - * Level zero image dimensions. These dimensions correspond to the - * logical width, height, and depth of the region as seen by client code. + * @name Level zero image dimensions + * @{ + * + * These dimensions correspond to the + * logical width, height, and depth of the texture as seen by client code. * Accordingly, they do not account for the extra width, height, and/or * depth that must be allocated in order to accommodate multisample * formats, nor do they account for the extra factor of 6 in depth that * must be allocated in order to accommodate cubemap textures. */ - uint32_t logical_width0, logical_height0, logical_depth0; /** - * For 1D array, 2D array, cube, and 2D multisampled surfaces on Gen7: true - * if the surface only contains LOD 0, and hence no space is for LOD's - * other than 0 in between array slices. + * @see RENDER_SURFACE_STATE.Width + * @see 3DSTATE_DEPTH_BUFFER.Width + */ + uint32_t logical_width0; + + /** + * @see RENDER_SURFACE_STATE.Height + * @see 3DSTATE_DEPTH_BUFFER.Height + */ + uint32_t logical_height0; + + /** + * @see RENDER_SURFACE_STATE.Depth + * @see 3DSTATE_DEPTH_BUFFER.Depth + */ + uint32_t logical_depth0; + /** @} */ + + /** + * Indicates if we use the standard miptree layout (ALL_LOD_IN_EACH_SLICE), + * or if we tightly pack array slices at each LOD (ALL_SLICES_AT_EACH_LOD). + */ + enum miptree_array_layout array_layout; + + /** + * The distance in between array slices. * - * Corresponds to the surface_array_spacing bit in gen7_surface_state. + * The value is the one that is sent in the surface state. The actual + * meaning depends on certain criteria. Usually it is simply the number of + * uncompressed rows between each slice. However on Gen9+ for compressed + * surfaces it is the number of blocks. For 1D array surfaces that have the + * mipmap tree stored horizontally it is the number of pixels between each + * slice. + * + * @see RENDER_SURFACE_STATE.SurfaceQPitch + * @see 3DSTATE_DEPTH_BUFFER.SurfaceQPitch + * @see 3DSTATE_HIER_DEPTH_BUFFER.SurfaceQPitch + * @see 3DSTATE_STENCIL_BUFFER.SurfaceQPitch */ - bool array_spacing_lod0; + uint32_t qpitch; /** * MSAA layout used by this buffer. + * + * @see RENDER_SURFACE_STATE.MultisampledSurfaceStorageFormat */ enum intel_msaa_layout msaa_layout; @@ -344,77 +556,39 @@ struct intel_mipmap_tree GLuint total_width; GLuint total_height; - /* The 3DSTATE_CLEAR_PARAMS value associated with the last depth clear to - * this depth mipmap tree, if any. + /** + * The depth value used during the most recent fast depth clear performed + * on the surface. This field is invalid only if surface has never + * underwent a fast depth clear. + * + * @see 3DSTATE_CLEAR_PARAMS.DepthClearValue */ uint32_t depth_clear_value; - /* Includes image offset tables: - */ + /* Includes image offset tables: */ struct intel_mipmap_level level[MAX_TEXTURE_LEVELS]; - /* The data is held here: - */ - struct intel_region *region; - - /* Offset into region bo where miptree starts: - */ - uint32_t offset; - /** - * \brief Singlesample miptree. - * - * This is used under two cases. + * Offset into bo where the surface starts. * - * --- Case 1: As persistent singlesample storage for multisample window - * system front and back buffers --- + * @see intel_mipmap_tree::bo * - * Suppose that the window system FBO was created with a multisample - * config. Let `back_irb` be the `intel_renderbuffer` for the FBO's back - * buffer. Then `back_irb` contains two miptrees: a parent multisample - * miptree (back_irb->mt) and a child singlesample miptree - * (back_irb->mt->singlesample_mt). The DRM buffer shared with DRI2 - * belongs to `back_irb->mt->singlesample_mt` and contains singlesample - * data. The singlesample miptree is created at the same time as and - * persists for the lifetime of its parent multisample miptree. - * - * When access to the singlesample data is needed, such as at - * eglSwapBuffers and glReadPixels, an automatic downsample occurs from - * `back_rb->mt` to `back_rb->mt->singlesample_mt` when necessary. - * - * This description of the back buffer applies analogously to the front - * buffer. - * - * - * --- Case 2: As temporary singlesample storage for mapping multisample - * miptrees --- - * - * Suppose the intel_miptree_map is called on a multisample miptree, `mt`, - * for which case 1 does not apply (that is, `mt` does not belong to - * a front or back buffer). Then `mt->singlesample_mt` is null at the - * start of the call. intel_miptree_map will create a temporary - * singlesample miptree, store it at `mt->singlesample_mt`, downsample from - * `mt` to `mt->singlesample_mt` if necessary, then map - * `mt->singlesample_mt`. The temporary miptree is later deleted during - * intel_miptree_unmap. + * @see RENDER_SURFACE_STATE.AuxiliarySurfaceBaseAddress + * @see 3DSTATE_DEPTH_BUFFER.SurfaceBaseAddress + * @see 3DSTATE_HIER_DEPTH_BUFFER.SurfaceBaseAddress + * @see 3DSTATE_STENCIL_BUFFER.SurfaceBaseAddress */ - struct intel_mipmap_tree *singlesample_mt; - - /** - * \brief A downsample is needed from this miptree to singlesample_mt. - */ - bool need_downsample; + uint32_t offset; /** - * \brief HiZ miptree + * \brief HiZ aux buffer * - * The hiz miptree contains the miptree's hiz buffer. To allocate the hiz - * miptree, use intel_miptree_alloc_hiz(). + * To allocate the hiz buffer, use intel_miptree_alloc_hiz(). * * To determine if hiz is enabled, do not check this pointer. Instead, use * intel_miptree_slice_has_hiz(). */ - struct intel_mipmap_tree *hiz_mt; + struct intel_miptree_aux_buffer *hiz_buf; /** * \brief Map of miptree slices to needed resolves. @@ -425,7 +599,7 @@ struct intel_mipmap_tree * \c mt->hiz_map. The resolve map of the child HiZ miptree, \c * mt->hiz_mt->hiz_map, is unused. */ - struct intel_resolve_map hiz_map; + struct exec_list hiz_map; /* List of intel_resolve_map. */ /** * \brief Stencil miptree for depthstencil textures. @@ -434,11 +608,24 @@ struct intel_mipmap_tree * require separate stencil. It always has the true copy of the stencil * bits, regardless of mt->format. * + * \see 3DSTATE_STENCIL_BUFFER * \see intel_miptree_map_depthstencil() * \see intel_miptree_unmap_depthstencil() */ struct intel_mipmap_tree *stencil_mt; + /** + * \brief Stencil texturing miptree for sampling from a stencil texture + * + * Some hardware doesn't support sampling from the stencil texture as + * required by the GL_ARB_stencil_texturing extenion. To workaround this we + * blit the texture into a new texture that can be sampled. + * + * \see intel_update_r8stencil() + */ + struct intel_mipmap_tree *r8stencil_mt; + bool r8stencil_needs_update; + /** * \brief MCS miptree. * @@ -451,83 +638,123 @@ struct intel_mipmap_tree struct intel_mipmap_tree *mcs_mt; /** - * MCS state for this buffer. + * Planes 1 and 2 in case this is a planar surface. + */ + struct intel_mipmap_tree *plane[2]; + + /** + * Fast clear state for this buffer. */ - enum intel_mcs_state mcs_state; + enum intel_fast_clear_state fast_clear_state; /** * The SURFACE_STATE bits associated with the last fast color clear to this * color mipmap tree, if any. * - * This value will only ever contain ones in bits 28-31, so it is safe to - * OR into dword 7 of SURFACE_STATE. + * Prior to GEN9 there is a single bit for RGBA clear values which gives you + * the option of 2^4 clear colors. Each bit determines if the color channel + * is fully saturated or unsaturated (Cherryview does add a 32b value per + * channel, but it is globally applied instead of being part of the render + * surface state). Starting with GEN9, the surface state accepts a 32b value + * for each color channel. + * + * @see RENDER_SURFACE_STATE.RedClearColor + * @see RENDER_SURFACE_STATE.GreenClearColor + * @see RENDER_SURFACE_STATE.BlueClearColor + * @see RENDER_SURFACE_STATE.AlphaClearColor + */ + union { + uint32_t fast_clear_color_value; + union gl_color_union gen9_fast_clear_color; + }; + + /** + * Disable allocation of auxiliary buffers, such as the HiZ buffer and MCS + * buffer. This is useful for sharing the miptree bo with an external client + * that doesn't understand auxiliary buffers. + */ + bool disable_aux_buffers; + + /** + * Tells if the underlying buffer is to be also consumed by entities other + * than the driver. This allows logic to turn off features such as lossless + * compression which is not currently understood by client applications. */ - uint32_t fast_clear_color_value; + bool is_scanout; /* These are also refcounted: */ GLuint refcount; }; -enum intel_miptree_tiling_mode { - INTEL_MIPTREE_TILING_ANY, - INTEL_MIPTREE_TILING_Y, - INTEL_MIPTREE_TILING_NONE, -}; +void +intel_get_non_msrt_mcs_alignment(const struct intel_mipmap_tree *mt, + unsigned *width_px, unsigned *height); bool -intel_is_non_msrt_mcs_buffer_supported(struct brw_context *brw, - struct intel_mipmap_tree *mt); +intel_miptree_is_lossless_compressed(const struct brw_context *brw, + const struct intel_mipmap_tree *mt); -void -intel_get_non_msrt_mcs_alignment(struct brw_context *brw, - struct intel_mipmap_tree *mt, - unsigned *width_px, unsigned *height); +bool +intel_tiling_supports_non_msrt_mcs(const struct brw_context *brw, + unsigned tiling); + +bool +intel_miptree_supports_non_msrt_fast_clear(struct brw_context *brw, + const struct intel_mipmap_tree *mt); + +bool +intel_miptree_supports_lossless_compressed(struct brw_context *brw, + const struct intel_mipmap_tree *mt); bool intel_miptree_alloc_non_msrt_mcs(struct brw_context *brw, - struct intel_mipmap_tree *mt); + struct intel_mipmap_tree *mt, + bool is_lossless_compressed); + +enum { + MIPTREE_LAYOUT_ACCELERATED_UPLOAD = 1 << 0, + MIPTREE_LAYOUT_FORCE_ALL_SLICE_AT_LOD = 1 << 1, + MIPTREE_LAYOUT_FOR_BO = 1 << 2, + MIPTREE_LAYOUT_DISABLE_AUX = 1 << 3, + MIPTREE_LAYOUT_FORCE_HALIGN16 = 1 << 4, + + MIPTREE_LAYOUT_TILING_Y = 1 << 5, + MIPTREE_LAYOUT_TILING_NONE = 1 << 6, + MIPTREE_LAYOUT_TILING_ANY = MIPTREE_LAYOUT_TILING_Y | + MIPTREE_LAYOUT_TILING_NONE, + + MIPTREE_LAYOUT_FOR_SCANOUT = 1 << 7, +}; struct intel_mipmap_tree *intel_miptree_create(struct brw_context *brw, GLenum target, - gl_format format, + mesa_format format, GLuint first_level, GLuint last_level, GLuint width0, GLuint height0, GLuint depth0, - bool expect_accelerated_upload, GLuint num_samples, - enum intel_miptree_tiling_mode); - -struct intel_mipmap_tree * -intel_miptree_create_layout(struct brw_context *brw, - GLenum target, - gl_format format, - GLuint first_level, - GLuint last_level, - GLuint width0, - GLuint height0, - GLuint depth0, - bool for_bo, - GLuint num_samples); + uint32_t flags); struct intel_mipmap_tree * intel_miptree_create_for_bo(struct brw_context *brw, drm_intel_bo *bo, - gl_format format, + mesa_format format, uint32_t offset, uint32_t width, uint32_t height, + uint32_t depth, int pitch, - uint32_t tiling); + uint32_t layout_flags); -struct intel_mipmap_tree* -intel_miptree_create_for_dri2_buffer(struct brw_context *brw, - unsigned dri_attachment, - gl_format format, - uint32_t num_samples, - struct intel_region *region); +void +intel_update_winsys_renderbuffer_miptree(struct brw_context *intel, + struct intel_renderbuffer *irb, + drm_intel_bo *bo, + uint32_t width, uint32_t height, + uint32_t pitch); /** * Create a miptree appropriate as the storage for a non-texture renderbuffer. @@ -538,17 +765,27 @@ intel_miptree_create_for_dri2_buffer(struct brw_context *brw, */ struct intel_mipmap_tree* intel_miptree_create_for_renderbuffer(struct brw_context *brw, - gl_format format, + mesa_format format, uint32_t width, uint32_t height, uint32_t num_samples); +mesa_format +intel_depth_format_for_depthstencil_format(mesa_format format); + +mesa_format +intel_lower_compressed_format(struct brw_context *brw, mesa_format format); + /** \brief Assert that the level and layer are valid for the miptree. */ static inline void intel_miptree_check_level_layer(struct intel_mipmap_tree *mt, uint32_t level, uint32_t layer) { + (void) mt; + (void) level; + (void) layer; + assert(level >= mt->first_level); assert(level <= mt->last_level); assert(layer < mt->level[level].depth); @@ -565,24 +802,56 @@ bool intel_miptree_match_image(struct intel_mipmap_tree *mt, struct gl_texture_image *image); void -intel_miptree_get_image_offset(struct intel_mipmap_tree *mt, +intel_miptree_get_image_offset(const struct intel_mipmap_tree *mt, GLuint level, GLuint slice, GLuint *x, GLuint *y); +enum isl_surf_dim +get_isl_surf_dim(GLenum target); + +enum isl_dim_layout +get_isl_dim_layout(const struct gen_device_info *devinfo, uint32_t tiling, + GLenum target); + +void +intel_miptree_get_isl_surf(struct brw_context *brw, + const struct intel_mipmap_tree *mt, + struct isl_surf *surf); +void +intel_miptree_get_aux_isl_surf(struct brw_context *brw, + const struct intel_mipmap_tree *mt, + struct isl_surf *surf, + enum isl_aux_usage *usage); + +union isl_color_value +intel_miptree_get_isl_clear_color(struct brw_context *brw, + const struct intel_mipmap_tree *mt); + +void +intel_get_image_dims(struct gl_texture_image *image, + int *width, int *height, int *depth); + +void +intel_get_tile_masks(uint32_t tiling, uint32_t tr_mode, uint32_t cpp, + uint32_t *mask_x, uint32_t *mask_y); + void -intel_miptree_get_dimensions_for_image(struct gl_texture_image *image, - int *width, int *height, int *depth); +intel_get_tile_dims(uint32_t tiling, uint32_t tr_mode, uint32_t cpp, + uint32_t *tile_w, uint32_t *tile_h); uint32_t -intel_miptree_get_tile_offsets(struct intel_mipmap_tree *mt, +intel_miptree_get_tile_offsets(const struct intel_mipmap_tree *mt, GLuint level, GLuint slice, uint32_t *tile_x, uint32_t *tile_y); +uint32_t +intel_miptree_get_aligned_offset(const struct intel_mipmap_tree *mt, + uint32_t x, uint32_t y, + bool map_stencil_as_y_tiled); void intel_miptree_set_level_info(struct intel_mipmap_tree *mt, GLuint level, - GLuint x, GLuint y, - GLuint w, GLuint h, GLuint d); + GLuint x, GLuint y, GLuint d); void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt, GLuint level, @@ -593,11 +862,6 @@ intel_miptree_copy_teximage(struct brw_context *brw, struct intel_texture_image *intelImage, struct intel_mipmap_tree *dst_mt, bool invalidate); -bool -intel_miptree_alloc_mcs(struct brw_context *brw, - struct intel_mipmap_tree *mt, - GLuint num_samples); - /** * \name Miptree HiZ functions * \{ @@ -606,20 +870,21 @@ intel_miptree_alloc_mcs(struct brw_context *brw, * functions on a miptree without HiZ. In that case, each function is a no-op. */ +bool +intel_miptree_wants_hiz_buffer(struct brw_context *brw, + struct intel_mipmap_tree *mt); + /** * \brief Allocate the miptree's embedded HiZ miptree. * \see intel_mipmap_tree:hiz_mt * \return false if allocation failed */ - bool intel_miptree_alloc_hiz(struct brw_context *brw, struct intel_mipmap_tree *mt); bool -intel_miptree_slice_has_hiz(struct intel_mipmap_tree *mt, - uint32_t level, - uint32_t layer); +intel_miptree_level_has_hiz(struct intel_mipmap_tree *mt, uint32_t level); void intel_miptree_slice_set_needs_hiz_resolve(struct intel_mipmap_tree *mt, @@ -679,33 +944,59 @@ intel_miptree_used_for_rendering(struct intel_mipmap_tree *mt) * unresolved state, since it won't be guaranteed to be clear after * rendering occurs. */ - if (mt->mcs_state == INTEL_MCS_STATE_CLEAR) - mt->mcs_state = INTEL_MCS_STATE_UNRESOLVED; + if (mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_CLEAR) + mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_UNRESOLVED; } -void +/** + * Flag values telling color resolve pass which special types of buffers + * can be ignored. + * + * INTEL_MIPTREE_IGNORE_CCS_E: Lossless compressed (single-sample + * compression scheme since gen9) + */ +#define INTEL_MIPTREE_IGNORE_CCS_E (1 << 0) + +bool intel_miptree_resolve_color(struct brw_context *brw, - struct intel_mipmap_tree *mt); + struct intel_mipmap_tree *mt, + int flags); void intel_miptree_make_shareable(struct brw_context *brw, struct intel_mipmap_tree *mt); void -intel_miptree_downsample(struct brw_context *brw, - struct intel_mipmap_tree *mt); +intel_miptree_updownsample(struct brw_context *brw, + struct intel_mipmap_tree *src, + struct intel_mipmap_tree *dst); void -intel_miptree_upsample(struct brw_context *brw, +intel_update_r8stencil(struct brw_context *brw, struct intel_mipmap_tree *mt); -void brw_miptree_layout(struct brw_context *brw, struct intel_mipmap_tree *mt); +/** + * Horizontal distance from one slice to the next in the two-dimensional + * miptree layout. + */ +unsigned +brw_miptree_get_horizontal_slice_pitch(const struct brw_context *brw, + const struct intel_mipmap_tree *mt, + unsigned level); -void *intel_miptree_map_raw(struct brw_context *brw, - struct intel_mipmap_tree *mt); +/** + * Vertical distance from one slice to the next in the two-dimensional miptree + * layout. + */ +unsigned +brw_miptree_get_vertical_slice_pitch(const struct brw_context *brw, + const struct intel_mipmap_tree *mt, + unsigned level); -void intel_miptree_unmap_raw(struct brw_context *brw, - struct intel_mipmap_tree *mt); +void +brw_miptree_layout(struct brw_context *brw, + struct intel_mipmap_tree *mt, + uint32_t layout_flags); void intel_miptree_map(struct brw_context *brw, @@ -718,7 +1009,7 @@ intel_miptree_map(struct brw_context *brw, unsigned int h, GLbitfield mode, void **out_ptr, - int *out_stride); + ptrdiff_t *out_stride); void intel_miptree_unmap(struct brw_context *brw, @@ -728,7 +1019,7 @@ intel_miptree_unmap(struct brw_context *brw, void intel_hiz_exec(struct brw_context *brw, struct intel_mipmap_tree *mt, - unsigned int level, unsigned int layer, enum gen6_hiz_op op); + unsigned int level, unsigned int layer, enum blorp_hiz_op op); #ifdef __cplusplus }