blob: b32854a04bf193810718dae911a57e3339d4af2a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup gpu
*
* Encapsulation of Frame-buffer states (attached textures, viewport, scissors).
*/
#pragma once
#include "BLI_assert.h"
#include "GPU_primitive.h"
#include <Metal/Metal.h>
namespace blender::gpu {
/** Utility functions **/
static inline MTLPrimitiveTopologyClass mtl_prim_type_to_topology_class(MTLPrimitiveType prim_type)
{
switch (prim_type) {
case MTLPrimitiveTypePoint:
return MTLPrimitiveTopologyClassPoint;
case MTLPrimitiveTypeLine:
case MTLPrimitiveTypeLineStrip:
return MTLPrimitiveTopologyClassLine;
case MTLPrimitiveTypeTriangle:
case MTLPrimitiveTypeTriangleStrip:
return MTLPrimitiveTopologyClassTriangle;
}
return MTLPrimitiveTopologyClassUnspecified;
}
static inline MTLPrimitiveType gpu_prim_type_to_metal(GPUPrimType prim_type)
{
switch (prim_type) {
case GPU_PRIM_POINTS:
return MTLPrimitiveTypePoint;
case GPU_PRIM_LINES:
case GPU_PRIM_LINES_ADJ:
case GPU_PRIM_LINE_LOOP:
return MTLPrimitiveTypeLine;
case GPU_PRIM_LINE_STRIP:
case GPU_PRIM_LINE_STRIP_ADJ:
return MTLPrimitiveTypeLineStrip;
case GPU_PRIM_TRIS:
case GPU_PRIM_TRI_FAN:
case GPU_PRIM_TRIS_ADJ:
return MTLPrimitiveTypeTriangle;
case GPU_PRIM_TRI_STRIP:
return MTLPrimitiveTypeTriangleStrip;
case GPU_PRIM_NONE:
return MTLPrimitiveTypePoint;
};
}
/* Certain primitive types are not supported in Metal, and require emulation.
* `GPU_PRIM_LINE_LOOP` and `GPU_PRIM_TRI_FAN` required index buffer patching.
* Adjacency types do not need emulation as the input structure is the same,
* and access is controlled from the vertex shader through SSBO vertex fetch.
* -- These Adj cases are only used in geometry shaders in OpenGL. */
static inline bool mtl_needs_topology_emulation(GPUPrimType prim_type)
{
BLI_assert(prim_type != GPU_PRIM_NONE);
switch (prim_type) {
case GPU_PRIM_LINE_LOOP:
case GPU_PRIM_TRI_FAN:
return true;
default:
return false;
}
return false;
}
static inline bool mtl_vertex_count_fits_primitive_type(uint32_t vertex_count,
MTLPrimitiveType prim_type)
{
if (vertex_count == 0) {
return false;
}
switch (prim_type) {
case MTLPrimitiveTypeLineStrip:
return (vertex_count > 1);
case MTLPrimitiveTypeLine:
return (vertex_count % 2 == 0);
case MTLPrimitiveTypePoint:
return (vertex_count > 0);
case MTLPrimitiveTypeTriangle:
return (vertex_count % 3 == 0);
case MTLPrimitiveTypeTriangleStrip:
return (vertex_count > 2);
}
BLI_assert(false);
return false;
}
} // namespace blender::gpu
|