Welcome to mirror list, hosted at ThFree Co, Russian Federation.

mtl_primitive.hh « metal « gpu « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
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