File: VideoCommon.h

package info (click to toggle)
dolphin-emu 2512%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 76,328 kB
  • sloc: cpp: 499,023; ansic: 119,674; python: 6,547; sh: 2,338; makefile: 1,093; asm: 726; pascal: 257; javascript: 183; perl: 97; objc: 75; xml: 30
file content (141 lines) | stat: -rw-r--r-- 4,120 bytes parent folder | download
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright 2008 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <algorithm>
#include <bit>

#include "Common/BitUtils.h"
#include "Common/CommonTypes.h"

#include "VideoCommon/BPMemory.h"

// These are accurate (disregarding AA modes).
constexpr u32 EFB_WIDTH = 640u;
constexpr u32 EFB_HEIGHT = 528u;

// The maximum depth that is written to the depth buffer should never exceed this value.
// This is necessary because we use a 2^24 divisor for all our depth values to prevent
// floating-point round-trip errors. However the console GPU doesn't ever write a value
// to the depth buffer that exceeds 2^24 - 1.
constexpr float MAX_EFB_DEPTH = 16777215.0f / 16777216.0f;

// Max XFB width is 720. You can only copy out 640 wide areas of efb to XFB
// so you need multiple copies to do the full width.
// The VI can do horizontal scaling (TODO: emulate).
constexpr u32 MAX_XFB_WIDTH = 720u;

// Although EFB height is 528, 576-line XFB's can be created either with
// vertical scaling by the EFB copy operation or copying to multiple XFB's
// that are next to each other in memory (TODO: handle that situation).
constexpr u32 MAX_XFB_HEIGHT = 576u;

#define PRIM_LOG(t, ...) DEBUG_LOG_FMT(VIDEO, t __VA_OPT__(, ) __VA_ARGS__)

// warning: mapping buffer should be disabled to use this
// #define LOG_VTX() DEBUG_LOG_FMT(VIDEO, "vtx: {} {} {}, ",
//                                 ((float*)g_vertex_manager_write_ptr)[-3],
//                                 ((float*)g_vertex_manager_write_ptr)[-2],
//                                 ((float*)g_vertex_manager_write_ptr)[-1]);

#define LOG_VTX()

enum class APIType
{
  OpenGL,
  D3D,
  Vulkan,
  Metal,
  Nothing
};

inline u32 RGBA8ToRGBA6ToRGBA8(u32 src)
{
  u32 color = src;
  color &= 0xFCFCFCFC;
  color |= (color >> 6) & 0x03030303;
  return color;
}

inline u32 RGBA8ToRGB565ToRGBA8(u32 src)
{
  u32 color = (src & 0xF8FCF8);
  color |= (color >> 5) & 0x070007;
  color |= (color >> 6) & 0x000300;
  color |= 0xFF000000;
  return color;
}

inline u32 Z24ToZ16ToZ24(u32 src)
{
  return (src & 0xFFFF00) | (src >> 16);
}

inline u32 CompressZ16(u32 z24depth, DepthFormat format)
{
  // Flipper offers a number of choices for 16bit Z formats that adjust
  // where the bulk of the precision lies.

  if (format == DepthFormat::ZLINEAR)
  {
    // This is just a linear depth buffer with 16 bits of precision
    return z24depth >> 8;
  }

  // ZNEAR/ZMID/ZFAR are custom floating point formats with 2/3/4 bits of exponent
  // The exponent is simply the number of leading ones that have been removed
  // The first zero bit is skipped and not stored. The mantissa contains the next 14/13/12 bits
  // If exponent is at the MAX (3, 7, or 12) then the next bit might still be a one, and can't
  // be skipped, so the mantissa simply contains the next 14/13/12 bits

  u32 leading_ones = static_cast<u32>(std::countl_one(z24depth << 8));
  bool next_bit_is_one = false;  // AKA: Did we clamp leading_ones?
  u32 exp_bits;

  switch (format)
  {
  case DepthFormat::ZNEAR:
    exp_bits = 2;
    if (leading_ones >= 3u)
    {
      leading_ones = 3u;
      next_bit_is_one = true;
    }
    break;
  case DepthFormat::ZMID:
    exp_bits = 3;
    if (leading_ones >= 7u)
    {
      leading_ones = 7u;
      next_bit_is_one = true;
    }
    break;
  case DepthFormat::ZFAR:
    exp_bits = 4;
    if (leading_ones >= 12u)
    {
      // The hardware implementation only uses values 0 to 12 in the exponent
      leading_ones = 12u;
      next_bit_is_one = true;
    }
    break;
  default:
    return z24depth >> 8;
  }

  u32 mantissa_bits = 16 - exp_bits;

  // Calculate which bits we need to extract from z24depth for our mantissa
  u32 top = std::max<u32>(24 - leading_ones, mantissa_bits);
  if (!next_bit_is_one)
  {
    top -= 1;  // We know the next bit is zero, so we don't need to include it.
  }
  u32 bottom = top - mantissa_bits;

  u32 exponent = leading_ones << mantissa_bits;  // Upper bits contain exponent
  u32 mantissa = Common::ExtractBits(z24depth, bottom, top - 1);

  return exponent | mantissa;
}