/* SPDX-License-Identifier: GPL-2.0 OR MIT */ /********************************************************** * * Copyright (c) 2021-2024 Broadcom. All Rights Reserved. The term * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * 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. *
**********************************************************/
/** * vmw_surface_get_desc - Look up the appropriate SVGA3dSurfaceDesc for the * given format.
*/ staticinlineconst SVGA3dSurfaceDesc *
vmw_surface_get_desc(SVGA3dSurfaceFormat format)
{ if (format < ARRAY_SIZE(g_SVGA3dSurfaceDescs)) return &g_SVGA3dSurfaceDescs[format];
/** * vmw_surface_get_image_buffer_size - Calculates image buffer size. * * Return the number of bytes of buffer space required to store one image of a * surface, optionally using the specified pitch. * * If pitch is zero, it is assumed that rows are tightly packed. * * This function is overflow-safe. If the result would have overflowed, instead * we return MAX_UINT32.
*/ staticinline u32
vmw_surface_get_image_buffer_size(const SVGA3dSurfaceDesc *desc, conststruct drm_vmw_size *size,
u32 pitch)
{
SVGA3dSize image_blocks;
u32 slice_size, total_size;
/** * vmw_surface_get_serialized_size_extended - Returns the number of bytes * required for a surface with given parameters. Support for sample count.
*/ staticinline u32
vmw_surface_get_serialized_size_extended(SVGA3dSurfaceFormat format, struct drm_vmw_size base_level_size,
u32 num_mip_levels,
u32 num_layers,
u32 num_samples)
{
uint64_t total_size =
vmw_surface_get_serialized_size(format,
base_level_size,
num_mip_levels,
num_layers);
total_size *= max_t(u32, 1, num_samples);
mipChainBytes = 0;
mipChainBytesToLevel = 0; for (i = 0; i < numMipLevels; i++) {
mipSize = vmw_surface_get_mip_size(baseLevelSize, i);
bytes = vmw_surface_get_image_buffer_size(desc, &mipSize, 0);
mipChainBytes += bytes; if (i < mip)
mipChainBytesToLevel += bytes;
}
offset = mipChainBytes * face + mipChainBytesToLevel;
return offset;
}
/** * vmw_surface_is_gb_screen_target_format - Is the specified format usable as * a ScreenTarget? * (with just the GBObjects cap-bit * set) * @format: format to queried * * RETURNS: * true if queried format is valid for screen targets
*/ staticinlinebool
vmw_surface_is_gb_screen_target_format(SVGA3dSurfaceFormat format)
{ return (format == SVGA3D_X8R8G8B8 ||
format == SVGA3D_A8R8G8B8 ||
format == SVGA3D_R5G6B5 ||
format == SVGA3D_X1R5G5B5 ||
format == SVGA3D_A1R5G5B5 ||
format == SVGA3D_P8);
}
/** * vmw_surface_is_dx_screen_target_format - Is the specified format usable as * a ScreenTarget? * (with DX10 enabled) * * @format: format to queried * * Results: * true if queried format is valid for screen targets
*/ staticinlinebool
vmw_surface_is_dx_screen_target_format(SVGA3dSurfaceFormat format)
{ return (format == SVGA3D_R8G8B8A8_UNORM ||
format == SVGA3D_B8G8R8A8_UNORM ||
format == SVGA3D_B8G8R8X8_UNORM);
}
/** * vmw_surface_is_screen_target_format - Is the specified format usable as a * ScreenTarget? * (for some combination of caps) * * @format: format to queried * * Results: * true if queried format is valid for screen targets
*/ staticinlinebool
vmw_surface_is_screen_target_format(SVGA3dSurfaceFormat format)
{ if (vmw_surface_is_gb_screen_target_format(format)) { returntrue;
} return vmw_surface_is_dx_screen_target_format(format);
}
/** * struct vmw_surface_mip - Mimpmap level information * @bytes: Bytes required in the backing store of this mipmap level. * @img_stride: Byte stride per image. * @row_stride: Byte stride per block row. * @size: The size of the mipmap.
*/ struct vmw_surface_mip {
size_t bytes;
size_t img_stride;
size_t row_stride; struct drm_vmw_size size;
};
/** * struct vmw_surface_cache - Cached surface information * @desc: Pointer to the surface descriptor * @mip: Array of mipmap level information. Valid size is @num_mip_levels. * @mip_chain_bytes: Bytes required in the backing store for the whole chain * of mip levels. * @sheet_bytes: Bytes required in the backing store for a sheet * representing a single sample. * @num_mip_levels: Valid size of the @mip array. Number of mipmap levels in * a chain. * @num_layers: Number of slices in an array texture or number of faces in * a cubemap texture.
*/ struct vmw_surface_cache { const SVGA3dSurfaceDesc *desc; struct vmw_surface_mip mip[DRM_VMW_MAX_MIP_LEVELS];
size_t mip_chain_bytes;
size_t sheet_bytes;
u32 num_mip_levels;
u32 num_layers;
};
/** * struct vmw_surface_loc - Surface location * @sheet: The multisample sheet. * @sub_resource: Surface subresource. Defined as layer * num_mip_levels + * mip_level. * @x: X coordinate. * @y: Y coordinate. * @z: Z coordinate.
*/ struct vmw_surface_loc {
u32 sheet;
u32 sub_resource;
u32 x, y, z;
};
/** * vmw_surface_subres - Compute the subresource from layer and mipmap. * @cache: Surface layout data. * @mip_level: The mipmap level. * @layer: The surface layer (face or array slice). * * Return: The subresource.
*/ staticinline u32 vmw_surface_subres(conststruct vmw_surface_cache *cache,
u32 mip_level, u32 layer)
{ return cache->num_mip_levels * layer + mip_level;
}
/** * vmw_surface_setup_cache - Build a surface cache entry * @size: The surface base level dimensions. * @format: The surface format. * @num_mip_levels: Number of mipmap levels. * @num_layers: Number of layers. * @cache: Pointer to a struct vmw_surface_cach object to be filled in. * * Return: Zero on success, -EINVAL on invalid surface layout.
*/ staticinlineint vmw_surface_setup_cache(conststruct drm_vmw_size *size,
SVGA3dSurfaceFormat format,
u32 num_mip_levels,
u32 num_layers,
u32 num_samples, struct vmw_surface_cache *cache)
{ const SVGA3dSurfaceDesc *desc;
u32 i;
memset(cache, 0, sizeof(*cache));
cache->desc = desc = vmw_surface_get_desc(format);
cache->num_mip_levels = num_mip_levels;
cache->num_layers = num_layers; for (i = 0; i < cache->num_mip_levels; i++) { struct vmw_surface_mip *mip = &cache->mip[i];
invalid_dim:
VMW_DEBUG_USER("Invalid surface layout for dirty tracking.\n"); return -EINVAL;
}
/** * vmw_surface_get_loc - Get a surface location from an offset into the * backing store * @cache: Surface layout data. * @loc: Pointer to a struct vmw_surface_loc to be filled in. * @offset: Offset into the surface backing store.
*/ staticinlinevoid
vmw_surface_get_loc(conststruct vmw_surface_cache *cache, struct vmw_surface_loc *loc,
size_t offset)
{ conststruct vmw_surface_mip *mip = &cache->mip[0]; const SVGA3dSurfaceDesc *desc = cache->desc;
u32 layer; int i;
/** * vmw_surface_inc_loc - Clamp increment a surface location with one block * size * in each dimension. * @loc: Pointer to a struct vmw_surface_loc to be incremented. * * When computing the size of a range as size = end - start, the range does not * include the end element. However a location representing the last byte * of a touched region in the backing store *is* included in the range. * This function modifies such a location to match the end definition * given as start + size which is the one used in a SVGA3dBox.
*/ staticinlinevoid
vmw_surface_inc_loc(conststruct vmw_surface_cache *cache, struct vmw_surface_loc *loc)
{ const SVGA3dSurfaceDesc *desc = cache->desc;
u32 mip = loc->sub_resource % cache->num_mip_levels; conststruct drm_vmw_size *size = &cache->mip[mip].size;
/** * vmw_surface_min_loc - The start location in a subresource * @cache: Surface layout data. * @sub_resource: The subresource. * @loc: Pointer to a struct vmw_surface_loc to be filled in.
*/ staticinlinevoid
vmw_surface_min_loc(conststruct vmw_surface_cache *cache,
u32 sub_resource, struct vmw_surface_loc *loc)
{
loc->sheet = 0;
loc->sub_resource = sub_resource;
loc->x = loc->y = loc->z = 0;
}
/** * vmw_surface_min_loc - The end location in a subresource * @cache: Surface layout data. * @sub_resource: The subresource. * @loc: Pointer to a struct vmw_surface_loc to be filled in. * * Following the end definition given in vmw_surface_inc_loc(), * Compute the end location of a surface subresource.
*/ staticinlinevoid
vmw_surface_max_loc(conststruct vmw_surface_cache *cache,
u32 sub_resource, struct vmw_surface_loc *loc)
{ conststruct drm_vmw_size *size;
u32 mip;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.