Example #1
0
static uint32_t
setup_slices(struct fd_resource *rsc, uint32_t alignment, enum pipe_format format)
{
	struct pipe_resource *prsc = &rsc->base.b;
	enum util_format_layout layout = util_format_description(format)->layout;
	uint32_t level, size = 0;
	uint32_t width = prsc->width0;
	uint32_t height = prsc->height0;
	uint32_t depth = prsc->depth0;
	/* in layer_first layout, the level (slice) contains just one
	 * layer (since in fact the layer contains the slices)
	 */
	uint32_t layers_in_level = rsc->layer_first ? 1 : prsc->array_size;

	for (level = 0; level <= prsc->last_level; level++) {
		struct fd_resource_slice *slice = fd_resource_slice(rsc, level);
		uint32_t blocks;

		if (layout == UTIL_FORMAT_LAYOUT_ASTC)
			slice->pitch = width =
				util_align_npot(width, 32 * util_format_get_blockwidth(format));
		else
			slice->pitch = width = align(width, 32);
		slice->offset = size;
		blocks = util_format_get_nblocks(format, width, height);
		/* 1d array and 2d array textures must all have the same layer size
		 * for each miplevel on a3xx. 3d textures can have different layer
		 * sizes for high levels, but the hw auto-sizer is buggy (or at least
		 * different than what this code does), so as soon as the layer size
		 * range gets into range, we stop reducing it.
		 */
		if (prsc->target == PIPE_TEXTURE_3D && (
					level == 1 ||
					(level > 1 && rsc->slices[level - 1].size0 > 0xf000)))
			slice->size0 = align(blocks * rsc->cpp, alignment);
		else if (level == 0 || rsc->layer_first || alignment == 1)
			slice->size0 = align(blocks * rsc->cpp, alignment);
		else
			slice->size0 = rsc->slices[level - 1].size0;

		size += slice->size0 * depth * layers_in_level;

		width = u_minify(width, 1);
		height = u_minify(height, 1);
		depth = u_minify(depth, 1);
	}

	return size;
}
static void r300_setup_cmask_properties(struct r300_screen *screen,
                                        struct r300_resource *tex)
{
    static unsigned cmask_align_x[4] = {16, 32, 48, 32};
    static unsigned cmask_align_y[4] = {16, 16, 16, 32};
    unsigned pipes, stride, cmask_num_dw, cmask_max_size;

    /* We need an AA colorbuffer, no mipmaps. */
    if (tex->b.b.nr_samples <= 1 ||
        tex->b.b.last_level > 0 ||
        util_format_is_depth_or_stencil(tex->b.b.format)) {
        return;
    }

    /* FP16 AA needs R500 and a fairly new DRM. */
    if ((tex->b.b.format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
         tex->b.b.format == PIPE_FORMAT_R16G16B16X16_FLOAT) &&
        (!screen->caps.is_r500 || screen->info.drm_minor < 29)) {
        return;
    }

    if (SCREEN_DBG_ON(screen, DBG_NO_CMASK)) {
        return;
    }

    /* CMASK is part of raster pipes. The number of Z pipes doesn't matter. */
    pipes = screen->info.r300_num_gb_pipes;

    /* The single-pipe cards have 5120 dwords of CMASK RAM,
     * the other cards have 4096 dwords of CMASK RAM per pipe. */
    cmask_max_size = pipes == 1 ? 5120 : pipes * 4096;

    stride = r300_stride_to_width(tex->b.b.format,
                                  tex->tex.stride_in_bytes[0]);
    stride = align(stride, 16);

    /* Get the CMASK size in dwords. */
    cmask_num_dw = r300_pixels_to_dwords(stride, tex->b.b.height0,
                                         cmask_align_x[pipes-1],
                                         cmask_align_y[pipes-1]);

    /* Check the CMASK size against the CMASK memory limit. */
    if (cmask_num_dw <= cmask_max_size) {
        tex->tex.cmask_dwords = cmask_num_dw;
        tex->tex.cmask_stride_in_pixels =
            util_align_npot(stride, cmask_align_x[pipes-1]);
    }
}
Example #3
0
/**
 * Callback exported to the draw module.
 *
 * Side effects:
 *    Updates hw_offset, sw_offset, index and may allocate
 *    a new buffer. Also updates may update the vbo state
 *    on the i915 context.
 */
static boolean
i915_vbuf_render_allocate_vertices(struct vbuf_render *render,
                                   ushort vertex_size,
                                   ushort nr_vertices)
{
   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
   size_t size = (size_t)vertex_size * (size_t)nr_vertices;
   size_t offset;

   /*
    * Align sw_offset with first multiple of vertex size from hw_offset.
    * Set index to be the multiples from from hw_offset to sw_offset.
    * i915_vbuf_render_new_buf will reset index, sw_offset, hw_offset
    * when it allocates a new buffer this is correct.
    */
   {
      offset = i915_render->vbo_sw_offset - i915_render->vbo_hw_offset;
      offset = util_align_npot(offset, vertex_size);
      i915_render->vbo_sw_offset = i915_render->vbo_hw_offset + offset;
      i915_render->vbo_index = offset / vertex_size;
   }

   if (!i915_vbuf_render_reserve(i915_render, size))
      i915_vbuf_render_new_buf(i915_render, size);

   /*
    * If a new buffer has been alocated sw_offset,
    * hw_offset & index will be reset by new_buf
    */

   i915_render->vertex_size = vertex_size;

   i915_vbuf_update_vbo_state(render);

   if (!i915_render->vbo)
      return FALSE;
   return TRUE;
}
Example #4
0
static void r300_setup_hyperz_properties(struct r300_screen *screen,
                                         struct r300_resource *tex)
{
    /* The tile size of 1 DWORD in ZMASK RAM is:
     *
     * GPU    Pipes    4x4 mode   8x8 mode
     * ------------------------------------------
     * R580   4P/1Z    32x32      64x64
     * RV570  3P/1Z    48x16      96x32
     * RV530  1P/2Z    32x16      64x32
     *        1P/1Z    16x16      32x32
     */
    static unsigned zmask_blocks_x_per_dw[4] = {4, 8, 12, 8};
    static unsigned zmask_blocks_y_per_dw[4] = {4, 4,  4, 8};

    /* In HIZ RAM, one dword is always 8x8 pixels (each byte is 4x4 pixels),
     * but the blocks have very weird ordering.
     *
     * With 2 pipes and an image of size 8xY, where Y >= 1,
     * clearing 4 dwords clears blocks like this:
     *
     *    01012323
     *
     * where numbers correspond to dword indices. The blocks are interleaved
     * in the X direction, so the alignment must be 4x1 blocks (32x8 pixels).
     *
     * With 4 pipes and an image of size 8xY, where Y >= 4,
     * clearing 8 dwords clears blocks like this:
     *    01012323
     *    45456767
     *    01012323
     *    45456767
     * where numbers correspond to dword indices. The blocks are interleaved
     * in both directions, so the alignment must be 4x4 blocks (32x32 pixels)
     */
    static unsigned hiz_align_x[4] = {8, 32, 48, 32};
    static unsigned hiz_align_y[4] = {8, 8, 8, 32};

    if (util_format_is_depth_or_stencil(tex->b.b.b.format) &&
        util_format_get_blocksizebits(tex->b.b.b.format) == 32 &&
        tex->tex.microtile) {
        unsigned i, pipes;

        if (screen->caps.family == CHIP_FAMILY_RV530) {
            pipes = screen->info.r300_num_z_pipes;
        } else {
            pipes = screen->info.r300_num_gb_pipes;
        }

        for (i = 0; i <= tex->b.b.b.last_level; i++) {
            unsigned zcomp_numdw, zcompsize, hiz_numdw, stride, height;

            stride = align(tex->tex.stride_in_pixels[i], 16);
            height = u_minify(tex->b.b.b.height0, i);

            /* The 8x8 compression mode needs macrotiling. */
            zcompsize = screen->caps.z_compress == R300_ZCOMP_8X8 &&
                       tex->tex.macrotile[i] &&
                       tex->b.b.b.nr_samples <= 1 ? 8 : 4;

            /* Get the ZMASK buffer size in dwords. */
            zcomp_numdw = r300_pixels_to_dwords(stride, height,
                                zmask_blocks_x_per_dw[pipes-1] * zcompsize,
                                zmask_blocks_y_per_dw[pipes-1] * zcompsize);

            /* Check whether we have enough ZMASK memory. */
            if (util_format_get_blocksizebits(tex->b.b.b.format) == 32 &&
                zcomp_numdw <= screen->caps.zmask_ram * pipes) {
                tex->tex.zmask_dwords[i] = zcomp_numdw;
                tex->tex.zcomp8x8[i] = zcompsize == 8;

                tex->tex.zmask_stride_in_pixels[i] =
                    util_align_npot(stride, zmask_blocks_x_per_dw[pipes-1] * zcompsize);
            } else {
                tex->tex.zmask_dwords[i] = 0;
                tex->tex.zcomp8x8[i] = FALSE;
                tex->tex.zmask_stride_in_pixels[i] = 0;
            }

            /* Now setup HIZ. */
            stride = util_align_npot(stride, hiz_align_x[pipes-1]);
            height = align(height, hiz_align_y[pipes-1]);

            /* Get the HIZ buffer size in dwords. */
            hiz_numdw = (stride * height) / (8*8 * pipes);

            /* Check whether we have enough HIZ memory. */
            if (hiz_numdw <= screen->caps.hiz_ram * pipes) {
                tex->tex.hiz_dwords[i] = hiz_numdw;
                tex->tex.hiz_stride_in_pixels[i] = stride;
            } else {
                tex->tex.hiz_dwords[i] = 0;
                tex->tex.hiz_stride_in_pixels[i] = 0;
            }
        }
    }
}
Example #5
0
static unsigned r300_pixels_to_dwords(unsigned stride,
                                      unsigned height,
                                      unsigned xblock, unsigned yblock)
{
    return (util_align_npot(stride, xblock) * align(height, yblock)) / (xblock * yblock);
}
Example #6
0
/**
 * In OpenGL the number of 1D array texture layers is the "height" and
 * the number of 2D array texture layers is the "depth".  In Gallium the
 * number of layers in an array texture is a separate 'array_size' field.
 * This function converts dimensions from the former to the later.
 */
void
st_gl_texture_dims_to_pipe_dims(GLenum texture,
                                unsigned widthIn,
                                uint16_t heightIn,
                                uint16_t depthIn,
                                unsigned *widthOut,
                                uint16_t *heightOut,
                                uint16_t *depthOut,
                                uint16_t *layersOut)
{
   switch (texture) {
   case GL_TEXTURE_1D:
   case GL_PROXY_TEXTURE_1D:
      assert(heightIn == 1);
      assert(depthIn == 1);
      *widthOut = widthIn;
      *heightOut = 1;
      *depthOut = 1;
      *layersOut = 1;
      break;
   case GL_TEXTURE_1D_ARRAY:
   case GL_PROXY_TEXTURE_1D_ARRAY:
      assert(depthIn == 1);
      *widthOut = widthIn;
      *heightOut = 1;
      *depthOut = 1;
      *layersOut = heightIn;
      break;
   case GL_TEXTURE_2D:
   case GL_PROXY_TEXTURE_2D:
   case GL_TEXTURE_RECTANGLE:
   case GL_PROXY_TEXTURE_RECTANGLE:
   case GL_TEXTURE_EXTERNAL_OES:
   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
   case GL_TEXTURE_2D_MULTISAMPLE:
      assert(depthIn == 1);
      *widthOut = widthIn;
      *heightOut = heightIn;
      *depthOut = 1;
      *layersOut = 1;
      break;
   case GL_TEXTURE_CUBE_MAP:
   case GL_PROXY_TEXTURE_CUBE_MAP:
   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
      assert(depthIn == 1);
      *widthOut = widthIn;
      *heightOut = heightIn;
      *depthOut = 1;
      *layersOut = 6;
      break;
   case GL_TEXTURE_2D_ARRAY:
   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
   case GL_PROXY_TEXTURE_2D_ARRAY:
   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
      *widthOut = widthIn;
      *heightOut = heightIn;
      *depthOut = 1;
      *layersOut = depthIn;
      break;
   case GL_TEXTURE_CUBE_MAP_ARRAY:
   case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
      *widthOut = widthIn;
      *heightOut = heightIn;
      *depthOut = 1;
      *layersOut = util_align_npot(depthIn, 6);
      break;
   default:
      assert(0 && "Unexpected texture in st_gl_texture_dims_to_pipe_dims()");
      /* fall-through */
   case GL_TEXTURE_3D:
   case GL_PROXY_TEXTURE_3D:
      *widthOut = widthIn;
      *heightOut = heightIn;
      *depthOut = depthIn;
      *layersOut = 1;
      break;
   }
}