1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2017 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the 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
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #ifndef __NVIDIA_3D_TYPES_H__
25 #define __NVIDIA_3D_TYPES_H__
26 
27 
28 #include "nvtypes.h"
29 #include "nvlimits.h"
30 #include "nvidia-push-methods.h"
31 
32 #include "nvidia-3d-shaders.h"
33 
34 enum Nv3dBlendOperation {
35     NV3D_BLEND_OP_CLEAR,
36     NV3D_BLEND_OP_SRC,
37     NV3D_BLEND_OP_DST,
38     NV3D_BLEND_OP_OVER,
39     NV3D_BLEND_OP_OVER_REVERSE,
40     NV3D_BLEND_OP_IN,
41     NV3D_BLEND_OP_IN_REVERSE,
42     NV3D_BLEND_OP_OUT,
43     NV3D_BLEND_OP_OUT_REVERSE,
44     NV3D_BLEND_OP_ATOP,
45     NV3D_BLEND_OP_ATOP_REVERSE,
46     NV3D_BLEND_OP_XOR,
47     NV3D_BLEND_OP_ADD,
48     NV3D_BLEND_OP_SATURATE,
49 };
50 
51 // We use two vertex streams: one for static attributes (values that are the
52 // same for all vertices) and one for dynamic attributes.
53 enum Nv3dVertexAttributeStreamType {
54     NV3D_VERTEX_ATTRIBUTE_STREAM_FIRST   = 0,
55     NV3D_VERTEX_ATTRIBUTE_STREAM_STATIC  = 0,
56     NV3D_VERTEX_ATTRIBUTE_STREAM_DYNAMIC = 1,
57     NV3D_VERTEX_ATTRIBUTE_STREAM_COUNT,
58 } __attribute__ ((__packed__));
59 
60 /* The data type of a vertex attribute. */
61 /* Names of enum Nv3dVertexAttributeDataType members follow
62  * "NV3D_VERTEX_ATTRIBUTE_DATA_TYPE_{N_elements}_{element_size}_{NUMERICAL_TYPE}" convention
63  * where {NUMERICAL_TYPE} gives information about NV9097_SET_VERTEX_ATTRIBUTE_A_NUMERICAL_TYPE
64  */
65 enum Nv3dVertexAttributeDataType {
66     NV3D_VERTEX_ATTRIBUTE_DATA_TYPE_2_32_FLOAT,  /* two floats */
67     NV3D_VERTEX_ATTRIBUTE_DATA_TYPE_4_32_FLOAT,  /* four floats */
68     NV3D_VERTEX_ATTRIBUTE_DATA_TYPE_4_16_UNORM,  /* four unsigned shorts mapped to floats: [0,65535] => [0.0f,1.0f] */
69     NV3D_VERTEX_ATTRIBUTE_DATA_TYPE_4_8_UNORM,   /* four unsigned bytes mapped to floats: [0,255] => [0.0f,1.0f] */
70     NV3D_VERTEX_ATTRIBUTE_DATA_TYPE_2_16_SSCALED,/* two shorts mapped to floats: [-32768,32767] => [-32768.0f,32767.0f] */
71 } __attribute__ ((__packed__));
72 
73 /* The possible vertex attributes. */
74 enum Nv3dVertexAttributeType {
75     NV3D_VERTEX_ATTRIBUTE_POSITION        = 0,
76     NV3D_VERTEX_ATTRIBUTE_VERTEX_WEIGHT   = 1,
77     NV3D_VERTEX_ATTRIBUTE_NORMAL          = 2,
78     NV3D_VERTEX_ATTRIBUTE_COLOR           = 3,
79     NV3D_VERTEX_ATTRIBUTE_SECONDARY_COLOR = 4,
80     NV3D_VERTEX_ATTRIBUTE_FOG_COORD       = 5,
81     NV3D_VERTEX_ATTRIBUTE_POINT_SIZE      = 6,
82     NV3D_VERTEX_ATTRIBUTE_MATRIX_INDEX    = 7,
83     NV3D_VERTEX_ATTRIBUTE_TEXCOORD0       = 8,
84     NV3D_VERTEX_ATTRIBUTE_TEXCOORD1       = 9,
85     NV3D_VERTEX_ATTRIBUTE_TEXCOORD2       = 10,
86     NV3D_VERTEX_ATTRIBUTE_TEXCOORD3       = 11,
87     /*
88      * The _END enum value is used as a sentinel to terminate arrays of
89      * Nv3dVertexAttributeInfoRec (see Nv3dVertexAttributeInfoRec, below).
90      */
91     NV3D_VERTEX_ATTRIBUTE_END             = 255,
92 } __attribute__ ((__packed__));
93 
94 /*
95  * Nv3dVertexAttributeInfoRec stores the triplet attribute, stream type, and
96  * data type.  Arrays of Nv3dVertexAttributeInfoRec are used to describe vertex
97  * attribute configurations to FermiSetupVertexArrays().
98  *
99  * The NV3D_ATTRIB_ENTRY() and NV3D_ATTRIB_END macros can be used to make
100  * Nv3dVertexAttributeInfoRec assignment more succinct.  E.g.,
101  *
102  *     Nv3dVertexAttributeInfoRec attribs[] = {
103  *         NV3D_ATTRIB_ENTRY(COLOR, STATIC, 4UB),
104  *         NV3D_ATTRIB_END,
105  *     };
106  */
107 typedef struct _Nv3dVertexAttributeInfoRec {
108     enum Nv3dVertexAttributeType attributeType;
109     enum Nv3dVertexAttributeStreamType streamType;
110     enum Nv3dVertexAttributeDataType dataType;
111 } Nv3dVertexAttributeInfoRec;
112 
113 #define NV3D_ATTRIB_TYPE_ENTRY(_i, _streamType, _dataType)           \
114     (Nv3dVertexAttributeInfoRec)                                     \
115     { .attributeType = _i,                                           \
116       .streamType    = NV3D_VERTEX_ATTRIBUTE_STREAM_##_streamType,   \
117       .dataType      = NV3D_VERTEX_ATTRIBUTE_DATA_TYPE_##_dataType }
118 
119 #define NV3D_ATTRIB_ENTRY(_attribType, _streamType, _dataType)       \
120     NV3D_ATTRIB_TYPE_ENTRY(NV3D_VERTEX_ATTRIBUTE_##_attribType, _streamType, _dataType)
121 
122 #define NV3D_ATTRIB_END                                              \
123     (Nv3dVertexAttributeInfoRec)                                     \
124     { .attributeType = NV3D_VERTEX_ATTRIBUTE_END }
125 
126 /*
127  * When built into kernel code, define Nv3dFloat to be an NvU32: it is the same
128  * size as a float, but the caller is responsible for storing float bit patterns
129  * to Nv3dFloat.
130  */
131 ct_assert(sizeof(float) == sizeof(NvU32));
132 #if NV_PUSH_ALLOW_FLOAT
133 typedef float Nv3dFloat;
134 #else
135 typedef NvU32 Nv3dFloat;
136 #endif
137 
nv3dPushFloat(NvPushChannelPtr p,const Nv3dFloat data)138 static inline void nv3dPushFloat(NvPushChannelPtr p, const Nv3dFloat data)
139 {
140 #if NV_PUSH_ALLOW_FLOAT
141     nvPushSetMethodDataF(p, data);
142 #else
143     nvPushSetMethodData(p, data);
144 #endif
145 }
146 
147 /*
148  * Vertex attribute data types.  Each of these types represents a different way
149  * of specifying vertex attribute data.
150  */
151 typedef struct __attribute__((packed)) {
152     Nv3dFloat x, y;
153 } Nv3dVertexAttrib2F;
154 
155 typedef struct __attribute__((packed)) {
156     NvU32 x, y;
157 } Nv3dVertexAttrib2U;
158 
159 typedef struct __attribute__((packed)) {
160     NvS32 x, y;
161 } Nv3dVertexAttrib2S;
162 
163 typedef struct __attribute__((packed)) {
164     Nv3dFloat x, y, z;
165 } Nv3dVertexAttrib3F;
166 
167 typedef struct __attribute__((packed)) {
168     NvU32 x, y, z;
169 } Nv3dVertexAttrib3U;
170 
171 typedef struct __attribute__((packed)) {
172     Nv3dFloat x, y, z, w;
173 } Nv3dVertexAttrib4F;
174 
175 typedef struct __attribute__((packed)) {
176     NvU16 x, y, z, w;
177 } Nv3dVertexAttrib4US;
178 
179 typedef struct __attribute__((packed)) {
180     NvU8 x, y, z, w;
181 } Nv3dVertexAttrib4UB;
182 
183 typedef struct {
184     NvU32 xyzw;
185 } Nv3dVertexAttrib4UBPacked;
186 
187 typedef struct __attribute__((packed)) {
188     NvU32 xy;
189 } Nv3dVertexAttrib2SPacked;
190 
191 // List of component sizes used for the internal representation of a
192 // texture header
193 enum Nv3dTexHeaderComponentSizes {
194     NV3D_TEXHEAD_A8B8G8R8,
195     NV3D_TEXHEAD_A2B10G10R10,
196     NV3D_TEXHEAD_B5G6R5,
197     NV3D_TEXHEAD_A1B5G5R5,
198     NV3D_TEXHEAD_R8,
199     NV3D_TEXHEAD_R32,
200     NV3D_TEXHEAD_R16,
201     NV3D_TEXHEAD_G8R8,
202     NV3D_TEXHEAD_R16G16B16A16,
203     NV3D_TEXHEAD_R32G32B32A32,
204     NV3D_TEXHEAD_Y8_VIDEO
205 };
206 
207 // List of component sources used for the internal representation of a
208 // texture header
209 enum Nv3dTexHeaderSource {
210     NV3D_TEXHEAD_IN_A,
211     NV3D_TEXHEAD_IN_R,
212     NV3D_TEXHEAD_IN_G,
213     NV3D_TEXHEAD_IN_B,
214     NV3D_TEXHEAD_IN_ZERO,
215     NV3D_TEXHEAD_IN_ONE_FLOAT
216 };
217 
218 // List of component data types used for the internal representation of
219 // a texture header
220 enum Nv3dTexHeaderDataType {
221     NV3D_TEXHEAD_NUM_UNORM,
222     NV3D_TEXHEAD_NUM_UINT,
223     NV3D_TEXHEAD_NUM_FLOAT,
224     NV3D_TEXHEAD_NUM_SNORM,
225     NV3D_TEXHEAD_NUM_SINT
226 };
227 
228 enum Nv3dTexHeaderRepeatType {
229     NV3D_TEXHEAD_REPEAT_TYPE_NONE,
230     NV3D_TEXHEAD_REPEAT_TYPE_NORMAL,
231     NV3D_TEXHEAD_REPEAT_TYPE_PAD,
232     NV3D_TEXHEAD_REPEAT_TYPE_REFLECT
233 };
234 
235 enum Nv3dTextureFilterType{
236     NV3D_TEXHEAD_FILTER_TYPE_NEAREST,
237     NV3D_TEXHEAD_FILTER_TYPE_LINEAR,
238     NV3D_TEXHEAD_FILTER_TYPE_ANISO_2X,
239     NV3D_TEXHEAD_FILTER_TYPE_ANISO_4X,
240     NV3D_TEXHEAD_FILTER_TYPE_ANISO_8X,
241     NV3D_TEXHEAD_FILTER_TYPE_ANISO_16X
242 };
243 
244 enum Nv3dTexType {
245     NV3D_TEX_TYPE_ONE_D,
246     NV3D_TEX_TYPE_ONE_D_BUFFER,
247     NV3D_TEX_TYPE_TWO_D_PITCH,
248     NV3D_TEX_TYPE_TWO_D_BLOCKLINEAR,
249 };
250 
251 typedef struct {
252     NvU32 x;
253     NvU32 y;
254     NvU32 z;
255 } Nv3dBlockLinearLog2GobsPerBlock;
256 
257 // Intermediate representation of a texture header
258 typedef struct {
259     NvBool error;
260 
261     enum Nv3dTexHeaderComponentSizes sizes;
262 
263     // Currently, we always use the same data type for all components.
264     enum Nv3dTexHeaderDataType dataType;
265 
266     struct {
267         enum Nv3dTexHeaderSource x;
268         enum Nv3dTexHeaderSource y;
269         enum Nv3dTexHeaderSource z;
270         enum Nv3dTexHeaderSource w;
271     } source;
272 
273     enum Nv3dTexType texType;
274 
275     NvU64 offset;
276     NvBool normalizedCoords;
277     enum Nv3dTexHeaderRepeatType repeatType;
278     enum Nv3dTextureFilterType filtering;
279     int pitch;
280     int width;
281     int height;
282 
283     Nv3dBlockLinearLog2GobsPerBlock log2GobsPerBlock;
284 } Nv3dRenderTexInfo;
285 
286 typedef NvU32 Nv3dTexSampler[8];
287 typedef NvU32 Nv3dTexHeader[8];
288 
289 // HW representation of a texture header
290 typedef struct {
291     Nv3dTexSampler samp;
292     Nv3dTexHeader head;
293 } Nv3dTexture;
294 
295 #define NV3D_CONSTANT_BUFFER_SIZE (4096 * 4)
296 
297 #define NV3D_TEXTURE_INDEX_INVALID (-1)
298 
299 #define NV3D_VERTEX_ATTRIBUTE_STREAM_SIZE (64 * 1024)
300 
301 /*
302  * The constant buffer alignment constraints, specifically for the methods:
303  *
304  *   NV*97_SET_CONSTANT_BUFFER_SELECTOR_A_SIZE
305  *   NV*97_SET_CONSTANT_BUFFER_SELECTOR_C_ADDRESS_LOWER
306  *
307  * have evolved over GPU architectures:
308  *
309  *          kepler  maxwell pascal  volta   turing
310  * SIZE     256     16      16      16      16
311  * ADDRESS  256     256     256     256     64
312  *
313  * But, using an alignment of 256 all the time is simpler.
314  */
315 #define NV3D_MIN_CONSTBUF_ALIGNMENT 256
316 
317 /*
318  * 3D engine pitch alignment requirements for texture surface.
319  */
320 #define NV3D_TEXTURE_PITCH_ALIGNMENT 256
321 
322 typedef struct _Nv3dStreamSurfaceRec {
323     NvU64 gpuAddress;
324     NvU64 size;
325 } Nv3dStreamSurfaceRec;
326 
327 typedef struct _Nv3dVertexAttributeStreamRec {
328     // Current GPU address within the stream.
329     NvU64 current;
330     // Terminating GPU address within the stream.
331     NvU64 end;
332     // Number of bytes per vertex.
333     NvU32 stride;
334     // Index of the next vertex to be launched.
335     int nextLaunch;
336 } Nv3dVertexAttributeStreamRec;
337 
338 typedef struct _Nv3dHal Nv3dHal;
339 
340 typedef struct _Nv3dDeviceCapsRec {
341     NvU32 hasSetBindlessTexture :1; /* Supports SetBindlessTexture method */
342     NvU32 hasProgramRegion   :1;
343 
344     NvU32 maxDim;                /*
345                                   * Maximum width or height of the
346                                   * texture surface in pixels.
347                                   */
348 } Nv3dDeviceCapsRec, *Nv3dDeviceCapsPtr;
349 
350 typedef struct  _Nv3dDeviceSpaVersionRec {
351     NvU16 major;
352     NvU16 minor;
353 } Nv3dDeviceSpaVersionRec;
354 
355 /*
356  * Enum for each compiled shader version.
357  */
358 enum Nv3dShaderArch {
359     NV3D_SHADER_ARCH_MAXWELL,
360     NV3D_SHADER_ARCH_PASCAL,
361     NV3D_SHADER_ARCH_VOLTA,
362     NV3D_SHADER_ARCH_TURING,
363     NV3D_SHADER_ARCH_AMPERE,
364     NV3D_SHADER_ARCH_HOPPER,
365     NV3D_SHADER_ARCH_BLACKWELL,
366     NV3D_SHADER_ARCH_COUNT,
367 };
368 
369 typedef struct _Nv3dDeviceRec {
370 
371     NvPushDevicePtr pPushDevice;
372     Nv3dDeviceCapsRec caps;
373     NvU32 classNumber;
374     enum Nv3dShaderArch shaderArch;
375 
376     Nv3dDeviceSpaVersionRec spaVersion;
377 
378     NvU32 maxThreadsPerWarp;
379     NvU32 maxWarps;
380 
381     const Nv3dHal *hal;
382 
383 } Nv3dDeviceRec, *Nv3dDevicePtr;
384 
385 typedef struct _Nv3dChannelProgramsRec {
386     /*
387      * An array of program descriptors, and the number of elements
388      * in the array.
389      */
390     size_t num;
391     const Nv3dProgramInfo *info;
392 
393     size_t maxLocalBytes;
394     size_t maxStackBytes;
395 
396     /*
397      * The shader program code segment.
398      *
399      * The size is in bytes.
400      */
401     struct {
402         size_t decompressedSize;
403         const unsigned char *compressedStart;
404         const unsigned char *compressedEnd;
405     } code;
406 
407     /*
408      * The constant buffers generated by the compiler for use with the above
409      * code segment.
410      *
411      * 'size' is the total size of the surface to allocate, in bytes.
412      * 'sizeAlign' is the minimum alignment required by the hardware for each
413      *             particular constant buffer.  (Although we may only have
414      *             N bytes of data to upload for each constant buffer, that
415      *             size should be padded out with zeroes to a multiple of this
416      *             value.)
417      * 'count' is the number of entries in the 'info' array.
418      * 'info' is a pointer to an array of Nv3dShaderConstBufInfo entries.
419      */
420     struct {
421         size_t size;
422         NvU32 sizeAlign;
423         NvU32 count;
424         const Nv3dShaderConstBufInfo *info;
425     } constants;
426 } Nv3dChannelProgramsRec;
427 
428 typedef struct _Nv3dChannelRec {
429 
430     Nv3dDevicePtr p3dDevice;
431     NvPushChannelPtr pPushChannel;
432 
433     NvU32 handle[NV_MAX_SUBDEVICES];
434     NvU16 numTextures;
435     NvU16 numTextureBindings;
436 
437     Nv3dVertexAttributeStreamRec
438         vertexStreams[NV3D_VERTEX_ATTRIBUTE_STREAM_COUNT];
439 
440     /*
441      * Begin / end state.  ~0 if outside begin/end, or NV9097_BEGIN_OP_* if
442      * inside.
443      */
444     NvU32 currentPrimitiveMode;
445 
446     Nv3dChannelProgramsRec programs;
447     int currentProgramIndex[NV3D_HW_SHADER_STAGE_COUNT];
448     NvU64 programLocalMemorySize;
449 
450     NvBool hasFrameBoundaries;
451 
452     struct {
453         NvU32 handle[NV_MAX_SUBDEVICES];
454         NvU64 gpuAddress;
455         NvU64 programOffset;
456         NvU64 programConstantsOffset;
457         NvU64 programLocalMemoryOffset;
458         NvU64 textureOffset;
459         NvU64 bindlessTextureConstantBufferOffset;
460         NvU64 constantBufferOffset;
461         NvU64 vertexStreamOffset[NV3D_VERTEX_ATTRIBUTE_STREAM_COUNT];
462         NvU64 totalSize;
463     } surface;
464 
465 } Nv3dChannelRec, *Nv3dChannelPtr;
466 
467 typedef struct {
468     Nv3dFloat red;
469     Nv3dFloat green;
470     Nv3dFloat blue;
471     Nv3dFloat alpha;
472 } Nv3dColor;
473 
474 typedef struct {
475     NvU32 blendFactorSrc; /* NV9097_SET_BLEND_COLOR/ALPHA_SOURCE_COEFF_ */
476     NvU32 blendFactorDst; /* NV9097_SET_BLEND_COLOR/ALPHA_DEST_COEFF_ */
477     NvU32 blendEquation;  /* NV9097_SET_BLEND_COLOR/ALPHA_OP_ */
478 } Nv3dBlendState;
479 #endif /* __NVIDIA_3D_TYPES_H__ */
480