Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/swr/rasterizer/memory/TilingFunctions.h
4574 views
1
/****************************************************************************
2
* Copyright (C) 2014-2015 Intel Corporation. All Rights Reserved.
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* IN THE SOFTWARE.
22
*
23
* @file TilingFunctions.h
24
*
25
* @brief Tiling functions.
26
*
27
******************************************************************************/
28
#pragma once
29
30
#include "core/state.h"
31
#include "core/format_traits.h"
32
#include "memory/tilingtraits.h"
33
#include "memory/SurfaceState.h"
34
35
#include <algorithm>
36
37
#define MAX_NUM_LOD 15
38
39
#define GFX_ALIGN(x, a) (((x) + ((a) - 1)) - (((x) + ((a) - 1)) & ((a) - 1))) // Alt implementation with bitwise not (~) has issue with uint32 align used with 64-bit value, since ~'ed value will remain 32-bit.
40
41
//////////////////////////////////////////////////////////////////////////
42
/// SimdTile SSE(2x2), AVX(4x2), or AVX-512(4x4?)
43
//////////////////////////////////////////////////////////////////////////
44
template<SWR_FORMAT HotTileFormat, SWR_FORMAT SrcOrDstFormat>
45
struct SimdTile
46
{
47
// SimdTile is SOA (e.g. rrrrrrrr gggggggg bbbbbbbb aaaaaaaa )
48
float color[FormatTraits<HotTileFormat>::numComps][KNOB_SIMD_WIDTH];
49
50
//////////////////////////////////////////////////////////////////////////
51
/// @brief Retrieve color from simd.
52
/// @param index - linear index to color within simd.
53
/// @param outputColor - output color
54
INLINE void GetSwizzledColor(
55
uint32_t index,
56
float outputColor[4])
57
{
58
// SOA pattern for 2x2 is a subset of 4x2.
59
// 0 1 4 5
60
// 2 3 6 7
61
// The offset converts pattern to linear
62
#if (SIMD_TILE_X_DIM == 4)
63
static const uint32_t offset[] = { 0, 1, 4, 5, 2, 3, 6, 7 };
64
#elif (SIMD_TILE_X_DIM == 2)
65
static const uint32_t offset[] = { 0, 1, 2, 3 };
66
#endif
67
68
for (uint32_t i = 0; i < FormatTraits<SrcOrDstFormat>::numComps; ++i)
69
{
70
outputColor[i] = this->color[FormatTraits<SrcOrDstFormat>::swizzle(i)][offset[index]];
71
}
72
}
73
74
//////////////////////////////////////////////////////////////////////////
75
/// @brief Retrieve color from simd.
76
/// @param index - linear index to color within simd.
77
/// @param outputColor - output color
78
INLINE void SetSwizzledColor(
79
uint32_t index,
80
const float src[4])
81
{
82
// SOA pattern for 2x2 is a subset of 4x2.
83
// 0 1 4 5
84
// 2 3 6 7
85
// The offset converts pattern to linear
86
#if (SIMD_TILE_X_DIM == 4)
87
static const uint32_t offset[] = { 0, 1, 4, 5, 2, 3, 6, 7 };
88
#elif (SIMD_TILE_X_DIM == 2)
89
static const uint32_t offset[] = { 0, 1, 2, 3 };
90
#endif
91
92
// Only loop over the components needed for destination.
93
for (uint32_t i = 0; i < FormatTraits<SrcOrDstFormat>::numComps; ++i)
94
{
95
this->color[i][offset[index]] = src[i];
96
}
97
}
98
};
99
100
template<>
101
struct SimdTile <R8_UINT,R8_UINT>
102
{
103
// SimdTile is SOA (e.g. rrrrrrrr gggggggg bbbbbbbb aaaaaaaa )
104
uint8_t color[FormatTraits<R8_UINT>::numComps][KNOB_SIMD_WIDTH];
105
106
//////////////////////////////////////////////////////////////////////////
107
/// @brief Retrieve color from simd.
108
/// @param index - linear index to color within simd.
109
/// @param outputColor - output color
110
INLINE void GetSwizzledColor(
111
uint32_t index,
112
float outputColor[4])
113
{
114
// SOA pattern for 2x2 is a subset of 4x2.
115
// 0 1 4 5
116
// 2 3 6 7
117
// The offset converts pattern to linear
118
#if (SIMD_TILE_X_DIM == 4)
119
static const uint32_t offset[] = { 0, 1, 4, 5, 2, 3, 6, 7 };
120
#elif (SIMD_TILE_X_DIM == 2)
121
static const uint32_t offset[] = { 0, 1, 2, 3 };
122
#endif
123
124
for (uint32_t i = 0; i < FormatTraits<R8_UINT>::numComps; ++i)
125
{
126
uint32_t src = this->color[FormatTraits<R8_UINT>::swizzle(i)][offset[index]];
127
outputColor[i] = *(float*)&src;
128
}
129
}
130
131
//////////////////////////////////////////////////////////////////////////
132
/// @brief Retrieve color from simd.
133
/// @param index - linear index to color within simd.
134
/// @param outputColor - output color
135
INLINE void SetSwizzledColor(
136
uint32_t index,
137
const float src[4])
138
{
139
// SOA pattern for 2x2 is a subset of 4x2.
140
// 0 1 4 5
141
// 2 3 6 7
142
// The offset converts pattern to linear
143
#if (SIMD_TILE_X_DIM == 4)
144
static const uint32_t offset[] = { 0, 1, 4, 5, 2, 3, 6, 7 };
145
#elif (SIMD_TILE_X_DIM == 2)
146
static const uint32_t offset[] = { 0, 1, 2, 3 };
147
#endif
148
149
// Only loop over the components needed for destination.
150
for (uint32_t i = 0; i < FormatTraits<R8_UINT>::numComps; ++i)
151
{
152
this->color[i][offset[index]] = *(uint8_t*)&src[i];
153
}
154
}
155
};
156
157
//////////////////////////////////////////////////////////////////////////
158
/// SimdTile 8x2 for AVX-512
159
//////////////////////////////////////////////////////////////////////////
160
161
template<SWR_FORMAT HotTileFormat, SWR_FORMAT SrcOrDstFormat>
162
struct SimdTile_16
163
{
164
// SimdTile is SOA (e.g. rrrrrrrrrrrrrrrr gggggggggggggggg bbbbbbbbbbbbbbbb aaaaaaaaaaaaaaaa )
165
float color[FormatTraits<HotTileFormat>::numComps][KNOB_SIMD16_WIDTH];
166
167
//////////////////////////////////////////////////////////////////////////
168
/// @brief Retrieve color from simd.
169
/// @param index - linear index to color within simd.
170
/// @param outputColor - output color
171
INLINE void GetSwizzledColor(
172
uint32_t index,
173
float outputColor[4])
174
{
175
// SOA pattern for 8x2..
176
// 0 1 4 5 8 9 C D
177
// 2 3 6 7 A B E F
178
// The offset converts pattern to linear
179
static const uint32_t offset[KNOB_SIMD16_WIDTH] = { 0, 1, 4, 5, 8, 9, 12, 13, 2, 3, 6, 7, 10, 11, 14, 15 };
180
181
for (uint32_t i = 0; i < FormatTraits<SrcOrDstFormat>::numComps; ++i)
182
{
183
outputColor[i] = this->color[FormatTraits<SrcOrDstFormat>::swizzle(i)][offset[index]];
184
}
185
}
186
187
//////////////////////////////////////////////////////////////////////////
188
/// @brief Retrieve color from simd.
189
/// @param index - linear index to color within simd.
190
/// @param outputColor - output color
191
INLINE void SetSwizzledColor(
192
uint32_t index,
193
const float src[4])
194
{
195
// SOA pattern for 8x2..
196
// 0 1 4 5 8 9 C D
197
// 2 3 6 7 A B E F
198
// The offset converts pattern to linear
199
static const uint32_t offset[KNOB_SIMD16_WIDTH] = { 0, 1, 4, 5, 8, 9, 12, 13, 2, 3, 6, 7, 10, 11, 14, 15 };
200
201
for (uint32_t i = 0; i < FormatTraits<SrcOrDstFormat>::numComps; ++i)
202
{
203
this->color[i][offset[index]] = src[i];
204
}
205
}
206
};
207
208
template<>
209
struct SimdTile_16 <R8_UINT, R8_UINT>
210
{
211
// SimdTile is SOA (e.g. rrrrrrrrrrrrrrrr gggggggggggggggg bbbbbbbbbbbbbbbb aaaaaaaaaaaaaaaa )
212
uint8_t color[FormatTraits<R8_UINT>::numComps][KNOB_SIMD16_WIDTH];
213
214
//////////////////////////////////////////////////////////////////////////
215
/// @brief Retrieve color from simd.
216
/// @param index - linear index to color within simd.
217
/// @param outputColor - output color
218
INLINE void GetSwizzledColor(
219
uint32_t index,
220
float outputColor[4])
221
{
222
// SOA pattern for 8x2..
223
// 0 1 4 5 8 9 C D
224
// 2 3 6 7 A B E F
225
// The offset converts pattern to linear
226
static const uint32_t offset[KNOB_SIMD16_WIDTH] = { 0, 1, 4, 5, 8, 9, 12, 13, 2, 3, 6, 7, 10, 11, 14, 15 };
227
228
for (uint32_t i = 0; i < FormatTraits<R8_UINT>::numComps; ++i)
229
{
230
uint32_t src = this->color[FormatTraits<R8_UINT>::swizzle(i)][offset[index]];
231
outputColor[i] = *(float*)&src;
232
}
233
}
234
235
//////////////////////////////////////////////////////////////////////////
236
/// @brief Retrieve color from simd.
237
/// @param index - linear index to color within simd.
238
/// @param outputColor - output color
239
INLINE void SetSwizzledColor(
240
uint32_t index,
241
const float src[4])
242
{
243
// SOA pattern for 8x2..
244
// 0 1 4 5 8 9 C D
245
// 2 3 6 7 A B E F
246
// The offset converts pattern to linear
247
static const uint32_t offset[KNOB_SIMD16_WIDTH] = { 0, 1, 4, 5, 8, 9, 12, 13, 2, 3, 6, 7, 10, 11, 14, 15 };
248
249
for (uint32_t i = 0; i < FormatTraits<R8_UINT>::numComps; ++i)
250
{
251
this->color[i][offset[index]] = *(uint8_t*)&src[i];
252
}
253
}
254
};
255
256
//////////////////////////////////////////////////////////////////////////
257
/// @brief Computes lod offset for 1D surface at specified lod.
258
/// @param baseWidth - width of basemip (mip 0).
259
/// @param hAlign - horizontal alignment per miip, in texels
260
/// @param lod - lod index
261
/// @param offset - output offset.
262
INLINE void ComputeLODOffset1D(
263
const SWR_FORMAT_INFO& info,
264
uint32_t baseWidth,
265
uint32_t hAlign,
266
uint32_t lod,
267
uint32_t &offset)
268
{
269
if (lod == 0)
270
{
271
offset = 0;
272
}
273
else
274
{
275
uint32_t curWidth = baseWidth;
276
// @note hAlign is already in blocks for compressed formats so upconvert
277
// so that we have the desired alignment post-divide.
278
if (info.isBC)
279
{
280
hAlign *= info.bcWidth;
281
}
282
283
offset = GFX_ALIGN(curWidth, hAlign);
284
for (uint32_t l = 1; l < lod; ++l)
285
{
286
curWidth = std::max<uint32_t>(curWidth >> 1, 1U);
287
offset += GFX_ALIGN(curWidth, hAlign);
288
}
289
290
if (info.isSubsampled || info.isBC)
291
{
292
offset /= info.bcWidth;
293
}
294
}
295
}
296
297
//////////////////////////////////////////////////////////////////////////
298
/// @brief Computes x lod offset for 2D surface at specified lod.
299
/// @param baseWidth - width of basemip (mip 0).
300
/// @param hAlign - horizontal alignment per mip, in texels
301
/// @param lod - lod index
302
/// @param offset - output offset.
303
INLINE void ComputeLODOffsetX(
304
const SWR_FORMAT_INFO& info,
305
uint32_t baseWidth,
306
uint32_t hAlign,
307
uint32_t lod,
308
uint32_t &offset)
309
{
310
if (lod < 2)
311
{
312
offset = 0;
313
}
314
else
315
{
316
uint32_t curWidth = baseWidth;
317
// @note hAlign is already in blocks for compressed formats so upconvert
318
// so that we have the desired alignment post-divide.
319
if (info.isBC)
320
{
321
hAlign *= info.bcWidth;
322
}
323
324
curWidth = std::max<uint32_t>(curWidth >> 1, 1U);
325
curWidth = GFX_ALIGN(curWidth, hAlign);
326
327
if (info.isSubsampled || info.isBC)
328
{
329
curWidth /= info.bcWidth;
330
}
331
332
offset = curWidth;
333
}
334
}
335
336
//////////////////////////////////////////////////////////////////////////
337
/// @brief Computes y lod offset for 2D surface at specified lod.
338
/// @param baseWidth - width of basemip (mip 0).
339
/// @param vAlign - vertical alignment per mip, in rows
340
/// @param lod - lod index
341
/// @param offset - output offset.
342
INLINE void ComputeLODOffsetY(
343
const SWR_FORMAT_INFO& info,
344
uint32_t baseHeight,
345
uint32_t vAlign,
346
uint32_t lod,
347
uint32_t &offset)
348
{
349
if (lod == 0)
350
{
351
offset = 0;
352
}
353
else
354
{
355
offset = 0;
356
uint32_t mipHeight = baseHeight;
357
358
// @note vAlign is already in blocks for compressed formats so upconvert
359
// so that we have the desired alignment post-divide.
360
if (info.isBC)
361
{
362
vAlign *= info.bcHeight;
363
}
364
365
for (uint32_t l = 1; l <= lod; ++l)
366
{
367
uint32_t alignedMipHeight = GFX_ALIGN(mipHeight, vAlign);
368
offset += ((l != 2) ? alignedMipHeight : 0);
369
mipHeight = std::max<uint32_t>(mipHeight >> 1, 1U);
370
}
371
372
if (info.isBC)
373
{
374
offset /= info.bcHeight;
375
}
376
}
377
}
378
379
//////////////////////////////////////////////////////////////////////////
380
/// @brief Computes 1D surface offset
381
/// @param x - offset from start of array slice at given lod.
382
/// @param array - array slice index
383
/// @param lod - lod index
384
/// @param pState - surface state
385
/// @param xOffsetBytes - output offset in bytes.
386
template<bool UseCachedOffsets>
387
INLINE void ComputeSurfaceOffset1D(
388
uint32_t x,
389
uint32_t array,
390
uint32_t lod,
391
const SWR_SURFACE_STATE *pState,
392
uint32_t &xOffsetBytes)
393
{
394
const SWR_FORMAT_INFO &info = GetFormatInfo(pState->format);
395
uint32_t lodOffset;
396
397
if (UseCachedOffsets)
398
{
399
lodOffset = pState->lodOffsets[0][lod];
400
}
401
else
402
{
403
ComputeLODOffset1D(info, pState->width, pState->halign, lod, lodOffset);
404
}
405
406
xOffsetBytes = (array * pState->qpitch + lodOffset + x) * info.Bpp;
407
}
408
409
//////////////////////////////////////////////////////////////////////////
410
/// @brief Adjusts the array slice for legacy TileY MSAA
411
/// @param pState - surface state
412
/// @param array - array slice index
413
/// @param sampleNum - requested sample
414
INLINE void AdjustCoordsForMSAA(const SWR_SURFACE_STATE *pState, uint32_t& x, uint32_t& y, uint32_t& arrayIndex, uint32_t sampleNum)
415
{
416
/// @todo: might want to templatize adjusting for sample slices when we support tileYS/tileYF.
417
if((pState->tileMode == SWR_TILE_MODE_YMAJOR ||
418
pState->tileMode == SWR_TILE_MODE_WMAJOR) &&
419
pState->bInterleavedSamples)
420
{
421
uint32_t newX, newY, newSampleX, newSampleY;
422
switch(pState->numSamples)
423
{
424
case 1:
425
newX = x;
426
newY = y;
427
newSampleX = newSampleY = 0;
428
break;
429
case 2:
430
{
431
assert(pState->type == SURFACE_2D);
432
static const uint32_t xMask = 0xFFFFFFFD;
433
static const uint32_t sampleMaskX = 0x1;
434
newX = pdep_u32(x, xMask);
435
newY = y;
436
newSampleX = pext_u32(sampleNum, sampleMaskX);
437
newSampleY = 0;
438
}
439
break;
440
case 4:
441
{
442
assert(pState->type == SURFACE_2D);
443
static const uint32_t mask = 0xFFFFFFFD;
444
static const uint32_t sampleMaskX = 0x1;
445
static const uint32_t sampleMaskY = 0x2;
446
newX = pdep_u32(x, mask);
447
newY = pdep_u32(y, mask);
448
newSampleX = pext_u32(sampleNum, sampleMaskX);
449
newSampleY = pext_u32(sampleNum, sampleMaskY);
450
}
451
break;
452
case 8:
453
{
454
assert(pState->type == SURFACE_2D);
455
static const uint32_t xMask = 0xFFFFFFF9;
456
static const uint32_t yMask = 0xFFFFFFFD;
457
static const uint32_t sampleMaskX = 0x5;
458
static const uint32_t sampleMaskY = 0x2;
459
newX = pdep_u32(x, xMask);
460
newY = pdep_u32(y, yMask);
461
newSampleX = pext_u32(sampleNum, sampleMaskX);
462
newSampleY = pext_u32(sampleNum, sampleMaskY);
463
}
464
break;
465
case 16:
466
{
467
assert(pState->type == SURFACE_2D);
468
static const uint32_t mask = 0xFFFFFFF9;
469
static const uint32_t sampleMaskX = 0x5;
470
static const uint32_t sampleMaskY = 0xA;
471
newX = pdep_u32(x, mask);
472
newY = pdep_u32(y, mask);
473
newSampleX = pext_u32(sampleNum, sampleMaskX);
474
newSampleY = pext_u32(sampleNum, sampleMaskY);
475
}
476
break;
477
default:
478
assert(0 && "Unsupported sample count");
479
newX = newY = 0;
480
newSampleX = newSampleY = 0;
481
break;
482
}
483
x = newX | (newSampleX << 1);
484
y = newY | (newSampleY << 1);
485
}
486
else if(pState->tileMode == SWR_TILE_MODE_YMAJOR ||
487
pState->tileMode == SWR_TILE_NONE)
488
{
489
uint32_t sampleShift;
490
switch(pState->numSamples)
491
{
492
case 1:
493
assert(sampleNum == 0);
494
sampleShift = 0;
495
break;
496
case 2:
497
assert(pState->type == SURFACE_2D);
498
sampleShift = 1;
499
break;
500
case 4:
501
assert(pState->type == SURFACE_2D);
502
sampleShift = 2;
503
break;
504
case 8:
505
assert(pState->type == SURFACE_2D);
506
sampleShift = 3;
507
break;
508
case 16:
509
assert(pState->type == SURFACE_2D);
510
sampleShift = 4;
511
break;
512
default:
513
assert(0 && "Unsupported sample count");
514
sampleShift = 0;
515
break;
516
}
517
arrayIndex = (arrayIndex << sampleShift) | sampleNum;
518
}
519
}
520
521
//////////////////////////////////////////////////////////////////////////
522
/// @brief Computes 2D surface offset
523
/// @param x - horizontal offset from start of array slice and lod.
524
/// @param y - vertical offset from start of array slice and lod.
525
/// @param array - array slice index
526
/// @param lod - lod index
527
/// @param pState - surface state
528
/// @param xOffsetBytes - output x offset in bytes.
529
/// @param yOffsetRows - output y offset in bytes.
530
template<bool UseCachedOffsets>
531
INLINE void ComputeSurfaceOffset2D(uint32_t x, uint32_t y, uint32_t array, uint32_t sampleNum, uint32_t lod, const SWR_SURFACE_STATE *pState, uint32_t &xOffsetBytes, uint32_t &yOffsetRows)
532
{
533
const SWR_FORMAT_INFO &info = GetFormatInfo(pState->format);
534
uint32_t lodOffsetX, lodOffsetY;
535
536
if (UseCachedOffsets)
537
{
538
lodOffsetX = pState->lodOffsets[0][lod];
539
lodOffsetY = pState->lodOffsets[1][lod];
540
}
541
else
542
{
543
ComputeLODOffsetX(info, pState->width, pState->halign, lod, lodOffsetX);
544
ComputeLODOffsetY(info, pState->height, pState->valign, lod, lodOffsetY);
545
}
546
547
AdjustCoordsForMSAA(pState, x, y, array, sampleNum);
548
xOffsetBytes = (x + lodOffsetX + pState->xOffset) * info.Bpp;
549
yOffsetRows = (array * pState->qpitch) + lodOffsetY + y + pState->yOffset;
550
}
551
552
//////////////////////////////////////////////////////////////////////////
553
/// @brief Computes 3D surface offset
554
/// @param x - horizontal offset from start of array slice and lod.
555
/// @param y - vertical offset from start of array slice and lod.
556
/// @param z - depth offset from start of array slice and lod.
557
/// @param lod - lod index
558
/// @param pState - surface state
559
/// @param xOffsetBytes - output x offset in bytes.
560
/// @param yOffsetRows - output y offset in rows.
561
/// @param zOffsetSlices - output y offset in slices.
562
template<bool UseCachedOffsets>
563
INLINE void ComputeSurfaceOffset3D(uint32_t x, uint32_t y, uint32_t z, uint32_t lod, const SWR_SURFACE_STATE *pState, uint32_t &xOffsetBytes, uint32_t &yOffsetRows, uint32_t &zOffsetSlices)
564
{
565
const SWR_FORMAT_INFO &info = GetFormatInfo(pState->format);
566
uint32_t lodOffsetX, lodOffsetY;
567
568
if (UseCachedOffsets)
569
{
570
lodOffsetX = pState->lodOffsets[0][lod];
571
lodOffsetY = pState->lodOffsets[1][lod];
572
}
573
else
574
{
575
ComputeLODOffsetX(info, pState->width, pState->halign, lod, lodOffsetX);
576
ComputeLODOffsetY(info, pState->height, pState->valign, lod, lodOffsetY);
577
}
578
579
xOffsetBytes = (x + lodOffsetX) * info.Bpp;
580
yOffsetRows = lodOffsetY + y;
581
zOffsetSlices = z;
582
}
583
584
//////////////////////////////////////////////////////////////////////////
585
/// @brief Swizzles the linear x,y offsets depending on surface tiling mode
586
/// and returns final surface address
587
/// @param xOffsetBytes - x offset from base of surface in bytes
588
/// @param yOffsetRows - y offset from base of surface in rows
589
/// @param pState - pointer to the surface state
590
template<typename TTraits>
591
INLINE uint32_t ComputeTileSwizzle2D(uint32_t xOffsetBytes, uint32_t yOffsetRows, const SWR_SURFACE_STATE *pState)
592
{
593
return ComputeOffset2D<TTraits>(pState->pitch, xOffsetBytes, yOffsetRows);
594
}
595
596
//////////////////////////////////////////////////////////////////////////
597
/// @brief Swizzles the linear x,y offsets depending on surface tiling mode
598
/// and returns final surface address
599
/// @param xOffsetBytes - x offset from base of surface in bytes
600
/// @param yOffsetRows - y offset from base of surface in rows
601
/// @param pState - pointer to the surface state
602
template<typename TTraits>
603
INLINE uint32_t ComputeTileSwizzle3D(uint32_t xOffsetBytes, uint32_t yOffsetRows, uint32_t zOffsetSlices, const SWR_SURFACE_STATE *pState)
604
{
605
return ComputeOffset3D<TTraits>(pState->qpitch, pState->pitch, xOffsetBytes, yOffsetRows, zOffsetSlices);
606
}
607
608
//////////////////////////////////////////////////////////////////////////
609
/// @brief Swizzles the linear x,y offsets depending on surface tiling mode
610
/// and returns final surface address
611
/// @param xOffsetBytes - x offset from base of surface in bytes
612
/// @param yOffsetRows - y offset from base of surface in rows
613
/// @param pState - pointer to the surface state
614
INLINE
615
uint32_t TileSwizzle2D(uint32_t xOffsetBytes, uint32_t yOffsetRows, const SWR_SURFACE_STATE *pState)
616
{
617
switch (pState->tileMode)
618
{
619
case SWR_TILE_NONE: return ComputeTileSwizzle2D<TilingTraits<SWR_TILE_NONE, 32> >(xOffsetBytes, yOffsetRows, pState);
620
case SWR_TILE_SWRZ: return ComputeTileSwizzle2D<TilingTraits<SWR_TILE_SWRZ, 32> >(xOffsetBytes, yOffsetRows, pState);
621
case SWR_TILE_MODE_XMAJOR: return ComputeTileSwizzle2D<TilingTraits<SWR_TILE_MODE_XMAJOR, 8> >(xOffsetBytes, yOffsetRows, pState);
622
case SWR_TILE_MODE_YMAJOR: return ComputeTileSwizzle2D<TilingTraits<SWR_TILE_MODE_YMAJOR, 32> >(xOffsetBytes, yOffsetRows, pState);
623
case SWR_TILE_MODE_WMAJOR: return ComputeTileSwizzle2D<TilingTraits<SWR_TILE_MODE_WMAJOR, 8> >(xOffsetBytes, yOffsetRows, pState);
624
default: SWR_INVALID("Unsupported tiling mode");
625
}
626
return 0;
627
}
628
629
//////////////////////////////////////////////////////////////////////////
630
/// @brief Swizzles the linear x,y,z offsets depending on surface tiling mode
631
/// and returns final surface address
632
/// @param xOffsetBytes - x offset from base of surface in bytes
633
/// @param yOffsetRows - y offset from base of surface in rows
634
/// @param zOffsetSlices - z offset from base of surface in slices
635
/// @param pState - pointer to the surface state
636
INLINE
637
uint32_t TileSwizzle3D(uint32_t xOffsetBytes, uint32_t yOffsetRows, uint32_t zOffsetSlices, const SWR_SURFACE_STATE *pState)
638
{
639
switch (pState->tileMode)
640
{
641
case SWR_TILE_NONE: return ComputeTileSwizzle3D<TilingTraits<SWR_TILE_NONE, 32> >(xOffsetBytes, yOffsetRows, zOffsetSlices, pState);
642
case SWR_TILE_SWRZ: return ComputeTileSwizzle3D<TilingTraits<SWR_TILE_SWRZ, 32> >(xOffsetBytes, yOffsetRows, zOffsetSlices, pState);
643
case SWR_TILE_MODE_YMAJOR: return ComputeTileSwizzle3D<TilingTraits<SWR_TILE_MODE_YMAJOR, 32> >(xOffsetBytes, yOffsetRows, zOffsetSlices, pState);
644
default: SWR_INVALID("Unsupported tiling mode");
645
}
646
return 0;
647
}
648
649
template<bool UseCachedOffsets>
650
INLINE
651
uint32_t ComputeSurfaceOffset(uint32_t x, uint32_t y, uint32_t z, uint32_t array, uint32_t sampleNum, uint32_t lod, const SWR_SURFACE_STATE *pState)
652
{
653
uint32_t offsetX = 0, offsetY = 0, offsetZ = 0;
654
switch (pState->type)
655
{
656
case SURFACE_BUFFER:
657
case SURFACE_STRUCTURED_BUFFER:
658
offsetX = x * pState->pitch;
659
return offsetX;
660
break;
661
case SURFACE_1D:
662
ComputeSurfaceOffset1D<UseCachedOffsets>(x, array, lod, pState, offsetX);
663
return TileSwizzle2D(offsetX, 0, pState);
664
break;
665
case SURFACE_2D:
666
ComputeSurfaceOffset2D<UseCachedOffsets>(x, y, array, sampleNum, lod, pState, offsetX, offsetY);
667
return TileSwizzle2D(offsetX, offsetY, pState);
668
case SURFACE_3D:
669
ComputeSurfaceOffset3D<UseCachedOffsets>(x, y, z, lod, pState, offsetX, offsetY, offsetZ);
670
return TileSwizzle3D(offsetX, offsetY, offsetZ, pState);
671
break;
672
case SURFACE_CUBE:
673
ComputeSurfaceOffset2D<UseCachedOffsets>(x, y, array, sampleNum, lod, pState, offsetX, offsetY);
674
return TileSwizzle2D(offsetX, offsetY, pState);
675
break;
676
default: SWR_INVALID("Unsupported format");
677
}
678
679
return 0;
680
}
681
682
typedef void*(*PFN_COMPUTESURFADDR)(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, const SWR_SURFACE_STATE*);
683
684
//////////////////////////////////////////////////////////////////////////
685
/// @brief Computes surface address at the given location and lod
686
/// @param x - x location in pixels
687
/// @param y - y location in rows
688
/// @param z - z location for 3D surfaces
689
/// @param array - array slice for 1D and 2D surfaces
690
/// @param lod - level of detail
691
/// @param pState - pointer to the surface state
692
template<bool UseCachedOffsets, bool IsRead>
693
INLINE
694
void* ComputeSurfaceAddress(uint32_t x, uint32_t y, uint32_t z, uint32_t array, uint32_t sampleNum, uint32_t lod, const SWR_SURFACE_STATE *pState)
695
{
696
return (void*)(pState->xpBaseAddress + ComputeSurfaceOffset<UseCachedOffsets>(x, y, z, array, sampleNum, lod, pState));
697
}
698
699