| 1 |
|
| 2 | |
| 3 | *
|
| 4 | * Copyright (c) 2021-2024 Broadcom. All Rights Reserved. The term
|
| 5 | * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
|
| 6 | *
|
| 7 | * Permission is hereby granted, free of charge, to any person
|
| 8 | * obtaining a copy of this software and associated documentation
|
| 9 | * files (the "Software"), to deal in the Software without
|
| 10 | * restriction, including without limitation the rights to use, copy,
|
| 11 | * modify, merge, publish, distribute, sublicense, and/or sell copies
|
| 12 | * of the Software, and to permit persons to whom the Software is
|
| 13 | * furnished to do so, subject to the following conditions:
|
| 14 | *
|
| 15 | * The above copyright notice and this permission notice shall be
|
| 16 | * included in all copies or substantial portions of the Software.
|
| 17 | *
|
| 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
| 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
| 22 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
| 23 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
| 24 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 25 | * SOFTWARE.
|
| 26 | *
|
| 27 | *********************************************************
|
| 28 |
|
| 29 | #ifndef VMW_SURFACE_CACHE_H
|
| 30 | #define VMW_SURFACE_CACHE_H
|
| 31 |
|
| 32 | #include "device_include/svga3d_surfacedefs.h"
|
| 33 |
|
| 34 | #include <drm/vmwgfx_drm.h>
|
| 35 |
|
| 36 | #define SVGA3D_FLAGS_UPPER_32(svga3d_flags) ((svga3d_flags) >> 32)
|
| 37 | #define SVGA3D_FLAGS_LOWER_32(svga3d_flags) \
|
| 38 | ((svga3d_flags) & ((uint64_t)U32_MAX))
|
| 39 |
|
| 40 | static inline u32 clamped_umul32(u32 a, u32 b)
|
| 41 | {
|
| 42 | uint64_t tmp = (uint64_t) a*b;
|
| 43 | return (tmp > (uint64_t) ((u32) -1)) ? (u32) -1 : tmp;
|
| 44 | }
|
| 45 |
|
| 46 | |
| 47 | * vmw_surface_get_desc - Look up the appropriate SVGA3dSurfaceDesc for the
|
| 48 | * given format.
|
| 49 |
|
| 50 | static inline const SVGA3dSurfaceDesc *
|
| 51 | vmw_surface_get_desc(SVGA3dSurfaceFormat format)
|
| 52 | {
|
| 53 | if (format < ARRAY_SIZE(g_SVGA3dSurfaceDescs))
|
| 54 | return &g_SVGA3dSurfaceDescs[format];
|
| 55 |
|
| 56 | return &g_SVGA3dSurfaceDescs[SVGA3D_FORMAT_INVALID];
|
| 57 | }
|
| 58 |
|
| 59 | |
| 60 | * vmw_surface_get_mip_size - Given a base level size and the mip level,
|
| 61 | * compute the size of the mip level.
|
| 62 |
|
| 63 | static inline struct drm_vmw_size
|
| 64 | vmw_surface_get_mip_size(struct drm_vmw_size base_level, u32 mip_level)
|
| 65 | {
|
| 66 | struct drm_vmw_size size = {
|
| 67 | .width = max_t(u32, base_level.width >> mip_level, 1),
|
| 68 | .height = max_t(u32, base_level.height >> mip_level, 1),
|
| 69 | .depth = max_t(u32, base_level.depth >> mip_level, 1)
|
| 70 | };
|
| 71 |
|
| 72 | return size;
|
| 73 | }
|
| 74 |
|
| 75 | static inline void
|
| 76 | vmw_surface_get_size_in_blocks(const SVGA3dSurfaceDesc *desc,
|
| 77 | const struct drm_vmw_size *pixel_size,
|
| 78 | SVGA3dSize *block_size)
|
| 79 | {
|
| 80 | block_size->width = __KERNEL_DIV_ROUND_UP(pixel_size->width,
|
| 81 | desc->blockSize.width);
|
| 82 | block_size->height = __KERNEL_DIV_ROUND_UP(pixel_size->height,
|
| 83 | desc->blockSize.height);
|
| 84 | block_size->depth = __KERNEL_DIV_ROUND_UP(pixel_size->depth,
|
| 85 | desc->blockSize.depth);
|
| 86 | }
|
| 87 |
|
| 88 | static inline bool
|
| 89 | vmw_surface_is_planar_surface(const SVGA3dSurfaceDesc *desc)
|
| 90 | {
|
| 91 | return (desc->blockDesc & SVGA3DBLOCKDESC_PLANAR_YUV) != 0;
|
| 92 | }
|
| 93 |
|
| 94 | static inline u32
|
| 95 | vmw_surface_calculate_pitch(const SVGA3dSurfaceDesc *desc,
|
| 96 | const struct drm_vmw_size *size)
|
| 97 | {
|
| 98 | u32 pitch;
|
| 99 | SVGA3dSize blocks;
|
| 100 |
|
| 101 | vmw_surface_get_size_in_blocks(desc, size, &blocks);
|
| 102 |
|
| 103 | pitch = blocks.width * desc->pitchBytesPerBlock;
|
| 104 |
|
| 105 | return pitch;
|
| 106 | }
|
| 107 |
|
| 108 | |
| 109 | * vmw_surface_get_image_buffer_size - Calculates image buffer size.
|
| 110 | *
|
| 111 | * Return the number of bytes of buffer space required to store one image of a
|
| 112 | * surface, optionally using the specified pitch.
|
| 113 | *
|
| 114 | * If pitch is zero, it is assumed that rows are tightly packed.
|
| 115 | *
|
| 116 | * This function is overflow-safe. If the result would have overflowed, instead
|
| 117 | * we return MAX_UINT32.
|
| 118 |
|
| 119 | static inline u32
|
| 120 | vmw_surface_get_image_buffer_size(const SVGA3dSurfaceDesc *desc,
|
| 121 | const struct drm_vmw_size *size,
|
| 122 | u32 pitch)
|
| 123 | {
|
| 124 | SVGA3dSize image_blocks;
|
| 125 | u32 slice_size, total_size;
|
| 126 |
|
| 127 | vmw_surface_get_size_in_blocks(desc, size, &image_blocks);
|
| 128 |
|
| 129 | if (vmw_surface_is_planar_surface(desc)) {
|
| 130 | total_size = clamped_umul32(image_blocks.width,
|
| 131 | image_blocks.height);
|
| 132 | total_size = clamped_umul32(total_size, image_blocks.depth);
|
| 133 | total_size = clamped_umul32(total_size, desc->bytesPerBlock);
|
| 134 | return total_size;
|
| 135 | }
|
| 136 |
|
| 137 | if (pitch == 0)
|
| 138 | pitch = vmw_surface_calculate_pitch(desc, size);
|
| 139 |
|
| 140 | slice_size = clamped_umul32(image_blocks.height, pitch);
|
| 141 | total_size = clamped_umul32(slice_size, image_blocks.depth);
|
| 142 |
|
| 143 | return total_size;
|
| 144 | }
|
| 145 |
|
| 146 | |
| 147 | * vmw_surface_get_serialized_size - Get the serialized size for the image.
|
| 148 |
|
| 149 | static inline u32
|
| 150 | vmw_surface_get_serialized_size(SVGA3dSurfaceFormat format,
|
| 151 | struct drm_vmw_size base_level_size,
|
| 152 | u32 num_mip_levels,
|
| 153 | u32 num_layers)
|
| 154 | {
|
| 155 | const SVGA3dSurfaceDesc *desc = vmw_surface_get_desc(format);
|
| 156 | u32 total_size = 0;
|
| 157 | u32 mip;
|
| 158 |
|
| 159 | for (mip = 0; mip < num_mip_levels; mip++) {
|
| 160 | struct drm_vmw_size size =
|
| 161 | vmw_surface_get_mip_size(base_level_size, mip);
|
| 162 | total_size += vmw_surface_get_image_buffer_size(desc,
|
| 163 | &size, 0);
|
| 164 | }
|
| 165 |
|
| 166 | return total_size * num_layers;
|
| 167 | }
|
| 168 |
|
| 169 | |
| 170 | * vmw_surface_get_serialized_size_extended - Returns the number of bytes
|
| 171 | * required for a surface with given parameters. Support for sample count.
|
| 172 |
|
| 173 | static inline u32
|
| 174 | vmw_surface_get_serialized_size_extended(SVGA3dSurfaceFormat format,
|
| 175 | struct drm_vmw_size base_level_size,
|
| 176 | u32 num_mip_levels,
|
| 177 | u32 num_layers,
|
| 178 | u32 num_samples)
|
| 179 | {
|
| 180 | uint64_t total_size =
|
| 181 | vmw_surface_get_serialized_size(format,
|
| 182 | base_level_size,
|
| 183 | num_mip_levels,
|
| 184 | num_layers);
|
| 185 | total_size *= max_t(u32, 1, num_samples);
|
| 186 |
|
| 187 | return min_t(uint64_t, total_size, (uint64_t)U32_MAX);
|
| 188 | }
|
| 189 |
|
| 190 | |
| 191 | * vmw_surface_get_pixel_offset - Compute the offset (in bytes) to a pixel
|
| 192 | * in an image (or volume).
|
| 193 | *
|
| 194 | * @width: The image width in pixels.
|
| 195 | * @height: The image height in pixels
|
| 196 |
|
| 197 | static inline u32
|
| 198 | vmw_surface_get_pixel_offset(SVGA3dSurfaceFormat format,
|
| 199 | u32 width, u32 height,
|
| 200 | u32 x, u32 y, u32 z)
|
| 201 | {
|
| 202 | const SVGA3dSurfaceDesc *desc = vmw_surface_get_desc(format);
|
| 203 | const u32 bw = desc->blockSize.width, bh = desc->blockSize.height;
|
| 204 | const u32 bd = desc->blockSize.depth;
|
| 205 | const u32 rowstride = __KERNEL_DIV_ROUND_UP(width, bw) *
|
| 206 | desc->bytesPerBlock;
|
| 207 | const u32 imgstride = __KERNEL_DIV_ROUND_UP(height, bh) * rowstride;
|
| 208 | const u32 offset = (z / bd * imgstride +
|
| 209 | y / bh * rowstride +
|
| 210 | x / bw * desc->bytesPerBlock);
|
| 211 | return offset;
|
| 212 | }
|
| 213 |
|
| 214 | static inline u32
|
| 215 | vmw_surface_get_image_offset(SVGA3dSurfaceFormat format,
|
| 216 | struct drm_vmw_size baseLevelSize,
|
| 217 | u32 numMipLevels,
|
| 218 | u32 face,
|
| 219 | u32 mip)
|
| 220 |
|
| 221 | {
|
| 222 | u32 offset;
|
| 223 | u32 mipChainBytes;
|
| 224 | u32 mipChainBytesToLevel;
|
| 225 | u32 i;
|
| 226 | const SVGA3dSurfaceDesc *desc;
|
| 227 | struct drm_vmw_size mipSize;
|
| 228 | u32 bytes;
|
| 229 |
|
| 230 | desc = vmw_surface_get_desc(format);
|
| 231 |
|
| 232 | mipChainBytes = 0;
|
| 233 | mipChainBytesToLevel = 0;
|
| 234 | for (i = 0; i < numMipLevels; i++) {
|
| 235 | mipSize = vmw_surface_get_mip_size(baseLevelSize, i);
|
| 236 | bytes = vmw_surface_get_image_buffer_size(desc, &mipSize, 0);
|
| 237 | mipChainBytes += bytes;
|
| 238 | if (i < mip)
|
| 239 | mipChainBytesToLevel += bytes;
|
| 240 | }
|
| 241 |
|
| 242 | offset = mipChainBytes * face + mipChainBytesToLevel;
|
| 243 |
|
| 244 | return offset;
|
| 245 | }
|
| 246 |
|
| 247 |
|
| 248 | |
| 249 | * vmw_surface_is_gb_screen_target_format - Is the specified format usable as
|
| 250 | * a ScreenTarget?
|
| 251 | * (with just the GBObjects cap-bit
|
| 252 | * set)
|
| 253 | * @format: format to queried
|
| 254 | *
|
| 255 | * RETURNS:
|
| 256 | * true if queried format is valid for screen targets
|
| 257 |
|
| 258 | static inline bool
|
| 259 | vmw_surface_is_gb_screen_target_format(SVGA3dSurfaceFormat format)
|
| 260 | {
|
| 261 | return (format == SVGA3D_X8R8G8B8 ||
|
| 262 | format == SVGA3D_A8R8G8B8 ||
|
| 263 | format == SVGA3D_R5G6B5 ||
|
| 264 | format == SVGA3D_X1R5G5B5 ||
|
| 265 | format == SVGA3D_A1R5G5B5 ||
|
| 266 | format == SVGA3D_P8);
|
| 267 | }
|
| 268 |
|
| 269 |
|
| 270 | |
| 271 | * vmw_surface_is_dx_screen_target_format - Is the specified format usable as
|
| 272 | * a ScreenTarget?
|
| 273 | * (with DX10 enabled)
|
| 274 | *
|
| 275 | * @format: format to queried
|
| 276 | *
|
| 277 | * Results:
|
| 278 | * true if queried format is valid for screen targets
|
| 279 |
|
| 280 | static inline bool
|
| 281 | vmw_surface_is_dx_screen_target_format(SVGA3dSurfaceFormat format)
|
| 282 | {
|
| 283 | return (format == SVGA3D_R8G8B8A8_UNORM ||
|
| 284 | format == SVGA3D_B8G8R8A8_UNORM ||
|
| 285 | format == SVGA3D_B8G8R8X8_UNORM);
|
| 286 | }
|
| 287 |
|
| 288 |
|
| 289 | |
| 290 | * vmw_surface_is_screen_target_format - Is the specified format usable as a
|
| 291 | * ScreenTarget?
|
| 292 | * (for some combination of caps)
|
| 293 | *
|
| 294 | * @format: format to queried
|
| 295 | *
|
| 296 | * Results:
|
| 297 | * true if queried format is valid for screen targets
|
| 298 |
|
| 299 | static inline bool
|
| 300 | vmw_surface_is_screen_target_format(SVGA3dSurfaceFormat format)
|
| 301 | {
|
| 302 | if (vmw_surface_is_gb_screen_target_format(format)) {
|
| 303 | return true;
|
| 304 | }
|
| 305 | return vmw_surface_is_dx_screen_target_format(format);
|
| 306 | }
|
| 307 |
|
| 308 | |
| 309 | * struct vmw_surface_mip - Mimpmap level information
|
| 310 | * @bytes: Bytes required in the backing store of this mipmap level.
|
| 311 | * @img_stride: Byte stride per image.
|
| 312 | * @row_stride: Byte stride per block row.
|
| 313 | * @size: The size of the mipmap.
|
| 314 |
|
| 315 | struct vmw_surface_mip {
|
| 316 | size_t bytes;
|
| 317 | size_t img_stride;
|
| 318 | size_t row_stride;
|
| 319 | struct drm_vmw_size size;
|
| 320 |
|
| 321 | };
|
| 322 |
|
| 323 | |
| 324 | * struct vmw_surface_cache - Cached surface information
|
| 325 | * @desc: Pointer to the surface descriptor
|
| 326 | * @mip: Array of mipmap level information. Valid size is @num_mip_levels.
|
| 327 | * @mip_chain_bytes: Bytes required in the backing store for the whole chain
|
| 328 | * of mip levels.
|
| 329 | * @sheet_bytes: Bytes required in the backing store for a sheet
|
| 330 | * representing a single sample.
|
| 331 | * @num_mip_levels: Valid size of the @mip array. Number of mipmap levels in
|
| 332 | * a chain.
|
| 333 | * @num_layers: Number of slices in an array texture or number of faces in
|
| 334 | * a cubemap texture.
|
| 335 |
|
| 336 | struct vmw_surface_cache {
|
| 337 | const SVGA3dSurfaceDesc *desc;
|
| 338 | struct vmw_surface_mip mip[DRM_VMW_MAX_MIP_LEVELS];
|
| 339 | size_t mip_chain_bytes;
|
| 340 | size_t sheet_bytes;
|
| 341 | u32 num_mip_levels;
|
| 342 | u32 num_layers;
|
| 343 | };
|
| 344 |
|
| 345 | |
| 346 | * struct vmw_surface_loc - Surface location
|
| 347 | * @sheet: The multisample sheet.
|
| 348 | * @sub_resource: Surface subresource. Defined as layer * num_mip_levels +
|
| 349 | * mip_level.
|
| 350 | * @x: X coordinate.
|
| 351 | * @y: Y coordinate.
|
| 352 | * @z: Z coordinate.
|
| 353 |
|
| 354 | struct vmw_surface_loc {
|
| 355 | u32 sheet;
|
| 356 | u32 sub_resource;
|
| 357 | u32 x, y, z;
|
| 358 | };
|
| 359 |
|
| 360 | |
| 361 | * vmw_surface_subres - Compute the subresource from layer and mipmap.
|
| 362 | * @cache: Surface layout data.
|
| 363 | * @mip_level: The mipmap level.
|
| 364 | * @layer: The surface layer (face or array slice).
|
| 365 | *
|
| 366 | * Return: The subresource.
|
| 367 |
|
| 368 | static inline u32 vmw_surface_subres(const struct vmw_surface_cache *cache,
|
| 369 | u32 mip_level, u32 layer)
|
| 370 | {
|
| 371 | return cache->num_mip_levels * layer + mip_level;
|
| 372 | }
|
| 373 |
|
| 374 | |
| 375 | * vmw_surface_setup_cache - Build a surface cache entry
|
| 376 | * @size: The surface base level dimensions.
|
| 377 | * @format: The surface format.
|
| 378 | * @num_mip_levels: Number of mipmap levels.
|
| 379 | * @num_layers: Number of layers.
|
| 380 | * @cache: Pointer to a struct vmw_surface_cach object to be filled in.
|
| 381 | *
|
| 382 | * Return: Zero on success, -EINVAL on invalid surface layout.
|
| 383 |
|
| 384 | static inline int vmw_surface_setup_cache(const struct drm_vmw_size *size,
|
| 385 | SVGA3dSurfaceFormat format,
|
| 386 | u32 num_mip_levels,
|
| 387 | u32 num_layers,
|
| 388 | u32 num_samples,
|
| 389 | struct vmw_surface_cache *cache)
|
| 390 | {
|
| 391 | const SVGA3dSurfaceDesc *desc;
|
| 392 | u32 i;
|
| 393 |
|
| 394 | memset(cache, 0, sizeof(*cache));
|
| 395 | cache->desc = desc = vmw_surface_get_desc(format);
|
| 396 | cache->num_mip_levels = num_mip_levels;
|
| 397 | cache->num_layers = num_layers;
|
| 398 | for (i = 0; i < cache->num_mip_levels; i++) {
|
| 399 | struct vmw_surface_mip *mip = &cache->mip[i];
|
| 400 |
|
| 401 | mip->size = vmw_surface_get_mip_size(*size, i);
|
| 402 | mip->bytes = vmw_surface_get_image_buffer_size
|
| 403 | (desc, &mip->size, 0);
|
| 404 | mip->row_stride =
|
| 405 | __KERNEL_DIV_ROUND_UP(mip->size.width,
|
| 406 | desc->blockSize.width) *
|
| 407 | desc->bytesPerBlock * num_samples;
|
| 408 | if (!mip->row_stride)
|
| 409 | goto invalid_dim;
|
| 410 |
|
| 411 | mip->img_stride =
|
| 412 | __KERNEL_DIV_ROUND_UP(mip->size.height,
|
| 413 | desc->blockSize.height) *
|
| 414 | mip->row_stride;
|
| 415 | if (!mip->img_stride)
|
| 416 | goto invalid_dim;
|
| 417 |
|
| 418 | cache->mip_chain_bytes += mip->bytes;
|
| 419 | }
|
| 420 | cache->sheet_bytes = cache->mip_chain_bytes * num_layers;
|
| 421 | if (!cache->sheet_bytes)
|
| 422 | goto invalid_dim;
|
| 423 |
|
| 424 | return 0;
|
| 425 |
|
| 426 | invalid_dim:
|
| 427 | VMW_DEBUG_USER("Invalid surface layout for dirty tracking.\n");
|
| 428 | return -EINVAL;
|
| 429 | }
|
| 430 |
|
| 431 | |
| 432 | * vmw_surface_get_loc - Get a surface location from an offset into the
|
| 433 | * backing store
|
| 434 | * @cache: Surface layout data.
|
| 435 | * @loc: Pointer to a struct vmw_surface_loc to be filled in.
|
| 436 | * @offset: Offset into the surface backing store.
|
| 437 |
|
| 438 | static inline void
|
| 439 | vmw_surface_get_loc(const struct vmw_surface_cache *cache,
|
| 440 | struct vmw_surface_loc *loc,
|
| 441 | size_t offset)
|
| 442 | {
|
| 443 | const struct vmw_surface_mip *mip = &cache->mip[0];
|
| 444 | const SVGA3dSurfaceDesc *desc = cache->desc;
|
| 445 | u32 layer;
|
| 446 | int i;
|
| 447 |
|
| 448 | loc->sheet = offset / cache->sheet_bytes;
|
| 449 | offset -= loc->sheet * cache->sheet_bytes;
|
| 450 |
|
| 451 | layer = offset / cache->mip_chain_bytes;
|
| 452 | offset -= layer * cache->mip_chain_bytes;
|
| 453 | for (i = 0; i < cache->num_mip_levels; ++i, ++mip) {
|
| 454 | if (mip->bytes > offset)
|
| 455 | break;
|
| 456 | offset -= mip->bytes;
|
| 457 | }
|
| 458 |
|
| 459 | loc->sub_resource = vmw_surface_subres(cache, i, layer);
|
| 460 | loc->z = offset / mip->img_stride;
|
| 461 | offset -= loc->z * mip->img_stride;
|
| 462 | loc->z *= desc->blockSize.depth;
|
| 463 | loc->y = offset / mip->row_stride;
|
| 464 | offset -= loc->y * mip->row_stride;
|
| 465 | loc->y *= desc->blockSize.height;
|
| 466 | loc->x = offset / desc->bytesPerBlock;
|
| 467 | loc->x *= desc->blockSize.width;
|
| 468 | }
|
| 469 |
|
| 470 | |
| 471 | * vmw_surface_inc_loc - Clamp increment a surface location with one block
|
| 472 | * size
|
| 473 | * in each dimension.
|
| 474 | * @loc: Pointer to a struct vmw_surface_loc to be incremented.
|
| 475 | *
|
| 476 | * When computing the size of a range as size = end - start, the range does not
|
| 477 | * include the end element. However a location representing the last byte
|
| 478 | * of a touched region in the backing store *is* included in the range.
|
| 479 | * This function modifies such a location to match the end definition
|
| 480 | * given as start + size which is the one used in a SVGA3dBox.
|
| 481 |
|
| 482 | static inline void
|
| 483 | vmw_surface_inc_loc(const struct vmw_surface_cache *cache,
|
| 484 | struct vmw_surface_loc *loc)
|
| 485 | {
|
| 486 | const SVGA3dSurfaceDesc *desc = cache->desc;
|
| 487 | u32 mip = loc->sub_resource % cache->num_mip_levels;
|
| 488 | const struct drm_vmw_size *size = &cache->mip[mip].size;
|
| 489 |
|
| 490 | loc->sub_resource++;
|
| 491 | loc->x += desc->blockSize.width;
|
| 492 | if (loc->x > size->width)
|
| 493 | loc->x = size->width;
|
| 494 | loc->y += desc->blockSize.height;
|
| 495 | if (loc->y > size->height)
|
| 496 | loc->y = size->height;
|
| 497 | loc->z += desc->blockSize.depth;
|
| 498 | if (loc->z > size->depth)
|
| 499 | loc->z = size->depth;
|
| 500 | }
|
| 501 |
|
| 502 | |
| 503 | * vmw_surface_min_loc - The start location in a subresource
|
| 504 | * @cache: Surface layout data.
|
| 505 | * @sub_resource: The subresource.
|
| 506 | * @loc: Pointer to a struct vmw_surface_loc to be filled in.
|
| 507 |
|
| 508 | static inline void
|
| 509 | vmw_surface_min_loc(const struct vmw_surface_cache *cache,
|
| 510 | u32 sub_resource,
|
| 511 | struct vmw_surface_loc *loc)
|
| 512 | {
|
| 513 | loc->sheet = 0;
|
| 514 | loc->sub_resource = sub_resource;
|
| 515 | loc->x = loc->y = loc->z = 0;
|
| 516 | }
|
| 517 |
|
| 518 | |
| 519 | * vmw_surface_min_loc - The end location in a subresource
|
| 520 | * @cache: Surface layout data.
|
| 521 | * @sub_resource: The subresource.
|
| 522 | * @loc: Pointer to a struct vmw_surface_loc to be filled in.
|
| 523 | *
|
| 524 | * Following the end definition given in vmw_surface_inc_loc(),
|
| 525 | * Compute the end location of a surface subresource.
|
| 526 |
|
| 527 | static inline void
|
| 528 | vmw_surface_max_loc(const struct vmw_surface_cache *cache,
|
| 529 | u32 sub_resource,
|
| 530 | struct vmw_surface_loc *loc)
|
| 531 | {
|
| 532 | const struct drm_vmw_size *size;
|
| 533 | u32 mip;
|
| 534 |
|
| 535 | loc->sheet = 0;
|
| 536 | loc->sub_resource = sub_resource + 1;
|
| 537 | mip = sub_resource % cache->num_mip_levels;
|
| 538 | size = &cache->mip[mip].size;
|
| 539 | loc->x = size->width;
|
| 540 | loc->y = size->height;
|
| 541 | loc->z = size->depth;
|
| 542 | }
|
| 543 |
|
| 544 |
|
| 545 | #endif
|