mirror of https://github.com/stenzek/duckstation
GPU: Move enums/types into separate file
parent
d3d881aa6b
commit
03d4f80883
@ -0,0 +1,224 @@
|
||||
#pragma once
|
||||
#include "common/bitfield.h"
|
||||
#include "common/rectangle.h"
|
||||
#include "types.h"
|
||||
#include <array>
|
||||
|
||||
enum : u32
|
||||
{
|
||||
VRAM_WIDTH = 1024,
|
||||
VRAM_HEIGHT = 512,
|
||||
VRAM_SIZE = VRAM_WIDTH * VRAM_HEIGHT * sizeof(u16),
|
||||
VRAM_WIDTH_MASK = VRAM_WIDTH - 1,
|
||||
VRAM_HEIGHT_MASK = VRAM_HEIGHT - 1,
|
||||
VRAM_COORD_MASK = 0x3FF,
|
||||
TEXTURE_PAGE_WIDTH = 256,
|
||||
TEXTURE_PAGE_HEIGHT = 256,
|
||||
MAX_PRIMITIVE_WIDTH = 1024,
|
||||
MAX_PRIMITIVE_HEIGHT = 512,
|
||||
DITHER_MATRIX_SIZE = 4
|
||||
};
|
||||
|
||||
enum class GPUPrimitive : u8
|
||||
{
|
||||
Reserved = 0,
|
||||
Polygon = 1,
|
||||
Line = 2,
|
||||
Rectangle = 3
|
||||
};
|
||||
|
||||
enum class GPUDrawRectangleSize : u8
|
||||
{
|
||||
Variable = 0,
|
||||
R1x1 = 1,
|
||||
R8x8 = 2,
|
||||
R16x16 = 3
|
||||
};
|
||||
|
||||
enum class GPUTextureMode : u8
|
||||
{
|
||||
Palette4Bit = 0,
|
||||
Palette8Bit = 1,
|
||||
Direct16Bit = 2,
|
||||
Reserved_Direct16Bit = 3,
|
||||
|
||||
// Not register values.
|
||||
RawTextureBit = 4,
|
||||
RawPalette4Bit = RawTextureBit | Palette4Bit,
|
||||
RawPalette8Bit = RawTextureBit | Palette8Bit,
|
||||
RawDirect16Bit = RawTextureBit | Direct16Bit,
|
||||
Reserved_RawDirect16Bit = RawTextureBit | Reserved_Direct16Bit,
|
||||
|
||||
Disabled = 8 // Not a register value
|
||||
};
|
||||
|
||||
IMPLEMENT_ENUM_CLASS_BITWISE_OPERATORS(GPUTextureMode);
|
||||
|
||||
enum class GPUTransparencyMode : u8
|
||||
{
|
||||
HalfBackgroundPlusHalfForeground = 0,
|
||||
BackgroundPlusForeground = 1,
|
||||
BackgroundMinusForeground = 2,
|
||||
BackgroundPlusQuarterForeground = 3,
|
||||
|
||||
Disabled = 4 // Not a register value
|
||||
};
|
||||
|
||||
enum class GPUInterlacedDisplayMode : u8
|
||||
{
|
||||
None,
|
||||
InterleavedFields,
|
||||
SeparateFields
|
||||
};
|
||||
|
||||
union GPURenderCommand
|
||||
{
|
||||
u32 bits;
|
||||
|
||||
BitField<u32, u32, 0, 24> color_for_first_vertex;
|
||||
BitField<u32, bool, 24, 1> raw_texture_enable; // not valid for lines
|
||||
BitField<u32, bool, 25, 1> transparency_enable;
|
||||
BitField<u32, bool, 26, 1> texture_enable;
|
||||
BitField<u32, GPUDrawRectangleSize, 27, 2> rectangle_size; // only for rectangles
|
||||
BitField<u32, bool, 27, 1> quad_polygon; // only for polygons
|
||||
BitField<u32, bool, 27, 1> polyline; // only for lines
|
||||
BitField<u32, bool, 28, 1> shading_enable; // 0 - flat, 1 = gouroud
|
||||
BitField<u32, GPUPrimitive, 29, 21> primitive;
|
||||
|
||||
/// Returns true if texturing should be enabled. Depends on the primitive type.
|
||||
ALWAYS_INLINE bool IsTexturingEnabled() const { return (primitive != GPUPrimitive::Line) ? texture_enable : false; }
|
||||
|
||||
/// Returns true if dithering should be enabled. Depends on the primitive type.
|
||||
ALWAYS_INLINE bool IsDitheringEnabled() const
|
||||
{
|
||||
switch (primitive)
|
||||
{
|
||||
case GPUPrimitive::Polygon:
|
||||
return shading_enable || (texture_enable && !raw_texture_enable);
|
||||
|
||||
case GPUPrimitive::Line:
|
||||
return true;
|
||||
|
||||
case GPUPrimitive::Rectangle:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Helper/format conversion functions.
|
||||
static constexpr u32 RGBA5551ToRGBA8888(u16 color)
|
||||
{
|
||||
u8 r = Truncate8(color & 31);
|
||||
u8 g = Truncate8((color >> 5) & 31);
|
||||
u8 b = Truncate8((color >> 10) & 31);
|
||||
u8 a = Truncate8((color >> 15) & 1);
|
||||
|
||||
// 00012345 -> 1234545
|
||||
b = (b << 3) | (b & 0b111);
|
||||
g = (g << 3) | (g & 0b111);
|
||||
r = (r << 3) | (r & 0b111);
|
||||
a = a ? 255 : 0;
|
||||
|
||||
return ZeroExtend32(r) | (ZeroExtend32(g) << 8) | (ZeroExtend32(b) << 16) | (ZeroExtend32(a) << 24);
|
||||
}
|
||||
|
||||
static constexpr u16 RGBA8888ToRGBA5551(u32 color)
|
||||
{
|
||||
const u16 r = Truncate16((color >> 3) & 0x1Fu);
|
||||
const u16 g = Truncate16((color >> 11) & 0x1Fu);
|
||||
const u16 b = Truncate16((color >> 19) & 0x1Fu);
|
||||
const u16 a = Truncate16((color >> 31) & 0x01u);
|
||||
|
||||
return r | (g << 5) | (b << 10) | (a << 15);
|
||||
}
|
||||
|
||||
union GPUVertexPosition
|
||||
{
|
||||
u32 bits;
|
||||
|
||||
BitField<u32, s32, 0, 11> x;
|
||||
BitField<u32, s32, 16, 11> y;
|
||||
};
|
||||
|
||||
// Sprites/rectangles should be clipped to 12 bits before drawing.
|
||||
static constexpr s32 TruncateGPUVertexPosition(s32 x)
|
||||
{
|
||||
return SignExtendN<11, s32>(x);
|
||||
}
|
||||
|
||||
// bits in GP0(E1h) or texpage part of polygon
|
||||
union GPUDrawModeReg
|
||||
{
|
||||
static constexpr u16 MASK = 0b1111111111111;
|
||||
static constexpr u16 TEXTURE_PAGE_MASK = UINT16_C(0b0000000000011111);
|
||||
|
||||
// Polygon texpage commands only affect bits 0-8, 11
|
||||
static constexpr u16 POLYGON_TEXPAGE_MASK = 0b0000100111111111;
|
||||
|
||||
// Bits 0..5 are returned in the GPU status register, latched at E1h/polygon draw time.
|
||||
static constexpr u32 GPUSTAT_MASK = 0b11111111111;
|
||||
|
||||
u16 bits;
|
||||
|
||||
BitField<u16, u8, 0, 4> texture_page_x_base;
|
||||
BitField<u16, u8, 4, 1> texture_page_y_base;
|
||||
BitField<u16, GPUTransparencyMode, 5, 2> transparency_mode;
|
||||
BitField<u16, GPUTextureMode, 7, 2> texture_mode;
|
||||
BitField<u16, bool, 9, 1> dither_enable;
|
||||
BitField<u16, bool, 10, 1> draw_to_displayed_field;
|
||||
BitField<u16, bool, 11, 1> texture_disable;
|
||||
BitField<u16, bool, 12, 1> texture_x_flip;
|
||||
BitField<u16, bool, 13, 1> texture_y_flip;
|
||||
|
||||
ALWAYS_INLINE u16 GetTexturePageBaseX() const { return ZeroExtend16(texture_page_x_base.GetValue()) * 64; }
|
||||
ALWAYS_INLINE u16 GetTexturePageBaseY() const { return ZeroExtend16(texture_page_y_base.GetValue()) * 256; }
|
||||
|
||||
/// Returns true if the texture mode requires a palette.
|
||||
bool IsUsingPalette() const { return (bits & (2 << 7)) == 0; }
|
||||
|
||||
/// Returns a rectangle comprising the texture page area.
|
||||
Common::Rectangle<u32> GetTexturePageRectangle() const
|
||||
{
|
||||
static constexpr std::array<u32, 4> texture_page_widths = {
|
||||
{TEXTURE_PAGE_WIDTH / 4, TEXTURE_PAGE_WIDTH / 2, TEXTURE_PAGE_WIDTH, TEXTURE_PAGE_WIDTH} };
|
||||
return Common::Rectangle<u32>::FromExtents(GetTexturePageBaseX(), GetTexturePageBaseY(),
|
||||
texture_page_widths[static_cast<u8>(texture_mode.GetValue())],
|
||||
TEXTURE_PAGE_HEIGHT);
|
||||
}
|
||||
|
||||
/// Returns a rectangle comprising the texture palette area.
|
||||
Common::Rectangle<u32> GetTexturePaletteRectangle() const
|
||||
{
|
||||
static constexpr std::array<u32, 4> palette_widths = { {16, 256, 0, 0} };
|
||||
return Common::Rectangle<u32>::FromExtents(GetTexturePageBaseX(), GetTexturePageBaseY(),
|
||||
palette_widths[static_cast<u8>(texture_mode.GetValue())], 1);
|
||||
}
|
||||
};
|
||||
|
||||
union GPUTexturePaletteReg
|
||||
{
|
||||
static constexpr u16 MASK = UINT16_C(0b0111111111111111);
|
||||
|
||||
u16 bits;
|
||||
|
||||
BitField<u16, u16, 0, 6> x;
|
||||
BitField<u16, u16, 6, 10> y;
|
||||
|
||||
ALWAYS_INLINE u32 GetXBase() const { return static_cast<u32>(x) * 16u; }
|
||||
ALWAYS_INLINE u32 GetYBase() const { return static_cast<u32>(y); }
|
||||
};
|
||||
|
||||
struct GPUTextureWindow
|
||||
{
|
||||
u8 and_x;
|
||||
u8 and_y;
|
||||
u8 or_x;
|
||||
u8 or_y;
|
||||
};
|
||||
|
||||
// 4x4 dither matrix.
|
||||
static constexpr s32 DITHER_MATRIX[DITHER_MATRIX_SIZE][DITHER_MATRIX_SIZE] = { {-4, +0, -3, +1}, // row 0
|
||||
{+2, -2, +3, -1}, // row 1
|
||||
{-3, +1, -4, +0}, // row 2
|
||||
{+4, -1, +2, -2} }; // row 3
|
||||
Loading…
Reference in New Issue