diff options
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_tex_layout.c | 36 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_tex_layout.c | 20 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_fbo.c | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_mipmap_tree.c | 191 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_mipmap_tree.h | 28 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_tex_image.c | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_tex_layout.c | 18 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_tex_validate.c | 1 |
8 files changed, 143 insertions, 153 deletions
diff --git a/src/mesa/drivers/dri/i915/i915_tex_layout.c b/src/mesa/drivers/dri/i915/i915_tex_layout.c index 1e3cfadddc8..90911a647c7 100644 --- a/src/mesa/drivers/dri/i915/i915_tex_layout.c +++ b/src/mesa/drivers/dri/i915/i915_tex_layout.c @@ -114,9 +114,9 @@ static GLint bottom_offsets[6] = { static void i915_miptree_layout_cube(struct intel_mipmap_tree * mt) { - const GLuint dim = mt->width0; + const GLuint dim = mt->physical_width0; GLuint face; - GLuint lvlWidth = mt->width0, lvlHeight = mt->height0; + GLuint lvlWidth = mt->physical_width0, lvlHeight = mt->physical_height0; GLint level; assert(lvlWidth == lvlHeight); /* cubemap images are square */ @@ -156,14 +156,14 @@ i915_miptree_layout_cube(struct intel_mipmap_tree * mt) static void i915_miptree_layout_3d(struct intel_mipmap_tree * mt) { - GLuint width = mt->width0; - GLuint height = mt->height0; - GLuint depth = mt->depth0; + GLuint width = mt->physical_width0; + GLuint height = mt->physical_height0; + GLuint depth = mt->physical_depth0; GLuint stack_height = 0; GLint level; /* Calculate the size of a single slice. */ - mt->total_width = mt->width0; + mt->total_width = mt->physical_width0; /* XXX: hardware expects/requires 9 levels at minimum. */ for (level = mt->first_level; level <= MAX2(8, mt->last_level); level++) { @@ -178,7 +178,7 @@ i915_miptree_layout_3d(struct intel_mipmap_tree * mt) } /* Fixup depth image_offsets: */ - depth = mt->depth0; + depth = mt->physical_depth0; for (level = mt->first_level; level <= mt->last_level; level++) { GLuint i; for (i = 0; i < depth; i++) { @@ -193,18 +193,18 @@ i915_miptree_layout_3d(struct intel_mipmap_tree * mt) * remarkable how wasteful of memory the i915 texture layouts * are. They are largely fixed in the i945. */ - mt->total_height = stack_height * mt->depth0; + mt->total_height = stack_height * mt->physical_depth0; } static void i915_miptree_layout_2d(struct intel_mipmap_tree * mt) { - GLuint width = mt->width0; - GLuint height = mt->height0; + GLuint width = mt->physical_width0; + GLuint height = mt->physical_height0; GLuint img_height; GLint level; - mt->total_width = mt->width0; + mt->total_width = mt->physical_width0; mt->total_height = 0; for (level = mt->first_level; level <= mt->last_level; level++) { @@ -312,9 +312,9 @@ i915_miptree_layout(struct intel_mipmap_tree * mt) static void i945_miptree_layout_cube(struct intel_mipmap_tree * mt) { - const GLuint dim = mt->width0; + const GLuint dim = mt->physical_width0; GLuint face; - GLuint lvlWidth = mt->width0, lvlHeight = mt->height0; + GLuint lvlWidth = mt->physical_width0, lvlHeight = mt->physical_height0; GLint level; assert(lvlWidth == lvlHeight); /* cubemap images are square */ @@ -402,17 +402,17 @@ i945_miptree_layout_cube(struct intel_mipmap_tree * mt) static void i945_miptree_layout_3d(struct intel_mipmap_tree * mt) { - GLuint width = mt->width0; - GLuint height = mt->height0; - GLuint depth = mt->depth0; + GLuint width = mt->physical_width0; + GLuint height = mt->physical_height0; + GLuint depth = mt->physical_depth0; GLuint pack_x_pitch, pack_x_nr; GLuint pack_y_pitch; GLuint level; - mt->total_width = mt->width0; + mt->total_width = mt->physical_width0; mt->total_height = 0; - pack_y_pitch = MAX2(mt->height0, 2); + pack_y_pitch = MAX2(mt->physical_height0, 2); pack_x_pitch = mt->total_width; pack_x_nr = 1; diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c index b661570e99b..1428396c907 100644 --- a/src/mesa/drivers/dri/i965/brw_tex_layout.c +++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c @@ -47,8 +47,8 @@ brw_miptree_layout_texture_array(struct intel_context *intel, GLuint qpitch = 0; int h0, h1, q; - h0 = ALIGN(mt->height0, mt->align_h); - h1 = ALIGN(minify(mt->height0), mt->align_h); + h0 = ALIGN(mt->physical_height0, mt->align_h); + h1 = ALIGN(minify(mt->physical_height0), mt->align_h); if (mt->array_spacing_lod0) qpitch = h0; else @@ -59,11 +59,11 @@ brw_miptree_layout_texture_array(struct intel_context *intel, i945_miptree_layout_2d(mt); for (level = mt->first_level; level <= mt->last_level; level++) { - for (q = 0; q < mt->depth0; q++) { + for (q = 0; q < mt->physical_depth0; q++) { intel_miptree_set_image_offset(mt, level, q, 0, q * qpitch); } } - mt->total_height = qpitch * mt->depth0; + mt->total_height = qpitch * mt->physical_depth0; } void @@ -84,13 +84,13 @@ brw_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree *mt) brw_miptree_layout_texture_array(intel, mt); break; } - assert(mt->depth0 == 6); + assert(mt->physical_depth0 == 6); /* FALLTHROUGH */ case GL_TEXTURE_3D: { - GLuint width = mt->width0; - GLuint height = mt->height0; - GLuint depth = mt->depth0; + GLuint width = mt->physical_width0; + GLuint height = mt->physical_height0; + GLuint depth = mt->physical_depth0; GLuint pack_x_pitch, pack_x_nr; GLuint pack_y_pitch; GLuint level; @@ -101,8 +101,8 @@ brw_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree *mt) mt->total_width = ALIGN(width, mt->align_w); pack_y_pitch = (height + 3) / 4; } else { - mt->total_width = mt->width0; - pack_y_pitch = ALIGN(mt->height0, mt->align_h); + mt->total_width = mt->physical_width0; + pack_y_pitch = ALIGN(mt->physical_height0, mt->align_h); } pack_x_pitch = width; diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index 05970153699..034fa8a96d5 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -939,7 +939,6 @@ intel_renderbuffer_move_to_temp(struct intel_context *intel, width, height, depth, true, irb->mt->num_samples, - irb->mt->msaa_layout, false /* force_y_tiling */); intel_miptree_copy_teximage(intel, intel_image, new_mt); diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index 12b77b6d47f..75422199d27 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -122,8 +122,7 @@ intel_miptree_create_internal(struct intel_context *intel, GLuint height0, GLuint depth0, bool for_region, - GLuint num_samples, - enum intel_msaa_layout msaa_layout) + GLuint num_samples) { struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1); int compress_byte = 0; @@ -140,18 +139,78 @@ intel_miptree_create_internal(struct intel_context *intel, mt->format = format; mt->first_level = first_level; mt->last_level = last_level; - mt->width0 = width0; - mt->height0 = height0; + mt->logical_width0 = width0; + mt->logical_height0 = height0; + mt->logical_depth0 = depth0; mt->cpp = compress_byte ? compress_byte : _mesa_get_format_bytes(mt->format); mt->num_samples = num_samples; mt->compressed = compress_byte ? 1 : 0; - mt->msaa_layout = msaa_layout; + mt->msaa_layout = INTEL_MSAA_LAYOUT_NONE; mt->refcount = 1; + if (num_samples > 1) { + /* Adjust width/height/depth for MSAA */ + mt->msaa_layout = compute_msaa_layout(intel, format); + if (mt->msaa_layout == INTEL_MSAA_LAYOUT_IMS) { + /* In the Sandy Bridge PRM, volume 4, part 1, page 31, it says: + * + * "Any of the other messages (sample*, LOD, load4) used with a + * (4x) multisampled surface will in-effect sample a surface with + * double the height and width as that indicated in the surface + * state. Each pixel position on the original-sized surface is + * replaced with a 2x2 of samples with the following arrangement: + * + * sample 0 sample 2 + * sample 1 sample 3" + * + * Thus, when sampling from a multisampled texture, it behaves as + * though the layout in memory for (x,y,sample) is: + * + * (0,0,0) (0,0,2) (1,0,0) (1,0,2) + * (0,0,1) (0,0,3) (1,0,1) (1,0,3) + * + * (0,1,0) (0,1,2) (1,1,0) (1,1,2) + * (0,1,1) (0,1,3) (1,1,1) (1,1,3) + * + * However, the actual layout of multisampled data in memory is: + * + * (0,0,0) (1,0,0) (0,0,1) (1,0,1) + * (0,1,0) (1,1,0) (0,1,1) (1,1,1) + * + * (0,0,2) (1,0,2) (0,0,3) (1,0,3) + * (0,1,2) (1,1,2) (0,1,3) (1,1,3) + * + * This pattern repeats for each 2x2 pixel block. + * + * As a result, when calculating the size of our 4-sample buffer for + * an odd width or height, we have to align before scaling up because + * sample 3 is in that bottom right 2x2 block. + */ + switch (num_samples) { + case 4: + width0 = ALIGN(width0, 2) * 2; + height0 = ALIGN(height0, 2) * 2; + break; + case 8: + width0 = ALIGN(width0, 2) * 4; + height0 = ALIGN(height0, 2) * 2; + break; + default: + /* num_samples should already have been quantized to 0, 1, 4, or + * 8. + */ + assert(false); + } + } else { + /* Non-interleaved */ + depth0 *= num_samples; + } + } + /* array_spacing_lod0 is only used for non-IMS MSAA surfaces. TODO: can we * use it elsewhere? */ - switch (msaa_layout) { + switch (mt->msaa_layout) { case INTEL_MSAA_LAYOUT_NONE: case INTEL_MSAA_LAYOUT_IMS: mt->array_spacing_lod0 = false; @@ -164,30 +223,28 @@ intel_miptree_create_internal(struct intel_context *intel, if (target == GL_TEXTURE_CUBE_MAP) { assert(depth0 == 1); - mt->depth0 = 6; - } else { - mt->depth0 = depth0; + depth0 = 6; } + mt->physical_width0 = width0; + mt->physical_height0 = height0; + mt->physical_depth0 = depth0; + if (!for_region && _mesa_is_depthstencil_format(_mesa_get_format_base_format(format)) && (intel->must_use_separate_stencil || (intel->has_separate_stencil && intel->vtbl.is_hiz_depth_format(intel, format)))) { - /* MSAA stencil surfaces always use IMS layout. */ - enum intel_msaa_layout msaa_layout = - num_samples > 1 ? INTEL_MSAA_LAYOUT_IMS : INTEL_MSAA_LAYOUT_NONE; mt->stencil_mt = intel_miptree_create(intel, mt->target, MESA_FORMAT_S8, mt->first_level, mt->last_level, - mt->width0, - mt->height0, - mt->depth0, + mt->logical_width0, + mt->logical_height0, + mt->logical_depth0, true, num_samples, - msaa_layout, false /* force_y_tiling */); if (!mt->stencil_mt) { intel_miptree_release(&mt); @@ -236,7 +293,6 @@ intel_miptree_create(struct intel_context *intel, GLuint depth0, bool expect_accelerated_upload, GLuint num_samples, - enum intel_msaa_layout msaa_layout, bool force_y_tiling) { struct intel_mipmap_tree *mt; @@ -282,7 +338,7 @@ intel_miptree_create(struct intel_context *intel, etc_format = (format != tex_format) ? tex_format : MESA_FORMAT_NONE; base_format = _mesa_get_format_base_format(format); - if (msaa_layout != INTEL_MSAA_LAYOUT_NONE) { + if (num_samples > 1) { /* From p82 of the Sandy Bridge PRM, dw3[1] of SURFACE_STATE ("Tiled * Surface"): * @@ -312,7 +368,7 @@ intel_miptree_create(struct intel_context *intel, mt = intel_miptree_create_internal(intel, target, format, first_level, last_level, width0, height0, depth0, - false, num_samples, msaa_layout); + false, num_samples); /* * pitch == 0 || height == 0 indicates the null texture */ @@ -364,8 +420,7 @@ intel_miptree_create_for_region(struct intel_context *intel, mt = intel_miptree_create_internal(intel, target, format, 0, 0, region->width, region->height, 1, - true, 0 /* num_samples */, - INTEL_MSAA_LAYOUT_NONE); + true, 0 /* num_samples */); if (!mt) return mt; @@ -440,73 +495,11 @@ intel_miptree_create_for_renderbuffer(struct intel_context *intel, { struct intel_mipmap_tree *mt; uint32_t depth = 1; - enum intel_msaa_layout msaa_layout = INTEL_MSAA_LAYOUT_NONE; - const uint32_t singlesample_width = width; - const uint32_t singlesample_height = height; bool ok; - if (num_samples > 1) { - /* Adjust width/height/depth for MSAA */ - msaa_layout = compute_msaa_layout(intel, format); - if (msaa_layout == INTEL_MSAA_LAYOUT_IMS) { - /* In the Sandy Bridge PRM, volume 4, part 1, page 31, it says: - * - * "Any of the other messages (sample*, LOD, load4) used with a - * (4x) multisampled surface will in-effect sample a surface with - * double the height and width as that indicated in the surface - * state. Each pixel position on the original-sized surface is - * replaced with a 2x2 of samples with the following arrangement: - * - * sample 0 sample 2 - * sample 1 sample 3" - * - * Thus, when sampling from a multisampled texture, it behaves as - * though the layout in memory for (x,y,sample) is: - * - * (0,0,0) (0,0,2) (1,0,0) (1,0,2) - * (0,0,1) (0,0,3) (1,0,1) (1,0,3) - * - * (0,1,0) (0,1,2) (1,1,0) (1,1,2) - * (0,1,1) (0,1,3) (1,1,1) (1,1,3) - * - * However, the actual layout of multisampled data in memory is: - * - * (0,0,0) (1,0,0) (0,0,1) (1,0,1) - * (0,1,0) (1,1,0) (0,1,1) (1,1,1) - * - * (0,0,2) (1,0,2) (0,0,3) (1,0,3) - * (0,1,2) (1,1,2) (0,1,3) (1,1,3) - * - * This pattern repeats for each 2x2 pixel block. - * - * As a result, when calculating the size of our 4-sample buffer for - * an odd width or height, we have to align before scaling up because - * sample 3 is in that bottom right 2x2 block. - */ - switch (num_samples) { - case 4: - width = ALIGN(width, 2) * 2; - height = ALIGN(height, 2) * 2; - break; - case 8: - width = ALIGN(width, 2) * 4; - height = ALIGN(height, 2) * 2; - break; - default: - /* num_samples should already have been quantized to 0, 1, 4, or - * 8. - */ - assert(false); - } - } else { - /* Non-interleaved */ - depth = num_samples; - } - } - mt = intel_miptree_create(intel, GL_TEXTURE_2D, format, 0, 0, width, height, depth, true, num_samples, - msaa_layout, false /* force_y_tiling */); + false /* force_y_tiling */); if (!mt) goto fail; @@ -522,9 +515,6 @@ intel_miptree_create_for_renderbuffer(struct intel_context *intel, goto fail; } - mt->singlesample_width0 = singlesample_width; - mt->singlesample_height0 = singlesample_height; - return mt; fail: @@ -835,12 +825,11 @@ intel_miptree_alloc_mcs(struct intel_context *intel, format, mt->first_level, mt->last_level, - mt->width0, - mt->height0, - mt->depth0, + mt->logical_width0, + mt->logical_height0, + mt->logical_depth0, true, 0 /* num_samples */, - INTEL_MSAA_LAYOUT_NONE, true /* force_y_tiling */); /* From the Ivy Bridge PRM, Vol 2 Part 1 p326: @@ -866,18 +855,16 @@ intel_miptree_alloc_hiz(struct intel_context *intel, GLuint num_samples) { assert(mt->hiz_mt == NULL); - /* MSAA HiZ surfaces always use IMS layout. */ mt->hiz_mt = intel_miptree_create(intel, mt->target, mt->format, mt->first_level, mt->last_level, - mt->width0, - mt->height0, - mt->depth0, + mt->logical_width0, + mt->logical_height0, + mt->logical_depth0, true, num_samples, - INTEL_MSAA_LAYOUT_IMS, false /* force_y_tiling */); if (!mt->hiz_mt) @@ -1067,8 +1054,8 @@ intel_miptree_downsample(struct intel_context *intel, return; intel_miptree_updownsample(intel, mt, mt->singlesample_mt, - mt->singlesample_mt->width0, - mt->singlesample_mt->height0); + mt->logical_width0, + mt->logical_height0); mt->need_downsample = false; /* Strictly speaking, after a downsample on a depth miptree, a hiz @@ -1094,8 +1081,8 @@ intel_miptree_upsample(struct intel_context *intel, intel_miptree_updownsample(intel, mt->singlesample_mt, mt, - mt->singlesample_mt->width0, - mt->singlesample_mt->height0); + mt->logical_width0, + mt->logical_height0); intel_miptree_slice_set_needs_hiz_resolve(mt, 0, 0); } @@ -1658,8 +1645,8 @@ intel_miptree_map_multisample(struct intel_context *intel, mt->singlesample_mt = intel_miptree_create_for_renderbuffer(intel, mt->format, - mt->singlesample_width0, - mt->singlesample_height0, + mt->logical_width0, + mt->logical_height0, 0 /*num_samples*/); if (!mt->singlesample_mt) goto fail; diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h index 8e84bef28ce..a3f013f4d85 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h @@ -215,22 +215,29 @@ struct intel_mipmap_tree GLuint first_level; GLuint last_level; - GLuint width0, height0, depth0; /**< Level zero image dimensions */ + /** + * Level zero image dimensions. These dimensions correspond to the + * physical layout of data in memory. Accordingly, they account for the + * extra width, height, and or depth that must be allocated in order to + * accommodate multisample formats, and they account for the extra factor + * of 6 in depth that must be allocated in order to accommodate cubemap + * textures. + */ + GLuint physical_width0, physical_height0, physical_depth0; + GLuint cpp; GLuint num_samples; bool compressed; /** - * If num_samples > 0, then singlesample_width0 is the value that width0 - * would have if instead a singlesample miptree were created. Note that, - * for non-interleaved msaa layouts, the two values are the same. - * - * If num_samples == 0, then singlesample_width0 is undefined. + * Level zero image dimensions. These dimensions correspond to the + * logical width, height, and depth of the region 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 singlesample_width0; - - /** \see singlesample_width0 */ - uint32_t singlesample_height0; + uint32_t logical_width0, logical_height0, logical_depth0; /** * For 1D array, 2D array, cube, and 2D multisampled surfaces on Gen7: true @@ -384,7 +391,6 @@ struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel, GLuint depth0, bool expect_accelerated_upload, GLuint num_samples, - enum intel_msaa_layout msaa_layout, bool force_y_tiling); struct intel_mipmap_tree * diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index f1ab07da120..d1b5826db42 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -101,7 +101,6 @@ intel_miptree_create_for_teximage(struct intel_context *intel, depth, expect_accelerated_upload, 0 /* num_samples */, - INTEL_MSAA_LAYOUT_NONE, false /* force_y_tiling */); } diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c index 65645bc46a4..35030dfcb32 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.c +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c @@ -143,14 +143,14 @@ void i945_miptree_layout_2d(struct intel_mipmap_tree *mt) GLuint level; GLuint x = 0; GLuint y = 0; - GLuint width = mt->width0; - GLuint height = mt->height0; - GLuint depth = mt->depth0; /* number of array layers. */ + GLuint width = mt->physical_width0; + GLuint height = mt->physical_height0; + GLuint depth = mt->physical_depth0; /* number of array layers. */ - mt->total_width = mt->width0; + mt->total_width = mt->physical_width0; if (mt->compressed) { - mt->total_width = ALIGN(mt->width0, mt->align_w); + mt->total_width = ALIGN(mt->physical_width0, mt->align_w); } /* May need to adjust width to accomodate the placement of @@ -162,11 +162,11 @@ void i945_miptree_layout_2d(struct intel_mipmap_tree *mt) GLuint mip1_width; if (mt->compressed) { - mip1_width = ALIGN(minify(mt->width0), mt->align_w) - + ALIGN(minify(minify(mt->width0)), mt->align_w); + mip1_width = ALIGN(minify(mt->physical_width0), mt->align_w) + + ALIGN(minify(minify(mt->physical_width0)), mt->align_w); } else { - mip1_width = ALIGN(minify(mt->width0), mt->align_w) - + minify(minify(mt->width0)); + mip1_width = ALIGN(minify(mt->physical_width0), mt->align_w) + + minify(minify(mt->physical_width0)); } if (mip1_width > mt->total_width) { diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c index eb1977406d8..c849366dbdb 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_validate.c +++ b/src/mesa/drivers/dri/intel/intel_tex_validate.c @@ -106,7 +106,6 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) depth, true, 0 /* num_samples */, - INTEL_MSAA_LAYOUT_NONE, false /* force_y_tiling */); if (!intelObj->mt) return false; |