diff --git a/Utilities/types.h b/Utilities/types.h new file mode 100644 index 0000000000..9b526253ba --- /dev/null +++ b/Utilities/types.h @@ -0,0 +1,1087 @@ +#pragma once +#include +#include +#include +#include + +using uchar = unsigned char; +using ushort = unsigned short; +using uint = unsigned int; +using ulong = unsigned long; +using ullong = unsigned long long; + +using llong = long long; + +using u8 = uint8_t; +using u16 = uint16_t; +using u32 = uint32_t; +using u64 = uint64_t; + +using s8 = int8_t; +using s16 = int16_t; +using s32 = int32_t; +using s64 = int64_t; + +union alignas(2) f16 +{ + u16 _u16; + u8 _u8[2]; +}; + +using f32 = float; +using f64 = double; + +#include "BEType.h" + +template +class pi_t +{ +public: + static constexpr T value = T(3.141592653589793238462643383279502884197169399375105820974944592307816406286); +}; + +template +using pi = pi_t; + +struct ignore +{ + template + ignore(T) + { + } +}; + +template +struct size2_base +{ + T width, height; + + /* + size2_base() : width{}, height{} + { + } + + size2_base(T width, T height) : width{ width }, height{ height } + { + } + */ + + size2_base operator -(const size2_base& rhs) const + { + return{ width - rhs.width, height - rhs.height }; + } + size2_base operator -(T rhs) const + { + return{ width - rhs, height - rhs }; + } + size2_base operator +(const size2_base& rhs) const + { + return{ width + rhs.width, height + rhs.height }; + } + size2_base operator +(T rhs) const + { + return{ width + rhs, height + rhs }; + } + size2_base operator /(const size2_base& rhs) const + { + return{ width / rhs.width, height / rhs.height }; + } + size2_base operator /(T rhs) const + { + return{ width / rhs, height / rhs }; + } + size2_base operator *(const size2_base& rhs) const + { + return{ width * rhs.width, height * rhs.height }; + } + size2_base operator *(T rhs) const + { + return{ width * rhs, height * rhs }; + } + + size2_base& operator -=(const size2_base& rhs) + { + width -= rhs.width; + height -= rhs.height; + return *this; + } + size2_base& operator -=(T rhs) + { + width -= rhs; + height -= rhs; + return *this; + } + size2_base& operator +=(const size2_base& rhs) + { + width += rhs.width; + height += rhs.height; + return *this; + } + size2_base& operator +=(T rhs) + { + width += rhs; + height += rhs; + return *this; + } + size2_base& operator /=(const size2_base& rhs) + { + width /= rhs.width; + height /= rhs.height; + return *this; + } + size2_base& operator /=(T rhs) + { + width /= rhs; + height /= rhs; + return *this; + } + size2_base& operator *=(const size2_base& rhs) + { + width *= rhs.width; + height *= rhs.height; + return *this; + } + size2_base& operator *=(T rhs) + { + width *= rhs; + height *= rhs; + return *this; + } + + bool operator == (const size2_base& rhs) const + { + return width == rhs.width && height == rhs.height; + } + + bool operator != (const size2_base& rhs) const + { + return width != rhs.width || height != rhs.height; + } + + template + operator size2_base() const + { + return{ (NT)width, (NT)height }; + } +}; + +template +struct position1_base +{ + T x; + + position1_base operator -(const position1_base& rhs) const + { + return{ x - rhs.x }; + } + position1_base operator -(T rhs) const + { + return{ x - rhs }; + } + position1_base operator +(const position1_base& rhs) const + { + return{ x + rhs.x }; + } + position1_base operator +(T rhs) const + { + return{ x + rhs }; + } + template + position1_base operator *(RhsT rhs) const + { + return{ T(x * rhs) }; + } + position1_base operator *(const position1_base& rhs) const + { + return{ T(x * rhs.x) }; + } + template + position1_base operator /(RhsT rhs) const + { + return{ x / rhs }; + } + position1_base operator /(const position1_base& rhs) const + { + return{ x / rhs.x }; + } + + position1_base& operator -=(const position1_base& rhs) + { + x -= rhs.x; + return *this; + } + position1_base& operator -=(T rhs) + { + x -= rhs; + return *this; + } + position1_base& operator +=(const position1_base& rhs) + { + x += rhs.x; + return *this; + } + position1_base& operator +=(T rhs) + { + x += rhs; + return *this; + } + + template + position1_base& operator *=(RhsT rhs) const + { + x *= rhs; + return *this; + } + position1_base& operator *=(const position1_base& rhs) const + { + x *= rhs.x; + return *this; + } + template + position1_base& operator /=(RhsT rhs) const + { + x /= rhs; + return *this; + } + position1_base& operator /=(const position1_base& rhs) const + { + x /= rhs.x; + return *this; + } + + bool operator ==(const position1_base& rhs) const + { + return x == rhs.x; + } + + bool operator ==(T rhs) const + { + return x == rhs; + } + + bool operator !=(const position1_base& rhs) const + { + return !(*this == rhs); + } + + bool operator !=(T rhs) const + { + return !(*this == rhs); + } + + template + operator position1_base() const + { + return{ (NT)x }; + } + + double distance(const position1_base& to) + { + return abs(x - to.x); + } +}; + +template +struct position2_base +{ + T x, y; + /* + position2_base() : x{}, y{} + { + } + + position2_base(T x, T y) : x{ x }, y{ y } + { + } + */ + + bool operator >(const position2_base& rhs) const + { + return x > rhs.x && y > rhs.y; + } + bool operator >(T rhs) const + { + return x > rhs && y > rhs; + } + bool operator <(const position2_base& rhs) const + { + return x < rhs.x && y < rhs.y; + } + bool operator <(T rhs) const + { + return x < rhs && y < rhs; + } + bool operator >=(const position2_base& rhs) const + { + return x >= rhs.x && y >= rhs.y; + } + bool operator >=(T rhs) const + { + return x >= rhs && y >= rhs; + } + bool operator <=(const position2_base& rhs) const + { + return x <= rhs.x && y <= rhs.y; + } + bool operator <=(T rhs) const + { + return x <= rhs && y <= rhs; + } + + position2_base operator -(const position2_base& rhs) const + { + return{ x - rhs.x, y - rhs.y }; + } + position2_base operator -(T rhs) const + { + return{ x - rhs, y - rhs }; + } + position2_base operator +(const position2_base& rhs) const + { + return{ x + rhs.x, y + rhs.y }; + } + position2_base operator +(T rhs) const + { + return{ x + rhs, y + rhs }; + } + template + position2_base operator *(RhsT rhs) const + { + return{ T(x * rhs), T(y * rhs) }; + } + position2_base operator *(const position2_base& rhs) const + { + return{ T(x * rhs.x), T(y * rhs.y) }; + } + template + position2_base operator /(RhsT rhs) const + { + return{ x / rhs, y / rhs }; + } + position2_base operator /(const position2_base& rhs) const + { + return{ x / rhs.x, y / rhs.y }; + } + position2_base operator /(const size2_base& rhs) const + { + return{ x / rhs.width, y / rhs.height }; + } + + position2_base& operator -=(const position2_base& rhs) + { + x -= rhs.x; + y -= rhs.y; + return *this; + } + position2_base& operator -=(T rhs) + { + x -= rhs; + y -= rhs; + return *this; + } + position2_base& operator +=(const position2_base& rhs) + { + x += rhs.x; + y += rhs.y; + return *this; + } + position2_base& operator +=(T rhs) + { + x += rhs; + y += rhs; + return *this; + } + + template + position2_base& operator *=(RhsT rhs) const + { + x *= rhs; + y *= rhs; + return *this; + } + position2_base& operator *=(const position2_base& rhs) const + { + x *= rhs.x; + y *= rhs.y; + return *this; + } + template + position2_base& operator /=(RhsT rhs) const + { + x /= rhs; + y /= rhs; + return *this; + } + position2_base& operator /=(const position2_base& rhs) const + { + x /= rhs.x; + y /= rhs.y; + return *this; + } + + bool operator ==(const position2_base& rhs) const + { + return x == rhs.x && y == rhs.y; + } + + bool operator ==(T rhs) const + { + return x == rhs && y == rhs; + } + + bool operator !=(const position2_base& rhs) const + { + return !(*this == rhs); + } + + bool operator !=(T rhs) const + { + return !(*this == rhs); + } + + template + operator position2_base() const + { + return{ (NT)x, (NT)y }; + } + + double distance(const position2_base& to) + { + return std::sqrt(double((x - to.x) * (x - to.x) + (y - to.y) * (y - to.y))); + } +}; + +template +struct position3_base +{ + T x, y, z; + /* + position3_base() : x{}, y{}, z{} + { + } + + position3_base(T x, T y, T z) : x{ x }, y{ y }, z{ z } + { + } + */ + + position3_base operator -(const position3_base& rhs) const + { + return{ x - rhs.x, y - rhs.y, z - rhs.z }; + } + position3_base operator -(T rhs) const + { + return{ x - rhs, y - rhs, z - rhs }; + } + position3_base operator +(const position3_base& rhs) const + { + return{ x + rhs.x, y + rhs.y, z + rhs.z }; + } + position3_base operator +(T rhs) const + { + return{ x + rhs, y + rhs, z + rhs }; + } + + position3_base& operator -=(const position3_base& rhs) + { + x -= rhs.x; + y -= rhs.y; + z -= rhs.z; + return *this; + } + position3_base& operator -=(T rhs) + { + x -= rhs; + y -= rhs; + z -= rhs; + return *this; + } + position3_base& operator +=(const position3_base& rhs) + { + x += rhs.x; + y += rhs.y; + z += rhs.z; + return *this; + } + position3_base& operator +=(T rhs) + { + x += rhs; + y += rhs; + z += rhs; + return *this; + } + + bool operator ==(const position3_base& rhs) const + { + return x == rhs.x && y == rhs.y && z == rhs.z; + } + + bool operator ==(T rhs) const + { + return x == rhs && y == rhs && z == rhs; + } + + bool operator !=(const position3_base& rhs) const + { + return !(*this == rhs); + } + + bool operator !=(T rhs) const + { + return !(*this == rhs); + } + + template + operator position3_base() const + { + return{ (NT)x, (NT)y, (NT)z }; + } +}; + +template +struct position4_base +{ + T x, y, z, w; + + constexpr position4_base() : x{}, y{}, z{}, w{} + { + } + + constexpr position4_base(T x, T y = {}, T z = {}, T w = {T(1)}) : x{ x }, y{ y }, z{ z }, w{ w } + { + } + + constexpr position4_base operator -(const position4_base& rhs) const + { + return{ x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w }; + } + constexpr position4_base operator -(T rhs) const + { + return{ x - rhs, y - rhs, z - rhs, w - rhs }; + } + constexpr position4_base operator +(const position4_base& rhs) const + { + return{ x + rhs.x, y + rhs.y, z + rhs.z, w + rhs.w }; + } + constexpr position4_base operator +(T rhs) const + { + return{ x + rhs, y + rhs, z + rhs, w + rhs }; + } + + position4_base& operator -=(const position4_base& rhs) + { + x -= rhs.x; + y -= rhs.y; + z -= rhs.z; + w -= rhs.w; + return *this; + } + position4_base& operator -=(T rhs) + { + x -= rhs; + y -= rhs; + z -= rhs; + w -= rhs; + return *this; + } + position4_base& operator +=(const position4_base& rhs) + { + x += rhs.x; + y += rhs.y; + z += rhs.z; + w += rhs.w; + return *this; + } + position4_base& operator +=(T rhs) + { + x += rhs; + y += rhs; + z += rhs; + w += rhs; + return *this; + } + + constexpr bool operator ==(const position4_base& rhs) const + { + return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w; + } + + constexpr bool operator ==(T rhs) const + { + return x == rhs && y == rhs && z == rhs && w == rhs; + } + + constexpr bool operator !=(const position4_base& rhs) const + { + return !(*this == rhs); + } + + constexpr bool operator !=(T rhs) const + { + return !(*this == rhs); + } + + template + constexpr operator position4_base() const + { + return{ (NT)x, (NT)y, (NT)z, (NT)w }; + } +}; + +template +using position_base = position2_base; + +template +struct coord_base +{ + union + { + position_base position; + struct { T x, y; }; + }; + + union + { + size2_base size; + struct { T width, height; }; + }; + + constexpr coord_base() : x{}, y{}, position{}, width{}, height{}, size{} + { + } + + constexpr coord_base(const position_base& position, const size2_base& size) + : x{ position.x }, y{ position.y }, position{ position }, width{ size.width }, height{ size.height }, size{ size } + { + } + + constexpr coord_base(T x, T y, T width, T height) : x{ x }, y{ y }, width{ width }, height{ height } + { + } + + constexpr bool test(const position_base& position) const + { + if (position.x < x || position.x >= x + width) + return false; + + if (position.y < y || position.y >= y + height) + return false; + + return true; + } + + constexpr bool operator == (const coord_base& rhs) const + { + return position == rhs.position && size == rhs.size; + } + + constexpr bool operator != (const coord_base& rhs) const + { + return position != rhs.position || size != rhs.size; + } + + template + constexpr operator coord_base() const + { + return{ (NT)x, (NT)y, (NT)width, (NT)height }; + } +}; + +template +struct area_base +{ + T x1, x2; + T y1, y2; + + constexpr area_base() : x1{}, x2{}, y1{}, y2{} + { + } + + constexpr area_base(T x1, T y1, T x2, T y2) : x1{ x1 }, x2{ x2 }, y1{ y1 }, y2{ y2 } + { + } + + constexpr area_base(const coord_base& coord) : x1{ coord.x }, x2{ coord.x + coord.width }, y1{ coord.y }, y2{ coord.y + coord.height } + { + } + + constexpr operator coord_base() const + { + return{ x1, y1, x2 - x1, y2 - y1 }; + } + + void flip_vertical() + { + std::swap(y1, y2); + } + + void flip_horizontal() + { + std::swap(x1, x2); + } + + constexpr area_base flipped_vertical() const + { + return{ x1, y2, x2, y1 }; + } + + constexpr area_base flipped_horizontal() const + { + return{ x2, y1, x1, y2 }; + } + + constexpr bool operator == (const area_base& rhs) const + { + return x1 == rhs.x1 && x2 == rhs.x2 && y1 == rhs.y1 && y2 == rhs.y2; + } + + constexpr bool operator != (const area_base& rhs) const + { + return !(*this == rhs); + } + + constexpr area_base operator - (const size2_base& size) const + { + return{ x1 - size.width, y1 - size.height, x2 - size.width, y2 - size.height }; + } + constexpr area_base operator - (const T& value) const + { + return{ x1 - value, y1 - value, x2 - value, y2 - value }; + } + constexpr area_base operator + (const size2_base& size) const + { + return{ x1 + size.width, y1 + size.height, x2 + size.width, y2 + size.height }; + } + constexpr area_base operator + (const T& value) const + { + return{ x1 + value, y1 + value, x2 + value, y2 + value }; + } + constexpr area_base operator / (const size2_base& size) const + { + return{ x1 / size.width, y1 / size.height, x2 / size.width, y2 / size.height }; + } + constexpr area_base operator / (const T& value) const + { + return{ x1 / value, y1 / value, x2 / value, y2 / value }; + } + constexpr area_base operator * (const size2_base& size) const + { + return{ x1 * size.width, y1 * size.height, x2 * size.width, y2 * size.height }; + } + constexpr area_base operator * (const T& value) const + { + return{ x1 * value, y1 * value, x2 * value, y2 * value }; + } + + template + constexpr operator area_base() const + { + return{(NT)x1, (NT)y1, (NT)x2, (NT)y2}; + } +}; + +template +struct size3_base +{ + T width, height, depth; + /* + size3_base() : width{}, height{}, depth{} + { + } + + size3_base(T width, T height, T depth) : width{ width }, height{ height }, depth{ depth } + { + } + */ +}; + +template +struct coord3_base +{ + union + { + position3_base position; + struct { T x, y, z; }; + }; + + union + { + size3_base size; + struct { T width, height, depth; }; + }; + + constexpr coord3_base() : position{}, size{} + { + } + + constexpr coord3_base(const position3_base& position, const size3_base& size) : position{ position }, size{ size } + { + } + + constexpr coord3_base(T x, T y, T z, T width, T height, T depth) : x{ x }, y{ y }, z{ z }, width{ width }, height{ height }, depth{ depth } + { + } + + constexpr bool test(const position3_base& position) const + { + if (position.x < x || position.x >= x + width) + return false; + + if (position.y < y || position.y >= y + height) + return false; + + if (position.z < z || position.z >= z + depth) + return false; + + return true; + } + + template + constexpr operator coord3_base() const + { + return{ (NT)x, (NT)y, (NT)z, (NT)width, (NT)height, (NT)depth }; + } +}; + + +template +struct color4_base +{ + union + { + struct + { + T r, g, b, a; + }; + + struct + { + T x, y, z, w; + }; + + T rgba[4]; + T xyzw[4]; + }; + + color4_base() + : x{} + , y{} + , z{} + , w{ T(1) } + { + } + + color4_base(T x, T y = {}, T z = {}, T w = {}) + : x(x) + , y(y) + , z(z) + , w(w) + { + } + + bool operator == (const color4_base& rhs) const + { + return r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a; + } + + bool operator != (const color4_base& rhs) const + { + return !(*this == rhs); + } + + template + operator color4_base() const + { + return{ (NT)x, (NT)y, (NT)z, (NT)w }; + } +}; + +template +struct color3_base +{ + union + { + struct + { + T r, g, b; + }; + + struct + { + T x, y, z; + }; + + T rgb[3]; + T xyz[3]; + }; + + constexpr color3_base(T x = {}, T y = {}, T z = {}) + : x(x) + , y(y) + , z(z) + { + } + + constexpr bool operator == (const color3_base& rhs) const + { + return r == rhs.r && g == rhs.g && b == rhs.b; + } + + constexpr bool operator != (const color3_base& rhs) const + { + return !(*this == rhs); + } + + template + constexpr operator color3_base() const + { + return{ (NT)x, (NT)y, (NT)z }; + } +}; + +template +struct color2_base +{ + union + { + struct + { + T r, g; + }; + + struct + { + T x, y; + }; + + T rg[2]; + T xy[2]; + }; + + constexpr color2_base(T x = {}, T y = {}) + : x(x) + , y(y) + { + } + + constexpr bool operator == (const color2_base& rhs) const + { + return r == rhs.r && g == rhs.g; + } + + constexpr bool operator != (const color2_base& rhs) const + { + return !(*this == rhs); + } + + template + constexpr operator color2_base() const + { + return{ (NT)x, (NT)y }; + } +}; + +template +struct color1_base +{ + union + { + T r; + T x; + }; + + constexpr color1_base(T x = {}) + : x(x) + { + } + + constexpr bool operator == (const color1_base& rhs) const + { + return r == rhs.r; + } + + constexpr bool operator != (const color1_base& rhs) const + { + return !(*this == rhs); + } + + template + constexpr operator color1_base() const + { + return{ (NT)x }; + } +}; + +//specializations +using positioni = position_base; +using positionf = position_base; +using positiond = position_base; + +using coordi = coord_base; +using coordf = coord_base; +using coordd = coord_base; + +using areai = area_base; +using areaf = area_base; +using aread = area_base; + +using position1i = position1_base; +using position1f = position1_base; +using position1d = position1_base; + +using position2i = position2_base; +using position2f = position2_base; +using position2d = position2_base; + +using position3i = position3_base; +using position3f = position3_base; +using position3d = position3_base; + +using position4i = position4_base; +using position4f = position4_base; +using position4d = position4_base; + +using size2i = size2_base; +using size2f = size2_base; +using size2d = size2_base; + +using sizei = size2i; +using sizef = size2f; +using sized = size2d; + +using size3i = size3_base; +using size3f = size3_base; +using size3d = size3_base; + +using coord3i = coord3_base; +using coord3f = coord3_base; +using coord3d = coord3_base; + +using color4i = color4_base; +using color4f = color4_base; +using color4d = color4_base; + +using color3i = color3_base; +using color3f = color3_base; +using color3d = color3_base; + +using color2i = color2_base; +using color2f = color2_base; +using color2d = color2_base; + +using color1i = color1_base; +using color1f = color1_base; +using color1d = color1_base; + +namespace std +{ + template<> + class hash + { + public: + size_t operator()(const position2i& position) const + { + return ((size_t)position.x << 32) | position.y; + } + }; +} diff --git a/rpcs3/Emu/RSX/GCM.h b/rpcs3/Emu/RSX/GCM.h index bddafa0380..f3cfb808e2 100644 --- a/rpcs3/Emu/RSX/GCM.h +++ b/rpcs3/Emu/RSX/GCM.h @@ -1,6 +1,5 @@ #pragma once - -namespace vm { using namespace ps3; } +#include "Utilities/types.h" enum { @@ -134,87 +133,6 @@ enum CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP_TO_EDGE = 6, CELL_GCM_TEXTURE_MIRROR_ONCE_BORDER = 7, CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP = 8, - - // Logic Op - CELL_GCM_CLEAR = 0x1500, - CELL_GCM_AND = 0x1501, - CELL_GCM_AND_REVERSE = 0x1502, - CELL_GCM_COPY = 0x1503, - CELL_GCM_AND_INVERTED = 0x1504, - CELL_GCM_NOOP = 0x1505, - CELL_GCM_XOR = 0x1506, - CELL_GCM_OR = 0x1507, - CELL_GCM_NOR = 0x1508, - CELL_GCM_EQUIV = 0x1509, - CELL_GCM_INVERT = 0x150A, - CELL_GCM_OR_REVERSE = 0x150B, - CELL_GCM_COPY_INVERTED = 0x150C, - CELL_GCM_OR_INVERTED = 0x150D, - CELL_GCM_NAND = 0x150E, - CELL_GCM_SET = 0x150F, - - // Blend Op - CELL_GCM_FUNC_ADD = 0x8006, - CELL_GCM_MIN = 0x8007, - CELL_GCM_MAX = 0x8008, - CELL_GCM_FUNC_SUBTRACT = 0x800A, - CELL_GCM_FUNC_REVERSE_SUBTRACT = 0x800B, - CELL_GCM_FUNC_REVERSE_SUBTRACT_SIGNED = 0x0000F005, - CELL_GCM_FUNC_ADD_SIGNED = 0x0000F006, - CELL_GCM_FUNC_REVERSE_ADD_SIGNED = 0x0000F007, - - // Blend Factor - CELL_GCM_ZERO = 0, - CELL_GCM_ONE = 1, - CELL_GCM_SRC_COLOR = 0x0300, - CELL_GCM_ONE_MINUS_SRC_COLOR = 0x0301, - CELL_GCM_SRC_ALPHA = 0x0302, - CELL_GCM_ONE_MINUS_SRC_ALPHA = 0x0303, - CELL_GCM_DST_ALPHA = 0x0304, - CELL_GCM_ONE_MINUS_DST_ALPHA = 0x0305, - CELL_GCM_DST_COLOR = 0x0306, - CELL_GCM_ONE_MINUS_DST_COLOR = 0x0307, - CELL_GCM_SRC_ALPHA_SATURATE = 0x0308, - CELL_GCM_CONSTANT_COLOR = 0x8001, - CELL_GCM_ONE_MINUS_CONSTANT_COLOR = 0x8002, - CELL_GCM_CONSTANT_ALPHA = 0x8003, - CELL_GCM_ONE_MINUS_CONSTANT_ALPHA = 0x8004, - - // Stencil/Depth Compare Function - CELL_GCM_NEVER = 0x0200, - CELL_GCM_LESS = 0x0201, - CELL_GCM_EQUAL = 0x0202, - CELL_GCM_LEQUAL = 0x0203, - CELL_GCM_GREATER = 0x0204, - CELL_GCM_NOTEQUAL = 0x0205, - CELL_GCM_GEQUAL = 0x0206, - CELL_GCM_ALWAYS = 0x0207, - - // Stencil Op - CELL_GCM_KEEP = 0x1E00, - CELL_GCM_REPLACE = 0x1E01, - CELL_GCM_INCR = 0x1E02, - CELL_GCM_DECR = 0x1E03, - CELL_GCM_INCR_WRAP = 0x8507, - CELL_GCM_DECR_WRAP = 0x8508, - - // Front Face - CELL_GCM_FRONT = 0x0404, - CELL_GCM_BACK = 0x0405, - CELL_GCM_FRONT_AND_BACK = 0x0408, - - // Cull Face - CELL_GCM_CW = 0x0900, - CELL_GCM_CCW = 0x0901, - - // Texture Filter - CELL_GCM_TEXTURE_NEAREST = 1, - CELL_GCM_TEXTURE_LINEAR = 2, - CELL_GCM_TEXTURE_NEAREST_NEAREST = 3, - CELL_GCM_TEXTURE_LINEAR_NEAREST = 4, - CELL_GCM_TEXTURE_NEAREST_LINEAR = 5, - CELL_GCM_TEXTURE_LINEAR_LINEAR = 6, - CELL_GCM_TEXTURE_CONVOLUTION_MIN = 7, }; // GCM Surface @@ -260,19 +178,233 @@ enum }; -// GCM Primitive enum { - CELL_GCM_PRIMITIVE_POINTS = 1, - CELL_GCM_PRIMITIVE_LINES = 2, - CELL_GCM_PRIMITIVE_LINE_LOOP = 3, - CELL_GCM_PRIMITIVE_LINE_STRIP = 4, - CELL_GCM_PRIMITIVE_TRIANGLES = 5, - CELL_GCM_PRIMITIVE_TRIANGLE_STRIP = 6, - CELL_GCM_PRIMITIVE_TRIANGLE_FAN = 7, - CELL_GCM_PRIMITIVE_QUADS = 8, - CELL_GCM_PRIMITIVE_QUAD_STRIP = 9, - CELL_GCM_PRIMITIVE_POLYGON = 10, + CELL_GCM_TEXTURE_UNSIGNED_REMAP_NORMAL = 0, + CELL_GCM_TEXTURE_UNSIGNED_REMAP_BIASED = 1, + + CELL_GCM_TEXTURE_SIGNED_REMAP_NORMAL = 0x0, + CELL_GCM_TEXTURE_SIGNED_REMAP_CLAMPED = 0x3, + + CELL_GCM_TEXTURE_ZFUNC_NEVER = 0, + CELL_GCM_TEXTURE_ZFUNC_LESS = 1, + CELL_GCM_TEXTURE_ZFUNC_EQUAL = 2, + CELL_GCM_TEXTURE_ZFUNC_LEQUAL = 3, + CELL_GCM_TEXTURE_ZFUNC_GREATER = 4, + CELL_GCM_TEXTURE_ZFUNC_NOTEQUAL = 5, + CELL_GCM_TEXTURE_ZFUNC_GEQUAL = 6, + CELL_GCM_TEXTURE_ZFUNC_ALWAYS = 7, + + CELL_GCM_TEXTURE_GAMMA_R = 1 << 0, + CELL_GCM_TEXTURE_GAMMA_G = 1 << 1, + CELL_GCM_TEXTURE_GAMMA_B = 1 << 2, + CELL_GCM_TEXTURE_GAMMA_A = 1 << 3, + + CELL_GCM_TEXTURE_ANISO_SPREAD_0_50_TEXEL = 0x0, + CELL_GCM_TEXTURE_ANISO_SPREAD_1_00_TEXEL = 0x1, + CELL_GCM_TEXTURE_ANISO_SPREAD_1_125_TEXEL = 0x2, + CELL_GCM_TEXTURE_ANISO_SPREAD_1_25_TEXEL = 0x3, + CELL_GCM_TEXTURE_ANISO_SPREAD_1_375_TEXEL = 0x4, + CELL_GCM_TEXTURE_ANISO_SPREAD_1_50_TEXEL = 0x5, + CELL_GCM_TEXTURE_ANISO_SPREAD_1_75_TEXEL = 0x6, + CELL_GCM_TEXTURE_ANISO_SPREAD_2_00_TEXEL = 0x7, + + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX0_U = 1 << 0, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX0_V = 1 << 1, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX0_P = 1 << 2, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX0_Q = 1 << 3, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX1_U = 1 << 4, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX1_V = 1 << 5, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX1_P = 1 << 6, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX1_Q = 1 << 7, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX2_U = 1 << 8, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX2_V = 1 << 9, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX2_P = 1 << 10, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX2_Q = 1 << 11, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX3_U = 1 << 12, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX3_V = 1 << 13, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX3_P = 1 << 14, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX3_Q = 1 << 15, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX4_U = 1 << 16, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX4_V = 1 << 17, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX4_P = 1 << 18, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX4_Q = 1 << 19, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX5_U = 1 << 20, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX5_V = 1 << 21, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX5_P = 1 << 22, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX5_Q = 1 << 23, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX6_U = 1 << 24, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX6_V = 1 << 25, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX6_P = 1 << 26, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX6_Q = 1 << 27, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX7_U = 1 << 28, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX7_V = 1 << 29, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX7_P = 1 << 30, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX7_Q = 1 << 31, + + CELL_GCM_PRIMITIVE_POINTS = 1, + CELL_GCM_PRIMITIVE_LINES = 2, + CELL_GCM_PRIMITIVE_LINE_LOOP = 3, + CELL_GCM_PRIMITIVE_LINE_STRIP = 4, + CELL_GCM_PRIMITIVE_TRIANGLES = 5, + CELL_GCM_PRIMITIVE_TRIANGLE_STRIP = 6, + CELL_GCM_PRIMITIVE_TRIANGLE_FAN = 7, + CELL_GCM_PRIMITIVE_QUADS = 8, + CELL_GCM_PRIMITIVE_QUAD_STRIP = 9, + CELL_GCM_PRIMITIVE_POLYGON = 10, + + CELL_GCM_COLOR_MASK_B = 1 << 0, + CELL_GCM_COLOR_MASK_G = 1 << 8, + CELL_GCM_COLOR_MASK_R = 1 << 16, + CELL_GCM_COLOR_MASK_A = 1 << 24, + + CELL_GCM_COLOR_MASK_MRT1_A = 1 << 4, + CELL_GCM_COLOR_MASK_MRT1_R = 1 << 5, + CELL_GCM_COLOR_MASK_MRT1_G = 1 << 6, + CELL_GCM_COLOR_MASK_MRT1_B = 1 << 7, + CELL_GCM_COLOR_MASK_MRT2_A = 1 << 8, + CELL_GCM_COLOR_MASK_MRT2_R = 1 << 9, + CELL_GCM_COLOR_MASK_MRT2_G = 1 << 10, + CELL_GCM_COLOR_MASK_MRT2_B = 1 << 11, + CELL_GCM_COLOR_MASK_MRT3_A = 1 << 12, + CELL_GCM_COLOR_MASK_MRT3_R = 1 << 13, + CELL_GCM_COLOR_MASK_MRT3_G = 1 << 14, + CELL_GCM_COLOR_MASK_MRT3_B = 1 << 15, + + CELL_GCM_NEVER = 0x0200, + CELL_GCM_LESS = 0x0201, + CELL_GCM_EQUAL = 0x0202, + CELL_GCM_LEQUAL = 0x0203, + CELL_GCM_GREATER = 0x0204, + CELL_GCM_NOTEQUAL = 0x0205, + CELL_GCM_GEQUAL = 0x0206, + CELL_GCM_ALWAYS = 0x0207, + + CELL_GCM_ZERO = 0, + CELL_GCM_ONE = 1, + CELL_GCM_SRC_COLOR = 0x0300, + CELL_GCM_ONE_MINUS_SRC_COLOR = 0x0301, + CELL_GCM_SRC_ALPHA = 0x0302, + CELL_GCM_ONE_MINUS_SRC_ALPHA = 0x0303, + CELL_GCM_DST_ALPHA = 0x0304, + CELL_GCM_ONE_MINUS_DST_ALPHA = 0x0305, + CELL_GCM_DST_COLOR = 0x0306, + CELL_GCM_ONE_MINUS_DST_COLOR = 0x0307, + CELL_GCM_SRC_ALPHA_SATURATE = 0x0308, + CELL_GCM_CONSTANT_COLOR = 0x8001, + CELL_GCM_ONE_MINUS_CONSTANT_COLOR = 0x8002, + CELL_GCM_CONSTANT_ALPHA = 0x8003, + CELL_GCM_ONE_MINUS_CONSTANT_ALPHA = 0x8004, + + CELL_GCM_FUNC_ADD = 0x8006, + CELL_GCM_MIN = 0x8007, + CELL_GCM_MAX = 0x8008, + CELL_GCM_FUNC_SUBTRACT = 0x800A, + CELL_GCM_FUNC_REVERSE_SUBTRACT = 0x800B, + CELL_GCM_FUNC_REVERSE_SUBTRACT_SIGNED = 0x0000F005, + CELL_GCM_FUNC_ADD_SIGNED = 0x0000F006, + CELL_GCM_FUNC_REVERSE_ADD_SIGNED = 0x0000F007, + + CELL_GCM_FRONT = 0x0404, + CELL_GCM_BACK = 0x0405, + CELL_GCM_FRONT_AND_BACK = 0x0408, + + CELL_GCM_CW = 0x0900, + CELL_GCM_CCW = 0x0901, + + CELL_GCM_CLEAR = 0x1500, + CELL_GCM_AND = 0x1501, + CELL_GCM_AND_REVERSE = 0x1502, + CELL_GCM_COPY = 0x1503, + CELL_GCM_AND_INVERTED = 0x1504, + CELL_GCM_NOOP = 0x1505, + CELL_GCM_XOR = 0x1506, + CELL_GCM_OR = 0x1507, + CELL_GCM_NOR = 0x1508, + CELL_GCM_EQUIV = 0x1509, + CELL_GCM_INVERT = 0x150A, + CELL_GCM_OR_REVERSE = 0x150B, + CELL_GCM_COPY_INVERTED = 0x150C, + CELL_GCM_OR_INVERTED = 0x150D, + CELL_GCM_NAND = 0x150E, + CELL_GCM_SET = 0x150F, + + CELL_GCM_KEEP = 0x1E00, + CELL_GCM_REPLACE = 0x1E01, + CELL_GCM_INCR = 0x1E02, + CELL_GCM_DECR = 0x1E03, + CELL_GCM_INCR_WRAP = 0x8507, + CELL_GCM_DECR_WRAP = 0x8508, + + CELL_GCM_TRANSFER_LOCAL_TO_LOCAL = 0, + CELL_GCM_TRANSFER_MAIN_TO_LOCAL = 1, + CELL_GCM_TRANSFER_LOCAL_TO_MAIN = 2, + CELL_GCM_TRANSFER_MAIN_TO_MAIN = 3, + + CELL_GCM_INVALIDATE_TEXTURE = 1, + CELL_GCM_INVALIDATE_VERTEX_TEXTURE = 2, + + CELL_GCM_COMPMODE_DISABLED = 0, + CELL_GCM_COMPMODE_C32_2X1 = 7, + CELL_GCM_COMPMODE_C32_2X2 = 8, + CELL_GCM_COMPMODE_Z32_SEPSTENCIL = 9, + CELL_GCM_COMPMODE_Z32_SEPSTENCIL_REG = 10, + CELL_GCM_COMPMODE_Z32_SEPSTENCIL_REGULAR = 10, + CELL_GCM_COMPMODE_Z32_SEPSTENCIL_DIAGONAL = 11, + CELL_GCM_COMPMODE_Z32_SEPSTENCIL_ROTATED = 12, + + CELL_GCM_ZCULL_Z16 = 1, + CELL_GCM_ZCULL_Z24S8 = 2, + CELL_GCM_ZCULL_MSB = 0, + CELL_GCM_ZCULL_LONES = 1, + CELL_GCM_ZCULL_LESS = 0, + CELL_GCM_ZCULL_GREATER = 1, + + CELL_GCM_SCULL_SFUNC_NEVER = 0, + CELL_GCM_SCULL_SFUNC_LESS = 1, + CELL_GCM_SCULL_SFUNC_EQUAL = 2, + CELL_GCM_SCULL_SFUNC_LEQUAL = 3, + CELL_GCM_SCULL_SFUNC_GREATER = 4, + CELL_GCM_SCULL_SFUNC_NOTEQUAL = 5, + CELL_GCM_SCULL_SFUNC_GEQUAL = 6, + CELL_GCM_SCULL_SFUNC_ALWAYS = 7, + + CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE = 1 << 0, + CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR = 1 << 1, + CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE = 1 << 2, + CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR = 1 << 3, + CELL_GCM_ATTRIB_OUTPUT_MASK_FOG = 1 << 4, + CELL_GCM_ATTRIB_OUTPUT_MASK_POINTSIZE = 1 << 5, + CELL_GCM_ATTRIB_OUTPUT_MASK_UC0 = 1 << 6, + CELL_GCM_ATTRIB_OUTPUT_MASK_UC1 = 1 << 7, + CELL_GCM_ATTRIB_OUTPUT_MASK_UC2 = 1 << 8, + CELL_GCM_ATTRIB_OUTPUT_MASK_UC3 = 1 << 9, + CELL_GCM_ATTRIB_OUTPUT_MASK_UC4 = 1 << 10, + CELL_GCM_ATTRIB_OUTPUT_MASK_UC5 = 1 << 11, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX8 = 1 << 12, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX9 = 1 << 13, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX0 = 1 << 14, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX1 = 1 << 15, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX2 = 1 << 16, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX3 = 1 << 17, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX4 = 1 << 18, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX5 = 1 << 19, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX6 = 1 << 20, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX7 = 1 << 21, + + CELL_GCM_FOG_MODE_LINEAR = 0x2601, + CELL_GCM_FOG_MODE_EXP = 0x0800, + CELL_GCM_FOG_MODE_EXP2 = 0x0801, + CELL_GCM_FOG_MODE_EXP_ABS = 0x0802, + CELL_GCM_FOG_MODE_EXP2_ABS = 0x0803, + CELL_GCM_FOG_MODE_LINEAR_ABS = 0x0804, + + CELL_GCM_POLYGON_MODE_POINT = 0x1B00, + CELL_GCM_POLYGON_MODE_LINE = 0x1B01, + CELL_GCM_POLYGON_MODE_FILL = 0x1B02, + + CELL_GCM_TRUE = 1, + CELL_GCM_FALSE = 0 }; // GCM Reports @@ -297,14 +429,6 @@ enum CELL_GCM_CONTEXT_DMA_NOTIFY_MAIN_0 = 0x6660420F, }; -// User Clip Values -enum -{ - CELL_GCM_USER_CLIP_PLANE_DISABLE = 0, - CELL_GCM_USER_CLIP_PLANE_ENABLE_LT = 1, - CELL_GCM_USER_CLIP_PLANE_ENABLE_GE = 2, -}; - struct CellGcmControl { atomic_be_t put; @@ -324,14 +448,14 @@ struct CellGcmConfig struct CellGcmContextData; -typedef s32(CellGcmContextCallback)(vm::ptr, u32); +typedef s32(CellGcmContextCallback)(vm::ps3::ptr, u32); struct CellGcmContextData { - vm::bptr begin; - vm::bptr end; - vm::bptr current; - vm::bptr callback; + vm::ps3::bptr begin; + vm::ps3::bptr end; + vm::ps3::bptr current; + vm::ps3::bptr callback; }; struct gcmInfo @@ -397,33 +521,33 @@ struct CellGcmTileInfo struct GcmZcullInfo { - u32 m_offset; - u32 m_width; - u32 m_height; - u32 m_cullStart; - u32 m_zFormat; - u32 m_aaFormat; - u32 m_zcullDir; - u32 m_zcullFormat; - u32 m_sFunc; - u32 m_sRef; - u32 m_sMask; - bool m_binded; + u32 offset; + u32 width; + u32 height; + u32 cullStart; + u32 zFormat; + u32 aaFormat; + u32 zcullDir; + u32 zcullFormat; + u32 sFunc; + u32 sRef; + u32 sMask; + bool binded; GcmZcullInfo() { memset(this, 0, sizeof(*this)); } - CellGcmZcullInfo Pack() + CellGcmZcullInfo pack() const { CellGcmZcullInfo ret; - ret.region = (1<<0) | (m_zFormat<<4) | (m_aaFormat<<8); - ret.size = ((m_width>>6)<<22) | ((m_height>>6)<<6); - ret.start = m_cullStart&(~0xFFF); - ret.offset = m_offset; - ret.status0 = (m_zcullDir<<1) | (m_zcullFormat<<2) | ((m_sFunc&0xF)<<12) | (m_sRef<<16) | (m_sMask<<24); + ret.region = (1<<0) | (zFormat<<4) | (aaFormat<<8); + ret.size = ((width>>6)<<22) | ((height>>6)<<6); + ret.start = cullStart&(~0xFFF); + ret.offset = offset; + ret.status0 = (zcullDir<<1) | (zcullFormat<<2) | ((sFunc&0xF)<<12) | (sRef<<16) | (sMask<<24); ret.status1 = (0x2000<<0) | (0x20<<16); return ret; @@ -432,28 +556,28 @@ struct GcmZcullInfo struct GcmTileInfo { - u8 m_location; - u32 m_offset; - u32 m_size; - u32 m_pitch; - u8 m_comp; - u16 m_base; - u8 m_bank; - bool m_binded; + u32 location; + u32 offset; + u32 size; + u32 pitch; + u32 comp; + u32 base; + u32 bank; + bool binded; GcmTileInfo() { memset(this, 0, sizeof(*this)); } - CellGcmTileInfo Pack() + CellGcmTileInfo pack() const { CellGcmTileInfo ret; - ret.tile = (m_location + 1) | (m_bank << 4) | ((m_offset / 0x10000) << 16) | (m_location << 31); - ret.limit = ((m_offset + m_size - 1) / 0x10000) << 16 | (m_location << 31); - ret.pitch = (m_pitch / 0x100) << 8; - ret.format = m_base | ((m_base + ((m_size - 1) / 0x10000)) << 13) | (m_comp << 26) | (1 << 30); + ret.tile = (location + 1) | (bank << 4) | ((offset / 0x10000) << 16) | (location << 31); + ret.limit = ((offset + size - 1) / 0x10000) << 16 | (location << 31); + ret.pitch = (pitch / 0x100) << 8; + ret.format = base | ((base + ((size - 1) / 0x10000)) << 13) | (comp << 26) | (1 << 30); return ret; } @@ -462,1012 +586,1055 @@ struct GcmTileInfo enum { // NV40_CHANNEL_DMA (NV406E) - NV406E_SET_REFERENCE = 0x00000050, - NV406E_SET_CONTEXT_DMA_SEMAPHORE = 0x00000060, - NV406E_SEMAPHORE_OFFSET = 0x00000064, - NV406E_SEMAPHORE_ACQUIRE = 0x00000068, - NV406E_SEMAPHORE_RELEASE = 0x0000006c, + NV406E_SET_REFERENCE = 0x00000050 >> 2, + NV406E_SET_CONTEXT_DMA_SEMAPHORE = 0x00000060 >> 2, + NV406E_SEMAPHORE_OFFSET = 0x00000064 >> 2, + NV406E_SEMAPHORE_ACQUIRE = 0x00000068 >> 2, + NV406E_SEMAPHORE_RELEASE = 0x0000006c >> 2, // NV40_CURIE_PRIMITIVE (NV4097) - NV4097_SET_OBJECT = 0x00000000, - NV4097_NO_OPERATION = 0x00000100, - NV4097_NOTIFY = 0x00000104, - NV4097_WAIT_FOR_IDLE = 0x00000110, - NV4097_PM_TRIGGER = 0x00000140, - NV4097_SET_CONTEXT_DMA_NOTIFIES = 0x00000180, - NV4097_SET_CONTEXT_DMA_A = 0x00000184, - NV4097_SET_CONTEXT_DMA_B = 0x00000188, - NV4097_SET_CONTEXT_DMA_COLOR_B = 0x0000018c, - NV4097_SET_CONTEXT_DMA_STATE = 0x00000190, - NV4097_SET_CONTEXT_DMA_COLOR_A = 0x00000194, - NV4097_SET_CONTEXT_DMA_ZETA = 0x00000198, - NV4097_SET_CONTEXT_DMA_VERTEX_A = 0x0000019c, - NV4097_SET_CONTEXT_DMA_VERTEX_B = 0x000001a0, - NV4097_SET_CONTEXT_DMA_SEMAPHORE = 0x000001a4, - NV4097_SET_CONTEXT_DMA_REPORT = 0x000001a8, - NV4097_SET_CONTEXT_DMA_CLIP_ID = 0x000001ac, - NV4097_SET_CONTEXT_DMA_CULL_DATA = 0x000001b0, - NV4097_SET_CONTEXT_DMA_COLOR_C = 0x000001b4, - NV4097_SET_CONTEXT_DMA_COLOR_D = 0x000001b8, - NV4097_SET_SURFACE_CLIP_HORIZONTAL = 0x00000200, - NV4097_SET_SURFACE_CLIP_VERTICAL = 0x00000204, - NV4097_SET_SURFACE_FORMAT = 0x00000208, - NV4097_SET_SURFACE_PITCH_A = 0x0000020c, - NV4097_SET_SURFACE_COLOR_AOFFSET = 0x00000210, - NV4097_SET_SURFACE_ZETA_OFFSET = 0x00000214, - NV4097_SET_SURFACE_COLOR_BOFFSET = 0x00000218, - NV4097_SET_SURFACE_PITCH_B = 0x0000021c, - NV4097_SET_SURFACE_COLOR_TARGET = 0x00000220, - NV4097_SET_SURFACE_PITCH_Z = 0x0000022c, - NV4097_INVALIDATE_ZCULL = 0x00000234, - NV4097_SET_CYLINDRICAL_WRAP = 0x00000238, - NV4097_SET_CYLINDRICAL_WRAP1 = 0x0000023c, - NV4097_SET_SURFACE_PITCH_C = 0x00000280, - NV4097_SET_SURFACE_PITCH_D = 0x00000284, - NV4097_SET_SURFACE_COLOR_COFFSET = 0x00000288, - NV4097_SET_SURFACE_COLOR_DOFFSET = 0x0000028c, - NV4097_SET_WINDOW_OFFSET = 0x000002b8, - NV4097_SET_WINDOW_CLIP_TYPE = 0x000002bc, - NV4097_SET_WINDOW_CLIP_HORIZONTAL = 0x000002c0, - NV4097_SET_WINDOW_CLIP_VERTICAL = 0x000002c4, - NV4097_SET_DITHER_ENABLE = 0x00000300, - NV4097_SET_ALPHA_TEST_ENABLE = 0x00000304, - NV4097_SET_ALPHA_FUNC = 0x00000308, - NV4097_SET_ALPHA_REF = 0x0000030c, - NV4097_SET_BLEND_ENABLE = 0x00000310, - NV4097_SET_BLEND_FUNC_SFACTOR = 0x00000314, - NV4097_SET_BLEND_FUNC_DFACTOR = 0x00000318, - NV4097_SET_BLEND_COLOR = 0x0000031c, - NV4097_SET_BLEND_EQUATION = 0x00000320, - NV4097_SET_COLOR_MASK = 0x00000324, - NV4097_SET_STENCIL_TEST_ENABLE = 0x00000328, - NV4097_SET_STENCIL_MASK = 0x0000032c, - NV4097_SET_STENCIL_FUNC = 0x00000330, - NV4097_SET_STENCIL_FUNC_REF = 0x00000334, - NV4097_SET_STENCIL_FUNC_MASK = 0x00000338, - NV4097_SET_STENCIL_OP_FAIL = 0x0000033c, - NV4097_SET_STENCIL_OP_ZFAIL = 0x00000340, - NV4097_SET_STENCIL_OP_ZPASS = 0x00000344, - NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE = 0x00000348, - NV4097_SET_BACK_STENCIL_MASK = 0x0000034c, - NV4097_SET_BACK_STENCIL_FUNC = 0x00000350, - NV4097_SET_BACK_STENCIL_FUNC_REF = 0x00000354, - NV4097_SET_BACK_STENCIL_FUNC_MASK = 0x00000358, - NV4097_SET_BACK_STENCIL_OP_FAIL = 0x0000035c, - NV4097_SET_BACK_STENCIL_OP_ZFAIL = 0x00000360, - NV4097_SET_BACK_STENCIL_OP_ZPASS = 0x00000364, - NV4097_SET_SHADE_MODE = 0x00000368, - NV4097_SET_BLEND_ENABLE_MRT = 0x0000036c, - NV4097_SET_COLOR_MASK_MRT = 0x00000370, - NV4097_SET_LOGIC_OP_ENABLE = 0x00000374, - NV4097_SET_LOGIC_OP = 0x00000378, - NV4097_SET_BLEND_COLOR2 = 0x0000037c, - NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE = 0x00000380, - NV4097_SET_DEPTH_BOUNDS_MIN = 0x00000384, - NV4097_SET_DEPTH_BOUNDS_MAX = 0x00000388, - NV4097_SET_CLIP_MIN = 0x00000394, - NV4097_SET_CLIP_MAX = 0x00000398, - NV4097_SET_CONTROL0 = 0x000003b0, - NV4097_SET_LINE_WIDTH = 0x000003b8, - NV4097_SET_LINE_SMOOTH_ENABLE = 0x000003bc, - NV4097_SET_ANISO_SPREAD = 0x000003c0, - NV4097_SET_SCISSOR_HORIZONTAL = 0x000008c0, - NV4097_SET_SCISSOR_VERTICAL = 0x000008c4, - NV4097_SET_FOG_MODE = 0x000008cc, - NV4097_SET_FOG_PARAMS = 0x000008d0, - NV4097_SET_SHADER_PROGRAM = 0x000008e4, - NV4097_SET_VERTEX_TEXTURE_OFFSET = 0x00000900, - NV4097_SET_VERTEX_TEXTURE_FORMAT = 0x00000904, - NV4097_SET_VERTEX_TEXTURE_ADDRESS = 0x00000908, - NV4097_SET_VERTEX_TEXTURE_CONTROL0 = 0x0000090c, - NV4097_SET_VERTEX_TEXTURE_CONTROL3 = 0x00000910, - NV4097_SET_VERTEX_TEXTURE_FILTER = 0x00000914, - NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT = 0x00000918, - NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR = 0x0000091c, - NV4097_SET_VIEWPORT_HORIZONTAL = 0x00000a00, - NV4097_SET_VIEWPORT_VERTICAL = 0x00000a04, - NV4097_SET_POINT_CENTER_MODE = 0x00000a0c, - NV4097_ZCULL_SYNC = 0x00000a1c, - NV4097_SET_VIEWPORT_OFFSET = 0x00000a20, - NV4097_SET_VIEWPORT_SCALE = 0x00000a30, - NV4097_SET_POLY_OFFSET_POINT_ENABLE = 0x00000a60, - NV4097_SET_POLY_OFFSET_LINE_ENABLE = 0x00000a64, - NV4097_SET_POLY_OFFSET_FILL_ENABLE = 0x00000a68, - NV4097_SET_DEPTH_FUNC = 0x00000a6c, - NV4097_SET_DEPTH_MASK = 0x00000a70, - NV4097_SET_DEPTH_TEST_ENABLE = 0x00000a74, - NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR = 0x00000a78, - NV4097_SET_POLYGON_OFFSET_BIAS = 0x00000a7c, - NV4097_SET_VERTEX_DATA_SCALED4S_M = 0x00000a80, - NV4097_SET_TEXTURE_CONTROL2 = 0x00000b00, - NV4097_SET_TEX_COORD_CONTROL = 0x00000b40, - NV4097_SET_TRANSFORM_PROGRAM = 0x00000b80, - NV4097_SET_SPECULAR_ENABLE = 0x00001428, - NV4097_SET_TWO_SIDE_LIGHT_EN = 0x0000142c, - NV4097_CLEAR_ZCULL_SURFACE = 0x00001438, - NV4097_SET_PERFORMANCE_PARAMS = 0x00001450, - NV4097_SET_FLAT_SHADE_OP = 0x00001454, - NV4097_SET_EDGE_FLAG = 0x0000145c, - NV4097_SET_USER_CLIP_PLANE_CONTROL = 0x00001478, - NV4097_SET_POLYGON_STIPPLE = 0x0000147c, - NV4097_SET_POLYGON_STIPPLE_PATTERN = 0x00001480, - NV4097_SET_VERTEX_DATA3F_M = 0x00001500, - NV4097_SET_VERTEX_DATA_ARRAY_OFFSET = 0x00001680, - NV4097_INVALIDATE_VERTEX_CACHE_FILE = 0x00001710, - NV4097_INVALIDATE_VERTEX_FILE = 0x00001714, - NV4097_PIPE_NOP = 0x00001718, - NV4097_SET_VERTEX_DATA_BASE_OFFSET = 0x00001738, - NV4097_SET_VERTEX_DATA_BASE_INDEX = 0x0000173c, - NV4097_SET_VERTEX_DATA_ARRAY_FORMAT = 0x00001740, - NV4097_CLEAR_REPORT_VALUE = 0x000017c8, - NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE = 0x000017cc, - NV4097_GET_REPORT = 0x00001800, - NV4097_SET_ZCULL_STATS_ENABLE = 0x00001804, - NV4097_SET_BEGIN_END = 0x00001808, - NV4097_ARRAY_ELEMENT16 = 0x0000180c, - NV4097_ARRAY_ELEMENT32 = 0x00001810, - NV4097_DRAW_ARRAYS = 0x00001814, - NV4097_INLINE_ARRAY = 0x00001818, - NV4097_SET_INDEX_ARRAY_ADDRESS = 0x0000181c, - NV4097_SET_INDEX_ARRAY_DMA = 0x00001820, - NV4097_DRAW_INDEX_ARRAY = 0x00001824, - NV4097_SET_FRONT_POLYGON_MODE = 0x00001828, - NV4097_SET_BACK_POLYGON_MODE = 0x0000182c, - NV4097_SET_CULL_FACE = 0x00001830, - NV4097_SET_FRONT_FACE = 0x00001834, - NV4097_SET_POLY_SMOOTH_ENABLE = 0x00001838, - NV4097_SET_CULL_FACE_ENABLE = 0x0000183c, - NV4097_SET_TEXTURE_CONTROL3 = 0x00001840, - NV4097_SET_VERTEX_DATA2F_M = 0x00001880, - NV4097_SET_VERTEX_DATA2S_M = 0x00001900, - NV4097_SET_VERTEX_DATA4UB_M = 0x00001940, - NV4097_SET_VERTEX_DATA4S_M = 0x00001980, - NV4097_SET_TEXTURE_OFFSET = 0x00001a00, - NV4097_SET_TEXTURE_FORMAT = 0x00001a04, - NV4097_SET_TEXTURE_ADDRESS = 0x00001a08, - NV4097_SET_TEXTURE_CONTROL0 = 0x00001a0c, - NV4097_SET_TEXTURE_CONTROL1 = 0x00001a10, - NV4097_SET_TEXTURE_FILTER = 0x00001a14, - NV4097_SET_TEXTURE_IMAGE_RECT = 0x00001a18, - NV4097_SET_TEXTURE_BORDER_COLOR = 0x00001a1c, - NV4097_SET_VERTEX_DATA4F_M = 0x00001c00, - NV4097_SET_COLOR_KEY_COLOR = 0x00001d00, - NV4097_SET_SHADER_CONTROL = 0x00001d60, - NV4097_SET_INDEXED_CONSTANT_READ_LIMITS = 0x00001d64, - NV4097_SET_SEMAPHORE_OFFSET = 0x00001d6c, - NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE = 0x00001d70, - NV4097_TEXTURE_READ_SEMAPHORE_RELEASE = 0x00001d74, - NV4097_SET_ZMIN_MAX_CONTROL = 0x00001d78, - NV4097_SET_ANTI_ALIASING_CONTROL = 0x00001d7c, - NV4097_SET_SURFACE_COMPRESSION = 0x00001d80, - NV4097_SET_ZCULL_EN = 0x00001d84, - NV4097_SET_SHADER_WINDOW = 0x00001d88, - NV4097_SET_ZSTENCIL_CLEAR_VALUE = 0x00001d8c, - NV4097_SET_COLOR_CLEAR_VALUE = 0x00001d90, - NV4097_CLEAR_SURFACE = 0x00001d94, - NV4097_SET_CLEAR_RECT_HORIZONTAL = 0x00001d98, - NV4097_SET_CLEAR_RECT_VERTICAL = 0x00001d9c, - NV4097_SET_CLIP_ID_TEST_ENABLE = 0x00001da4, - NV4097_SET_RESTART_INDEX_ENABLE = 0x00001dac, - NV4097_SET_RESTART_INDEX = 0x00001db0, - NV4097_SET_LINE_STIPPLE = 0x00001db4, - NV4097_SET_LINE_STIPPLE_PATTERN = 0x00001db8, - NV4097_SET_VERTEX_DATA1F_M = 0x00001e40, - NV4097_SET_TRANSFORM_EXECUTION_MODE = 0x00001e94, - NV4097_SET_RENDER_ENABLE = 0x00001e98, - NV4097_SET_TRANSFORM_PROGRAM_LOAD = 0x00001e9c, - NV4097_SET_TRANSFORM_PROGRAM_START = 0x00001ea0, - NV4097_SET_ZCULL_CONTROL0 = 0x00001ea4, - NV4097_SET_ZCULL_CONTROL1 = 0x00001ea8, - NV4097_SET_SCULL_CONTROL = 0x00001eac, - NV4097_SET_POINT_SIZE = 0x00001ee0, - NV4097_SET_POINT_PARAMS_ENABLE = 0x00001ee4, - NV4097_SET_POINT_SPRITE_CONTROL = 0x00001ee8, - NV4097_SET_TRANSFORM_TIMEOUT = 0x00001ef8, - NV4097_SET_TRANSFORM_CONSTANT_LOAD = 0x00001efc, - NV4097_SET_TRANSFORM_CONSTANT = 0x00001f00, - NV4097_SET_FREQUENCY_DIVIDER_OPERATION = 0x00001fc0, - NV4097_SET_ATTRIB_COLOR = 0x00001fc4, - NV4097_SET_ATTRIB_TEX_COORD = 0x00001fc8, - NV4097_SET_ATTRIB_TEX_COORD_EX = 0x00001fcc, - NV4097_SET_ATTRIB_UCLIP0 = 0x00001fd0, - NV4097_SET_ATTRIB_UCLIP1 = 0x00001fd4, - NV4097_INVALIDATE_L2 = 0x00001fd8, - NV4097_SET_REDUCE_DST_COLOR = 0x00001fe0, - NV4097_SET_NO_PARANOID_TEXTURE_FETCHES = 0x00001fe8, - NV4097_SET_SHADER_PACKER = 0x00001fec, - NV4097_SET_VERTEX_ATTRIB_INPUT_MASK = 0x00001ff0, - NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK = 0x00001ff4, - NV4097_SET_TRANSFORM_BRANCH_BITS = 0x00001ff8, + NV4097_SET_OBJECT = 0x00000000 >> 2, + NV4097_NO_OPERATION = 0x00000100 >> 2, + NV4097_NOTIFY = 0x00000104 >> 2, + NV4097_WAIT_FOR_IDLE = 0x00000110 >> 2, + NV4097_PM_TRIGGER = 0x00000140 >> 2, + NV4097_SET_CONTEXT_DMA_NOTIFIES = 0x00000180 >> 2, + NV4097_SET_CONTEXT_DMA_A = 0x00000184 >> 2, + NV4097_SET_CONTEXT_DMA_B = 0x00000188 >> 2, + NV4097_SET_CONTEXT_DMA_COLOR_B = 0x0000018c >> 2, + NV4097_SET_CONTEXT_DMA_STATE = 0x00000190 >> 2, + NV4097_SET_CONTEXT_DMA_COLOR_A = 0x00000194 >> 2, + NV4097_SET_CONTEXT_DMA_ZETA = 0x00000198 >> 2, + NV4097_SET_CONTEXT_DMA_VERTEX_A = 0x0000019c >> 2, + NV4097_SET_CONTEXT_DMA_VERTEX_B = 0x000001a0 >> 2, + NV4097_SET_CONTEXT_DMA_SEMAPHORE = 0x000001a4 >> 2, + NV4097_SET_CONTEXT_DMA_REPORT = 0x000001a8 >> 2, + NV4097_SET_CONTEXT_DMA_CLIP_ID = 0x000001ac >> 2, + NV4097_SET_CONTEXT_DMA_CULL_DATA = 0x000001b0 >> 2, + NV4097_SET_CONTEXT_DMA_COLOR_C = 0x000001b4 >> 2, + NV4097_SET_CONTEXT_DMA_COLOR_D = 0x000001b8 >> 2, + NV4097_SET_SURFACE_CLIP_HORIZONTAL = 0x00000200 >> 2, + NV4097_SET_SURFACE_CLIP_VERTICAL = 0x00000204 >> 2, + NV4097_SET_SURFACE_FORMAT = 0x00000208 >> 2, + NV4097_SET_SURFACE_PITCH_A = 0x0000020c >> 2, + NV4097_SET_SURFACE_COLOR_AOFFSET = 0x00000210 >> 2, + NV4097_SET_SURFACE_ZETA_OFFSET = 0x00000214 >> 2, + NV4097_SET_SURFACE_COLOR_BOFFSET = 0x00000218 >> 2, + NV4097_SET_SURFACE_PITCH_B = 0x0000021c >> 2, + NV4097_SET_SURFACE_COLOR_TARGET = 0x00000220 >> 2, + NV4097_SET_SURFACE_PITCH_Z = 0x0000022c >> 2, + NV4097_INVALIDATE_ZCULL = 0x00000234 >> 2, + NV4097_SET_CYLINDRICAL_WRAP = 0x00000238 >> 2, + NV4097_SET_CYLINDRICAL_WRAP1 = 0x0000023c >> 2, + NV4097_SET_SURFACE_PITCH_C = 0x00000280 >> 2, + NV4097_SET_SURFACE_PITCH_D = 0x00000284 >> 2, + NV4097_SET_SURFACE_COLOR_COFFSET = 0x00000288 >> 2, + NV4097_SET_SURFACE_COLOR_DOFFSET = 0x0000028c >> 2, + NV4097_SET_WINDOW_OFFSET = 0x000002b8 >> 2, + NV4097_SET_WINDOW_CLIP_TYPE = 0x000002bc >> 2, + NV4097_SET_WINDOW_CLIP_HORIZONTAL = 0x000002c0 >> 2, + NV4097_SET_WINDOW_CLIP_VERTICAL = 0x000002c4 >> 2, + NV4097_SET_DITHER_ENABLE = 0x00000300 >> 2, + NV4097_SET_ALPHA_TEST_ENABLE = 0x00000304 >> 2, + NV4097_SET_ALPHA_FUNC = 0x00000308 >> 2, + NV4097_SET_ALPHA_REF = 0x0000030c >> 2, + NV4097_SET_BLEND_ENABLE = 0x00000310 >> 2, + NV4097_SET_BLEND_FUNC_SFACTOR = 0x00000314 >> 2, + NV4097_SET_BLEND_FUNC_DFACTOR = 0x00000318 >> 2, + NV4097_SET_BLEND_COLOR = 0x0000031c >> 2, + NV4097_SET_BLEND_EQUATION = 0x00000320 >> 2, + NV4097_SET_COLOR_MASK = 0x00000324 >> 2, + NV4097_SET_STENCIL_TEST_ENABLE = 0x00000328 >> 2, + NV4097_SET_STENCIL_MASK = 0x0000032c >> 2, + NV4097_SET_STENCIL_FUNC = 0x00000330 >> 2, + NV4097_SET_STENCIL_FUNC_REF = 0x00000334 >> 2, + NV4097_SET_STENCIL_FUNC_MASK = 0x00000338 >> 2, + NV4097_SET_STENCIL_OP_FAIL = 0x0000033c >> 2, + NV4097_SET_STENCIL_OP_ZFAIL = 0x00000340 >> 2, + NV4097_SET_STENCIL_OP_ZPASS = 0x00000344 >> 2, + NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE = 0x00000348 >> 2, + NV4097_SET_BACK_STENCIL_MASK = 0x0000034c >> 2, + NV4097_SET_BACK_STENCIL_FUNC = 0x00000350 >> 2, + NV4097_SET_BACK_STENCIL_FUNC_REF = 0x00000354 >> 2, + NV4097_SET_BACK_STENCIL_FUNC_MASK = 0x00000358 >> 2, + NV4097_SET_BACK_STENCIL_OP_FAIL = 0x0000035c >> 2, + NV4097_SET_BACK_STENCIL_OP_ZFAIL = 0x00000360 >> 2, + NV4097_SET_BACK_STENCIL_OP_ZPASS = 0x00000364 >> 2, + NV4097_SET_SHADE_MODE = 0x00000368 >> 2, + NV4097_SET_BLEND_ENABLE_MRT = 0x0000036c >> 2, + NV4097_SET_COLOR_MASK_MRT = 0x00000370 >> 2, + NV4097_SET_LOGIC_OP_ENABLE = 0x00000374 >> 2, + NV4097_SET_LOGIC_OP = 0x00000378 >> 2, + NV4097_SET_BLEND_COLOR2 = 0x0000037c >> 2, + NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE = 0x00000380 >> 2, + NV4097_SET_DEPTH_BOUNDS_MIN = 0x00000384 >> 2, + NV4097_SET_DEPTH_BOUNDS_MAX = 0x00000388 >> 2, + NV4097_SET_CLIP_MIN = 0x00000394 >> 2, + NV4097_SET_CLIP_MAX = 0x00000398 >> 2, + NV4097_SET_CONTROL0 = 0x000003b0 >> 2, + NV4097_SET_LINE_WIDTH = 0x000003b8 >> 2, + NV4097_SET_LINE_SMOOTH_ENABLE = 0x000003bc >> 2, + NV4097_SET_ANISO_SPREAD = 0x000003c0 >> 2, + NV4097_SET_SCISSOR_HORIZONTAL = 0x000008c0 >> 2, + NV4097_SET_SCISSOR_VERTICAL = 0x000008c4 >> 2, + NV4097_SET_FOG_MODE = 0x000008cc >> 2, + NV4097_SET_FOG_PARAMS = 0x000008d0 >> 2, + NV4097_SET_SHADER_PROGRAM = 0x000008e4 >> 2, + NV4097_SET_VERTEX_TEXTURE_OFFSET = 0x00000900 >> 2, + NV4097_SET_VERTEX_TEXTURE_FORMAT = 0x00000904 >> 2, + NV4097_SET_VERTEX_TEXTURE_ADDRESS = 0x00000908 >> 2, + NV4097_SET_VERTEX_TEXTURE_CONTROL0 = 0x0000090c >> 2, + NV4097_SET_VERTEX_TEXTURE_CONTROL3 = 0x00000910 >> 2, + NV4097_SET_VERTEX_TEXTURE_FILTER = 0x00000914 >> 2, + NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT = 0x00000918 >> 2, + NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR = 0x0000091c >> 2, + NV4097_SET_VIEWPORT_HORIZONTAL = 0x00000a00 >> 2, + NV4097_SET_VIEWPORT_VERTICAL = 0x00000a04 >> 2, + NV4097_SET_POINT_CENTER_MODE = 0x00000a0c >> 2, + NV4097_ZCULL_SYNC = 0x00000a1c >> 2, + NV4097_SET_VIEWPORT_OFFSET = 0x00000a20 >> 2, + NV4097_SET_VIEWPORT_SCALE = 0x00000a30 >> 2, + NV4097_SET_POLY_OFFSET_POINT_ENABLE = 0x00000a60 >> 2, + NV4097_SET_POLY_OFFSET_LINE_ENABLE = 0x00000a64 >> 2, + NV4097_SET_POLY_OFFSET_FILL_ENABLE = 0x00000a68 >> 2, + NV4097_SET_DEPTH_FUNC = 0x00000a6c >> 2, + NV4097_SET_DEPTH_MASK = 0x00000a70 >> 2, + NV4097_SET_DEPTH_TEST_ENABLE = 0x00000a74 >> 2, + NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR = 0x00000a78 >> 2, + NV4097_SET_POLYGON_OFFSET_BIAS = 0x00000a7c >> 2, + NV4097_SET_VERTEX_DATA_SCALED4S_M = 0x00000a80 >> 2, + NV4097_SET_TEXTURE_CONTROL2 = 0x00000b00 >> 2, + NV4097_SET_TEX_COORD_CONTROL = 0x00000b40 >> 2, + NV4097_SET_TRANSFORM_PROGRAM = 0x00000b80 >> 2, + NV4097_SET_SPECULAR_ENABLE = 0x00001428 >> 2, + NV4097_SET_TWO_SIDE_LIGHT_EN = 0x0000142c >> 2, + NV4097_CLEAR_ZCULL_SURFACE = 0x00001438 >> 2, + NV4097_SET_PERFORMANCE_PARAMS = 0x00001450 >> 2, + NV4097_SET_FLAT_SHADE_OP = 0x00001454 >> 2, + NV4097_SET_EDGE_FLAG = 0x0000145c >> 2, + NV4097_SET_USER_CLIP_PLANE_CONTROL = 0x00001478 >> 2, + NV4097_SET_POLYGON_STIPPLE = 0x0000147c >> 2, + NV4097_SET_POLYGON_STIPPLE_PATTERN = 0x00001480 >> 2, + NV4097_SET_VERTEX_DATA3F_M = 0x00001500 >> 2, + NV4097_SET_VERTEX_DATA_ARRAY_OFFSET = 0x00001680 >> 2, + NV4097_INVALIDATE_VERTEX_CACHE_FILE = 0x00001710 >> 2, + NV4097_INVALIDATE_VERTEX_FILE = 0x00001714 >> 2, + NV4097_PIPE_NOP = 0x00001718 >> 2, + NV4097_SET_VERTEX_DATA_BASE_OFFSET = 0x00001738 >> 2, + NV4097_SET_VERTEX_DATA_BASE_INDEX = 0x0000173c >> 2, + NV4097_SET_VERTEX_DATA_ARRAY_FORMAT = 0x00001740 >> 2, + NV4097_CLEAR_REPORT_VALUE = 0x000017c8 >> 2, + NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE = 0x000017cc >> 2, + NV4097_GET_REPORT = 0x00001800 >> 2, + NV4097_SET_ZCULL_STATS_ENABLE = 0x00001804 >> 2, + NV4097_SET_BEGIN_END = 0x00001808 >> 2, + NV4097_ARRAY_ELEMENT16 = 0x0000180c >> 2, + NV4097_ARRAY_ELEMENT32 = 0x00001810 >> 2, + NV4097_DRAW_ARRAYS = 0x00001814 >> 2, + NV4097_INLINE_ARRAY = 0x00001818 >> 2, + NV4097_SET_INDEX_ARRAY_ADDRESS = 0x0000181c >> 2, + NV4097_SET_INDEX_ARRAY_DMA = 0x00001820 >> 2, + NV4097_DRAW_INDEX_ARRAY = 0x00001824 >> 2, + NV4097_SET_FRONT_POLYGON_MODE = 0x00001828 >> 2, + NV4097_SET_BACK_POLYGON_MODE = 0x0000182c >> 2, + NV4097_SET_CULL_FACE = 0x00001830 >> 2, + NV4097_SET_FRONT_FACE = 0x00001834 >> 2, + NV4097_SET_POLY_SMOOTH_ENABLE = 0x00001838 >> 2, + NV4097_SET_CULL_FACE_ENABLE = 0x0000183c >> 2, + NV4097_SET_TEXTURE_CONTROL3 = 0x00001840 >> 2, + NV4097_SET_VERTEX_DATA2F_M = 0x00001880 >> 2, + NV4097_SET_VERTEX_DATA2S_M = 0x00001900 >> 2, + NV4097_SET_VERTEX_DATA4UB_M = 0x00001940 >> 2, + NV4097_SET_VERTEX_DATA4S_M = 0x00001980 >> 2, + NV4097_SET_TEXTURE_OFFSET = 0x00001a00 >> 2, + NV4097_SET_TEXTURE_FORMAT = 0x00001a04 >> 2, + NV4097_SET_TEXTURE_ADDRESS = 0x00001a08 >> 2, + NV4097_SET_TEXTURE_CONTROL0 = 0x00001a0c >> 2, + NV4097_SET_TEXTURE_CONTROL1 = 0x00001a10 >> 2, + NV4097_SET_TEXTURE_FILTER = 0x00001a14 >> 2, + NV4097_SET_TEXTURE_IMAGE_RECT = 0x00001a18 >> 2, + NV4097_SET_TEXTURE_BORDER_COLOR = 0x00001a1c >> 2, + NV4097_SET_VERTEX_DATA4F_M = 0x00001c00 >> 2, + NV4097_SET_COLOR_KEY_COLOR = 0x00001d00 >> 2, + NV4097_SET_SHADER_CONTROL = 0x00001d60 >> 2, + NV4097_SET_INDEXED_CONSTANT_READ_LIMITS = 0x00001d64 >> 2, + NV4097_SET_SEMAPHORE_OFFSET = 0x00001d6c >> 2, + NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE = 0x00001d70 >> 2, + NV4097_TEXTURE_READ_SEMAPHORE_RELEASE = 0x00001d74 >> 2, + NV4097_SET_ZMIN_MAX_CONTROL = 0x00001d78 >> 2, + NV4097_SET_ANTI_ALIASING_CONTROL = 0x00001d7c >> 2, + NV4097_SET_SURFACE_COMPRESSION = 0x00001d80 >> 2, + NV4097_SET_ZCULL_EN = 0x00001d84 >> 2, + NV4097_SET_SHADER_WINDOW = 0x00001d88 >> 2, + NV4097_SET_ZSTENCIL_CLEAR_VALUE = 0x00001d8c >> 2, + NV4097_SET_COLOR_CLEAR_VALUE = 0x00001d90 >> 2, + NV4097_CLEAR_SURFACE = 0x00001d94 >> 2, + NV4097_SET_CLEAR_RECT_HORIZONTAL = 0x00001d98 >> 2, + NV4097_SET_CLEAR_RECT_VERTICAL = 0x00001d9c >> 2, + NV4097_SET_CLIP_ID_TEST_ENABLE = 0x00001da4 >> 2, + NV4097_SET_RESTART_INDEX_ENABLE = 0x00001dac >> 2, + NV4097_SET_RESTART_INDEX = 0x00001db0 >> 2, + NV4097_SET_LINE_STIPPLE = 0x00001db4 >> 2, + NV4097_SET_LINE_STIPPLE_PATTERN = 0x00001db8 >> 2, + NV4097_SET_VERTEX_DATA1F_M = 0x00001e40 >> 2, + NV4097_SET_TRANSFORM_EXECUTION_MODE = 0x00001e94 >> 2, + NV4097_SET_RENDER_ENABLE = 0x00001e98 >> 2, + NV4097_SET_TRANSFORM_PROGRAM_LOAD = 0x00001e9c >> 2, + NV4097_SET_TRANSFORM_PROGRAM_START = 0x00001ea0 >> 2, + NV4097_SET_ZCULL_CONTROL0 = 0x00001ea4 >> 2, + NV4097_SET_ZCULL_CONTROL1 = 0x00001ea8 >> 2, + NV4097_SET_SCULL_CONTROL = 0x00001eac >> 2, + NV4097_SET_POINT_SIZE = 0x00001ee0 >> 2, + NV4097_SET_POINT_PARAMS_ENABLE = 0x00001ee4 >> 2, + NV4097_SET_POINT_SPRITE_CONTROL = 0x00001ee8 >> 2, + NV4097_SET_TRANSFORM_TIMEOUT = 0x00001ef8 >> 2, + NV4097_SET_TRANSFORM_CONSTANT_LOAD = 0x00001efc >> 2, + NV4097_SET_TRANSFORM_CONSTANT = 0x00001f00 >> 2, + NV4097_SET_FREQUENCY_DIVIDER_OPERATION = 0x00001fc0 >> 2, + NV4097_SET_ATTRIB_COLOR = 0x00001fc4 >> 2, + NV4097_SET_ATTRIB_TEX_COORD = 0x00001fc8 >> 2, + NV4097_SET_ATTRIB_TEX_COORD_EX = 0x00001fcc >> 2, + NV4097_SET_ATTRIB_UCLIP0 = 0x00001fd0 >> 2, + NV4097_SET_ATTRIB_UCLIP1 = 0x00001fd4 >> 2, + NV4097_INVALIDATE_L2 = 0x00001fd8 >> 2, + NV4097_SET_REDUCE_DST_COLOR = 0x00001fe0 >> 2, + NV4097_SET_NO_PARANOID_TEXTURE_FETCHES = 0x00001fe8 >> 2, + NV4097_SET_SHADER_PACKER = 0x00001fec >> 2, + NV4097_SET_VERTEX_ATTRIB_INPUT_MASK = 0x00001ff0 >> 2, + NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK = 0x00001ff4 >> 2, + NV4097_SET_TRANSFORM_BRANCH_BITS = 0x00001ff8 >> 2, // NV03_MEMORY_TO_MEMORY_FORMAT (NV0039) - NV0039_SET_OBJECT = 0x00002000, - NV0039_SET_CONTEXT_DMA_NOTIFIES = 0x00002180, - NV0039_SET_CONTEXT_DMA_BUFFER_IN = 0x00002184, - NV0039_SET_CONTEXT_DMA_BUFFER_OUT = 0x00002188, - NV0039_OFFSET_IN = 0x0000230C, - NV0039_OFFSET_OUT = 0x00002310, - NV0039_PITCH_IN = 0x00002314, - NV0039_PITCH_OUT = 0x00002318, - NV0039_LINE_LENGTH_IN = 0x0000231C, - NV0039_LINE_COUNT = 0x00002320, - NV0039_FORMAT = 0x00002324, - NV0039_BUFFER_NOTIFY = 0x00002328, + NV0039_SET_OBJECT = 0x00002000 >> 2, + NV0039_SET_CONTEXT_DMA_NOTIFIES = 0x00002180 >> 2, + NV0039_SET_CONTEXT_DMA_BUFFER_IN = 0x00002184 >> 2, + NV0039_SET_CONTEXT_DMA_BUFFER_OUT = 0x00002188 >> 2, + NV0039_OFFSET_IN = 0x0000230C >> 2, + NV0039_OFFSET_OUT = 0x00002310 >> 2, + NV0039_PITCH_IN = 0x00002314 >> 2, + NV0039_PITCH_OUT = 0x00002318 >> 2, + NV0039_LINE_LENGTH_IN = 0x0000231C >> 2, + NV0039_LINE_COUNT = 0x00002320 >> 2, + NV0039_FORMAT = 0x00002324 >> 2, + NV0039_BUFFER_NOTIFY = 0x00002328 >> 2, // NV30_CONTEXT_SURFACES_2D (NV3062) - NV3062_SET_OBJECT = 0x00006000, - NV3062_SET_CONTEXT_DMA_NOTIFIES = 0x00006180, - NV3062_SET_CONTEXT_DMA_IMAGE_SOURCE = 0x00006184, - NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN = 0x00006188, - NV3062_SET_COLOR_FORMAT = 0x00006300, - NV3062_SET_PITCH = 0x00006304, - NV3062_SET_OFFSET_SOURCE = 0x00006308, - NV3062_SET_OFFSET_DESTIN = 0x0000630C, + NV3062_SET_OBJECT = 0x00006000 >> 2, + NV3062_SET_CONTEXT_DMA_NOTIFIES = 0x00006180 >> 2, + NV3062_SET_CONTEXT_DMA_IMAGE_SOURCE = 0x00006184 >> 2, + NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN = 0x00006188 >> 2, + NV3062_SET_COLOR_FORMAT = 0x00006300 >> 2, + NV3062_SET_PITCH = 0x00006304 >> 2, + NV3062_SET_OFFSET_SOURCE = 0x00006308 >> 2, + NV3062_SET_OFFSET_DESTIN = 0x0000630C >> 2, // NV30_CONTEXT_SURFACE_SWIZZLED (NV309E) - NV309E_SET_OBJECT = 0x00008000, - NV309E_SET_CONTEXT_DMA_NOTIFIES = 0x00008180, - NV309E_SET_CONTEXT_DMA_IMAGE = 0x00008184, - NV309E_SET_FORMAT = 0x00008300, - NV309E_SET_OFFSET = 0x00008304, + NV309E_SET_OBJECT = 0x00008000 >> 2, + NV309E_SET_CONTEXT_DMA_NOTIFIES = 0x00008180 >> 2, + NV309E_SET_CONTEXT_DMA_IMAGE = 0x00008184 >> 2, + NV309E_SET_FORMAT = 0x00008300 >> 2, + NV309E_SET_OFFSET = 0x00008304 >> 2, // NV30_IMAGE_FROM_CPU (NV308A) - NV308A_SET_OBJECT = 0x0000A000, - NV308A_SET_CONTEXT_DMA_NOTIFIES = 0x0000A180, - NV308A_SET_CONTEXT_COLOR_KEY = 0x0000A184, - NV308A_SET_CONTEXT_CLIP_RECTANGLE = 0x0000A188, - NV308A_SET_CONTEXT_PATTERN = 0x0000A18C, - NV308A_SET_CONTEXT_ROP = 0x0000A190, - NV308A_SET_CONTEXT_BETA1 = 0x0000A194, - NV308A_SET_CONTEXT_BETA4 = 0x0000A198, - NV308A_SET_CONTEXT_SURFACE = 0x0000A19C, - NV308A_SET_COLOR_CONVERSION = 0x0000A2F8, - NV308A_SET_OPERATION = 0x0000A2FC, - NV308A_SET_COLOR_FORMAT = 0x0000A300, - NV308A_POINT = 0x0000A304, - NV308A_SIZE_OUT = 0x0000A308, - NV308A_SIZE_IN = 0x0000A30C, - NV308A_COLOR = 0x0000A400, + NV308A_SET_OBJECT = 0x0000A000 >> 2, + NV308A_SET_CONTEXT_DMA_NOTIFIES = 0x0000A180 >> 2, + NV308A_SET_CONTEXT_COLOR_KEY = 0x0000A184 >> 2, + NV308A_SET_CONTEXT_CLIP_RECTANGLE = 0x0000A188 >> 2, + NV308A_SET_CONTEXT_PATTERN = 0x0000A18C >> 2, + NV308A_SET_CONTEXT_ROP = 0x0000A190 >> 2, + NV308A_SET_CONTEXT_BETA1 = 0x0000A194 >> 2, + NV308A_SET_CONTEXT_BETA4 = 0x0000A198 >> 2, + NV308A_SET_CONTEXT_SURFACE = 0x0000A19C >> 2, + NV308A_SET_COLOR_CONVERSION = 0x0000A2F8 >> 2, + NV308A_SET_OPERATION = 0x0000A2FC >> 2, + NV308A_SET_COLOR_FORMAT = 0x0000A300 >> 2, + NV308A_POINT = 0x0000A304 >> 2, + NV308A_SIZE_OUT = 0x0000A308 >> 2, + NV308A_SIZE_IN = 0x0000A30C >> 2, + NV308A_COLOR = 0x0000A400 >> 2, // NV30_SCALED_IMAGE_FROM_MEMORY (NV3089) - NV3089_SET_OBJECT = 0x0000C000, - NV3089_SET_CONTEXT_DMA_NOTIFIES = 0x0000C180, - NV3089_SET_CONTEXT_DMA_IMAGE = 0x0000C184, - NV3089_SET_CONTEXT_PATTERN = 0x0000C188, - NV3089_SET_CONTEXT_ROP = 0x0000C18C, - NV3089_SET_CONTEXT_BETA1 = 0x0000C190, - NV3089_SET_CONTEXT_BETA4 = 0x0000C194, - NV3089_SET_CONTEXT_SURFACE = 0x0000C198, - NV3089_SET_COLOR_CONVERSION = 0x0000C2FC, - NV3089_SET_COLOR_FORMAT = 0x0000C300, - NV3089_SET_OPERATION = 0x0000C304, - NV3089_CLIP_POINT = 0x0000C308, - NV3089_CLIP_SIZE = 0x0000C30C, - NV3089_IMAGE_OUT_POINT = 0x0000C310, - NV3089_IMAGE_OUT_SIZE = 0x0000C314, - NV3089_DS_DX = 0x0000C318, - NV3089_DT_DY = 0x0000C31C, - NV3089_IMAGE_IN_SIZE = 0x0000C400, - NV3089_IMAGE_IN_FORMAT = 0x0000C404, - NV3089_IMAGE_IN_OFFSET = 0x0000C408, - NV3089_IMAGE_IN = 0x0000C40C, + NV3089_SET_OBJECT = 0x0000C000 >> 2, + NV3089_SET_CONTEXT_DMA_NOTIFIES = 0x0000C180 >> 2, + NV3089_SET_CONTEXT_DMA_IMAGE = 0x0000C184 >> 2, + NV3089_SET_CONTEXT_PATTERN = 0x0000C188 >> 2, + NV3089_SET_CONTEXT_ROP = 0x0000C18C >> 2, + NV3089_SET_CONTEXT_BETA1 = 0x0000C190 >> 2, + NV3089_SET_CONTEXT_BETA4 = 0x0000C194 >> 2, + NV3089_SET_CONTEXT_SURFACE = 0x0000C198 >> 2, + NV3089_SET_COLOR_CONVERSION = 0x0000C2FC >> 2, + NV3089_SET_COLOR_FORMAT = 0x0000C300 >> 2, + NV3089_SET_OPERATION = 0x0000C304 >> 2, + NV3089_CLIP_POINT = 0x0000C308 >> 2, + NV3089_CLIP_SIZE = 0x0000C30C >> 2, + NV3089_IMAGE_OUT_POINT = 0x0000C310 >> 2, + NV3089_IMAGE_OUT_SIZE = 0x0000C314 >> 2, + NV3089_DS_DX = 0x0000C318 >> 2, + NV3089_DT_DY = 0x0000C31C >> 2, + NV3089_IMAGE_IN_SIZE = 0x0000C400 >> 2, + NV3089_IMAGE_IN_FORMAT = 0x0000C404 >> 2, + NV3089_IMAGE_IN_OFFSET = 0x0000C408 >> 2, + NV3089_IMAGE_IN = 0x0000C40C >> 2, - GCM_SET_USER_COMMAND = 0x0000EB00, + GCM_SET_USER_COMMAND = 0x0000EB00 >> 2, + + GCM_FLIP_COMMAND = 0x0000FEAC >> 2 }; -static const std::string GetMethodName(const u32 id) -{ - struct MethodName - { - const u32 id; - const std::string& name; - } static const METHOD_NAME_LIST[] = { - { NV4097_NO_OPERATION , "NV4097_NO_OPERATION" }, - { NV4097_NOTIFY , "NV4097_NOTIFY" }, - { NV4097_WAIT_FOR_IDLE , "NV4097_WAIT_FOR_IDLE" }, - { NV4097_PM_TRIGGER , "NV4097_PM_TRIGGER" }, - { NV4097_SET_CONTEXT_DMA_NOTIFIES , "NV4097_SET_CONTEXT_DMA_NOTIFIES" }, - { NV4097_SET_CONTEXT_DMA_A , "NV4097_SET_CONTEXT_DMA_A" }, - { NV4097_SET_CONTEXT_DMA_B , "NV4097_SET_CONTEXT_DMA_B" }, - { NV4097_SET_CONTEXT_DMA_COLOR_B , "NV4097_SET_CONTEXT_DMA_COLOR_B" }, - { NV4097_SET_CONTEXT_DMA_STATE , "NV4097_SET_CONTEXT_DMA_STATE" }, - { NV4097_SET_CONTEXT_DMA_COLOR_A , "NV4097_SET_CONTEXT_DMA_COLOR_A" }, - { NV4097_SET_CONTEXT_DMA_ZETA , "NV4097_SET_CONTEXT_DMA_ZETA" }, - { NV4097_SET_CONTEXT_DMA_VERTEX_A , "NV4097_SET_CONTEXT_DMA_VERTEX_A" }, - { NV4097_SET_CONTEXT_DMA_VERTEX_B , "NV4097_SET_CONTEXT_DMA_VERTEX_B" }, - { NV4097_SET_CONTEXT_DMA_SEMAPHORE , "NV4097_SET_CONTEXT_DMA_SEMAPHORE" }, - { NV4097_SET_CONTEXT_DMA_REPORT , "NV4097_SET_CONTEXT_DMA_REPORT" }, - { NV4097_SET_CONTEXT_DMA_CLIP_ID , "NV4097_SET_CONTEXT_DMA_CLIP_ID" }, - { NV4097_SET_CONTEXT_DMA_CULL_DATA , "NV4097_SET_CONTEXT_DMA_CULL_DATA" }, - { NV4097_SET_CONTEXT_DMA_COLOR_C , "NV4097_SET_CONTEXT_DMA_COLOR_C" }, - { NV4097_SET_CONTEXT_DMA_COLOR_D , "NV4097_SET_CONTEXT_DMA_COLOR_D" }, - { NV4097_SET_SURFACE_CLIP_HORIZONTAL , "NV4097_SET_SURFACE_CLIP_HORIZONTAL" }, - { NV4097_SET_SURFACE_CLIP_VERTICAL , "NV4097_SET_SURFACE_CLIP_VERTICAL" }, - { NV4097_SET_SURFACE_FORMAT , "NV4097_SET_SURFACE_FORMAT" }, - { NV4097_SET_SURFACE_PITCH_A , "NV4097_SET_SURFACE_PITCH_A" }, - { NV4097_SET_SURFACE_COLOR_AOFFSET , "NV4097_SET_SURFACE_COLOR_AOFFSET" }, - { NV4097_SET_SURFACE_ZETA_OFFSET , "NV4097_SET_SURFACE_ZETA_OFFSET" }, - { NV4097_SET_SURFACE_COLOR_BOFFSET , "NV4097_SET_SURFACE_COLOR_BOFFSET" }, - { NV4097_SET_SURFACE_PITCH_B , "NV4097_SET_SURFACE_PITCH_B" }, - { NV4097_SET_SURFACE_COLOR_TARGET , "NV4097_SET_SURFACE_COLOR_TARGET" }, - { NV4097_SET_SURFACE_PITCH_Z , "NV4097_SET_SURFACE_PITCH_Z" }, - { NV4097_INVALIDATE_ZCULL , "NV4097_INVALIDATE_ZCULL" }, - { NV4097_SET_CYLINDRICAL_WRAP , "NV4097_SET_CYLINDRICAL_WRAP" }, - { NV4097_SET_CYLINDRICAL_WRAP1 , "NV4097_SET_CYLINDRICAL_WRAP1" }, - { NV4097_SET_SURFACE_PITCH_C , "NV4097_SET_SURFACE_PITCH_C" }, - { NV4097_SET_SURFACE_PITCH_D , "NV4097_SET_SURFACE_PITCH_D" }, - { NV4097_SET_SURFACE_COLOR_COFFSET , "NV4097_SET_SURFACE_COLOR_COFFSET" }, - { NV4097_SET_SURFACE_COLOR_DOFFSET , "NV4097_SET_SURFACE_COLOR_DOFFSET" }, - { NV4097_SET_WINDOW_OFFSET , "NV4097_SET_WINDOW_OFFSET" }, - { NV4097_SET_DITHER_ENABLE , "NV4097_SET_DITHER_ENABLE" }, - { NV4097_SET_ALPHA_TEST_ENABLE , "NV4097_SET_ALPHA_TEST_ENABLE" }, - { NV4097_SET_ALPHA_FUNC , "NV4097_SET_ALPHA_FUNC" }, - { NV4097_SET_ALPHA_REF , "NV4097_SET_ALPHA_REF" }, - { NV4097_SET_BLEND_ENABLE , "NV4097_SET_BLEND_ENABLE" }, - { NV4097_SET_BLEND_FUNC_SFACTOR , "NV4097_SET_BLEND_FUNC_SFACTOR" }, - { NV4097_SET_BLEND_FUNC_DFACTOR , "NV4097_SET_BLEND_FUNC_DFACTOR" }, - { NV4097_SET_BLEND_COLOR , "NV4097_SET_BLEND_COLOR" }, - { NV4097_SET_BLEND_EQUATION , "NV4097_SET_BLEND_EQUATION" }, - { NV4097_SET_COLOR_MASK , "NV4097_SET_COLOR_MASK" }, - { NV4097_SET_STENCIL_TEST_ENABLE , "NV4097_SET_STENCIL_TEST_ENABLE" }, - { NV4097_SET_STENCIL_MASK , "NV4097_SET_STENCIL_MASK" }, - { NV4097_SET_STENCIL_FUNC , "NV4097_SET_STENCIL_FUNC" }, - { NV4097_SET_STENCIL_FUNC_REF , "NV4097_SET_STENCIL_FUNC_REF" }, - { NV4097_SET_STENCIL_FUNC_MASK , "NV4097_SET_STENCIL_FUNC_MASK" }, - { NV4097_SET_STENCIL_OP_FAIL , "NV4097_SET_STENCIL_OP_FAIL" }, - { NV4097_SET_STENCIL_OP_ZFAIL , "NV4097_SET_STENCIL_OP_ZFAIL" }, - { NV4097_SET_STENCIL_OP_ZPASS , "NV4097_SET_STENCIL_OP_ZPASS" }, - { NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE , "NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE" }, - { NV4097_SET_BACK_STENCIL_MASK , "NV4097_SET_BACK_STENCIL_MASK" }, - { NV4097_SET_BACK_STENCIL_FUNC , "NV4097_SET_BACK_STENCIL_FUNC" }, - { NV4097_SET_BACK_STENCIL_FUNC_REF , "NV4097_SET_BACK_STENCIL_FUNC_REF" }, - { NV4097_SET_BACK_STENCIL_FUNC_MASK , "NV4097_SET_BACK_STENCIL_FUNC_MASK" }, - { NV4097_SET_BACK_STENCIL_OP_FAIL , "NV4097_SET_BACK_STENCIL_OP_FAIL" }, - { NV4097_SET_BACK_STENCIL_OP_ZFAIL , "NV4097_SET_BACK_STENCIL_OP_ZFAIL" }, - { NV4097_SET_BACK_STENCIL_OP_ZPASS , "NV4097_SET_BACK_STENCIL_OP_ZPASS" }, - { NV4097_SET_SHADE_MODE , "NV4097_SET_SHADE_MODE" }, - { NV4097_SET_BLEND_ENABLE_MRT , "NV4097_SET_BLEND_ENABLE_MRT" }, - { NV4097_SET_COLOR_MASK_MRT , "NV4097_SET_COLOR_MASK_MRT" }, - { NV4097_SET_LOGIC_OP_ENABLE , "NV4097_SET_LOGIC_OP_ENABLE" }, - { NV4097_SET_LOGIC_OP , "NV4097_SET_LOGIC_OP" }, - { NV4097_SET_BLEND_COLOR2 , "NV4097_SET_BLEND_COLOR2" }, - { NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE , "NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE" }, - { NV4097_SET_DEPTH_BOUNDS_MIN , "NV4097_SET_DEPTH_BOUNDS_MIN" }, - { NV4097_SET_DEPTH_BOUNDS_MAX , "NV4097_SET_DEPTH_BOUNDS_MAX" }, - { NV4097_SET_CLIP_MIN , "NV4097_SET_CLIP_MIN" }, - { NV4097_SET_CLIP_MAX , "NV4097_SET_CLIP_MAX" }, - { NV4097_SET_CONTROL0 , "NV4097_SET_CONTROL0" }, - { NV4097_SET_LINE_WIDTH , "NV4097_SET_LINE_WIDTH" }, - { NV4097_SET_LINE_SMOOTH_ENABLE , "NV4097_SET_LINE_SMOOTH_ENABLE" }, - { NV4097_SET_ANISO_SPREAD , "NV4097_SET_ANISO_SPREAD" }, - { NV4097_SET_ANISO_SPREAD + 4 , "NV4097_SET_ANISO_SPREAD + 4" }, - { NV4097_SET_ANISO_SPREAD + 8 , "NV4097_SET_ANISO_SPREAD + 8" }, - { NV4097_SET_ANISO_SPREAD + 12 , "NV4097_SET_ANISO_SPREAD + 12" }, - { NV4097_SET_ANISO_SPREAD + 16 , "NV4097_SET_ANISO_SPREAD + 16" }, - { NV4097_SET_ANISO_SPREAD + 20 , "NV4097_SET_ANISO_SPREAD + 20" }, - { NV4097_SET_ANISO_SPREAD + 24 , "NV4097_SET_ANISO_SPREAD + 24" }, - { NV4097_SET_ANISO_SPREAD + 28 , "NV4097_SET_ANISO_SPREAD + 28" }, - { NV4097_SET_ANISO_SPREAD + 32 , "NV4097_SET_ANISO_SPREAD + 32" }, - { NV4097_SET_ANISO_SPREAD + 36 , "NV4097_SET_ANISO_SPREAD + 36" }, - { NV4097_SET_ANISO_SPREAD + 40 , "NV4097_SET_ANISO_SPREAD + 40" }, - { NV4097_SET_ANISO_SPREAD + 44 , "NV4097_SET_ANISO_SPREAD + 44" }, - { NV4097_SET_ANISO_SPREAD + 48 , "NV4097_SET_ANISO_SPREAD + 48" }, - { NV4097_SET_ANISO_SPREAD + 52 , "NV4097_SET_ANISO_SPREAD + 52" }, - { NV4097_SET_ANISO_SPREAD + 56 , "NV4097_SET_ANISO_SPREAD + 56" }, - { NV4097_SET_ANISO_SPREAD + 60 , "NV4097_SET_ANISO_SPREAD + 60" }, - { NV4097_SET_SCISSOR_HORIZONTAL , "NV4097_SET_SCISSOR_HORIZONTAL" }, - { NV4097_SET_SCISSOR_VERTICAL , "NV4097_SET_SCISSOR_VERTICAL" }, - { NV4097_SET_FOG_MODE , "NV4097_SET_FOG_MODE" }, - { NV4097_SET_FOG_PARAMS , "NV4097_SET_FOG_PARAMS" }, - { NV4097_SET_FOG_PARAMS + 4 , "NV4097_SET_FOG_PARAMS + 4" }, - { NV4097_SET_FOG_PARAMS + 8 , "NV4097_SET_FOG_PARAMS + 8" }, - { NV4097_SET_SHADER_PROGRAM , "NV4097_SET_SHADER_PROGRAM" }, - { NV4097_SET_VERTEX_TEXTURE_OFFSET , "NV4097_SET_VERTEX_TEXTURE_OFFSET" }, - { NV4097_SET_VERTEX_TEXTURE_FORMAT , "NV4097_SET_VERTEX_TEXTURE_FORMAT" }, - { NV4097_SET_VERTEX_TEXTURE_ADDRESS , "NV4097_SET_VERTEX_TEXTURE_ADDRESS" }, - { NV4097_SET_VERTEX_TEXTURE_CONTROL0 , "NV4097_SET_VERTEX_TEXTURE_CONTROL0" }, - { NV4097_SET_VERTEX_TEXTURE_CONTROL3 , "NV4097_SET_VERTEX_TEXTURE_CONTROL3" }, - { NV4097_SET_VERTEX_TEXTURE_FILTER , "NV4097_SET_VERTEX_TEXTURE_FILTER" }, - { NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT , "NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT" }, - { NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR , "NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR" }, - { NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x20, "NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x20" }, - { NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x20, "NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x20" }, - { NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x20, "NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x20" }, - { NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x20, "NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x20" }, - { NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x20, "NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x20" }, - { NV4097_SET_VERTEX_TEXTURE_FILTER + 0x20, "NV4097_SET_VERTEX_TEXTURE_FILTER + 0x20" }, - { NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x20, "NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x20" }, - { NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x20, "NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x20" }, - { NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x40, "NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x40" }, - { NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x40, "NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x40" }, - { NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x40, "NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x40" }, - { NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x40, "NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x40" }, - { NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x40, "NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x40" }, - { NV4097_SET_VERTEX_TEXTURE_FILTER + 0x40, "NV4097_SET_VERTEX_TEXTURE_FILTER + 0x40" }, - { NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x40, "NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x40" }, - { NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x40, "NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x40" }, - { NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x60, "NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x60" }, - { NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x60, "NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x60" }, - { NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x60, "NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x60" }, - { NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x60, "NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x60" }, - { NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x60, "NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x60" }, - { NV4097_SET_VERTEX_TEXTURE_FILTER + 0x60, "NV4097_SET_VERTEX_TEXTURE_FILTER + 0x60" }, - { NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x60, "NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x60" }, - { NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x60, "NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x60" }, - { NV4097_SET_VIEWPORT_HORIZONTAL , "NV4097_SET_VIEWPORT_HORIZONTAL" }, - { NV4097_SET_VIEWPORT_VERTICAL , "NV4097_SET_VIEWPORT_VERTICAL" }, - { NV4097_SET_VIEWPORT_OFFSET , "NV4097_SET_VIEWPORT_OFFSET" }, - { NV4097_SET_VIEWPORT_SCALE , "NV4097_SET_VIEWPORT_SCALE" }, - { NV4097_SET_POLY_OFFSET_LINE_ENABLE , "NV4097_SET_POLY_OFFSET_LINE_ENABLE" }, - { NV4097_SET_POLY_OFFSET_FILL_ENABLE , "NV4097_SET_POLY_OFFSET_FILL_ENABLE" }, - { NV4097_SET_DEPTH_FUNC , "NV4097_SET_DEPTH_FUNC" }, - { NV4097_SET_DEPTH_MASK , "NV4097_SET_DEPTH_MASK" }, - { NV4097_SET_DEPTH_TEST_ENABLE , "NV4097_SET_DEPTH_TEST_ENABLE" }, - { NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR , "NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR" }, - { NV4097_SET_POLYGON_OFFSET_BIAS , "NV4097_SET_POLYGON_OFFSET_BIAS" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M , "NV4097_SET_VERTEX_DATA_SCALED4S_M" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 4 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 4" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 8 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 8" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 12 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 12" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 16 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 16" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 20 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 20" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 24 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 24" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 28 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 28" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 32 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 32" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 36 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 36" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 40, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 40" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 44 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 44" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 48 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 48" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 52 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 52" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 56 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 56" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 60 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 60" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 64 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 64" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 68 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 68" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 72 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 72" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 76 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 76" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 80 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 80" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 84 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 84" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 88 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 88" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 92 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 92" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 96 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 96" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 100 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 100" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 104 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 104" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 108 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 108" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 112 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 112" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 116 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 116" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 120 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 120" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 124 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 124" }, - { NV4097_SET_TEXTURE_CONTROL2 , "NV4097_SET_TEXTURE_CONTROL2" }, - { NV4097_SET_TEXTURE_CONTROL2 + 4 , "NV4097_SET_TEXTURE_CONTROL2 + 4" }, - { NV4097_SET_TEXTURE_CONTROL2 + 8 , "NV4097_SET_TEXTURE_CONTROL2 + 8" }, - { NV4097_SET_TEXTURE_CONTROL2 + 12 , "NV4097_SET_TEXTURE_CONTROL2 + 12" }, - { NV4097_SET_TEXTURE_CONTROL2 + 16 , "NV4097_SET_TEXTURE_CONTROL2 + 16" }, - { NV4097_SET_TEXTURE_CONTROL2 + 20 , "NV4097_SET_TEXTURE_CONTROL2 + 20" }, - { NV4097_SET_TEXTURE_CONTROL2 + 24 , "NV4097_SET_TEXTURE_CONTROL2 + 24" }, - { NV4097_SET_TEXTURE_CONTROL2 + 28 , "NV4097_SET_TEXTURE_CONTROL2 + 28" }, - { NV4097_SET_TEXTURE_CONTROL2 + 32 , "NV4097_SET_TEXTURE_CONTROL2 + 32" }, - { NV4097_SET_TEXTURE_CONTROL2 + 36 , "NV4097_SET_TEXTURE_CONTROL2 + 36" }, - { NV4097_SET_TEXTURE_CONTROL2 + 40 , "NV4097_SET_TEXTURE_CONTROL2 + 40" }, - { NV4097_SET_TEXTURE_CONTROL2 + 44 , "NV4097_SET_TEXTURE_CONTROL2 + 44" }, - { NV4097_SET_TEXTURE_CONTROL2 + 48 , "NV4097_SET_TEXTURE_CONTROL2 + 48" }, - { NV4097_SET_TEXTURE_CONTROL2 + 52 , "NV4097_SET_TEXTURE_CONTROL2 + 52" }, - { NV4097_SET_TEXTURE_CONTROL2 + 56 , "NV4097_SET_TEXTURE_CONTROL2 + 56" }, - { NV4097_SET_TEXTURE_CONTROL2 + 60 , "NV4097_SET_TEXTURE_CONTROL2 + 60" }, - { NV4097_SET_TEX_COORD_CONTROL , "NV4097_SET_TEX_COORD_CONTROL" }, - { NV4097_SET_TEX_COORD_CONTROL + 4 , "NV4097_SET_TEX_COORD_CONTROL + 4" }, - { NV4097_SET_TEX_COORD_CONTROL + 8 , "NV4097_SET_TEX_COORD_CONTROL + 8" }, - { NV4097_SET_TEX_COORD_CONTROL + 12 , "NV4097_SET_TEX_COORD_CONTROL + 12" }, - { NV4097_SET_TEX_COORD_CONTROL + 16 , "NV4097_SET_TEX_COORD_CONTROL + 16" }, - { NV4097_SET_TEX_COORD_CONTROL + 20 , "NV4097_SET_TEX_COORD_CONTROL + 20" }, - { NV4097_SET_TEX_COORD_CONTROL + 24 , "NV4097_SET_TEX_COORD_CONTROL + 24" }, - { NV4097_SET_TEX_COORD_CONTROL + 28 , "NV4097_SET_TEX_COORD_CONTROL + 28" }, - { NV4097_SET_TEX_COORD_CONTROL + 32 , "NV4097_SET_TEX_COORD_CONTROL + 32" }, - { NV4097_SET_TEX_COORD_CONTROL + 36 , "NV4097_SET_TEX_COORD_CONTROL + 36" }, - { NV4097_SET_TRANSFORM_PROGRAM , "NV4097_SET_TRANSFORM_PROGRAM" }, - { NV4097_SET_TRANSFORM_PROGRAM + 4 , "NV4097_SET_TRANSFORM_PROGRAM + 4" }, - { NV4097_SET_TRANSFORM_PROGRAM + 8 , "NV4097_SET_TRANSFORM_PROGRAM + 8" }, - { NV4097_SET_TRANSFORM_PROGRAM + 12 , "NV4097_SET_TRANSFORM_PROGRAM + 12" }, - { NV4097_SET_TRANSFORM_PROGRAM + 16 , "NV4097_SET_TRANSFORM_PROGRAM + 16" }, - { NV4097_SET_TRANSFORM_PROGRAM + 20 , "NV4097_SET_TRANSFORM_PROGRAM + 20" }, - { NV4097_SET_TRANSFORM_PROGRAM + 24 , "NV4097_SET_TRANSFORM_PROGRAM + 24" }, - { NV4097_SET_TRANSFORM_PROGRAM + 28 , "NV4097_SET_TRANSFORM_PROGRAM + 28" }, - { NV4097_SET_TRANSFORM_PROGRAM + 32 , "NV4097_SET_TRANSFORM_PROGRAM + 32" }, - { NV4097_SET_TRANSFORM_PROGRAM + 36 , "NV4097_SET_TRANSFORM_PROGRAM + 36" }, - { NV4097_SET_TRANSFORM_PROGRAM + 40 , "NV4097_SET_TRANSFORM_PROGRAM + 40" }, - { NV4097_SET_TRANSFORM_PROGRAM + 44 , "NV4097_SET_TRANSFORM_PROGRAM + 44" }, - { NV4097_SET_TRANSFORM_PROGRAM + 48 , "NV4097_SET_TRANSFORM_PROGRAM + 48" }, - { NV4097_SET_TRANSFORM_PROGRAM + 52 , "NV4097_SET_TRANSFORM_PROGRAM + 52" }, - { NV4097_SET_TRANSFORM_PROGRAM + 56 , "NV4097_SET_TRANSFORM_PROGRAM + 56" }, - { NV4097_SET_TRANSFORM_PROGRAM + 60 , "NV4097_SET_TRANSFORM_PROGRAM + 60" }, - { NV4097_SET_TRANSFORM_PROGRAM + 64 , "NV4097_SET_TRANSFORM_PROGRAM + 64" }, - { NV4097_SET_TRANSFORM_PROGRAM + 68 , "NV4097_SET_TRANSFORM_PROGRAM + 68" }, - { NV4097_SET_TRANSFORM_PROGRAM + 72 , "NV4097_SET_TRANSFORM_PROGRAM + 72" }, - { NV4097_SET_TRANSFORM_PROGRAM + 76 , "NV4097_SET_TRANSFORM_PROGRAM + 76" }, - { NV4097_SET_TRANSFORM_PROGRAM + 80 , "NV4097_SET_TRANSFORM_PROGRAM + 80" }, - { NV4097_SET_TRANSFORM_PROGRAM + 84 , "NV4097_SET_TRANSFORM_PROGRAM + 84" }, - { NV4097_SET_TRANSFORM_PROGRAM + 88 , "NV4097_SET_TRANSFORM_PROGRAM + 88" }, - { NV4097_SET_TRANSFORM_PROGRAM + 92 , "NV4097_SET_TRANSFORM_PROGRAM + 92" }, - { NV4097_SET_TRANSFORM_PROGRAM + 96 , "NV4097_SET_TRANSFORM_PROGRAM + 96" }, - { NV4097_SET_TRANSFORM_PROGRAM + 100 , "NV4097_SET_TRANSFORM_PROGRAM + 100" }, - { NV4097_SET_TRANSFORM_PROGRAM + 104 , "NV4097_SET_TRANSFORM_PROGRAM + 104" }, - { NV4097_SET_TRANSFORM_PROGRAM + 108 , "NV4097_SET_TRANSFORM_PROGRAM + 108" }, - { NV4097_SET_TRANSFORM_PROGRAM + 112 , "NV4097_SET_TRANSFORM_PROGRAM + 112" }, - { NV4097_SET_TRANSFORM_PROGRAM + 116 , "NV4097_SET_TRANSFORM_PROGRAM + 116" }, - { NV4097_SET_TRANSFORM_PROGRAM + 120 , "NV4097_SET_TRANSFORM_PROGRAM + 120" }, - { NV4097_SET_TRANSFORM_PROGRAM + 124 , "NV4097_SET_TRANSFORM_PROGRAM + 124" }, - { NV4097_SET_TWO_SIDE_LIGHT_EN , "NV4097_SET_TWO_SIDE_LIGHT_EN" }, - { NV4097_CLEAR_ZCULL_SURFACE , "NV4097_CLEAR_ZCULL_SURFACE" }, - { NV4097_SET_USER_CLIP_PLANE_CONTROL , "NV4097_SET_USER_CLIP_PLANE_CONTROL" }, - { NV4097_SET_POLYGON_STIPPLE , "NV4097_SET_POLYGON_STIPPLE" }, - { NV4097_SET_POLYGON_STIPPLE_PATTERN , "NV4097_SET_POLYGON_STIPPLE_PATTERN" }, - { NV4097_SET_VERTEX_DATA3F_M , "NV4097_SET_VERTEX_DATA3F_M" }, - { NV4097_SET_VERTEX_DATA3F_M + 4 , "NV4097_SET_VERTEX_DATA3F_M + 4" }, - { NV4097_SET_VERTEX_DATA3F_M + 8 , "NV4097_SET_VERTEX_DATA3F_M + 8" }, - { NV4097_SET_VERTEX_DATA3F_M + 12 , "NV4097_SET_VERTEX_DATA3F_M + 12" }, - { NV4097_SET_VERTEX_DATA3F_M + 16 , "NV4097_SET_VERTEX_DATA3F_M + 16" }, - { NV4097_SET_VERTEX_DATA3F_M + 20 , "NV4097_SET_VERTEX_DATA3F_M + 20" }, - { NV4097_SET_VERTEX_DATA3F_M + 24 , "NV4097_SET_VERTEX_DATA3F_M + 24" }, - { NV4097_SET_VERTEX_DATA3F_M + 28 , "NV4097_SET_VERTEX_DATA3F_M + 28" }, - { NV4097_SET_VERTEX_DATA3F_M + 32 , "NV4097_SET_VERTEX_DATA3F_M + 32" }, - { NV4097_SET_VERTEX_DATA3F_M + 36 , "NV4097_SET_VERTEX_DATA3F_M + 36" }, - { NV4097_SET_VERTEX_DATA3F_M + 40 , "NV4097_SET_VERTEX_DATA3F_M + 40" }, - { NV4097_SET_VERTEX_DATA3F_M + 44 , "NV4097_SET_VERTEX_DATA3F_M + 44" }, - { NV4097_SET_VERTEX_DATA3F_M + 48 , "NV4097_SET_VERTEX_DATA3F_M + 48" }, - { NV4097_SET_VERTEX_DATA3F_M + 52 , "NV4097_SET_VERTEX_DATA3F_M + 52" }, - { NV4097_SET_VERTEX_DATA3F_M + 56 , "NV4097_SET_VERTEX_DATA3F_M + 56" }, - { NV4097_SET_VERTEX_DATA3F_M + 60 , "NV4097_SET_VERTEX_DATA3F_M + 60" }, - { NV4097_SET_VERTEX_DATA3F_M + 64 , "NV4097_SET_VERTEX_DATA3F_M + 64" }, - { NV4097_SET_VERTEX_DATA3F_M + 68 , "NV4097_SET_VERTEX_DATA3F_M + 68" }, - { NV4097_SET_VERTEX_DATA3F_M + 72 , "NV4097_SET_VERTEX_DATA3F_M + 72" }, - { NV4097_SET_VERTEX_DATA3F_M + 76 , "NV4097_SET_VERTEX_DATA3F_M + 76" }, - { NV4097_SET_VERTEX_DATA3F_M + 80 , "NV4097_SET_VERTEX_DATA3F_M + 80" }, - { NV4097_SET_VERTEX_DATA3F_M + 84 , "NV4097_SET_VERTEX_DATA3F_M + 84" }, - { NV4097_SET_VERTEX_DATA3F_M + 88 , "NV4097_SET_VERTEX_DATA3F_M + 88" }, - { NV4097_SET_VERTEX_DATA3F_M + 92 , "NV4097_SET_VERTEX_DATA3F_M + 92" }, - { NV4097_SET_VERTEX_DATA3F_M + 96 , "NV4097_SET_VERTEX_DATA3F_M + 96" }, - { NV4097_SET_VERTEX_DATA3F_M + 100 , "NV4097_SET_VERTEX_DATA3F_M + 100" }, - { NV4097_SET_VERTEX_DATA3F_M + 104 , "NV4097_SET_VERTEX_DATA3F_M + 104" }, - { NV4097_SET_VERTEX_DATA3F_M + 108 , "NV4097_SET_VERTEX_DATA3F_M + 108" }, - { NV4097_SET_VERTEX_DATA3F_M + 112 , "NV4097_SET_VERTEX_DATA3F_M + 112" }, - { NV4097_SET_VERTEX_DATA3F_M + 116 , "NV4097_SET_VERTEX_DATA3F_M + 116" }, - { NV4097_SET_VERTEX_DATA3F_M + 120 , "NV4097_SET_VERTEX_DATA3F_M + 120" }, - { NV4097_SET_VERTEX_DATA3F_M + 124 , "NV4097_SET_VERTEX_DATA3F_M + 124" }, - { NV4097_SET_VERTEX_DATA3F_M + 128 , "NV4097_SET_VERTEX_DATA3F_M + 128" }, - { NV4097_SET_VERTEX_DATA3F_M + 132 , "NV4097_SET_VERTEX_DATA3F_M + 132" }, - { NV4097_SET_VERTEX_DATA3F_M + 136 , "NV4097_SET_VERTEX_DATA3F_M + 136" }, - { NV4097_SET_VERTEX_DATA3F_M + 140 , "NV4097_SET_VERTEX_DATA3F_M + 140" }, - { NV4097_SET_VERTEX_DATA3F_M + 144 , "NV4097_SET_VERTEX_DATA3F_M + 144" }, - { NV4097_SET_VERTEX_DATA3F_M + 148 , "NV4097_SET_VERTEX_DATA3F_M + 148" }, - { NV4097_SET_VERTEX_DATA3F_M + 152 , "NV4097_SET_VERTEX_DATA3F_M + 152" }, - { NV4097_SET_VERTEX_DATA3F_M + 156 , "NV4097_SET_VERTEX_DATA3F_M + 156" }, - { NV4097_SET_VERTEX_DATA3F_M + 160 , "NV4097_SET_VERTEX_DATA3F_M + 160" }, - { NV4097_SET_VERTEX_DATA3F_M + 164 , "NV4097_SET_VERTEX_DATA3F_M + 164" }, - { NV4097_SET_VERTEX_DATA3F_M + 168 , "NV4097_SET_VERTEX_DATA3F_M + 168" }, - { NV4097_SET_VERTEX_DATA3F_M + 172 , "NV4097_SET_VERTEX_DATA3F_M + 172" }, - { NV4097_SET_VERTEX_DATA3F_M + 176 , "NV4097_SET_VERTEX_DATA3F_M + 176" }, - { NV4097_SET_VERTEX_DATA3F_M + 180 , "NV4097_SET_VERTEX_DATA3F_M + 180" }, - { NV4097_SET_VERTEX_DATA3F_M + 184 , "NV4097_SET_VERTEX_DATA3F_M + 184" }, - { NV4097_SET_VERTEX_DATA3F_M + 188 , "NV4097_SET_VERTEX_DATA3F_M + 188" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 4 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 4" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 8 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 8" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 12 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 12" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 16 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 16" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 20 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 20" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 24 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 24" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 28 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 28" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 32 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 32" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 36 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 36" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 40 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 40" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 44 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 44" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 48 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 48" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 52 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 52" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 56 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 56" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 60 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 60" }, - { NV4097_INVALIDATE_VERTEX_CACHE_FILE , "NV4097_INVALIDATE_VERTEX_CACHE_FILE" }, - { NV4097_INVALIDATE_VERTEX_FILE , "NV4097_INVALIDATE_VERTEX_FILE" }, - { NV4097_SET_VERTEX_DATA_BASE_OFFSET , "NV4097_SET_VERTEX_DATA_BASE_OFFSET" }, - { NV4097_SET_VERTEX_DATA_BASE_INDEX , "NV4097_SET_VERTEX_DATA_BASE_INDEX" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 4 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 4" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 8 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 8" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 12 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 12" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 16 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 16" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 20 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 20" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 24 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 24" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 28 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 28" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 32 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 32" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 36 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 36" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 40 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 40" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 44 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 44" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 48 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 48" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 52 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 52" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 56 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 56" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 60 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 60" }, - { NV4097_CLEAR_REPORT_VALUE , "NV4097_CLEAR_REPORT_VALUE" }, - { NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE , "NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE" }, - { NV4097_GET_REPORT , "NV4097_GET_REPORT" }, - { NV4097_SET_ZCULL_STATS_ENABLE , "NV4097_SET_ZCULL_STATS_ENABLE" }, - { NV4097_SET_BEGIN_END , "NV4097_SET_BEGIN_END" }, - { NV4097_ARRAY_ELEMENT16 , "NV4097_ARRAY_ELEMENT16" }, - { NV4097_ARRAY_ELEMENT32 , "NV4097_ARRAY_ELEMENT32" }, - { NV4097_DRAW_ARRAYS , "NV4097_DRAW_ARRAYS" }, - { NV4097_INLINE_ARRAY , "NV4097_INLINE_ARRAY" }, - { NV4097_SET_INDEX_ARRAY_ADDRESS , "NV4097_SET_INDEX_ARRAY_ADDRESS" }, - { NV4097_SET_INDEX_ARRAY_DMA , "NV4097_SET_INDEX_ARRAY_DMA" }, - { NV4097_DRAW_INDEX_ARRAY , "NV4097_DRAW_INDEX_ARRAY" }, - { NV4097_SET_FRONT_POLYGON_MODE , "NV4097_SET_FRONT_POLYGON_MODE" }, - { NV4097_SET_BACK_POLYGON_MODE , "NV4097_SET_BACK_POLYGON_MODE" }, - { NV4097_SET_CULL_FACE , "NV4097_SET_CULL_FACE" }, - { NV4097_SET_FRONT_FACE , "NV4097_SET_FRONT_FACE" }, - { NV4097_SET_POLY_SMOOTH_ENABLE , "NV4097_SET_POLY_SMOOTH_ENABLE" }, - { NV4097_SET_CULL_FACE_ENABLE , "NV4097_SET_CULL_FACE_ENABLE" }, - { NV4097_SET_TEXTURE_CONTROL3 , "NV4097_SET_TEXTURE_CONTROL3" }, - { NV4097_SET_TEXTURE_CONTROL3 + 4 , "NV4097_SET_TEXTURE_CONTROL3 + 4" }, - { NV4097_SET_TEXTURE_CONTROL3 + 8 , "NV4097_SET_TEXTURE_CONTROL3 + 8" }, - { NV4097_SET_TEXTURE_CONTROL3 + 12 , "NV4097_SET_TEXTURE_CONTROL3 + 12" }, - { NV4097_SET_TEXTURE_CONTROL3 + 16 , "NV4097_SET_TEXTURE_CONTROL3 + 16" }, - { NV4097_SET_TEXTURE_CONTROL3 + 20 , "NV4097_SET_TEXTURE_CONTROL3 + 20" }, - { NV4097_SET_TEXTURE_CONTROL3 + 24 , "NV4097_SET_TEXTURE_CONTROL3 + 24" }, - { NV4097_SET_TEXTURE_CONTROL3 + 28 , "NV4097_SET_TEXTURE_CONTROL3 + 28" }, - { NV4097_SET_TEXTURE_CONTROL3 + 32 , "NV4097_SET_TEXTURE_CONTROL3 + 32" }, - { NV4097_SET_TEXTURE_CONTROL3 + 36 , "NV4097_SET_TEXTURE_CONTROL3 + 36" }, - { NV4097_SET_TEXTURE_CONTROL3 + 40 , "NV4097_SET_TEXTURE_CONTROL3 + 40" }, - { NV4097_SET_TEXTURE_CONTROL3 + 44 , "NV4097_SET_TEXTURE_CONTROL3 + 44" }, - { NV4097_SET_TEXTURE_CONTROL3 + 48 , "NV4097_SET_TEXTURE_CONTROL3 + 48" }, - { NV4097_SET_TEXTURE_CONTROL3 + 52 , "NV4097_SET_TEXTURE_CONTROL3 + 52" }, - { NV4097_SET_TEXTURE_CONTROL3 + 56 , "NV4097_SET_TEXTURE_CONTROL3 + 56" }, - { NV4097_SET_TEXTURE_CONTROL3 + 60 , "NV4097_SET_TEXTURE_CONTROL3 + 60" }, - { NV4097_SET_VERTEX_DATA2F_M , "NV4097_SET_VERTEX_DATA2F_M" }, - { NV4097_SET_VERTEX_DATA2F_M + 4 , "NV4097_SET_VERTEX_DATA2F_M + 4" }, - { NV4097_SET_VERTEX_DATA2F_M + 8 , "NV4097_SET_VERTEX_DATA2F_M + 8" }, - { NV4097_SET_VERTEX_DATA2F_M + 12 , "NV4097_SET_VERTEX_DATA2F_M + 12" }, - { NV4097_SET_VERTEX_DATA2F_M + 16 , "NV4097_SET_VERTEX_DATA2F_M + 16" }, - { NV4097_SET_VERTEX_DATA2F_M + 20 , "NV4097_SET_VERTEX_DATA2F_M + 20" }, - { NV4097_SET_VERTEX_DATA2F_M + 24 , "NV4097_SET_VERTEX_DATA2F_M + 24" }, - { NV4097_SET_VERTEX_DATA2F_M + 28 , "NV4097_SET_VERTEX_DATA2F_M + 28" }, - { NV4097_SET_VERTEX_DATA2F_M + 32 , "NV4097_SET_VERTEX_DATA2F_M + 32" }, - { NV4097_SET_VERTEX_DATA2F_M + 36 , "NV4097_SET_VERTEX_DATA2F_M + 36" }, - { NV4097_SET_VERTEX_DATA2F_M + 40 , "NV4097_SET_VERTEX_DATA2F_M + 40" }, - { NV4097_SET_VERTEX_DATA2F_M + 44 , "NV4097_SET_VERTEX_DATA2F_M + 44" }, - { NV4097_SET_VERTEX_DATA2F_M + 48 , "NV4097_SET_VERTEX_DATA2F_M + 48" }, - { NV4097_SET_VERTEX_DATA2F_M + 52 , "NV4097_SET_VERTEX_DATA2F_M + 52" }, - { NV4097_SET_VERTEX_DATA2F_M + 56 , "NV4097_SET_VERTEX_DATA2F_M + 56" }, - { NV4097_SET_VERTEX_DATA2F_M + 60 , "NV4097_SET_VERTEX_DATA2F_M + 60" }, - { NV4097_SET_VERTEX_DATA2F_M + 64 , "NV4097_SET_VERTEX_DATA2F_M + 64" }, - { NV4097_SET_VERTEX_DATA2F_M + 68 , "NV4097_SET_VERTEX_DATA2F_M + 68" }, - { NV4097_SET_VERTEX_DATA2F_M + 72 , "NV4097_SET_VERTEX_DATA2F_M + 72" }, - { NV4097_SET_VERTEX_DATA2F_M + 76 , "NV4097_SET_VERTEX_DATA2F_M + 76" }, - { NV4097_SET_VERTEX_DATA2F_M + 80 , "NV4097_SET_VERTEX_DATA2F_M + 80" }, - { NV4097_SET_VERTEX_DATA2F_M + 84 , "NV4097_SET_VERTEX_DATA2F_M + 84" }, - { NV4097_SET_VERTEX_DATA2F_M + 88 , "NV4097_SET_VERTEX_DATA2F_M + 88" }, - { NV4097_SET_VERTEX_DATA2F_M + 92 , "NV4097_SET_VERTEX_DATA2F_M + 92" }, - { NV4097_SET_VERTEX_DATA2F_M + 96 , "NV4097_SET_VERTEX_DATA2F_M + 96" }, - { NV4097_SET_VERTEX_DATA2F_M + 100 , "NV4097_SET_VERTEX_DATA2F_M + 100" }, - { NV4097_SET_VERTEX_DATA2F_M + 104 , "NV4097_SET_VERTEX_DATA2F_M + 104" }, - { NV4097_SET_VERTEX_DATA2F_M + 108 , "NV4097_SET_VERTEX_DATA2F_M + 108" }, - { NV4097_SET_VERTEX_DATA2F_M + 112 , "NV4097_SET_VERTEX_DATA2F_M + 112" }, - { NV4097_SET_VERTEX_DATA2F_M + 116 , "NV4097_SET_VERTEX_DATA2F_M + 116" }, - { NV4097_SET_VERTEX_DATA2F_M + 120 , "NV4097_SET_VERTEX_DATA2F_M + 120" }, - { NV4097_SET_VERTEX_DATA2F_M + 124 , "NV4097_SET_VERTEX_DATA2F_M + 124" }, - { NV4097_SET_VERTEX_DATA2S_M , "NV4097_SET_VERTEX_DATA2S_M" }, - { NV4097_SET_VERTEX_DATA2S_M + 4 , "NV4097_SET_VERTEX_DATA2S_M + 4" }, - { NV4097_SET_VERTEX_DATA2S_M + 8 , "NV4097_SET_VERTEX_DATA2S_M + 8" }, - { NV4097_SET_VERTEX_DATA2S_M + 12 , "NV4097_SET_VERTEX_DATA2S_M + 12" }, - { NV4097_SET_VERTEX_DATA2S_M + 16 , "NV4097_SET_VERTEX_DATA2S_M + 16" }, - { NV4097_SET_VERTEX_DATA2S_M + 20 , "NV4097_SET_VERTEX_DATA2S_M + 20" }, - { NV4097_SET_VERTEX_DATA2S_M + 24 , "NV4097_SET_VERTEX_DATA2S_M + 24" }, - { NV4097_SET_VERTEX_DATA2S_M + 28 , "NV4097_SET_VERTEX_DATA2S_M + 28" }, - { NV4097_SET_VERTEX_DATA2S_M + 32 , "NV4097_SET_VERTEX_DATA2S_M + 32" }, - { NV4097_SET_VERTEX_DATA2S_M + 36 , "NV4097_SET_VERTEX_DATA2S_M + 36" }, - { NV4097_SET_VERTEX_DATA2S_M + 40 , "NV4097_SET_VERTEX_DATA2S_M + 40" }, - { NV4097_SET_VERTEX_DATA2S_M + 44 , "NV4097_SET_VERTEX_DATA2S_M + 44" }, - { NV4097_SET_VERTEX_DATA2S_M + 48 , "NV4097_SET_VERTEX_DATA2S_M + 48" }, - { NV4097_SET_VERTEX_DATA2S_M + 52 , "NV4097_SET_VERTEX_DATA2S_M + 52" }, - { NV4097_SET_VERTEX_DATA2S_M + 56 , "NV4097_SET_VERTEX_DATA2S_M + 56" }, - { NV4097_SET_VERTEX_DATA2S_M + 60 , "NV4097_SET_VERTEX_DATA2S_M + 60" }, - { NV4097_SET_VERTEX_DATA4UB_M , "NV4097_SET_VERTEX_DATA4UB_M" }, - { NV4097_SET_VERTEX_DATA4UB_M + 4 , "NV4097_SET_VERTEX_DATA4UB_M + 4" }, - { NV4097_SET_VERTEX_DATA4UB_M + 8 , "NV4097_SET_VERTEX_DATA4UB_M + 8" }, - { NV4097_SET_VERTEX_DATA4UB_M + 12 , "NV4097_SET_VERTEX_DATA4UB_M + 12" }, - { NV4097_SET_VERTEX_DATA4UB_M + 16 , "NV4097_SET_VERTEX_DATA4UB_M + 16" }, - { NV4097_SET_VERTEX_DATA4UB_M + 20 , "NV4097_SET_VERTEX_DATA4UB_M + 20" }, - { NV4097_SET_VERTEX_DATA4UB_M + 24 , "NV4097_SET_VERTEX_DATA4UB_M + 24" }, - { NV4097_SET_VERTEX_DATA4UB_M + 28 , "NV4097_SET_VERTEX_DATA4UB_M + 28" }, - { NV4097_SET_VERTEX_DATA4UB_M + 32 , "NV4097_SET_VERTEX_DATA4UB_M + 32" }, - { NV4097_SET_VERTEX_DATA4UB_M + 36 , "NV4097_SET_VERTEX_DATA4UB_M + 36" }, - { NV4097_SET_VERTEX_DATA4UB_M + 40 , "NV4097_SET_VERTEX_DATA4UB_M + 40" }, - { NV4097_SET_VERTEX_DATA4UB_M + 44 , "NV4097_SET_VERTEX_DATA4UB_M + 44" }, - { NV4097_SET_VERTEX_DATA4UB_M + 48 , "NV4097_SET_VERTEX_DATA4UB_M + 48" }, - { NV4097_SET_VERTEX_DATA4UB_M + 52 , "NV4097_SET_VERTEX_DATA4UB_M + 52" }, - { NV4097_SET_VERTEX_DATA4UB_M + 56 , "NV4097_SET_VERTEX_DATA4UB_M + 56" }, - { NV4097_SET_VERTEX_DATA4UB_M + 60 , "NV4097_SET_VERTEX_DATA4UB_M + 60" }, - { NV4097_SET_VERTEX_DATA4S_M , "NV4097_SET_VERTEX_DATA4S_M" }, - { NV4097_SET_VERTEX_DATA4S_M + 4 , "NV4097_SET_VERTEX_DATA4S_M + 4" }, - { NV4097_SET_VERTEX_DATA4S_M + 8 , "NV4097_SET_VERTEX_DATA4S_M + 8" }, - { NV4097_SET_VERTEX_DATA4S_M + 12 , "NV4097_SET_VERTEX_DATA4S_M + 12" }, - { NV4097_SET_VERTEX_DATA4S_M + 16 , "NV4097_SET_VERTEX_DATA4S_M + 16" }, - { NV4097_SET_VERTEX_DATA4S_M + 20 , "NV4097_SET_VERTEX_DATA4S_M + 20" }, - { NV4097_SET_VERTEX_DATA4S_M + 24 , "NV4097_SET_VERTEX_DATA4S_M + 24" }, - { NV4097_SET_VERTEX_DATA4S_M + 28 , "NV4097_SET_VERTEX_DATA4S_M + 28" }, - { NV4097_SET_VERTEX_DATA4S_M + 32 , "NV4097_SET_VERTEX_DATA4S_M + 32" }, - { NV4097_SET_VERTEX_DATA4S_M + 36 , "NV4097_SET_VERTEX_DATA4S_M + 36" }, - { NV4097_SET_VERTEX_DATA4S_M + 40 , "NV4097_SET_VERTEX_DATA4S_M + 40" }, - { NV4097_SET_VERTEX_DATA4S_M + 44 , "NV4097_SET_VERTEX_DATA4S_M + 44" }, - { NV4097_SET_VERTEX_DATA4S_M + 48 , "NV4097_SET_VERTEX_DATA4S_M + 48" }, - { NV4097_SET_VERTEX_DATA4S_M + 52 , "NV4097_SET_VERTEX_DATA4S_M + 52" }, - { NV4097_SET_VERTEX_DATA4S_M + 56 , "NV4097_SET_VERTEX_DATA4S_M + 56" }, - { NV4097_SET_VERTEX_DATA4S_M + 60 , "NV4097_SET_VERTEX_DATA4S_M + 60" }, - { NV4097_SET_VERTEX_DATA4S_M + 64 , "NV4097_SET_VERTEX_DATA4S_M + 64" }, - { NV4097_SET_VERTEX_DATA4S_M + 68 , "NV4097_SET_VERTEX_DATA4S_M + 68" }, - { NV4097_SET_VERTEX_DATA4S_M + 72 , "NV4097_SET_VERTEX_DATA4S_M + 72" }, - { NV4097_SET_VERTEX_DATA4S_M + 76 , "NV4097_SET_VERTEX_DATA4S_M + 76" }, - { NV4097_SET_VERTEX_DATA4S_M + 80 , "NV4097_SET_VERTEX_DATA4S_M + 80" }, - { NV4097_SET_VERTEX_DATA4S_M + 84 , "NV4097_SET_VERTEX_DATA4S_M + 84" }, - { NV4097_SET_VERTEX_DATA4S_M + 88 , "NV4097_SET_VERTEX_DATA4S_M + 88" }, - { NV4097_SET_VERTEX_DATA4S_M + 92 , "NV4097_SET_VERTEX_DATA4S_M + 92" }, - { NV4097_SET_VERTEX_DATA4S_M + 96 , "NV4097_SET_VERTEX_DATA4S_M + 96" }, - { NV4097_SET_VERTEX_DATA4S_M + 100 , "NV4097_SET_VERTEX_DATA4S_M + 100" }, - { NV4097_SET_VERTEX_DATA4S_M + 104 , "NV4097_SET_VERTEX_DATA4S_M + 104" }, - { NV4097_SET_VERTEX_DATA4S_M + 108 , "NV4097_SET_VERTEX_DATA4S_M + 108" }, - { NV4097_SET_VERTEX_DATA4S_M + 112 , "NV4097_SET_VERTEX_DATA4S_M + 112" }, - { NV4097_SET_VERTEX_DATA4S_M + 116 , "NV4097_SET_VERTEX_DATA4S_M + 116" }, - { NV4097_SET_VERTEX_DATA4S_M + 120 , "NV4097_SET_VERTEX_DATA4S_M + 120" }, - { NV4097_SET_VERTEX_DATA4S_M + 124 , "NV4097_SET_VERTEX_DATA4S_M + 124" }, - { NV4097_SET_TEXTURE_OFFSET , "NV4097_SET_TEXTURE_OFFSET" }, - { NV4097_SET_TEXTURE_FORMAT , "NV4097_SET_TEXTURE_FORMAT" }, - { NV4097_SET_TEXTURE_ADDRESS , "NV4097_SET_TEXTURE_ADDRESS" }, - { NV4097_SET_TEXTURE_CONTROL0 , "NV4097_SET_TEXTURE_CONTROL0" }, - { NV4097_SET_TEXTURE_CONTROL1 , "NV4097_SET_TEXTURE_CONTROL1" }, - { NV4097_SET_TEXTURE_FILTER , "NV4097_SET_TEXTURE_FILTER" }, - { NV4097_SET_TEXTURE_IMAGE_RECT , "NV4097_SET_TEXTURE_IMAGE_RECT" }, - { NV4097_SET_TEXTURE_BORDER_COLOR , "NV4097_SET_TEXTURE_BORDER_COLOR" }, - { NV4097_SET_TEXTURE_OFFSET + 0x20 , "NV4097_SET_TEXTURE_OFFSET + 0x20" }, - { NV4097_SET_TEXTURE_FORMAT + 0x20 , "NV4097_SET_TEXTURE_FORMAT + 0x20" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x20 , "NV4097_SET_TEXTURE_ADDRESS + 0x20" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x20 , "NV4097_SET_TEXTURE_CONTROL0 + 0x20" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x20 , "NV4097_SET_TEXTURE_CONTROL1 + 0x20" }, - { NV4097_SET_TEXTURE_FILTER + 0x20 , "NV4097_SET_TEXTURE_FILTER + 0x20" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x20 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x20" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x20 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x20" }, - { NV4097_SET_TEXTURE_OFFSET + 0x40 , "NV4097_SET_TEXTURE_OFFSET + 0x40" }, - { NV4097_SET_TEXTURE_FORMAT + 0x40 , "NV4097_SET_TEXTURE_FORMAT + 0x40" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x40 , "NV4097_SET_TEXTURE_ADDRESS + 0x40" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x40 , "NV4097_SET_TEXTURE_CONTROL0 + 0x40" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x40 , "NV4097_SET_TEXTURE_CONTROL1 + 0x40" }, - { NV4097_SET_TEXTURE_FILTER + 0x40 , "NV4097_SET_TEXTURE_FILTER + 0x40" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x40 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x40" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x40 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x40" }, - { NV4097_SET_TEXTURE_OFFSET + 0x60 , "NV4097_SET_TEXTURE_OFFSET + 0x60" }, - { NV4097_SET_TEXTURE_FORMAT + 0x60 , "NV4097_SET_TEXTURE_FORMAT + 0x60" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x60 , "NV4097_SET_TEXTURE_ADDRESS + 0x60" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x60 , "NV4097_SET_TEXTURE_CONTROL0 + 0x60" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x60 , "NV4097_SET_TEXTURE_CONTROL1 + 0x60" }, - { NV4097_SET_TEXTURE_FILTER + 0x60 , "NV4097_SET_TEXTURE_FILTER + 0x60" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x60 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x60" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x60 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x60" }, - { NV4097_SET_TEXTURE_OFFSET + 0x80 , "NV4097_SET_TEXTURE_OFFSET + 0x80" }, - { NV4097_SET_TEXTURE_FORMAT + 0x80 , "NV4097_SET_TEXTURE_FORMAT + 0x80" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x80 , "NV4097_SET_TEXTURE_ADDRESS + 0x80" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x80 , "NV4097_SET_TEXTURE_CONTROL0 + 0x80" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x80 , "NV4097_SET_TEXTURE_CONTROL1 + 0x80" }, - { NV4097_SET_TEXTURE_FILTER + 0x80 , "NV4097_SET_TEXTURE_FILTER + 0x80" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x80 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x80" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x80 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x80" }, - { NV4097_SET_TEXTURE_OFFSET + 0xa0 , "NV4097_SET_TEXTURE_OFFSET + 0xa0" }, - { NV4097_SET_TEXTURE_FORMAT + 0xa0 , "NV4097_SET_TEXTURE_FORMAT + 0xa0" }, - { NV4097_SET_TEXTURE_ADDRESS + 0xa0 , "NV4097_SET_TEXTURE_ADDRESS + 0xa0" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0xa0 , "NV4097_SET_TEXTURE_CONTROL0 + 0xa0" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0xa0 , "NV4097_SET_TEXTURE_CONTROL1 + 0xa0" }, - { NV4097_SET_TEXTURE_FILTER + 0xa0 , "NV4097_SET_TEXTURE_FILTER + 0xa0" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0xa0 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0xa0" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0xa0 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0xa0" }, - { NV4097_SET_TEXTURE_OFFSET + 0xc0 , "NV4097_SET_TEXTURE_OFFSET + 0xc0" }, - { NV4097_SET_TEXTURE_FORMAT + 0xc0 , "NV4097_SET_TEXTURE_FORMAT + 0xc0" }, - { NV4097_SET_TEXTURE_ADDRESS + 0xc0 , "NV4097_SET_TEXTURE_ADDRESS + 0xc0" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0xc0 , "NV4097_SET_TEXTURE_CONTROL0 + 0xc0" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0xc0 , "NV4097_SET_TEXTURE_CONTROL1 + 0xc0" }, - { NV4097_SET_TEXTURE_FILTER + 0xc0 , "NV4097_SET_TEXTURE_FILTER + 0xc0" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0xc0 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0xc0" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0xc0 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0xc0" }, - { NV4097_SET_TEXTURE_OFFSET + 0xe0 , "NV4097_SET_TEXTURE_OFFSET + 0xe0" }, - { NV4097_SET_TEXTURE_FORMAT + 0xe0 , "NV4097_SET_TEXTURE_FORMAT + 0xe0" }, - { NV4097_SET_TEXTURE_ADDRESS + 0xe0 , "NV4097_SET_TEXTURE_ADDRESS + 0xe0" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0xe0 , "NV4097_SET_TEXTURE_CONTROL0 + 0xe0" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0xe0 , "NV4097_SET_TEXTURE_CONTROL1 + 0xe0" }, - { NV4097_SET_TEXTURE_FILTER + 0xe0 , "NV4097_SET_TEXTURE_FILTER + 0xe0" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0xe0 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0xe0" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0xe0 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0xe0" }, - { NV4097_SET_TEXTURE_OFFSET + 0x100 , "NV4097_SET_TEXTURE_OFFSET + 0x100" }, - { NV4097_SET_TEXTURE_FORMAT + 0x100 , "NV4097_SET_TEXTURE_FORMAT + 0x100" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x100 , "NV4097_SET_TEXTURE_ADDRESS + 0x100" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x100 , "NV4097_SET_TEXTURE_CONTROL0 + 0x100" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x100 , "NV4097_SET_TEXTURE_CONTROL1 + 0x100" }, - { NV4097_SET_TEXTURE_FILTER + 0x100 , "NV4097_SET_TEXTURE_FILTER + 0x100" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x100 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x100" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x100 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x100" }, - { NV4097_SET_TEXTURE_OFFSET + 0x120 , "NV4097_SET_TEXTURE_OFFSET + 0x120" }, - { NV4097_SET_TEXTURE_FORMAT + 0x120 , "NV4097_SET_TEXTURE_FORMAT + 0x120" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x120 , "NV4097_SET_TEXTURE_ADDRESS + 0x120" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x120 , "NV4097_SET_TEXTURE_CONTROL0 + 0x120" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x120 , "NV4097_SET_TEXTURE_CONTROL1 + 0x120" }, - { NV4097_SET_TEXTURE_FILTER + 0x120 , "NV4097_SET_TEXTURE_FILTER + 0x120" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x120 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x120" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x120 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x120" }, - { NV4097_SET_TEXTURE_OFFSET + 0x140 , "NV4097_SET_TEXTURE_OFFSET + 0x140" }, - { NV4097_SET_TEXTURE_FORMAT + 0x140 , "NV4097_SET_TEXTURE_FORMAT + 0x140" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x140 , "NV4097_SET_TEXTURE_ADDRESS + 0x140" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x140 , "NV4097_SET_TEXTURE_CONTROL0 + 0x140" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x140 , "NV4097_SET_TEXTURE_CONTROL1 + 0x140" }, - { NV4097_SET_TEXTURE_FILTER + 0x140 , "NV4097_SET_TEXTURE_FILTER + 0x140" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x140 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x140" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x140 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x140" }, - { NV4097_SET_TEXTURE_OFFSET + 0x160 , "NV4097_SET_TEXTURE_OFFSET + 0x160" }, - { NV4097_SET_TEXTURE_FORMAT + 0x160 , "NV4097_SET_TEXTURE_FORMAT + 0x160" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x160 , "NV4097_SET_TEXTURE_ADDRESS + 0x160" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x160 , "NV4097_SET_TEXTURE_CONTROL0 + 0x160" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x160 , "NV4097_SET_TEXTURE_CONTROL1 + 0x160" }, - { NV4097_SET_TEXTURE_FILTER + 0x160 , "NV4097_SET_TEXTURE_FILTER + 0x160" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x160 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x160" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x160 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x160" }, - { NV4097_SET_TEXTURE_OFFSET + 0x180 , "NV4097_SET_TEXTURE_OFFSET + 0x180" }, - { NV4097_SET_TEXTURE_FORMAT + 0x180 , "NV4097_SET_TEXTURE_FORMAT + 0x180" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x180 , "NV4097_SET_TEXTURE_ADDRESS + 0x180" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x180 , "NV4097_SET_TEXTURE_CONTROL0 + 0x180" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x180 , "NV4097_SET_TEXTURE_CONTROL1 + 0x180" }, - { NV4097_SET_TEXTURE_FILTER + 0x180 , "NV4097_SET_TEXTURE_FILTER + 0x180" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x180 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x180" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x180 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x180" }, - { NV4097_SET_TEXTURE_OFFSET + 0x1a0 , "NV4097_SET_TEXTURE_OFFSET + 0x1a0" }, - { NV4097_SET_TEXTURE_FORMAT + 0x1a0 , "NV4097_SET_TEXTURE_FORMAT + 0x1a0" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x1a0 , "NV4097_SET_TEXTURE_ADDRESS + 0x1a0" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x1a0 , "NV4097_SET_TEXTURE_CONTROL0 + 0x1a0" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x1a0 , "NV4097_SET_TEXTURE_CONTROL1 + 0x1a0" }, - { NV4097_SET_TEXTURE_FILTER + 0x1a0 , "NV4097_SET_TEXTURE_FILTER + 0x1a0" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x1a0 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x1a0" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x1a0 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x1a0" }, - { NV4097_SET_TEXTURE_OFFSET + 0x1c0 , "NV4097_SET_TEXTURE_OFFSET + 0x1c0" }, - { NV4097_SET_TEXTURE_FORMAT + 0x1c0 , "NV4097_SET_TEXTURE_FORMAT + 0x1c0" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x1c0 , "NV4097_SET_TEXTURE_ADDRESS + 0x1c0" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x1c0 , "NV4097_SET_TEXTURE_CONTROL0 + 0x1c0" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x1c0 , "NV4097_SET_TEXTURE_CONTROL1 + 0x1c0" }, - { NV4097_SET_TEXTURE_FILTER + 0x1c0 , "NV4097_SET_TEXTURE_FILTER + 0x1c0" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x1c0 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x1c0" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x1c0 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x1c0" }, - { NV4097_SET_TEXTURE_OFFSET + 0x1e0 , "NV4097_SET_TEXTURE_OFFSET + 0x1e0" }, - { NV4097_SET_TEXTURE_FORMAT + 0x1e0 , "NV4097_SET_TEXTURE_FORMAT + 0x1e0" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x1e0 , "NV4097_SET_TEXTURE_ADDRESS + 0x1e0" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x1e0 , "NV4097_SET_TEXTURE_CONTROL0 + 0x1e0" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x1e0 , "NV4097_SET_TEXTURE_CONTROL1 + 0x1e0" }, - { NV4097_SET_TEXTURE_FILTER + 0x1e0 , "NV4097_SET_TEXTURE_FILTER + 0x1e0" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x1e0 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x1e0" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x1e0 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x1e0" }, - { NV4097_SET_VERTEX_DATA4F_M , "NV4097_SET_VERTEX_DATA4F_M" }, - { NV4097_SET_VERTEX_DATA4F_M + 4 , "NV4097_SET_VERTEX_DATA4F_M + 4" }, - { NV4097_SET_VERTEX_DATA4F_M + 8 , "NV4097_SET_VERTEX_DATA4F_M + 8" }, - { NV4097_SET_VERTEX_DATA4F_M + 12 , "NV4097_SET_VERTEX_DATA4F_M + 12" }, - { NV4097_SET_VERTEX_DATA4F_M + 16 , "NV4097_SET_VERTEX_DATA4F_M + 16" }, - { NV4097_SET_VERTEX_DATA4F_M + 20 , "NV4097_SET_VERTEX_DATA4F_M + 20" }, - { NV4097_SET_VERTEX_DATA4F_M + 24 , "NV4097_SET_VERTEX_DATA4F_M + 24" }, - { NV4097_SET_VERTEX_DATA4F_M + 28 , "NV4097_SET_VERTEX_DATA4F_M + 28" }, - { NV4097_SET_VERTEX_DATA4F_M + 32 , "NV4097_SET_VERTEX_DATA4F_M + 32" }, - { NV4097_SET_VERTEX_DATA4F_M + 36 , "NV4097_SET_VERTEX_DATA4F_M + 36" }, - { NV4097_SET_VERTEX_DATA4F_M + 40 , "NV4097_SET_VERTEX_DATA4F_M + 40" }, - { NV4097_SET_VERTEX_DATA4F_M + 44 , "NV4097_SET_VERTEX_DATA4F_M + 44" }, - { NV4097_SET_VERTEX_DATA4F_M + 48 , "NV4097_SET_VERTEX_DATA4F_M + 48" }, - { NV4097_SET_VERTEX_DATA4F_M + 52 , "NV4097_SET_VERTEX_DATA4F_M + 52" }, - { NV4097_SET_VERTEX_DATA4F_M + 56 , "NV4097_SET_VERTEX_DATA4F_M + 56" }, - { NV4097_SET_VERTEX_DATA4F_M + 60 , "NV4097_SET_VERTEX_DATA4F_M + 60" }, - { NV4097_SET_VERTEX_DATA4F_M + 64 , "NV4097_SET_VERTEX_DATA4F_M + 64" }, - { NV4097_SET_VERTEX_DATA4F_M + 68 , "NV4097_SET_VERTEX_DATA4F_M + 68" }, - { NV4097_SET_VERTEX_DATA4F_M + 72 , "NV4097_SET_VERTEX_DATA4F_M + 72" }, - { NV4097_SET_VERTEX_DATA4F_M + 76 , "NV4097_SET_VERTEX_DATA4F_M + 76" }, - { NV4097_SET_VERTEX_DATA4F_M + 80 , "NV4097_SET_VERTEX_DATA4F_M + 80" }, - { NV4097_SET_VERTEX_DATA4F_M + 84 , "NV4097_SET_VERTEX_DATA4F_M + 84" }, - { NV4097_SET_VERTEX_DATA4F_M + 88 , "NV4097_SET_VERTEX_DATA4F_M + 88" }, - { NV4097_SET_VERTEX_DATA4F_M + 92 , "NV4097_SET_VERTEX_DATA4F_M + 92" }, - { NV4097_SET_VERTEX_DATA4F_M + 96 , "NV4097_SET_VERTEX_DATA4F_M + 96" }, - { NV4097_SET_VERTEX_DATA4F_M + 100 , "NV4097_SET_VERTEX_DATA4F_M + 100" }, - { NV4097_SET_VERTEX_DATA4F_M + 104 , "NV4097_SET_VERTEX_DATA4F_M + 104" }, - { NV4097_SET_VERTEX_DATA4F_M + 108 , "NV4097_SET_VERTEX_DATA4F_M + 108" }, - { NV4097_SET_VERTEX_DATA4F_M + 112 , "NV4097_SET_VERTEX_DATA4F_M + 112" }, - { NV4097_SET_VERTEX_DATA4F_M + 116 , "NV4097_SET_VERTEX_DATA4F_M + 116" }, - { NV4097_SET_VERTEX_DATA4F_M + 120 , "NV4097_SET_VERTEX_DATA4F_M + 120" }, - { NV4097_SET_VERTEX_DATA4F_M + 124 , "NV4097_SET_VERTEX_DATA4F_M + 124" }, - { NV4097_SET_VERTEX_DATA4F_M + 128 , "NV4097_SET_VERTEX_DATA4F_M + 128" }, - { NV4097_SET_VERTEX_DATA4F_M + 132 , "NV4097_SET_VERTEX_DATA4F_M + 132" }, - { NV4097_SET_VERTEX_DATA4F_M + 136 , "NV4097_SET_VERTEX_DATA4F_M + 136" }, - { NV4097_SET_VERTEX_DATA4F_M + 140 , "NV4097_SET_VERTEX_DATA4F_M + 140" }, - { NV4097_SET_VERTEX_DATA4F_M + 144 , "NV4097_SET_VERTEX_DATA4F_M + 144" }, - { NV4097_SET_VERTEX_DATA4F_M + 148 , "NV4097_SET_VERTEX_DATA4F_M + 148" }, - { NV4097_SET_VERTEX_DATA4F_M + 152 , "NV4097_SET_VERTEX_DATA4F_M + 152" }, - { NV4097_SET_VERTEX_DATA4F_M + 156 , "NV4097_SET_VERTEX_DATA4F_M + 156" }, - { NV4097_SET_VERTEX_DATA4F_M + 160 , "NV4097_SET_VERTEX_DATA4F_M + 160" }, - { NV4097_SET_VERTEX_DATA4F_M + 164 , "NV4097_SET_VERTEX_DATA4F_M + 164" }, - { NV4097_SET_VERTEX_DATA4F_M + 168 , "NV4097_SET_VERTEX_DATA4F_M + 168" }, - { NV4097_SET_VERTEX_DATA4F_M + 172 , "NV4097_SET_VERTEX_DATA4F_M + 172" }, - { NV4097_SET_VERTEX_DATA4F_M + 176 , "NV4097_SET_VERTEX_DATA4F_M + 176" }, - { NV4097_SET_VERTEX_DATA4F_M + 180 , "NV4097_SET_VERTEX_DATA4F_M + 180" }, - { NV4097_SET_VERTEX_DATA4F_M + 184 , "NV4097_SET_VERTEX_DATA4F_M + 184" }, - { NV4097_SET_VERTEX_DATA4F_M + 188 , "NV4097_SET_VERTEX_DATA4F_M + 188" }, - { NV4097_SET_VERTEX_DATA4F_M + 192 , "NV4097_SET_VERTEX_DATA4F_M + 192" }, - { NV4097_SET_VERTEX_DATA4F_M + 196 , "NV4097_SET_VERTEX_DATA4F_M + 196" }, - { NV4097_SET_VERTEX_DATA4F_M + 200 , "NV4097_SET_VERTEX_DATA4F_M + 200" }, - { NV4097_SET_VERTEX_DATA4F_M + 204 , "NV4097_SET_VERTEX_DATA4F_M + 204" }, - { NV4097_SET_VERTEX_DATA4F_M + 208 , "NV4097_SET_VERTEX_DATA4F_M + 208" }, - { NV4097_SET_VERTEX_DATA4F_M + 212 , "NV4097_SET_VERTEX_DATA4F_M + 212" }, - { NV4097_SET_VERTEX_DATA4F_M + 216 , "NV4097_SET_VERTEX_DATA4F_M + 216" }, - { NV4097_SET_VERTEX_DATA4F_M + 220 , "NV4097_SET_VERTEX_DATA4F_M + 220" }, - { NV4097_SET_VERTEX_DATA4F_M + 224 , "NV4097_SET_VERTEX_DATA4F_M + 224" }, - { NV4097_SET_VERTEX_DATA4F_M + 228 , "NV4097_SET_VERTEX_DATA4F_M + 228" }, - { NV4097_SET_VERTEX_DATA4F_M + 232 , "NV4097_SET_VERTEX_DATA4F_M + 232" }, - { NV4097_SET_VERTEX_DATA4F_M + 236 , "NV4097_SET_VERTEX_DATA4F_M + 236" }, - { NV4097_SET_VERTEX_DATA4F_M + 240 , "NV4097_SET_VERTEX_DATA4F_M + 240" }, - { NV4097_SET_VERTEX_DATA4F_M + 244 , "NV4097_SET_VERTEX_DATA4F_M + 244" }, - { NV4097_SET_VERTEX_DATA4F_M + 248 , "NV4097_SET_VERTEX_DATA4F_M + 248" }, - { NV4097_SET_VERTEX_DATA4F_M + 252 , "NV4097_SET_VERTEX_DATA4F_M + 252" }, - { NV4097_SET_SHADER_CONTROL , "NV4097_SET_SHADER_CONTROL" }, - { NV4097_SET_SEMAPHORE_OFFSET , "NV4097_SET_SEMAPHORE_OFFSET" }, - { NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE , "NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE" }, - { NV4097_TEXTURE_READ_SEMAPHORE_RELEASE , "NV4097_TEXTURE_READ_SEMAPHORE_RELEASE" }, - { NV4097_SET_ZMIN_MAX_CONTROL , "NV4097_SET_ZMIN_MAX_CONTROL" }, - { NV4097_SET_ANTI_ALIASING_CONTROL , "NV4097_SET_ANTI_ALIASING_CONTROL" }, - { NV4097_SET_ZCULL_EN , "NV4097_SET_ZCULL_EN" }, - { NV4097_SET_SHADER_WINDOW , "NV4097_SET_SHADER_WINDOW" }, - { NV4097_SET_ZSTENCIL_CLEAR_VALUE , "NV4097_SET_ZSTENCIL_CLEAR_VALUE" }, - { NV4097_SET_COLOR_CLEAR_VALUE , "NV4097_SET_COLOR_CLEAR_VALUE" }, - { NV4097_CLEAR_SURFACE , "NV4097_CLEAR_SURFACE" }, - { NV4097_SET_RESTART_INDEX_ENABLE , "NV4097_SET_RESTART_INDEX_ENABLE" }, - { NV4097_SET_RESTART_INDEX , "NV4097_SET_RESTART_INDEX" }, - { NV4097_SET_LINE_STIPPLE , "NV4097_SET_LINE_STIPPLE" }, - { NV4097_SET_LINE_STIPPLE_PATTERN , "NV4097_SET_LINE_STIPPLE_PATTERN" }, - { NV4097_SET_VERTEX_DATA1F_M , "NV4097_SET_VERTEX_DATA1F_M" }, - { NV4097_SET_VERTEX_DATA1F_M + 4 , "NV4097_SET_VERTEX_DATA1F_M + 4" }, - { NV4097_SET_VERTEX_DATA1F_M + 8 , "NV4097_SET_VERTEX_DATA1F_M + 8" }, - { NV4097_SET_VERTEX_DATA1F_M + 12 , "NV4097_SET_VERTEX_DATA1F_M + 12" }, - { NV4097_SET_VERTEX_DATA1F_M + 16 , "NV4097_SET_VERTEX_DATA1F_M + 16" }, - { NV4097_SET_VERTEX_DATA1F_M + 20 , "NV4097_SET_VERTEX_DATA1F_M + 20" }, - { NV4097_SET_VERTEX_DATA1F_M + 24 , "NV4097_SET_VERTEX_DATA1F_M + 24" }, - { NV4097_SET_VERTEX_DATA1F_M + 28 , "NV4097_SET_VERTEX_DATA1F_M + 28" }, - { NV4097_SET_VERTEX_DATA1F_M + 32 , "NV4097_SET_VERTEX_DATA1F_M + 32" }, - { NV4097_SET_VERTEX_DATA1F_M + 36 , "NV4097_SET_VERTEX_DATA1F_M + 36" }, - { NV4097_SET_VERTEX_DATA1F_M + 40 , "NV4097_SET_VERTEX_DATA1F_M + 40" }, - { NV4097_SET_VERTEX_DATA1F_M + 44 , "NV4097_SET_VERTEX_DATA1F_M + 44" }, - { NV4097_SET_VERTEX_DATA1F_M + 48 , "NV4097_SET_VERTEX_DATA1F_M + 48" }, - { NV4097_SET_VERTEX_DATA1F_M + 52 , "NV4097_SET_VERTEX_DATA1F_M + 52" }, - { NV4097_SET_VERTEX_DATA1F_M + 56 , "NV4097_SET_VERTEX_DATA1F_M + 56" }, - { NV4097_SET_VERTEX_DATA1F_M + 60 , "NV4097_SET_VERTEX_DATA1F_M + 60" }, - { NV4097_SET_RENDER_ENABLE , "NV4097_SET_RENDER_ENABLE" }, - { NV4097_SET_TRANSFORM_PROGRAM_LOAD , "NV4097_SET_TRANSFORM_PROGRAM_LOAD" }, - { NV4097_SET_TRANSFORM_PROGRAM_START , "NV4097_SET_TRANSFORM_PROGRAM_START" }, - { NV4097_SET_ZCULL_CONTROL0 , "NV4097_SET_ZCULL_CONTROL0" }, - { NV4097_SET_ZCULL_CONTROL1 , "NV4097_SET_ZCULL_CONTROL1" }, - { NV4097_SET_SCULL_CONTROL , "NV4097_SET_SCULL_CONTROL" }, - { NV4097_SET_POINT_SIZE , "NV4097_SET_POINT_SIZE" }, - { NV4097_SET_POINT_PARAMS_ENABLE , "NV4097_SET_POINT_PARAMS_ENABLE" }, - { NV4097_SET_POINT_SPRITE_CONTROL , "NV4097_SET_POINT_SPRITE_CONTROL" }, - { NV4097_SET_TRANSFORM_TIMEOUT , "NV4097_SET_TRANSFORM_TIMEOUT" }, - { NV4097_SET_TRANSFORM_CONSTANT_LOAD , "NV4097_SET_TRANSFORM_CONSTANT_LOAD" }, - { NV4097_SET_FREQUENCY_DIVIDER_OPERATION , "NV4097_SET_FREQUENCY_DIVIDER_OPERATION" }, - { NV4097_SET_ATTRIB_COLOR, "NV4097_SET_ATTRIB_COLOR" }, - { NV4097_SET_ATTRIB_TEX_COORD, "NV4097_SET_ATTRIB_TEX_COORD" }, - { NV4097_SET_ATTRIB_TEX_COORD_EX, "NV4097_SET_ATTRIB_TEX_COORD_EX" }, - { NV4097_SET_ATTRIB_UCLIP0, "NV4097_SET_ATTRIB_UCLIP0" }, - { NV4097_SET_ATTRIB_UCLIP1, "NV4097_SET_ATTRIB_UCLIP1" }, - { NV4097_INVALIDATE_L2, "NV4097_INVALIDATE_L2" }, - { NV4097_SET_REDUCE_DST_COLOR, "NV4097_SET_REDUCE_DST_COLOR" }, - { NV4097_SET_NO_PARANOID_TEXTURE_FETCHES, "NV4097_SET_NO_PARANOID_TEXTURE_FETCHES" }, - { NV4097_SET_SHADER_PACKER, "NV4097_SET_SHADER_PACKER" }, - { NV4097_SET_VERTEX_ATTRIB_INPUT_MASK, "NV4097_SET_VERTEX_ATTRIB_INPUT_MASK" }, - { NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK, "NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK" }, - { NV4097_SET_TRANSFORM_BRANCH_BITS, "NV4097_SET_TRANSFORM_BRANCH_BITS" } - }; - for (auto& s: METHOD_NAME_LIST) +enum Method +{ + CELL_GCM_METHOD_FLAG_NON_INCREMENT = 0x40000000, + CELL_GCM_METHOD_FLAG_JUMP = 0x20000000, + CELL_GCM_METHOD_FLAG_CALL = 0x00000002, + CELL_GCM_METHOD_FLAG_RETURN = 0x00020000, +}; + +namespace rsx +{ + template + static std::initializer_list make_command(u32 start_register, T... values) { - if (s.id == id) - return s.name; + return{ (start_register << 2) | (sizeof...(values) << 18), values... }; } - return fmt::format("unknown/illegal method [0x%08x]", id); -} + static u32 make_jump(u32 offset) + { + return CELL_GCM_METHOD_FLAG_JUMP | offset; + } + + template + static size_t make_command(vm::ps3::ptr& dst, u32 start_register, T... values) + { + std::initializer_list commands = make_command(start_register, values...); + + for (auto &&command : commands) + { + vm::ps3::write32(dst.addr(), command); + dst++; + } + + return commands.size(); + } + + static size_t make_jump(vm::ps3::ptr& dst, u32 offset) + { + vm::ps3::write32(dst.addr(), make_jump(offset)); + dst++; + return 1; + } + + static const std::string get_method_name(const u32 id) + { + static const std::unordered_map methods = + { + { NV4097_NO_OPERATION, "NV4097_NO_OPERATION" }, + { NV4097_NOTIFY, "NV4097_NOTIFY" }, + { NV4097_WAIT_FOR_IDLE, "NV4097_WAIT_FOR_IDLE" }, + { NV4097_PM_TRIGGER, "NV4097_PM_TRIGGER" }, + { NV4097_SET_CONTEXT_DMA_NOTIFIES, "NV4097_SET_CONTEXT_DMA_NOTIFIES" }, + { NV4097_SET_CONTEXT_DMA_A, "NV4097_SET_CONTEXT_DMA_A" }, + { NV4097_SET_CONTEXT_DMA_B, "NV4097_SET_CONTEXT_DMA_B" }, + { NV4097_SET_CONTEXT_DMA_COLOR_B, "NV4097_SET_CONTEXT_DMA_COLOR_B" }, + { NV4097_SET_CONTEXT_DMA_STATE, "NV4097_SET_CONTEXT_DMA_STATE" }, + { NV4097_SET_CONTEXT_DMA_COLOR_A, "NV4097_SET_CONTEXT_DMA_COLOR_A" }, + { NV4097_SET_CONTEXT_DMA_ZETA, "NV4097_SET_CONTEXT_DMA_ZETA" }, + { NV4097_SET_CONTEXT_DMA_VERTEX_A, "NV4097_SET_CONTEXT_DMA_VERTEX_A" }, + { NV4097_SET_CONTEXT_DMA_VERTEX_B, "NV4097_SET_CONTEXT_DMA_VERTEX_B" }, + { NV4097_SET_CONTEXT_DMA_SEMAPHORE, "NV4097_SET_CONTEXT_DMA_SEMAPHORE" }, + { NV4097_SET_CONTEXT_DMA_REPORT, "NV4097_SET_CONTEXT_DMA_REPORT" }, + { NV4097_SET_CONTEXT_DMA_CLIP_ID, "NV4097_SET_CONTEXT_DMA_CLIP_ID" }, + { NV4097_SET_CONTEXT_DMA_CULL_DATA, "NV4097_SET_CONTEXT_DMA_CULL_DATA" }, + { NV4097_SET_CONTEXT_DMA_COLOR_C, "NV4097_SET_CONTEXT_DMA_COLOR_C" }, + { NV4097_SET_CONTEXT_DMA_COLOR_D, "NV4097_SET_CONTEXT_DMA_COLOR_D" }, + { NV4097_SET_SURFACE_CLIP_HORIZONTAL, "NV4097_SET_SURFACE_CLIP_HORIZONTAL" }, + { NV4097_SET_SURFACE_CLIP_VERTICAL, "NV4097_SET_SURFACE_CLIP_VERTICAL" }, + { NV4097_SET_SURFACE_FORMAT, "NV4097_SET_SURFACE_FORMAT" }, + { NV4097_SET_SURFACE_PITCH_A, "NV4097_SET_SURFACE_PITCH_A" }, + { NV4097_SET_SURFACE_COLOR_AOFFSET, "NV4097_SET_SURFACE_COLOR_AOFFSET" }, + { NV4097_SET_SURFACE_ZETA_OFFSET, "NV4097_SET_SURFACE_ZETA_OFFSET" }, + { NV4097_SET_SURFACE_COLOR_BOFFSET, "NV4097_SET_SURFACE_COLOR_BOFFSET" }, + { NV4097_SET_SURFACE_PITCH_B, "NV4097_SET_SURFACE_PITCH_B" }, + { NV4097_SET_SURFACE_COLOR_TARGET, "NV4097_SET_SURFACE_COLOR_TARGET" }, + { NV4097_SET_SURFACE_PITCH_Z, "NV4097_SET_SURFACE_PITCH_Z" }, + { NV4097_INVALIDATE_ZCULL, "NV4097_INVALIDATE_ZCULL" }, + { NV4097_SET_CYLINDRICAL_WRAP, "NV4097_SET_CYLINDRICAL_WRAP" }, + { NV4097_SET_CYLINDRICAL_WRAP1, "NV4097_SET_CYLINDRICAL_WRAP1" }, + { NV4097_SET_SURFACE_PITCH_C, "NV4097_SET_SURFACE_PITCH_C" }, + { NV4097_SET_SURFACE_PITCH_D, "NV4097_SET_SURFACE_PITCH_D" }, + { NV4097_SET_SURFACE_COLOR_COFFSET, "NV4097_SET_SURFACE_COLOR_COFFSET" }, + { NV4097_SET_SURFACE_COLOR_DOFFSET, "NV4097_SET_SURFACE_COLOR_DOFFSET" }, + { NV4097_SET_WINDOW_OFFSET, "NV4097_SET_WINDOW_OFFSET" }, + { NV4097_SET_DITHER_ENABLE, "NV4097_SET_DITHER_ENABLE" }, + { NV4097_SET_ALPHA_TEST_ENABLE, "NV4097_SET_ALPHA_TEST_ENABLE" }, + { NV4097_SET_ALPHA_FUNC, "NV4097_SET_ALPHA_FUNC" }, + { NV4097_SET_ALPHA_REF, "NV4097_SET_ALPHA_REF" }, + { NV4097_SET_BLEND_ENABLE, "NV4097_SET_BLEND_ENABLE" }, + { NV4097_SET_BLEND_FUNC_SFACTOR, "NV4097_SET_BLEND_FUNC_SFACTOR" }, + { NV4097_SET_BLEND_FUNC_DFACTOR, "NV4097_SET_BLEND_FUNC_DFACTOR" }, + { NV4097_SET_BLEND_COLOR, "NV4097_SET_BLEND_COLOR" }, + { NV4097_SET_BLEND_EQUATION, "NV4097_SET_BLEND_EQUATION" }, + { NV4097_SET_COLOR_MASK, "NV4097_SET_COLOR_MASK" }, + { NV4097_SET_STENCIL_TEST_ENABLE, "NV4097_SET_STENCIL_TEST_ENABLE" }, + { NV4097_SET_STENCIL_MASK, "NV4097_SET_STENCIL_MASK" }, + { NV4097_SET_STENCIL_FUNC, "NV4097_SET_STENCIL_FUNC" }, + { NV4097_SET_STENCIL_FUNC_REF, "NV4097_SET_STENCIL_FUNC_REF" }, + { NV4097_SET_STENCIL_FUNC_MASK, "NV4097_SET_STENCIL_FUNC_MASK" }, + { NV4097_SET_STENCIL_OP_FAIL, "NV4097_SET_STENCIL_OP_FAIL" }, + { NV4097_SET_STENCIL_OP_ZFAIL, "NV4097_SET_STENCIL_OP_ZFAIL" }, + { NV4097_SET_STENCIL_OP_ZPASS, "NV4097_SET_STENCIL_OP_ZPASS" }, + { NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE, "NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE" }, + { NV4097_SET_BACK_STENCIL_MASK, "NV4097_SET_BACK_STENCIL_MASK" }, + { NV4097_SET_BACK_STENCIL_FUNC, "NV4097_SET_BACK_STENCIL_FUNC" }, + { NV4097_SET_BACK_STENCIL_FUNC_REF, "NV4097_SET_BACK_STENCIL_FUNC_REF" }, + { NV4097_SET_BACK_STENCIL_FUNC_MASK, "NV4097_SET_BACK_STENCIL_FUNC_MASK" }, + { NV4097_SET_BACK_STENCIL_OP_FAIL, "NV4097_SET_BACK_STENCIL_OP_FAIL" }, + { NV4097_SET_BACK_STENCIL_OP_ZFAIL, "NV4097_SET_BACK_STENCIL_OP_ZFAIL" }, + { NV4097_SET_BACK_STENCIL_OP_ZPASS, "NV4097_SET_BACK_STENCIL_OP_ZPASS" }, + { NV4097_SET_SHADE_MODE, "NV4097_SET_SHADE_MODE" }, + { NV4097_SET_BLEND_ENABLE_MRT, "NV4097_SET_BLEND_ENABLE_MRT" }, + { NV4097_SET_COLOR_MASK_MRT, "NV4097_SET_COLOR_MASK_MRT" }, + { NV4097_SET_LOGIC_OP_ENABLE, "NV4097_SET_LOGIC_OP_ENABLE" }, + { NV4097_SET_LOGIC_OP, "NV4097_SET_LOGIC_OP" }, + { NV4097_SET_BLEND_COLOR2, "NV4097_SET_BLEND_COLOR2" }, + { NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE, "NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE" }, + { NV4097_SET_DEPTH_BOUNDS_MIN, "NV4097_SET_DEPTH_BOUNDS_MIN" }, + { NV4097_SET_DEPTH_BOUNDS_MAX, "NV4097_SET_DEPTH_BOUNDS_MAX" }, + { NV4097_SET_CLIP_MIN, "NV4097_SET_CLIP_MIN" }, + { NV4097_SET_CLIP_MAX, "NV4097_SET_CLIP_MAX" }, + { NV4097_SET_CONTROL0, "NV4097_SET_CONTROL0" }, + { NV4097_SET_LINE_WIDTH, "NV4097_SET_LINE_WIDTH" }, + { NV4097_SET_LINE_SMOOTH_ENABLE, "NV4097_SET_LINE_SMOOTH_ENABLE" }, + { NV4097_SET_ANISO_SPREAD, "NV4097_SET_ANISO_SPREAD" }, + { NV4097_SET_ANISO_SPREAD + 4 / 4, "NV4097_SET_ANISO_SPREAD + 4" }, + { NV4097_SET_ANISO_SPREAD + 8 / 4, "NV4097_SET_ANISO_SPREAD + 8" }, + { NV4097_SET_ANISO_SPREAD + 12 / 4, "NV4097_SET_ANISO_SPREAD + 12" }, + { NV4097_SET_ANISO_SPREAD + 16 / 4, "NV4097_SET_ANISO_SPREAD + 16" }, + { NV4097_SET_ANISO_SPREAD + 20 / 4, "NV4097_SET_ANISO_SPREAD + 20" }, + { NV4097_SET_ANISO_SPREAD + 24 / 4, "NV4097_SET_ANISO_SPREAD + 24" }, + { NV4097_SET_ANISO_SPREAD + 28 / 4, "NV4097_SET_ANISO_SPREAD + 28" }, + { NV4097_SET_ANISO_SPREAD + 32 / 4, "NV4097_SET_ANISO_SPREAD + 32" }, + { NV4097_SET_ANISO_SPREAD + 36 / 4, "NV4097_SET_ANISO_SPREAD + 36" }, + { NV4097_SET_ANISO_SPREAD + 40 / 4, "NV4097_SET_ANISO_SPREAD + 40" }, + { NV4097_SET_ANISO_SPREAD + 44 / 4, "NV4097_SET_ANISO_SPREAD + 44" }, + { NV4097_SET_ANISO_SPREAD + 48 / 4, "NV4097_SET_ANISO_SPREAD + 48" }, + { NV4097_SET_ANISO_SPREAD + 52 / 4, "NV4097_SET_ANISO_SPREAD + 52" }, + { NV4097_SET_ANISO_SPREAD + 56 / 4, "NV4097_SET_ANISO_SPREAD + 56" }, + { NV4097_SET_ANISO_SPREAD + 60 / 4, "NV4097_SET_ANISO_SPREAD + 60" }, + { NV4097_SET_SCISSOR_HORIZONTAL, "NV4097_SET_SCISSOR_HORIZONTAL" }, + { NV4097_SET_SCISSOR_VERTICAL, "NV4097_SET_SCISSOR_VERTICAL" }, + { NV4097_SET_FOG_MODE, "NV4097_SET_FOG_MODE" }, + { NV4097_SET_FOG_PARAMS, "NV4097_SET_FOG_PARAMS" }, + { NV4097_SET_FOG_PARAMS + 4 / 4, "NV4097_SET_FOG_PARAMS + 4" }, + { NV4097_SET_FOG_PARAMS + 8 / 4, "NV4097_SET_FOG_PARAMS + 8" }, + { NV4097_SET_SHADER_PROGRAM, "NV4097_SET_SHADER_PROGRAM" }, + { NV4097_SET_VERTEX_TEXTURE_OFFSET, "NV4097_SET_VERTEX_TEXTURE_OFFSET" }, + { NV4097_SET_VERTEX_TEXTURE_FORMAT, "NV4097_SET_VERTEX_TEXTURE_FORMAT" }, + { NV4097_SET_VERTEX_TEXTURE_ADDRESS, "NV4097_SET_VERTEX_TEXTURE_ADDRESS" }, + { NV4097_SET_VERTEX_TEXTURE_CONTROL0, "NV4097_SET_VERTEX_TEXTURE_CONTROL0" }, + { NV4097_SET_VERTEX_TEXTURE_CONTROL3, "NV4097_SET_VERTEX_TEXTURE_CONTROL3" }, + { NV4097_SET_VERTEX_TEXTURE_FILTER, "NV4097_SET_VERTEX_TEXTURE_FILTER" }, + { NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT, "NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT" }, + { NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR, "NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR" }, + { NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x20 / 4, "NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x20" }, + { NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x20 / 4, "NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x20" }, + { NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x20 / 4, "NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x20" }, + { NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x20 / 4, "NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x20" }, + { NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x20 / 4, "NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x20" }, + { NV4097_SET_VERTEX_TEXTURE_FILTER + 0x20 / 4, "NV4097_SET_VERTEX_TEXTURE_FILTER + 0x20" }, + { NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x20 / 4, "NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x20" }, + { NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x20 / 4, "NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x20" }, + { NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x40 / 4, "NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x40" }, + { NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x40 / 4, "NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x40" }, + { NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x40 / 4, "NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x40" }, + { NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x40 / 4, "NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x40" }, + { NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x40 / 4, "NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x40" }, + { NV4097_SET_VERTEX_TEXTURE_FILTER + 0x40 / 4, "NV4097_SET_VERTEX_TEXTURE_FILTER + 0x40" }, + { NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x40 / 4, "NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x40" }, + { NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x40 / 4, "NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x40" }, + { NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x60 / 4, "NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x60" }, + { NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x60 / 4, "NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x60" }, + { NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x60 / 4, "NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x60" }, + { NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x60 / 4, "NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x60" }, + { NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x60 / 4, "NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x60" }, + { NV4097_SET_VERTEX_TEXTURE_FILTER + 0x60 / 4, "NV4097_SET_VERTEX_TEXTURE_FILTER + 0x60" }, + { NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x60 / 4, "NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x60" }, + { NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x60 / 4, "NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x60" }, + { NV4097_SET_VIEWPORT_HORIZONTAL, "NV4097_SET_VIEWPORT_HORIZONTAL" }, + { NV4097_SET_VIEWPORT_VERTICAL, "NV4097_SET_VIEWPORT_VERTICAL" }, + { NV4097_SET_VIEWPORT_OFFSET, "NV4097_SET_VIEWPORT_OFFSET" }, + { NV4097_SET_VIEWPORT_SCALE, "NV4097_SET_VIEWPORT_SCALE" }, + { NV4097_SET_POLY_OFFSET_LINE_ENABLE, "NV4097_SET_POLY_OFFSET_LINE_ENABLE" }, + { NV4097_SET_POLY_OFFSET_FILL_ENABLE, "NV4097_SET_POLY_OFFSET_FILL_ENABLE" }, + { NV4097_SET_DEPTH_FUNC, "NV4097_SET_DEPTH_FUNC" }, + { NV4097_SET_DEPTH_MASK, "NV4097_SET_DEPTH_MASK" }, + { NV4097_SET_DEPTH_TEST_ENABLE, "NV4097_SET_DEPTH_TEST_ENABLE" }, + { NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR, "NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR" }, + { NV4097_SET_POLYGON_OFFSET_BIAS, "NV4097_SET_POLYGON_OFFSET_BIAS" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M, "NV4097_SET_VERTEX_DATA_SCALED4S_M" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 4 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 4" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 8 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 8" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 12 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 12" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 16 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 16" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 20 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 20" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 24 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 24" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 28 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 28" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 32 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 32" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 36 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 36" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 40, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 40" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 44 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 44" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 48 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 48" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 52 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 52" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 56 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 56" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 60 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 60" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 64 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 64" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 68 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 68" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 72 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 72" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 76 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 76" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 80 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 80" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 84 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 84" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 88 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 88" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 92 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 92" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 96 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 96" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 100 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 100" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 104 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 104" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 108 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 108" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 112 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 112" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 116 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 116" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 120 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 120" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 124 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 124" }, + { NV4097_SET_TEXTURE_CONTROL2, "NV4097_SET_TEXTURE_CONTROL2" }, + { NV4097_SET_TEXTURE_CONTROL2 + 4 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 4" }, + { NV4097_SET_TEXTURE_CONTROL2 + 8 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 8" }, + { NV4097_SET_TEXTURE_CONTROL2 + 12 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 12" }, + { NV4097_SET_TEXTURE_CONTROL2 + 16 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 16" }, + { NV4097_SET_TEXTURE_CONTROL2 + 20 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 20" }, + { NV4097_SET_TEXTURE_CONTROL2 + 24 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 24" }, + { NV4097_SET_TEXTURE_CONTROL2 + 28 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 28" }, + { NV4097_SET_TEXTURE_CONTROL2 + 32 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 32" }, + { NV4097_SET_TEXTURE_CONTROL2 + 36 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 36" }, + { NV4097_SET_TEXTURE_CONTROL2 + 40 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 40" }, + { NV4097_SET_TEXTURE_CONTROL2 + 44 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 44" }, + { NV4097_SET_TEXTURE_CONTROL2 + 48 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 48" }, + { NV4097_SET_TEXTURE_CONTROL2 + 52 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 52" }, + { NV4097_SET_TEXTURE_CONTROL2 + 56 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 56" }, + { NV4097_SET_TEXTURE_CONTROL2 + 60 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 60" }, + { NV4097_SET_TEX_COORD_CONTROL, "NV4097_SET_TEX_COORD_CONTROL" }, + { NV4097_SET_TEX_COORD_CONTROL + 4 / 4, "NV4097_SET_TEX_COORD_CONTROL + 4" }, + { NV4097_SET_TEX_COORD_CONTROL + 8 / 4, "NV4097_SET_TEX_COORD_CONTROL + 8" }, + { NV4097_SET_TEX_COORD_CONTROL + 12 / 4, "NV4097_SET_TEX_COORD_CONTROL + 12" }, + { NV4097_SET_TEX_COORD_CONTROL + 16 / 4, "NV4097_SET_TEX_COORD_CONTROL + 16" }, + { NV4097_SET_TEX_COORD_CONTROL + 20 / 4, "NV4097_SET_TEX_COORD_CONTROL + 20" }, + { NV4097_SET_TEX_COORD_CONTROL + 24 / 4, "NV4097_SET_TEX_COORD_CONTROL + 24" }, + { NV4097_SET_TEX_COORD_CONTROL + 28 / 4, "NV4097_SET_TEX_COORD_CONTROL + 28" }, + { NV4097_SET_TEX_COORD_CONTROL + 32 / 4, "NV4097_SET_TEX_COORD_CONTROL + 32" }, + { NV4097_SET_TEX_COORD_CONTROL + 36 / 4, "NV4097_SET_TEX_COORD_CONTROL + 36" }, + { NV4097_SET_TRANSFORM_PROGRAM, "NV4097_SET_TRANSFORM_PROGRAM" }, + { NV4097_SET_TRANSFORM_PROGRAM + 4 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 4" }, + { NV4097_SET_TRANSFORM_PROGRAM + 8 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 8" }, + { NV4097_SET_TRANSFORM_PROGRAM + 12 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 12" }, + { NV4097_SET_TRANSFORM_PROGRAM + 16 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 16" }, + { NV4097_SET_TRANSFORM_PROGRAM + 20 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 20" }, + { NV4097_SET_TRANSFORM_PROGRAM + 24 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 24" }, + { NV4097_SET_TRANSFORM_PROGRAM + 28 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 28" }, + { NV4097_SET_TRANSFORM_PROGRAM + 32 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 32" }, + { NV4097_SET_TRANSFORM_PROGRAM + 36 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 36" }, + { NV4097_SET_TRANSFORM_PROGRAM + 40 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 40" }, + { NV4097_SET_TRANSFORM_PROGRAM + 44 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 44" }, + { NV4097_SET_TRANSFORM_PROGRAM + 48 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 48" }, + { NV4097_SET_TRANSFORM_PROGRAM + 52 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 52" }, + { NV4097_SET_TRANSFORM_PROGRAM + 56 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 56" }, + { NV4097_SET_TRANSFORM_PROGRAM + 60 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 60" }, + { NV4097_SET_TRANSFORM_PROGRAM + 64 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 64" }, + { NV4097_SET_TRANSFORM_PROGRAM + 68 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 68" }, + { NV4097_SET_TRANSFORM_PROGRAM + 72 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 72" }, + { NV4097_SET_TRANSFORM_PROGRAM + 76 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 76" }, + { NV4097_SET_TRANSFORM_PROGRAM + 80 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 80" }, + { NV4097_SET_TRANSFORM_PROGRAM + 84 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 84" }, + { NV4097_SET_TRANSFORM_PROGRAM + 88 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 88" }, + { NV4097_SET_TRANSFORM_PROGRAM + 92 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 92" }, + { NV4097_SET_TRANSFORM_PROGRAM + 96 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 96" }, + { NV4097_SET_TRANSFORM_PROGRAM + 100 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 100" }, + { NV4097_SET_TRANSFORM_PROGRAM + 104 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 104" }, + { NV4097_SET_TRANSFORM_PROGRAM + 108 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 108" }, + { NV4097_SET_TRANSFORM_PROGRAM + 112 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 112" }, + { NV4097_SET_TRANSFORM_PROGRAM + 116 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 116" }, + { NV4097_SET_TRANSFORM_PROGRAM + 120 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 120" }, + { NV4097_SET_TRANSFORM_PROGRAM + 124 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 124" }, + { NV4097_SET_TWO_SIDE_LIGHT_EN, "NV4097_SET_TWO_SIDE_LIGHT_EN" }, + { NV4097_CLEAR_ZCULL_SURFACE, "NV4097_CLEAR_ZCULL_SURFACE" }, + { NV4097_SET_USER_CLIP_PLANE_CONTROL, "NV4097_SET_USER_CLIP_PLANE_CONTROL" }, + { NV4097_SET_POLYGON_STIPPLE, "NV4097_SET_POLYGON_STIPPLE" }, + { NV4097_SET_POLYGON_STIPPLE_PATTERN, "NV4097_SET_POLYGON_STIPPLE_PATTERN" }, + { NV4097_SET_VERTEX_DATA3F_M, "NV4097_SET_VERTEX_DATA3F_M" }, + { NV4097_SET_VERTEX_DATA3F_M + 4 / 4, "NV4097_SET_VERTEX_DATA3F_M + 4" }, + { NV4097_SET_VERTEX_DATA3F_M + 8 / 4, "NV4097_SET_VERTEX_DATA3F_M + 8" }, + { NV4097_SET_VERTEX_DATA3F_M + 12 / 4, "NV4097_SET_VERTEX_DATA3F_M + 12" }, + { NV4097_SET_VERTEX_DATA3F_M + 16 / 4, "NV4097_SET_VERTEX_DATA3F_M + 16" }, + { NV4097_SET_VERTEX_DATA3F_M + 20 / 4, "NV4097_SET_VERTEX_DATA3F_M + 20" }, + { NV4097_SET_VERTEX_DATA3F_M + 24 / 4, "NV4097_SET_VERTEX_DATA3F_M + 24" }, + { NV4097_SET_VERTEX_DATA3F_M + 28 / 4, "NV4097_SET_VERTEX_DATA3F_M + 28" }, + { NV4097_SET_VERTEX_DATA3F_M + 32 / 4, "NV4097_SET_VERTEX_DATA3F_M + 32" }, + { NV4097_SET_VERTEX_DATA3F_M + 36 / 4, "NV4097_SET_VERTEX_DATA3F_M + 36" }, + { NV4097_SET_VERTEX_DATA3F_M + 40 / 4, "NV4097_SET_VERTEX_DATA3F_M + 40" }, + { NV4097_SET_VERTEX_DATA3F_M + 44 / 4, "NV4097_SET_VERTEX_DATA3F_M + 44" }, + { NV4097_SET_VERTEX_DATA3F_M + 48 / 4, "NV4097_SET_VERTEX_DATA3F_M + 48" }, + { NV4097_SET_VERTEX_DATA3F_M + 52 / 4, "NV4097_SET_VERTEX_DATA3F_M + 52" }, + { NV4097_SET_VERTEX_DATA3F_M + 56 / 4, "NV4097_SET_VERTEX_DATA3F_M + 56" }, + { NV4097_SET_VERTEX_DATA3F_M + 60 / 4, "NV4097_SET_VERTEX_DATA3F_M + 60" }, + { NV4097_SET_VERTEX_DATA3F_M + 64 / 4, "NV4097_SET_VERTEX_DATA3F_M + 64" }, + { NV4097_SET_VERTEX_DATA3F_M + 68 / 4, "NV4097_SET_VERTEX_DATA3F_M + 68" }, + { NV4097_SET_VERTEX_DATA3F_M + 72 / 4, "NV4097_SET_VERTEX_DATA3F_M + 72" }, + { NV4097_SET_VERTEX_DATA3F_M + 76 / 4, "NV4097_SET_VERTEX_DATA3F_M + 76" }, + { NV4097_SET_VERTEX_DATA3F_M + 80 / 4, "NV4097_SET_VERTEX_DATA3F_M + 80" }, + { NV4097_SET_VERTEX_DATA3F_M + 84 / 4, "NV4097_SET_VERTEX_DATA3F_M + 84" }, + { NV4097_SET_VERTEX_DATA3F_M + 88 / 4, "NV4097_SET_VERTEX_DATA3F_M + 88" }, + { NV4097_SET_VERTEX_DATA3F_M + 92 / 4, "NV4097_SET_VERTEX_DATA3F_M + 92" }, + { NV4097_SET_VERTEX_DATA3F_M + 96 / 4, "NV4097_SET_VERTEX_DATA3F_M + 96" }, + { NV4097_SET_VERTEX_DATA3F_M + 100 / 4, "NV4097_SET_VERTEX_DATA3F_M + 100" }, + { NV4097_SET_VERTEX_DATA3F_M + 104 / 4, "NV4097_SET_VERTEX_DATA3F_M + 104" }, + { NV4097_SET_VERTEX_DATA3F_M + 108 / 4, "NV4097_SET_VERTEX_DATA3F_M + 108" }, + { NV4097_SET_VERTEX_DATA3F_M + 112 / 4, "NV4097_SET_VERTEX_DATA3F_M + 112" }, + { NV4097_SET_VERTEX_DATA3F_M + 116 / 4, "NV4097_SET_VERTEX_DATA3F_M + 116" }, + { NV4097_SET_VERTEX_DATA3F_M + 120 / 4, "NV4097_SET_VERTEX_DATA3F_M + 120" }, + { NV4097_SET_VERTEX_DATA3F_M + 124 / 4, "NV4097_SET_VERTEX_DATA3F_M + 124" }, + { NV4097_SET_VERTEX_DATA3F_M + 128 / 4, "NV4097_SET_VERTEX_DATA3F_M + 128" }, + { NV4097_SET_VERTEX_DATA3F_M + 132 / 4, "NV4097_SET_VERTEX_DATA3F_M + 132" }, + { NV4097_SET_VERTEX_DATA3F_M + 136 / 4, "NV4097_SET_VERTEX_DATA3F_M + 136" }, + { NV4097_SET_VERTEX_DATA3F_M + 140 / 4, "NV4097_SET_VERTEX_DATA3F_M + 140" }, + { NV4097_SET_VERTEX_DATA3F_M + 144 / 4, "NV4097_SET_VERTEX_DATA3F_M + 144" }, + { NV4097_SET_VERTEX_DATA3F_M + 148 / 4, "NV4097_SET_VERTEX_DATA3F_M + 148" }, + { NV4097_SET_VERTEX_DATA3F_M + 152 / 4, "NV4097_SET_VERTEX_DATA3F_M + 152" }, + { NV4097_SET_VERTEX_DATA3F_M + 156 / 4, "NV4097_SET_VERTEX_DATA3F_M + 156" }, + { NV4097_SET_VERTEX_DATA3F_M + 160 / 4, "NV4097_SET_VERTEX_DATA3F_M + 160" }, + { NV4097_SET_VERTEX_DATA3F_M + 164 / 4, "NV4097_SET_VERTEX_DATA3F_M + 164" }, + { NV4097_SET_VERTEX_DATA3F_M + 168 / 4, "NV4097_SET_VERTEX_DATA3F_M + 168" }, + { NV4097_SET_VERTEX_DATA3F_M + 172 / 4, "NV4097_SET_VERTEX_DATA3F_M + 172" }, + { NV4097_SET_VERTEX_DATA3F_M + 176 / 4, "NV4097_SET_VERTEX_DATA3F_M + 176" }, + { NV4097_SET_VERTEX_DATA3F_M + 180 / 4, "NV4097_SET_VERTEX_DATA3F_M + 180" }, + { NV4097_SET_VERTEX_DATA3F_M + 184 / 4, "NV4097_SET_VERTEX_DATA3F_M + 184" }, + { NV4097_SET_VERTEX_DATA3F_M + 188 / 4, "NV4097_SET_VERTEX_DATA3F_M + 188" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 4 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 4" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 8 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 8" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 12 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 12" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 16 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 16" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 20 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 20" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 24 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 24" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 28 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 28" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 32 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 32" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 36 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 36" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 40 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 40" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 44 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 44" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 48 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 48" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 52 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 52" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 56 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 56" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 60 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 60" }, + { NV4097_INVALIDATE_VERTEX_CACHE_FILE, "NV4097_INVALIDATE_VERTEX_CACHE_FILE" }, + { NV4097_INVALIDATE_VERTEX_FILE, "NV4097_INVALIDATE_VERTEX_FILE" }, + { NV4097_SET_VERTEX_DATA_BASE_OFFSET, "NV4097_SET_VERTEX_DATA_BASE_OFFSET" }, + { NV4097_SET_VERTEX_DATA_BASE_INDEX, "NV4097_SET_VERTEX_DATA_BASE_INDEX" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 4 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 4" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 8 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 8" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 12 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 12" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 16 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 16" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 20 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 20" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 24 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 24" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 28 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 28" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 32 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 32" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 36 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 36" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 40 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 40" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 44 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 44" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 48 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 48" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 52 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 52" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 56 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 56" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 60 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 60" }, + { NV4097_CLEAR_REPORT_VALUE, "NV4097_CLEAR_REPORT_VALUE" }, + { NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE, "NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE" }, + { NV4097_GET_REPORT, "NV4097_GET_REPORT" }, + { NV4097_SET_ZCULL_STATS_ENABLE, "NV4097_SET_ZCULL_STATS_ENABLE" }, + { NV4097_SET_BEGIN_END, "NV4097_SET_BEGIN_END" }, + { NV4097_ARRAY_ELEMENT16, "NV4097_ARRAY_ELEMENT16" }, + { NV4097_ARRAY_ELEMENT32, "NV4097_ARRAY_ELEMENT32" }, + { NV4097_DRAW_ARRAYS, "NV4097_DRAW_ARRAYS" }, + { NV4097_INLINE_ARRAY, "NV4097_INLINE_ARRAY" }, + { NV4097_SET_INDEX_ARRAY_ADDRESS, "NV4097_SET_INDEX_ARRAY_ADDRESS" }, + { NV4097_SET_INDEX_ARRAY_DMA, "NV4097_SET_INDEX_ARRAY_DMA" }, + { NV4097_DRAW_INDEX_ARRAY, "NV4097_DRAW_INDEX_ARRAY" }, + { NV4097_SET_FRONT_POLYGON_MODE, "NV4097_SET_FRONT_POLYGON_MODE" }, + { NV4097_SET_BACK_POLYGON_MODE, "NV4097_SET_BACK_POLYGON_MODE" }, + { NV4097_SET_CULL_FACE, "NV4097_SET_CULL_FACE" }, + { NV4097_SET_FRONT_FACE, "NV4097_SET_FRONT_FACE" }, + { NV4097_SET_POLY_SMOOTH_ENABLE, "NV4097_SET_POLY_SMOOTH_ENABLE" }, + { NV4097_SET_CULL_FACE_ENABLE, "NV4097_SET_CULL_FACE_ENABLE" }, + { NV4097_SET_TEXTURE_CONTROL3, "NV4097_SET_TEXTURE_CONTROL3" }, + { NV4097_SET_TEXTURE_CONTROL3 + 4 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 4" }, + { NV4097_SET_TEXTURE_CONTROL3 + 8 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 8" }, + { NV4097_SET_TEXTURE_CONTROL3 + 12 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 12" }, + { NV4097_SET_TEXTURE_CONTROL3 + 16 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 16" }, + { NV4097_SET_TEXTURE_CONTROL3 + 20 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 20" }, + { NV4097_SET_TEXTURE_CONTROL3 + 24 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 24" }, + { NV4097_SET_TEXTURE_CONTROL3 + 28 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 28" }, + { NV4097_SET_TEXTURE_CONTROL3 + 32 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 32" }, + { NV4097_SET_TEXTURE_CONTROL3 + 36 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 36" }, + { NV4097_SET_TEXTURE_CONTROL3 + 40 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 40" }, + { NV4097_SET_TEXTURE_CONTROL3 + 44 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 44" }, + { NV4097_SET_TEXTURE_CONTROL3 + 48 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 48" }, + { NV4097_SET_TEXTURE_CONTROL3 + 52 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 52" }, + { NV4097_SET_TEXTURE_CONTROL3 + 56 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 56" }, + { NV4097_SET_TEXTURE_CONTROL3 + 60 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 60" }, + { NV4097_SET_VERTEX_DATA2F_M, "NV4097_SET_VERTEX_DATA2F_M" }, + { NV4097_SET_VERTEX_DATA2F_M + 4 / 4, "NV4097_SET_VERTEX_DATA2F_M + 4" }, + { NV4097_SET_VERTEX_DATA2F_M + 8 / 4, "NV4097_SET_VERTEX_DATA2F_M + 8" }, + { NV4097_SET_VERTEX_DATA2F_M + 12 / 4, "NV4097_SET_VERTEX_DATA2F_M + 12" }, + { NV4097_SET_VERTEX_DATA2F_M + 16 / 4, "NV4097_SET_VERTEX_DATA2F_M + 16" }, + { NV4097_SET_VERTEX_DATA2F_M + 20 / 4, "NV4097_SET_VERTEX_DATA2F_M + 20" }, + { NV4097_SET_VERTEX_DATA2F_M + 24 / 4, "NV4097_SET_VERTEX_DATA2F_M + 24" }, + { NV4097_SET_VERTEX_DATA2F_M + 28 / 4, "NV4097_SET_VERTEX_DATA2F_M + 28" }, + { NV4097_SET_VERTEX_DATA2F_M + 32 / 4, "NV4097_SET_VERTEX_DATA2F_M + 32" }, + { NV4097_SET_VERTEX_DATA2F_M + 36 / 4, "NV4097_SET_VERTEX_DATA2F_M + 36" }, + { NV4097_SET_VERTEX_DATA2F_M + 40 / 4, "NV4097_SET_VERTEX_DATA2F_M + 40" }, + { NV4097_SET_VERTEX_DATA2F_M + 44 / 4, "NV4097_SET_VERTEX_DATA2F_M + 44" }, + { NV4097_SET_VERTEX_DATA2F_M + 48 / 4, "NV4097_SET_VERTEX_DATA2F_M + 48" }, + { NV4097_SET_VERTEX_DATA2F_M + 52 / 4, "NV4097_SET_VERTEX_DATA2F_M + 52" }, + { NV4097_SET_VERTEX_DATA2F_M + 56 / 4, "NV4097_SET_VERTEX_DATA2F_M + 56" }, + { NV4097_SET_VERTEX_DATA2F_M + 60 / 4, "NV4097_SET_VERTEX_DATA2F_M + 60" }, + { NV4097_SET_VERTEX_DATA2F_M + 64 / 4, "NV4097_SET_VERTEX_DATA2F_M + 64" }, + { NV4097_SET_VERTEX_DATA2F_M + 68 / 4, "NV4097_SET_VERTEX_DATA2F_M + 68" }, + { NV4097_SET_VERTEX_DATA2F_M + 72 / 4, "NV4097_SET_VERTEX_DATA2F_M + 72" }, + { NV4097_SET_VERTEX_DATA2F_M + 76 / 4, "NV4097_SET_VERTEX_DATA2F_M + 76" }, + { NV4097_SET_VERTEX_DATA2F_M + 80 / 4, "NV4097_SET_VERTEX_DATA2F_M + 80" }, + { NV4097_SET_VERTEX_DATA2F_M + 84 / 4, "NV4097_SET_VERTEX_DATA2F_M + 84" }, + { NV4097_SET_VERTEX_DATA2F_M + 88 / 4, "NV4097_SET_VERTEX_DATA2F_M + 88" }, + { NV4097_SET_VERTEX_DATA2F_M + 92 / 4, "NV4097_SET_VERTEX_DATA2F_M + 92" }, + { NV4097_SET_VERTEX_DATA2F_M + 96 / 4, "NV4097_SET_VERTEX_DATA2F_M + 96" }, + { NV4097_SET_VERTEX_DATA2F_M + 100 / 4, "NV4097_SET_VERTEX_DATA2F_M + 100" }, + { NV4097_SET_VERTEX_DATA2F_M + 104 / 4, "NV4097_SET_VERTEX_DATA2F_M + 104" }, + { NV4097_SET_VERTEX_DATA2F_M + 108 / 4, "NV4097_SET_VERTEX_DATA2F_M + 108" }, + { NV4097_SET_VERTEX_DATA2F_M + 112 / 4, "NV4097_SET_VERTEX_DATA2F_M + 112" }, + { NV4097_SET_VERTEX_DATA2F_M + 116 / 4, "NV4097_SET_VERTEX_DATA2F_M + 116" }, + { NV4097_SET_VERTEX_DATA2F_M + 120 / 4, "NV4097_SET_VERTEX_DATA2F_M + 120" }, + { NV4097_SET_VERTEX_DATA2F_M + 124 / 4, "NV4097_SET_VERTEX_DATA2F_M + 124" }, + { NV4097_SET_VERTEX_DATA2S_M, "NV4097_SET_VERTEX_DATA2S_M" }, + { NV4097_SET_VERTEX_DATA2S_M + 4 / 4, "NV4097_SET_VERTEX_DATA2S_M + 4" }, + { NV4097_SET_VERTEX_DATA2S_M + 8 / 4, "NV4097_SET_VERTEX_DATA2S_M + 8" }, + { NV4097_SET_VERTEX_DATA2S_M + 12 / 4, "NV4097_SET_VERTEX_DATA2S_M + 12" }, + { NV4097_SET_VERTEX_DATA2S_M + 16 / 4, "NV4097_SET_VERTEX_DATA2S_M + 16" }, + { NV4097_SET_VERTEX_DATA2S_M + 20 / 4, "NV4097_SET_VERTEX_DATA2S_M + 20" }, + { NV4097_SET_VERTEX_DATA2S_M + 24 / 4, "NV4097_SET_VERTEX_DATA2S_M + 24" }, + { NV4097_SET_VERTEX_DATA2S_M + 28 / 4, "NV4097_SET_VERTEX_DATA2S_M + 28" }, + { NV4097_SET_VERTEX_DATA2S_M + 32 / 4, "NV4097_SET_VERTEX_DATA2S_M + 32" }, + { NV4097_SET_VERTEX_DATA2S_M + 36 / 4, "NV4097_SET_VERTEX_DATA2S_M + 36" }, + { NV4097_SET_VERTEX_DATA2S_M + 40 / 4, "NV4097_SET_VERTEX_DATA2S_M + 40" }, + { NV4097_SET_VERTEX_DATA2S_M + 44 / 4, "NV4097_SET_VERTEX_DATA2S_M + 44" }, + { NV4097_SET_VERTEX_DATA2S_M + 48 / 4, "NV4097_SET_VERTEX_DATA2S_M + 48" }, + { NV4097_SET_VERTEX_DATA2S_M + 52 / 4, "NV4097_SET_VERTEX_DATA2S_M + 52" }, + { NV4097_SET_VERTEX_DATA2S_M + 56 / 4, "NV4097_SET_VERTEX_DATA2S_M + 56" }, + { NV4097_SET_VERTEX_DATA2S_M + 60 / 4, "NV4097_SET_VERTEX_DATA2S_M + 60" }, + { NV4097_SET_VERTEX_DATA4UB_M, "NV4097_SET_VERTEX_DATA4UB_M" }, + { NV4097_SET_VERTEX_DATA4UB_M + 4 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 4" }, + { NV4097_SET_VERTEX_DATA4UB_M + 8 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 8" }, + { NV4097_SET_VERTEX_DATA4UB_M + 12 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 12" }, + { NV4097_SET_VERTEX_DATA4UB_M + 16 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 16" }, + { NV4097_SET_VERTEX_DATA4UB_M + 20 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 20" }, + { NV4097_SET_VERTEX_DATA4UB_M + 24 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 24" }, + { NV4097_SET_VERTEX_DATA4UB_M + 28 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 28" }, + { NV4097_SET_VERTEX_DATA4UB_M + 32 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 32" }, + { NV4097_SET_VERTEX_DATA4UB_M + 36 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 36" }, + { NV4097_SET_VERTEX_DATA4UB_M + 40 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 40" }, + { NV4097_SET_VERTEX_DATA4UB_M + 44 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 44" }, + { NV4097_SET_VERTEX_DATA4UB_M + 48 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 48" }, + { NV4097_SET_VERTEX_DATA4UB_M + 52 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 52" }, + { NV4097_SET_VERTEX_DATA4UB_M + 56 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 56" }, + { NV4097_SET_VERTEX_DATA4UB_M + 60 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 60" }, + { NV4097_SET_VERTEX_DATA4S_M, "NV4097_SET_VERTEX_DATA4S_M" }, + { NV4097_SET_VERTEX_DATA4S_M + 4 / 4, "NV4097_SET_VERTEX_DATA4S_M + 4" }, + { NV4097_SET_VERTEX_DATA4S_M + 8 / 4, "NV4097_SET_VERTEX_DATA4S_M + 8" }, + { NV4097_SET_VERTEX_DATA4S_M + 12 / 4, "NV4097_SET_VERTEX_DATA4S_M + 12" }, + { NV4097_SET_VERTEX_DATA4S_M + 16 / 4, "NV4097_SET_VERTEX_DATA4S_M + 16" }, + { NV4097_SET_VERTEX_DATA4S_M + 20 / 4, "NV4097_SET_VERTEX_DATA4S_M + 20" }, + { NV4097_SET_VERTEX_DATA4S_M + 24 / 4, "NV4097_SET_VERTEX_DATA4S_M + 24" }, + { NV4097_SET_VERTEX_DATA4S_M + 28 / 4, "NV4097_SET_VERTEX_DATA4S_M + 28" }, + { NV4097_SET_VERTEX_DATA4S_M + 32 / 4, "NV4097_SET_VERTEX_DATA4S_M + 32" }, + { NV4097_SET_VERTEX_DATA4S_M + 36 / 4, "NV4097_SET_VERTEX_DATA4S_M + 36" }, + { NV4097_SET_VERTEX_DATA4S_M + 40 / 4, "NV4097_SET_VERTEX_DATA4S_M + 40" }, + { NV4097_SET_VERTEX_DATA4S_M + 44 / 4, "NV4097_SET_VERTEX_DATA4S_M + 44" }, + { NV4097_SET_VERTEX_DATA4S_M + 48 / 4, "NV4097_SET_VERTEX_DATA4S_M + 48" }, + { NV4097_SET_VERTEX_DATA4S_M + 52 / 4, "NV4097_SET_VERTEX_DATA4S_M + 52" }, + { NV4097_SET_VERTEX_DATA4S_M + 56 / 4, "NV4097_SET_VERTEX_DATA4S_M + 56" }, + { NV4097_SET_VERTEX_DATA4S_M + 60 / 4, "NV4097_SET_VERTEX_DATA4S_M + 60" }, + { NV4097_SET_VERTEX_DATA4S_M + 64 / 4, "NV4097_SET_VERTEX_DATA4S_M + 64" }, + { NV4097_SET_VERTEX_DATA4S_M + 68 / 4, "NV4097_SET_VERTEX_DATA4S_M + 68" }, + { NV4097_SET_VERTEX_DATA4S_M + 72 / 4, "NV4097_SET_VERTEX_DATA4S_M + 72" }, + { NV4097_SET_VERTEX_DATA4S_M + 76 / 4, "NV4097_SET_VERTEX_DATA4S_M + 76" }, + { NV4097_SET_VERTEX_DATA4S_M + 80 / 4, "NV4097_SET_VERTEX_DATA4S_M + 80" }, + { NV4097_SET_VERTEX_DATA4S_M + 84 / 4, "NV4097_SET_VERTEX_DATA4S_M + 84" }, + { NV4097_SET_VERTEX_DATA4S_M + 88 / 4, "NV4097_SET_VERTEX_DATA4S_M + 88" }, + { NV4097_SET_VERTEX_DATA4S_M + 92 / 4, "NV4097_SET_VERTEX_DATA4S_M + 92" }, + { NV4097_SET_VERTEX_DATA4S_M + 96 / 4, "NV4097_SET_VERTEX_DATA4S_M + 96" }, + { NV4097_SET_VERTEX_DATA4S_M + 100 / 4, "NV4097_SET_VERTEX_DATA4S_M + 100" }, + { NV4097_SET_VERTEX_DATA4S_M + 104 / 4, "NV4097_SET_VERTEX_DATA4S_M + 104" }, + { NV4097_SET_VERTEX_DATA4S_M + 108 / 4, "NV4097_SET_VERTEX_DATA4S_M + 108" }, + { NV4097_SET_VERTEX_DATA4S_M + 112 / 4, "NV4097_SET_VERTEX_DATA4S_M + 112" }, + { NV4097_SET_VERTEX_DATA4S_M + 116 / 4, "NV4097_SET_VERTEX_DATA4S_M + 116" }, + { NV4097_SET_VERTEX_DATA4S_M + 120 / 4, "NV4097_SET_VERTEX_DATA4S_M + 120" }, + { NV4097_SET_VERTEX_DATA4S_M + 124 / 4, "NV4097_SET_VERTEX_DATA4S_M + 124" }, + { NV4097_SET_TEXTURE_OFFSET, "NV4097_SET_TEXTURE_OFFSET" }, + { NV4097_SET_TEXTURE_FORMAT, "NV4097_SET_TEXTURE_FORMAT" }, + { NV4097_SET_TEXTURE_ADDRESS, "NV4097_SET_TEXTURE_ADDRESS" }, + { NV4097_SET_TEXTURE_CONTROL0, "NV4097_SET_TEXTURE_CONTROL0" }, + { NV4097_SET_TEXTURE_CONTROL1, "NV4097_SET_TEXTURE_CONTROL1" }, + { NV4097_SET_TEXTURE_FILTER, "NV4097_SET_TEXTURE_FILTER" }, + { NV4097_SET_TEXTURE_IMAGE_RECT, "NV4097_SET_TEXTURE_IMAGE_RECT" }, + { NV4097_SET_TEXTURE_BORDER_COLOR, "NV4097_SET_TEXTURE_BORDER_COLOR" }, + { NV4097_SET_TEXTURE_OFFSET + 0x20 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x20" }, + { NV4097_SET_TEXTURE_FORMAT + 0x20 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x20" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x20 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x20" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x20 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x20" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x20 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x20" }, + { NV4097_SET_TEXTURE_FILTER + 0x20 / 4, "NV4097_SET_TEXTURE_FILTER + 0x20" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x20 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x20" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x20 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x20" }, + { NV4097_SET_TEXTURE_OFFSET + 0x40 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x40" }, + { NV4097_SET_TEXTURE_FORMAT + 0x40 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x40" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x40 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x40" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x40 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x40" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x40 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x40" }, + { NV4097_SET_TEXTURE_FILTER + 0x40 / 4, "NV4097_SET_TEXTURE_FILTER + 0x40" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x40 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x40" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x40 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x40" }, + { NV4097_SET_TEXTURE_OFFSET + 0x60 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x60" }, + { NV4097_SET_TEXTURE_FORMAT + 0x60 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x60" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x60 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x60" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x60 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x60" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x60 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x60" }, + { NV4097_SET_TEXTURE_FILTER + 0x60 / 4, "NV4097_SET_TEXTURE_FILTER + 0x60" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x60 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x60" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x60 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x60" }, + { NV4097_SET_TEXTURE_OFFSET + 0x80 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x80" }, + { NV4097_SET_TEXTURE_FORMAT + 0x80 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x80" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x80 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x80" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x80 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x80" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x80 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x80" }, + { NV4097_SET_TEXTURE_FILTER + 0x80 / 4, "NV4097_SET_TEXTURE_FILTER + 0x80" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x80 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x80" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x80 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x80" }, + { NV4097_SET_TEXTURE_OFFSET + 0xa0 / 4, "NV4097_SET_TEXTURE_OFFSET + 0xa0" }, + { NV4097_SET_TEXTURE_FORMAT + 0xa0 / 4, "NV4097_SET_TEXTURE_FORMAT + 0xa0" }, + { NV4097_SET_TEXTURE_ADDRESS + 0xa0 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0xa0" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0xa0 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0xa0" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0xa0 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0xa0" }, + { NV4097_SET_TEXTURE_FILTER + 0xa0 / 4, "NV4097_SET_TEXTURE_FILTER + 0xa0" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0xa0 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0xa0" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0xa0 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0xa0" }, + { NV4097_SET_TEXTURE_OFFSET + 0xc0 / 4, "NV4097_SET_TEXTURE_OFFSET + 0xc0" }, + { NV4097_SET_TEXTURE_FORMAT + 0xc0 / 4, "NV4097_SET_TEXTURE_FORMAT + 0xc0" }, + { NV4097_SET_TEXTURE_ADDRESS + 0xc0 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0xc0" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0xc0 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0xc0" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0xc0 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0xc0" }, + { NV4097_SET_TEXTURE_FILTER + 0xc0 / 4, "NV4097_SET_TEXTURE_FILTER + 0xc0" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0xc0 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0xc0" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0xc0 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0xc0" }, + { NV4097_SET_TEXTURE_OFFSET + 0xe0 / 4, "NV4097_SET_TEXTURE_OFFSET + 0xe0" }, + { NV4097_SET_TEXTURE_FORMAT + 0xe0 / 4, "NV4097_SET_TEXTURE_FORMAT + 0xe0" }, + { NV4097_SET_TEXTURE_ADDRESS + 0xe0 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0xe0" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0xe0 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0xe0" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0xe0 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0xe0" }, + { NV4097_SET_TEXTURE_FILTER + 0xe0 / 4, "NV4097_SET_TEXTURE_FILTER + 0xe0" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0xe0 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0xe0" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0xe0 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0xe0" }, + { NV4097_SET_TEXTURE_OFFSET + 0x100 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x100" }, + { NV4097_SET_TEXTURE_FORMAT + 0x100 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x100" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x100 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x100" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x100 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x100" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x100 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x100" }, + { NV4097_SET_TEXTURE_FILTER + 0x100 / 4, "NV4097_SET_TEXTURE_FILTER + 0x100" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x100 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x100" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x100 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x100" }, + { NV4097_SET_TEXTURE_OFFSET + 0x120 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x120" }, + { NV4097_SET_TEXTURE_FORMAT + 0x120 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x120" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x120 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x120" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x120 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x120" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x120 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x120" }, + { NV4097_SET_TEXTURE_FILTER + 0x120 / 4, "NV4097_SET_TEXTURE_FILTER + 0x120" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x120 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x120" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x120 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x120" }, + { NV4097_SET_TEXTURE_OFFSET + 0x140 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x140" }, + { NV4097_SET_TEXTURE_FORMAT + 0x140 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x140" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x140 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x140" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x140 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x140" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x140 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x140" }, + { NV4097_SET_TEXTURE_FILTER + 0x140 / 4, "NV4097_SET_TEXTURE_FILTER + 0x140" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x140 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x140" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x140 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x140" }, + { NV4097_SET_TEXTURE_OFFSET + 0x160 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x160" }, + { NV4097_SET_TEXTURE_FORMAT + 0x160 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x160" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x160 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x160" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x160 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x160" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x160 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x160" }, + { NV4097_SET_TEXTURE_FILTER + 0x160 / 4, "NV4097_SET_TEXTURE_FILTER + 0x160" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x160 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x160" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x160 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x160" }, + { NV4097_SET_TEXTURE_OFFSET + 0x180 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x180" }, + { NV4097_SET_TEXTURE_FORMAT + 0x180 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x180" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x180 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x180" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x180 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x180" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x180 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x180" }, + { NV4097_SET_TEXTURE_FILTER + 0x180 / 4, "NV4097_SET_TEXTURE_FILTER + 0x180" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x180 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x180" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x180 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x180" }, + { NV4097_SET_TEXTURE_OFFSET + 0x1a0 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x1a0" }, + { NV4097_SET_TEXTURE_FORMAT + 0x1a0 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x1a0" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x1a0 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x1a0" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x1a0 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x1a0" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x1a0 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x1a0" }, + { NV4097_SET_TEXTURE_FILTER + 0x1a0 / 4, "NV4097_SET_TEXTURE_FILTER + 0x1a0" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x1a0 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x1a0" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x1a0 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x1a0" }, + { NV4097_SET_TEXTURE_OFFSET + 0x1c0 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x1c0" }, + { NV4097_SET_TEXTURE_FORMAT + 0x1c0 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x1c0" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x1c0 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x1c0" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x1c0 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x1c0" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x1c0 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x1c0" }, + { NV4097_SET_TEXTURE_FILTER + 0x1c0 / 4, "NV4097_SET_TEXTURE_FILTER + 0x1c0" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x1c0 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x1c0" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x1c0 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x1c0" }, + { NV4097_SET_TEXTURE_OFFSET + 0x1e0 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x1e0" }, + { NV4097_SET_TEXTURE_FORMAT + 0x1e0 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x1e0" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x1e0 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x1e0" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x1e0 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x1e0" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x1e0 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x1e0" }, + { NV4097_SET_TEXTURE_FILTER + 0x1e0 / 4, "NV4097_SET_TEXTURE_FILTER + 0x1e0" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x1e0 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x1e0" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x1e0 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x1e0" }, + { NV4097_SET_VERTEX_DATA4F_M, "NV4097_SET_VERTEX_DATA4F_M" }, + { NV4097_SET_VERTEX_DATA4F_M + 4 / 4, "NV4097_SET_VERTEX_DATA4F_M + 4" }, + { NV4097_SET_VERTEX_DATA4F_M + 8 / 4, "NV4097_SET_VERTEX_DATA4F_M + 8" }, + { NV4097_SET_VERTEX_DATA4F_M + 12 / 4, "NV4097_SET_VERTEX_DATA4F_M + 12" }, + { NV4097_SET_VERTEX_DATA4F_M + 16 / 4, "NV4097_SET_VERTEX_DATA4F_M + 16" }, + { NV4097_SET_VERTEX_DATA4F_M + 20 / 4, "NV4097_SET_VERTEX_DATA4F_M + 20" }, + { NV4097_SET_VERTEX_DATA4F_M + 24 / 4, "NV4097_SET_VERTEX_DATA4F_M + 24" }, + { NV4097_SET_VERTEX_DATA4F_M + 28 / 4, "NV4097_SET_VERTEX_DATA4F_M + 28" }, + { NV4097_SET_VERTEX_DATA4F_M + 32 / 4, "NV4097_SET_VERTEX_DATA4F_M + 32" }, + { NV4097_SET_VERTEX_DATA4F_M + 36 / 4, "NV4097_SET_VERTEX_DATA4F_M + 36" }, + { NV4097_SET_VERTEX_DATA4F_M + 40 / 4, "NV4097_SET_VERTEX_DATA4F_M + 40" }, + { NV4097_SET_VERTEX_DATA4F_M + 44 / 4, "NV4097_SET_VERTEX_DATA4F_M + 44" }, + { NV4097_SET_VERTEX_DATA4F_M + 48 / 4, "NV4097_SET_VERTEX_DATA4F_M + 48" }, + { NV4097_SET_VERTEX_DATA4F_M + 52 / 4, "NV4097_SET_VERTEX_DATA4F_M + 52" }, + { NV4097_SET_VERTEX_DATA4F_M + 56 / 4, "NV4097_SET_VERTEX_DATA4F_M + 56" }, + { NV4097_SET_VERTEX_DATA4F_M + 60 / 4, "NV4097_SET_VERTEX_DATA4F_M + 60" }, + { NV4097_SET_VERTEX_DATA4F_M + 64 / 4, "NV4097_SET_VERTEX_DATA4F_M + 64" }, + { NV4097_SET_VERTEX_DATA4F_M + 68 / 4, "NV4097_SET_VERTEX_DATA4F_M + 68" }, + { NV4097_SET_VERTEX_DATA4F_M + 72 / 4, "NV4097_SET_VERTEX_DATA4F_M + 72" }, + { NV4097_SET_VERTEX_DATA4F_M + 76 / 4, "NV4097_SET_VERTEX_DATA4F_M + 76" }, + { NV4097_SET_VERTEX_DATA4F_M + 80 / 4, "NV4097_SET_VERTEX_DATA4F_M + 80" }, + { NV4097_SET_VERTEX_DATA4F_M + 84 / 4, "NV4097_SET_VERTEX_DATA4F_M + 84" }, + { NV4097_SET_VERTEX_DATA4F_M + 88 / 4, "NV4097_SET_VERTEX_DATA4F_M + 88" }, + { NV4097_SET_VERTEX_DATA4F_M + 92 / 4, "NV4097_SET_VERTEX_DATA4F_M + 92" }, + { NV4097_SET_VERTEX_DATA4F_M + 96 / 4, "NV4097_SET_VERTEX_DATA4F_M + 96" }, + { NV4097_SET_VERTEX_DATA4F_M + 100 / 4, "NV4097_SET_VERTEX_DATA4F_M + 100" }, + { NV4097_SET_VERTEX_DATA4F_M + 104 / 4, "NV4097_SET_VERTEX_DATA4F_M + 104" }, + { NV4097_SET_VERTEX_DATA4F_M + 108 / 4, "NV4097_SET_VERTEX_DATA4F_M + 108" }, + { NV4097_SET_VERTEX_DATA4F_M + 112 / 4, "NV4097_SET_VERTEX_DATA4F_M + 112" }, + { NV4097_SET_VERTEX_DATA4F_M + 116 / 4, "NV4097_SET_VERTEX_DATA4F_M + 116" }, + { NV4097_SET_VERTEX_DATA4F_M + 120 / 4, "NV4097_SET_VERTEX_DATA4F_M + 120" }, + { NV4097_SET_VERTEX_DATA4F_M + 124 / 4, "NV4097_SET_VERTEX_DATA4F_M + 124" }, + { NV4097_SET_VERTEX_DATA4F_M + 128 / 4, "NV4097_SET_VERTEX_DATA4F_M + 128" }, + { NV4097_SET_VERTEX_DATA4F_M + 132 / 4, "NV4097_SET_VERTEX_DATA4F_M + 132" }, + { NV4097_SET_VERTEX_DATA4F_M + 136 / 4, "NV4097_SET_VERTEX_DATA4F_M + 136" }, + { NV4097_SET_VERTEX_DATA4F_M + 140 / 4, "NV4097_SET_VERTEX_DATA4F_M + 140" }, + { NV4097_SET_VERTEX_DATA4F_M + 144 / 4, "NV4097_SET_VERTEX_DATA4F_M + 144" }, + { NV4097_SET_VERTEX_DATA4F_M + 148 / 4, "NV4097_SET_VERTEX_DATA4F_M + 148" }, + { NV4097_SET_VERTEX_DATA4F_M + 152 / 4, "NV4097_SET_VERTEX_DATA4F_M + 152" }, + { NV4097_SET_VERTEX_DATA4F_M + 156 / 4, "NV4097_SET_VERTEX_DATA4F_M + 156" }, + { NV4097_SET_VERTEX_DATA4F_M + 160 / 4, "NV4097_SET_VERTEX_DATA4F_M + 160" }, + { NV4097_SET_VERTEX_DATA4F_M + 164 / 4, "NV4097_SET_VERTEX_DATA4F_M + 164" }, + { NV4097_SET_VERTEX_DATA4F_M + 168 / 4, "NV4097_SET_VERTEX_DATA4F_M + 168" }, + { NV4097_SET_VERTEX_DATA4F_M + 172 / 4, "NV4097_SET_VERTEX_DATA4F_M + 172" }, + { NV4097_SET_VERTEX_DATA4F_M + 176 / 4, "NV4097_SET_VERTEX_DATA4F_M + 176" }, + { NV4097_SET_VERTEX_DATA4F_M + 180 / 4, "NV4097_SET_VERTEX_DATA4F_M + 180" }, + { NV4097_SET_VERTEX_DATA4F_M + 184 / 4, "NV4097_SET_VERTEX_DATA4F_M + 184" }, + { NV4097_SET_VERTEX_DATA4F_M + 188 / 4, "NV4097_SET_VERTEX_DATA4F_M + 188" }, + { NV4097_SET_VERTEX_DATA4F_M + 192 / 4, "NV4097_SET_VERTEX_DATA4F_M + 192" }, + { NV4097_SET_VERTEX_DATA4F_M + 196 / 4, "NV4097_SET_VERTEX_DATA4F_M + 196" }, + { NV4097_SET_VERTEX_DATA4F_M + 200 / 4, "NV4097_SET_VERTEX_DATA4F_M + 200" }, + { NV4097_SET_VERTEX_DATA4F_M + 204 / 4, "NV4097_SET_VERTEX_DATA4F_M + 204" }, + { NV4097_SET_VERTEX_DATA4F_M + 208 / 4, "NV4097_SET_VERTEX_DATA4F_M + 208" }, + { NV4097_SET_VERTEX_DATA4F_M + 212 / 4, "NV4097_SET_VERTEX_DATA4F_M + 212" }, + { NV4097_SET_VERTEX_DATA4F_M + 216 / 4, "NV4097_SET_VERTEX_DATA4F_M + 216" }, + { NV4097_SET_VERTEX_DATA4F_M + 220 / 4, "NV4097_SET_VERTEX_DATA4F_M + 220" }, + { NV4097_SET_VERTEX_DATA4F_M + 224 / 4, "NV4097_SET_VERTEX_DATA4F_M + 224" }, + { NV4097_SET_VERTEX_DATA4F_M + 228 / 4, "NV4097_SET_VERTEX_DATA4F_M + 228" }, + { NV4097_SET_VERTEX_DATA4F_M + 232 / 4, "NV4097_SET_VERTEX_DATA4F_M + 232" }, + { NV4097_SET_VERTEX_DATA4F_M + 236 / 4, "NV4097_SET_VERTEX_DATA4F_M + 236" }, + { NV4097_SET_VERTEX_DATA4F_M + 240 / 4, "NV4097_SET_VERTEX_DATA4F_M + 240" }, + { NV4097_SET_VERTEX_DATA4F_M + 244 / 4, "NV4097_SET_VERTEX_DATA4F_M + 244" }, + { NV4097_SET_VERTEX_DATA4F_M + 248 / 4, "NV4097_SET_VERTEX_DATA4F_M + 248" }, + { NV4097_SET_VERTEX_DATA4F_M + 252 / 4, "NV4097_SET_VERTEX_DATA4F_M + 252" }, + { NV4097_SET_SHADER_CONTROL, "NV4097_SET_SHADER_CONTROL" }, + { NV4097_SET_SEMAPHORE_OFFSET, "NV4097_SET_SEMAPHORE_OFFSET" }, + { NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE, "NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE" }, + { NV4097_TEXTURE_READ_SEMAPHORE_RELEASE, "NV4097_TEXTURE_READ_SEMAPHORE_RELEASE" }, + { NV4097_SET_ZMIN_MAX_CONTROL, "NV4097_SET_ZMIN_MAX_CONTROL" }, + { NV4097_SET_ANTI_ALIASING_CONTROL, "NV4097_SET_ANTI_ALIASING_CONTROL" }, + { NV4097_SET_ZCULL_EN, "NV4097_SET_ZCULL_EN" }, + { NV4097_SET_SHADER_WINDOW, "NV4097_SET_SHADER_WINDOW" }, + { NV4097_SET_ZSTENCIL_CLEAR_VALUE, "NV4097_SET_ZSTENCIL_CLEAR_VALUE" }, + { NV4097_SET_COLOR_CLEAR_VALUE, "NV4097_SET_COLOR_CLEAR_VALUE" }, + { NV4097_CLEAR_SURFACE, "NV4097_CLEAR_SURFACE" }, + { NV4097_SET_RESTART_INDEX_ENABLE, "NV4097_SET_RESTART_INDEX_ENABLE" }, + { NV4097_SET_RESTART_INDEX, "NV4097_SET_RESTART_INDEX" }, + { NV4097_SET_LINE_STIPPLE, "NV4097_SET_LINE_STIPPLE" }, + { NV4097_SET_LINE_STIPPLE_PATTERN, "NV4097_SET_LINE_STIPPLE_PATTERN" }, + { NV4097_SET_VERTEX_DATA1F_M, "NV4097_SET_VERTEX_DATA1F_M" }, + { NV4097_SET_VERTEX_DATA1F_M + 4 / 4, "NV4097_SET_VERTEX_DATA1F_M + 4" }, + { NV4097_SET_VERTEX_DATA1F_M + 8 / 4, "NV4097_SET_VERTEX_DATA1F_M + 8" }, + { NV4097_SET_VERTEX_DATA1F_M + 12 / 4, "NV4097_SET_VERTEX_DATA1F_M + 12" }, + { NV4097_SET_VERTEX_DATA1F_M + 16 / 4, "NV4097_SET_VERTEX_DATA1F_M + 16" }, + { NV4097_SET_VERTEX_DATA1F_M + 20 / 4, "NV4097_SET_VERTEX_DATA1F_M + 20" }, + { NV4097_SET_VERTEX_DATA1F_M + 24 / 4, "NV4097_SET_VERTEX_DATA1F_M + 24" }, + { NV4097_SET_VERTEX_DATA1F_M + 28 / 4, "NV4097_SET_VERTEX_DATA1F_M + 28" }, + { NV4097_SET_VERTEX_DATA1F_M + 32 / 4, "NV4097_SET_VERTEX_DATA1F_M + 32" }, + { NV4097_SET_VERTEX_DATA1F_M + 36 / 4, "NV4097_SET_VERTEX_DATA1F_M + 36" }, + { NV4097_SET_VERTEX_DATA1F_M + 40 / 4, "NV4097_SET_VERTEX_DATA1F_M + 40" }, + { NV4097_SET_VERTEX_DATA1F_M + 44 / 4, "NV4097_SET_VERTEX_DATA1F_M + 44" }, + { NV4097_SET_VERTEX_DATA1F_M + 48 / 4, "NV4097_SET_VERTEX_DATA1F_M + 48" }, + { NV4097_SET_VERTEX_DATA1F_M + 52 / 4, "NV4097_SET_VERTEX_DATA1F_M + 52" }, + { NV4097_SET_VERTEX_DATA1F_M + 56 / 4, "NV4097_SET_VERTEX_DATA1F_M + 56" }, + { NV4097_SET_VERTEX_DATA1F_M + 60 / 4, "NV4097_SET_VERTEX_DATA1F_M + 60" }, + { NV4097_SET_RENDER_ENABLE, "NV4097_SET_RENDER_ENABLE" }, + { NV4097_SET_TRANSFORM_PROGRAM_LOAD, "NV4097_SET_TRANSFORM_PROGRAM_LOAD" }, + { NV4097_SET_TRANSFORM_PROGRAM_START, "NV4097_SET_TRANSFORM_PROGRAM_START" }, + { NV4097_SET_ZCULL_CONTROL0, "NV4097_SET_ZCULL_CONTROL0" }, + { NV4097_SET_ZCULL_CONTROL1, "NV4097_SET_ZCULL_CONTROL1" }, + { NV4097_SET_SCULL_CONTROL, "NV4097_SET_SCULL_CONTROL" }, + { NV4097_SET_POINT_SIZE, "NV4097_SET_POINT_SIZE" }, + { NV4097_SET_POINT_PARAMS_ENABLE, "NV4097_SET_POINT_PARAMS_ENABLE" }, + { NV4097_SET_POINT_SPRITE_CONTROL, "NV4097_SET_POINT_SPRITE_CONTROL" }, + { NV4097_SET_TRANSFORM_TIMEOUT, "NV4097_SET_TRANSFORM_TIMEOUT" }, + { NV4097_SET_TRANSFORM_CONSTANT_LOAD, "NV4097_SET_TRANSFORM_CONSTANT_LOAD" }, + { NV4097_SET_FREQUENCY_DIVIDER_OPERATION, "NV4097_SET_FREQUENCY_DIVIDER_OPERATION" }, + { NV4097_SET_ATTRIB_COLOR, "NV4097_SET_ATTRIB_COLOR" }, + { NV4097_SET_ATTRIB_TEX_COORD, "NV4097_SET_ATTRIB_TEX_COORD" }, + { NV4097_SET_ATTRIB_TEX_COORD_EX, "NV4097_SET_ATTRIB_TEX_COORD_EX" }, + { NV4097_SET_ATTRIB_UCLIP0, "NV4097_SET_ATTRIB_UCLIP0" }, + { NV4097_SET_ATTRIB_UCLIP1, "NV4097_SET_ATTRIB_UCLIP1" }, + { NV4097_INVALIDATE_L2, "NV4097_INVALIDATE_L2" }, + { NV4097_SET_REDUCE_DST_COLOR, "NV4097_SET_REDUCE_DST_COLOR" }, + { NV4097_SET_NO_PARANOID_TEXTURE_FETCHES, "NV4097_SET_NO_PARANOID_TEXTURE_FETCHES" }, + { NV4097_SET_SHADER_PACKER, "NV4097_SET_SHADER_PACKER" }, + { NV4097_SET_VERTEX_ATTRIB_INPUT_MASK, "NV4097_SET_VERTEX_ATTRIB_INPUT_MASK" }, + { NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK, "NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK" }, + { NV4097_SET_TRANSFORM_BRANCH_BITS, "NV4097_SET_TRANSFORM_BRANCH_BITS" } + }; + + auto found = methods.find(id); + if (found != methods.end()) + { + return "CELL_GCM_" + found->second; + } + + return fmt::format("unknown/illegal method [0x%08x]", id); + } +} \ No newline at end of file diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 03b0946261..2489dc4275 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -6,54 +6,21 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "GLGSRender.h" -#include "../Common/TextureUtils.h" -#define CMD_DEBUG 0 #define DUMP_VERTEX_DATA 0 -#if CMD_DEBUG -#define CMD_LOG(...) LOG_NOTICE(RSX, __VA_ARGS__) -#else -#define CMD_LOG(...) -#endif - -GLuint g_flip_tex, g_depth_tex, g_pbo[6]; -int last_width = 0, last_height = 0, last_depth_format = 0; - -GLenum g_last_gl_error = GL_NO_ERROR; -void printGlError(GLenum err, const char* situation) -{ - if (err != GL_NO_ERROR) - { - LOG_ERROR(RSX, "%s: opengl error 0x%04x", situation, err); - Emu.Pause(); - } -} -void printGlError(GLenum err, const std::string& situation) -{ - printGlError(err, situation.c_str()); -} - -#if 0 -#define checkForGlError(x) /*x*/ -#endif - -void GLTexture::Create() +void GLTexture::create() { if (m_id) { - Delete(); + remove(); } - if (!m_id) - { - glGenTextures(1, &m_id); - checkForGlError("GLTexture::Init() -> glGenTextures"); - Bind(); - } + glGenTextures(1, &m_id); + bind(); } -int GLTexture::GetGlWrap(int wrap) +int GLTexture::gl_wrap(int wrap) { switch (wrap) { @@ -71,7 +38,7 @@ int GLTexture::GetGlWrap(int wrap) return GL_REPEAT; } -float GLTexture::GetMaxAniso(int aniso) +float GLTexture::max_aniso(int aniso) { switch (aniso) { @@ -89,24 +56,21 @@ float GLTexture::GetMaxAniso(int aniso) return 1.0f; } -void GLTexture::Init(RSXTexture& tex) +void GLTexture::init(rsx::texture& tex) { - if (tex.GetLocation() > 1) - { - return; - } + if (!m_id) + create(); - Bind(); + bind(); - const u32 texaddr = GetAddress(tex.GetOffset(), tex.GetLocation()); + const u32 texaddr = rsx::get_address(tex.offset(), tex.location()); //LOG_WARNING(RSX, "texture addr = 0x%x, width = %d, height = %d, max_aniso=%d, mipmap=%d, remap=0x%x, zfunc=0x%x, wraps=0x%x, wrapt=0x%x, wrapr=0x%x, minlod=0x%x, maxlod=0x%x", // m_offset, m_width, m_height, m_maxaniso, m_mipmap, m_remap, m_zfunc, m_wraps, m_wrapt, m_wrapr, m_minlod, m_maxlod); //TODO: safe init - checkForGlError("GLTexture::Init() -> glBindTexture"); - int format = tex.GetFormat() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); - bool is_swizzled = !(tex.GetFormat() & CELL_GCM_TEXTURE_LN); + int format = tex.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); + bool is_swizzled = !(tex.format() & CELL_GCM_TEXTURE_LN); auto pixels = vm::get_ptr(texaddr); u8 *unswizzledPixels; @@ -118,8 +82,7 @@ void GLTexture::Init(RSXTexture& tex) { case CELL_GCM_TEXTURE_B8: // One 8-bit fixed-point number { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BLUE, GL_UNSIGNED_BYTE, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_B8)"); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BLUE, GL_UNSIGNED_BYTE, pixels); static const GLint swizzleMaskB8[] = { GL_BLUE, GL_BLUE, GL_BLUE, GL_BLUE }; glRemap = swizzleMaskB8; @@ -129,21 +92,16 @@ void GLTexture::Init(RSXTexture& tex) case CELL_GCM_TEXTURE_A1R5G5B5: { glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei"); // TODO: texture swizzling - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_A1R5G5B5)"); - + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixels); glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_A1R5G5B5)"); break; } case CELL_GCM_TEXTURE_A4R4G4B4: { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_A4R4G4B4)"); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixels); // We read it in as R4G4B4A4, so we need to remap each component. static const GLint swizzleMaskA4R4G4B4[] = { GL_BLUE, GL_ALPHA, GL_RED, GL_GREEN }; @@ -154,13 +112,8 @@ void GLTexture::Init(RSXTexture& tex) case CELL_GCM_TEXTURE_R5G6B5: { glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_R5G6B5)"); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex.GetWidth(), tex.GetHeight(), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_R5G6B5)"); - + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex.width(), tex.height(), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels); glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_R5G6B5)"); break; } @@ -171,58 +124,53 @@ void GLTexture::Init(RSXTexture& tex) u32 *src, *dst; u32 log2width, log2height; - unswizzledPixels = (u8*)malloc(tex.GetWidth() * tex.GetHeight() * 4); + unswizzledPixels = (u8*)malloc(tex.width() * tex.height() * 4); src = (u32*)pixels; dst = (u32*)unswizzledPixels; - log2width = log(tex.GetWidth()) / log(2); - log2height = log(tex.GetHeight()) / log(2); + log2width = (u32)log2(tex.width()); + log2height = (u32)log2(tex.height()); - for (int i = 0; i < tex.GetHeight(); i++) + for (int i = 0; i < tex.height(); i++) { - for (int j = 0; j < tex.GetWidth(); j++) + for (int j = 0; j < tex.width(); j++) { - dst[(i * tex.GetWidth()) + j] = src[LinearToSwizzleAddress(j, i, 0, log2width, log2height, 0)]; + dst[(i*tex.height()) + j] = src[rsx::linear_to_swizzle(j, i, 0, log2width, log2height, 0)]; } } } - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, is_swizzled ? unswizzledPixels : pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_A8R8G8B8)"); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, is_swizzled ? unswizzledPixels : pixels); break; } case CELL_GCM_TEXTURE_COMPRESSED_DXT1: // Compressed 4x4 pixels into 8 bytes { - u32 size = ((tex.GetWidth() + 3) / 4) * ((tex.GetHeight() + 3) / 4) * 8; + u32 size = ((tex.width() + 3) / 4) * ((tex.height() + 3) / 4) * 8; - glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, tex.GetWidth(), tex.GetHeight(), 0, size, pixels); - checkForGlError("GLTexture::Init() -> glCompressedTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_DXT1)"); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, tex.width(), tex.height(), 0, size, pixels); break; } case CELL_GCM_TEXTURE_COMPRESSED_DXT23: // Compressed 4x4 pixels into 16 bytes { - u32 size = ((tex.GetWidth() + 3) / 4) * ((tex.GetHeight() + 3) / 4) * 16; + u32 size = ((tex.width() + 3) / 4) * ((tex.height() + 3) / 4) * 16; - glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, tex.GetWidth(), tex.GetHeight(), 0, size, pixels); - checkForGlError("GLTexture::Init() -> glCompressedTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_DXT23)"); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, tex.width(), tex.height(), 0, size, pixels); } break; case CELL_GCM_TEXTURE_COMPRESSED_DXT45: // Compressed 4x4 pixels into 16 bytes { - u32 size = ((tex.GetWidth() + 3) / 4) * ((tex.GetHeight() + 3) / 4) * 16; + u32 size = ((tex.width() + 3) / 4) * ((tex.height() + 3) / 4) * 16; - glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, tex.GetWidth(), tex.GetHeight(), 0, size, pixels); - checkForGlError("GLTexture::Init() -> glCompressedTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_DXT45)"); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, tex.width(), tex.height(), 0, size, pixels); break; } case CELL_GCM_TEXTURE_G8B8: { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RG, GL_UNSIGNED_BYTE, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_G8B8)"); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_UNSIGNED_BYTE, pixels); static const GLint swizzleMaskG8B8[] = { GL_RED, GL_GREEN, GL_RED, GL_GREEN }; glRemap = swizzleMaskG8B8; @@ -232,19 +180,18 @@ void GLTexture::Init(RSXTexture& tex) case CELL_GCM_TEXTURE_R6G5B5: { // TODO: Probably need to actually unswizzle if is_swizzled. - const u32 numPixels = tex.GetWidth() * tex.GetHeight(); + const u32 numPixels = tex.width() * tex.height(); unswizzledPixels = (u8 *)malloc(numPixels * 4); // TODO: Speed. for (u32 i = 0; i < numPixels; ++i) { u16 c = reinterpret_cast *>(pixels)[i]; - unswizzledPixels[i * 4 + 0] = Convert6To8((c >> 10) & 0x3F); - unswizzledPixels[i * 4 + 1] = Convert5To8((c >> 5) & 0x1F); - unswizzledPixels[i * 4 + 2] = Convert5To8((c >> 0) & 0x1F); + unswizzledPixels[i * 4 + 0] = convert_6_to_8((c >> 10) & 0x3F); + unswizzledPixels[i * 4 + 1] = convert_5_to_8((c >> 5) & 0x1F); + unswizzledPixels[i * 4 + 2] = convert_5_to_8((c >> 0) & 0x1F); unswizzledPixels[i * 4 + 3] = 255; } - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_R6G5B5)"); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels); free(unswizzledPixels); break; @@ -252,42 +199,33 @@ void GLTexture::Init(RSXTexture& tex) case CELL_GCM_TEXTURE_DEPTH24_D8: // 24-bit unsigned fixed-point number and 8 bits of garbage { - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex.GetWidth(), tex.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH24_D8)"); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, pixels); break; } case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: // 24-bit unsigned float and 8 bits of garbage { - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex.GetWidth(), tex.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT)"); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels); break; } case CELL_GCM_TEXTURE_DEPTH16: // 16-bit unsigned fixed-point number { - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, tex.GetWidth(), tex.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_SHORT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH16)"); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_SHORT, pixels); break; } case CELL_GCM_TEXTURE_DEPTH16_FLOAT: // 16-bit unsigned float { - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, tex.GetWidth(), tex.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH16_FLOAT)"); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels); break; } case CELL_GCM_TEXTURE_X16: // A 16-bit fixed-point number { glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_X16)"); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RED, GL_UNSIGNED_SHORT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_X16)"); - + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RED, GL_UNSIGNED_SHORT, pixels); glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_X16)"); static const GLint swizzleMaskX16[] = { GL_RED, GL_ONE, GL_RED, GL_ONE }; glRemap = swizzleMaskX16; @@ -297,14 +235,8 @@ void GLTexture::Init(RSXTexture& tex) case CELL_GCM_TEXTURE_Y16_X16: // Two 16-bit fixed-point numbers { glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_Y16_X16)"); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RG, GL_UNSIGNED_SHORT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_Y16_X16)"); - + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_UNSIGNED_SHORT, pixels); glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_Y16_X16)"); - static const GLint swizzleMaskX32_Y16_X16[] = { GL_GREEN, GL_RED, GL_GREEN, GL_RED }; glRemap = swizzleMaskX32_Y16_X16; break; @@ -313,40 +245,28 @@ void GLTexture::Init(RSXTexture& tex) case CELL_GCM_TEXTURE_R5G5B5A1: { glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_R5G5B5A1)"); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_R5G5B5A1)"); - + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixels); glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_R5G5B5A1)"); break; } case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: // Four fp16 values { glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT)"); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_HALF_FLOAT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT)"); - + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_HALF_FLOAT, pixels); glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT)"); break; } case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: // Four fp32 values { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_FLOAT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT)"); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_FLOAT, pixels); break; } case CELL_GCM_TEXTURE_X32_FLOAT: // One 32-bit floating-point number { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RED, GL_FLOAT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_X32_FLOAT)"); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RED, GL_FLOAT, pixels); static const GLint swizzleMaskX32_FLOAT[] = { GL_RED, GL_ONE, GL_ONE, GL_ONE }; glRemap = swizzleMaskX32_FLOAT; @@ -356,24 +276,21 @@ void GLTexture::Init(RSXTexture& tex) case CELL_GCM_TEXTURE_D1R5G5B5: { glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_D1R5G5B5)"); + // TODO: Texture swizzling - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_D1R5G5B5)"); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixels); static const GLint swizzleMaskX32_D1R5G5B5[] = { GL_ONE, GL_RED, GL_GREEN, GL_BLUE }; glRemap = swizzleMaskX32_D1R5G5B5; glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_D1R5G5B5)"); break; } case CELL_GCM_TEXTURE_D8R8G8B8: // 8 bits of garbage and three unsigned 8-bit fixed-point numbers { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_D8R8G8B8)"); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels); static const GLint swizzleMaskX32_D8R8G8B8[] = { GL_ONE, GL_RED, GL_GREEN, GL_BLUE }; glRemap = swizzleMaskX32_D8R8G8B8; @@ -384,13 +301,8 @@ void GLTexture::Init(RSXTexture& tex) case CELL_GCM_TEXTURE_Y16_X16_FLOAT: // Two fp16 values { glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_Y16_X16_FLOAT)"); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RG, GL_HALF_FLOAT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_Y16_X16_FLOAT)"); - + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_HALF_FLOAT, pixels); glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_Y16_X16_FLOAT)"); static const GLint swizzleMaskX32_Y16_X16_FLOAT[] = { GL_RED, GL_GREEN, GL_RED, GL_GREEN }; glRemap = swizzleMaskX32_Y16_X16_FLOAT; @@ -399,7 +311,7 @@ void GLTexture::Init(RSXTexture& tex) case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: { - const u32 numPixels = tex.GetWidth() * tex.GetHeight(); + const u32 numPixels = tex.width() * tex.height(); unswizzledPixels = (u8 *)malloc(numPixels * 4); // TODO: Speed. for (u32 i = 0; i < numPixels; i += 2) @@ -416,16 +328,14 @@ void GLTexture::Init(RSXTexture& tex) unswizzledPixels[i * 4 + 4 + 3] = 255; } - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN)"); - + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels); free(unswizzledPixels); break; } case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: { - const u32 numPixels = tex.GetWidth() * tex.GetHeight(); + const u32 numPixels = tex.width() * tex.height(); unswizzledPixels = (u8 *)malloc(numPixels * 4); // TODO: Speed. for (u32 i = 0; i < numPixels; i += 2) @@ -442,29 +352,27 @@ void GLTexture::Init(RSXTexture& tex) unswizzledPixels[i * 4 + 4 + 3] = 255; } - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN)"); - + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels); free(unswizzledPixels); break; } default: { - LOG_ERROR(RSX, "Init tex error: Bad tex format (0x%x | %s | 0x%x)", format, (is_swizzled ? "swizzled" : "linear"), tex.GetFormat() & 0x40); + LOG_ERROR(RSX, "Init tex error: Bad tex format (0x%x | %s | 0x%x)", format, (is_swizzled ? "swizzled" : "linear"), tex.format() & 0x40); break; } } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex.GetMipmap() - 1); - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, tex.GetMipmap() > 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex.mipmap() - 1); + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, tex.mipmap() > 1); if (format != CELL_GCM_TEXTURE_B8 && format != CELL_GCM_TEXTURE_X16 && format != CELL_GCM_TEXTURE_X32_FLOAT) { - u8 remap_a = tex.GetRemap() & 0x3; - u8 remap_r = (tex.GetRemap() >> 2) & 0x3; - u8 remap_g = (tex.GetRemap() >> 4) & 0x3; - u8 remap_b = (tex.GetRemap() >> 6) & 0x3; + u8 remap_a = tex.remap() & 0x3; + u8 remap_r = (tex.remap() >> 2) & 0x3; + u8 remap_g = (tex.remap() >> 4) & 0x3; + u8 remap_b = (tex.remap() >> 6) & 0x3; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, glRemap[remap_a]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, glRemap[remap_r]); @@ -480,8 +388,6 @@ void GLTexture::Init(RSXTexture& tex) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, glRemap[3]); } - checkForGlError("GLTexture::Init() -> remap"); - static const int gl_tex_zfunc[] = { GL_NEVER, @@ -494,21 +400,17 @@ void GLTexture::Init(RSXTexture& tex) GL_ALWAYS, }; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GetGlWrap(tex.GetWrapS())); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GetGlWrap(tex.GetWrapT())); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GetGlWrap(tex.GetWrapR())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gl_wrap(tex.wrap_s())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gl_wrap(tex.wrap_t())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, gl_wrap(tex.wrap_r())); - checkForGlError("GLTexture::Init() -> wrap"); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[tex.zfunc()]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[tex.GetZfunc()]); + glTexEnvi(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, tex.bias()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8)); - checkForGlError("GLTexture::Init() -> compare"); - - glTexEnvi(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, tex.GetBias()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, (tex.GetMinLOD() >> 8)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (tex.GetMaxLOD() >> 8)); - - checkForGlError("GLTexture::Init() -> lod"); + static const int gl_tex_min_filter[] = { @@ -530,16 +432,9 @@ void GLTexture::Init(RSXTexture& tex) GL_LINEAR // CELL_GCM_TEXTURE_CONVOLUTION_MAG }; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_min_filter[tex.GetMinFilter()]); - - checkForGlError("GLTexture::Init() -> min filters"); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_mag_filter[tex.GetMagFilter()]); - - checkForGlError("GLTexture::Init() -> mag filters"); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, GetMaxAniso(tex.GetMaxAniso())); - - checkForGlError("GLTexture::Init() -> max anisotropy"); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_min_filter[tex.min_filter()]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_mag_filter[tex.mag_filter()]); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_aniso(tex.max_aniso())); //Unbind(); @@ -549,17 +444,17 @@ void GLTexture::Init(RSXTexture& tex) } } -void GLTexture::Save(RSXTexture& tex, const std::string& name) +void GLTexture::save(rsx::texture& tex, const std::string& name) { - if (!m_id || !tex.GetOffset() || !tex.GetWidth() || !tex.GetHeight()) return; + if (!m_id || !tex.offset() || !tex.width() || !tex.height()) return; - const u32 texPixelCount = tex.GetWidth() * tex.GetHeight(); + const u32 texPixelCount = tex.width() * tex.height(); u32* alldata = new u32[texPixelCount]; - Bind(); + bind(); - switch (tex.GetFormat() & ~(0x20 | 0x40)) + switch (tex.format() & ~(0x20 | 0x40)) { case CELL_GCM_TEXTURE_B8: glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, alldata); @@ -574,7 +469,7 @@ void GLTexture::Save(RSXTexture& tex, const std::string& name) return; } - fs::file(name + ".raw", fom::write | fom::create | fom::trunc).write(alldata, texPixelCount * 4); + fs::file(name + ".raw", o_write | o_create | o_trunc).write(alldata, texPixelCount * 4); u8* data = new u8[texPixelCount * 3]; u8* alpha = new u8[texPixelCount]; @@ -591,7 +486,7 @@ void GLTexture::Save(RSXTexture& tex, const std::string& name) } rImage out; - out.Create(tex.GetWidth(), tex.GetHeight(), data, alpha); + out.Create(tex.width(), tex.height(), data, alpha); out.SaveFile(name, rBITMAP_TYPE_PNG); delete[] alldata; @@ -599,7 +494,7 @@ void GLTexture::Save(RSXTexture& tex, const std::string& name) //free(alpha); } -void GLTexture::Save(RSXTexture& tex) +void GLTexture::save(rsx::texture& tex) { static const std::string& dir_path = "textures"; static const std::string& file_fmt = dir_path + "/" + "tex[%d].png"; @@ -608,20 +503,20 @@ void GLTexture::Save(RSXTexture& tex) u32 count = 0; while (fs::exists(fmt::format(file_fmt.c_str(), count))) count++; - Save(tex, fmt::format(file_fmt.c_str(), count)); + save(tex, fmt::format(file_fmt.c_str(), count)); } -void GLTexture::Bind() +void GLTexture::bind() { glBindTexture(GL_TEXTURE_2D, m_id); } -void GLTexture::Unbind() +void GLTexture::unbind() { glBindTexture(GL_TEXTURE_2D, 0); } -void GLTexture::Delete() +void GLTexture::remove() { if (m_id) { @@ -630,171 +525,25 @@ void GLTexture::Delete() } } -void PostDrawObj::Draw() +u32 GLTexture::id() const { - static bool s_is_initialized = false; - - if (!s_is_initialized) - { - s_is_initialized = true; - Initialize(); - } - else - { - m_program.Use(); - } -} - -void PostDrawObj::Initialize() -{ - InitializeShaders(); - m_fp.Compile(); - m_vp.Compile(); - m_program.Create(m_vp.id, m_fp.id); - m_program.Use(); - InitializeLocations(); -} - -void DrawCursorObj::Draw() -{ - checkForGlError("PostDrawObj : Unknown error."); - - PostDrawObj::Draw(); - checkForGlError("PostDrawObj::Draw"); - - if (!m_fbo.IsCreated()) - { - m_fbo.Create(); - checkForGlError("DrawCursorObj : m_fbo.Create"); - m_fbo.Bind(); - checkForGlError("DrawCursorObj : m_fbo.Bind"); - - m_rbo.Create(); - checkForGlError("DrawCursorObj : m_rbo.Create"); - m_rbo.Bind(); - checkForGlError("DrawCursorObj : m_rbo.Bind"); - m_rbo.Storage(GL_RGBA, m_width, m_height); - checkForGlError("DrawCursorObj : m_rbo.Storage"); - - m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0, m_rbo.GetId()); - checkForGlError("DrawCursorObj : m_fbo.Renderbuffer"); - } - - m_fbo.Bind(); - checkForGlError("DrawCursorObj : m_fbo.Bind"); - glDrawBuffer(GL_COLOR_ATTACHMENT0); - checkForGlError("DrawCursorObj : glDrawBuffer"); - - m_program.Use(); - checkForGlError("DrawCursorObj : m_program.Use"); - - if (m_update_texture) - { - glUniform2f(m_program.GetLocation("in_tc"), m_width, m_height); - checkForGlError("DrawCursorObj : glUniform2f"); - if (!m_tex_id) - { - glGenTextures(1, &m_tex_id); - checkForGlError("DrawCursorObj : glGenTextures"); - } - - glActiveTexture(GL_TEXTURE0); - checkForGlError("DrawCursorObj : glActiveTexture"); - glBindTexture(GL_TEXTURE_2D, m_tex_id); - checkForGlError("DrawCursorObj : glBindTexture"); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_pixels); - checkForGlError("DrawCursorObj : glTexImage2D"); - m_program.SetTex(0); - } - - if (m_update_pos) - { - glUniform4f(m_program.GetLocation("in_pos"), m_pos_x, m_pos_y, m_pos_z, 1.0f); - checkForGlError("DrawCursorObj : glUniform4f"); - } - - glDrawArrays(GL_QUADS, 0, 4); - checkForGlError("DrawCursorObj : glDrawArrays"); - - m_fbo.Bind(GL_READ_FRAMEBUFFER); - checkForGlError("DrawCursorObj : m_fbo.Bind(GL_READ_FRAMEBUFFER)"); - GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0); - checkForGlError("DrawCursorObj : GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0)"); - GLfbo::Blit(0, 0, m_width, m_height, 0, 0, m_width, m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST); - checkForGlError("DrawCursorObj : GLfbo::Blit"); - m_fbo.Bind(); - checkForGlError("DrawCursorObj : m_fbo.Bind"); -} - -void DrawCursorObj::InitializeShaders() -{ - m_vp.shader = - "#version 420\n" - "\n" - "uniform vec4 in_pos;\n" - "uniform vec2 in_tc;\n" - "out vec2 tc;\n" - "\n" - "void main()\n" - "{\n" - " tc = in_tc;\n" - " gl_Position = in_pos;\n" - "}\n"; - - m_fp.shader = - "#version 420\n" - "\n" - "in vec2 tc;\n" - "layout (binding = 0) uniform sampler2D tex0;\n" - "layout (location = 0) out vec4 res;\n" - "\n" - "void main()\n" - "{\n" - " res = texture(tex0, tc);\n" - "}\n"; -} - -void DrawCursorObj::SetTexture(void* pixels, int width, int height) -{ - m_pixels = pixels; - m_width = width; - m_height = height; - - m_update_texture = true; -} - -void DrawCursorObj::SetPosition(float x, float y, float z) -{ - m_pos_x = x; - m_pos_y = y; - m_pos_z = z; - m_update_pos = true; -} - -void DrawCursorObj::InitializeLocations() -{ - //LOG_WARNING(RSX, "tex0 location = 0x%x", m_program.GetLocation("tex0")); + return m_id; } GLGSRender::GLGSRender() - : GSRender() - , m_frame(nullptr) - , m_fp_buf_num(-1) - , m_vp_buf_num(-1) - , m_context(nullptr) { m_frame = Emu.GetCallbacks().get_gs_frame().release(); } GLGSRender::~GLGSRender() { - m_frame->Close(); - m_frame->DeleteContext(m_context); + m_context = nullptr; + m_frame->close(); } -void GLGSRender::Enable(bool enable, const u32 cap) +u32 GLGSRender::enable(u32 condition, u32 cap) { - if (enable) + if (condition) { glEnable(cap); } @@ -802,1355 +551,1248 @@ void GLGSRender::Enable(bool enable, const u32 cap) { glDisable(cap); } + + return condition; +} + +u32 GLGSRender::enable(u32 condition, u32 cap, u32 index) +{ + if (condition) + { + glEnablei(cap, index); + } + else + { + glDisablei(cap, index); + } + + return condition; } extern CellGcmContextData current_context; -void GLGSRender::Close() +void GLGSRender::close() { if (joinable()) { join(); } - if (m_frame->IsShown()) + if (m_frame->shown()) { - m_frame->Hide(); + m_frame->hide(); } - m_ctrl = nullptr; } -void GLGSRender::EnableVertexData(bool indexed_draw) +void GLGSRender::begin() { - static u32 offset_list[m_vertex_count]; - u32 cur_offset = 0; - - const u32 data_offset = indexed_draw ? 0 : m_draw_array_first; - - for (u32 i = 0; i < m_vertex_count; ++i) + rsx::thread::begin(); + if (!load_program()) { - if (0) + //no program - no drawing + return; + } + + init_buffers(); + + draw_fbo.bind(); + + u32 color_mask = rsx::method_registers[NV4097_SET_COLOR_MASK]; + bool color_mask_b = rsx::method_registers[NV4097_SET_COLOR_MASK] & 0xff; + bool color_mask_g = (rsx::method_registers[NV4097_SET_COLOR_MASK]) >> 8; + bool color_mask_r = (rsx::method_registers[NV4097_SET_COLOR_MASK]) >> 16; + bool color_mask_a = rsx::method_registers[NV4097_SET_COLOR_MASK] >> 24; + + __glcheck glColorMask(color_mask_r, color_mask_g, color_mask_b, color_mask_a); + __glcheck glDepthMask(rsx::method_registers[NV4097_SET_DEPTH_MASK]); + __glcheck glStencilMask(rsx::method_registers[NV4097_SET_STENCIL_MASK]); + + int viewport_x = int(rsx::method_registers[NV4097_SET_VIEWPORT_HORIZONTAL] & 0xffff); + int viewport_y = int(rsx::method_registers[NV4097_SET_VIEWPORT_VERTICAL] & 0xffff); + int viewport_w = int(rsx::method_registers[NV4097_SET_VIEWPORT_HORIZONTAL] >> 16); + int viewport_h = int(rsx::method_registers[NV4097_SET_VIEWPORT_VERTICAL] >> 16); + glViewport(viewport_x, viewport_y, viewport_w, viewport_h); + + //scissor test is always enabled + glEnable(GL_SCISSOR_TEST); + + u32 scissor_horizontal = rsx::method_registers[NV4097_SET_SCISSOR_HORIZONTAL]; + u32 scissor_vertical = rsx::method_registers[NV4097_SET_SCISSOR_VERTICAL]; + u16 scissor_x = scissor_horizontal; + u16 scissor_w = scissor_horizontal >> 16; + u16 scissor_y = scissor_vertical; + u16 scissor_h = scissor_vertical >> 16; + + __glcheck glScissor(scissor_x, scissor_y, scissor_w, scissor_h); + + if (enable(rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE], GL_DEPTH_TEST)) + { + //glcheck(glDepthFunc(rsx::method_registers[NV4097_SET_DEPTH_FUNC])); + //glcheck(glDepthMask(rsx::method_registers[NV4097_SET_DEPTH_MASK])); + } + + if (enable(rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE], GL_DEPTH_BOUNDS_TEST_EXT)) + { + __glcheck glDepthBoundsEXT((f32&)rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_MIN], (f32&)rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_MAX]); + } + + __glcheck glDepthRange((f32&)rsx::method_registers[NV4097_SET_CLIP_MIN], (f32&)rsx::method_registers[NV4097_SET_CLIP_MAX]); + __glcheck glDepthFunc(rsx::method_registers[NV4097_SET_DEPTH_FUNC]); + + enable(rsx::method_registers[NV4097_SET_DITHER_ENABLE], GL_DITHER); + if (enable(rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE], GL_ALPHA_TEST)) + { + //TODO: NV4097_SET_ALPHA_REF must be converted to f32 + //glcheck(glAlphaFunc(rsx::method_registers[NV4097_SET_ALPHA_FUNC], rsx::method_registers[NV4097_SET_ALPHA_REF])); + } + + if (enable(rsx::method_registers[NV4097_SET_BLEND_ENABLE], GL_BLEND)) + { + u32 sfactor = rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR]; + u32 dfactor = rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR]; + u16 sfactor_rgb = sfactor; + u16 sfactor_a = sfactor >> 16; + u16 dfactor_rgb = dfactor; + u16 dfactor_a = dfactor >> 16; + + __glcheck glBlendFuncSeparate(sfactor_rgb, dfactor_rgb, sfactor_a, dfactor_a); + + if (m_surface.color_format == CELL_GCM_SURFACE_F_W16Z16Y16X16) //TODO: check another color formats { - u32 data_format = methodRegisters[NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + i * 4]; - u16 frequency = data_format >> 16; - u8 stride = (data_format >> 8) & 0xff; - u8 size = (data_format >> 4) & 0xf; - u8 type = data_format & 0xf; + u32 blend_color = rsx::method_registers[NV4097_SET_BLEND_COLOR]; + u32 blend_color2 = rsx::method_registers[NV4097_SET_BLEND_COLOR2]; - u32 type_size = 1; - switch (type) - { - case CELL_GCM_VERTEX_S1: type_size = 2; break; - case CELL_GCM_VERTEX_F: type_size = 4; break; - case CELL_GCM_VERTEX_SF: type_size = 2; break; - case CELL_GCM_VERTEX_UB: type_size = 1; break; - case CELL_GCM_VERTEX_S32K: type_size = 2; break; - case CELL_GCM_VERTEX_CMP: type_size = 4; break; - case CELL_GCM_VERTEX_UB256: type_size = 1; break; + u16 blend_color_r = blend_color; + u16 blend_color_g = blend_color >> 16; + u16 blend_color_b = blend_color2; + u16 blend_color_a = blend_color2 >> 16; - default: - LOG_ERROR(RSX, "RSXVertexData::GetTypeSize: Bad vertex data type (%d)!", type); - break; - } + __glcheck glBlendColor(blend_color_r / 65535.f, blend_color_g / 65535.f, blend_color_b / 65535.f, blend_color_a / 65535.f); + } + else + { + u32 blend_color = rsx::method_registers[NV4097_SET_BLEND_COLOR]; + u8 blend_color_r = blend_color; + u8 blend_color_g = blend_color >> 8; + u8 blend_color_b = blend_color >> 16; + u8 blend_color_a = blend_color >> 24; - int item_size = size * type_size; + __glcheck glBlendColor(blend_color_r / 255.f, blend_color_g / 255.f, blend_color_b / 255.f, blend_color_a / 255.f); } - offset_list[i] = cur_offset; + u32 equation = rsx::method_registers[NV4097_SET_BLEND_EQUATION]; + u16 equation_rgb = equation; + u16 equation_a = equation >> 16; - if (!m_vertex_data[i].IsEnabled()) continue; - const size_t item_size = m_vertex_data[i].GetTypeSize() * m_vertex_data[i].size; - const size_t data_size = m_vertex_data[i].data.size() - data_offset * item_size; - const u32 pos = m_vdata.size(); - - cur_offset += data_size; - m_vdata.resize(m_vdata.size() + data_size); - memcpy(&m_vdata[pos], &m_vertex_data[i].data[data_offset * item_size], data_size); + __glcheck glBlendEquationSeparate(equation_rgb, equation_a); } - - m_vao.Create(); - m_vao.Bind(); - checkForGlError("initializing vao"); - - m_vbo.Create(indexed_draw ? 2 : 1); - m_vbo.Bind(0); - m_vbo.SetData(m_vdata.data(), m_vdata.size()); - - if (indexed_draw) + + if (enable(rsx::method_registers[NV4097_SET_STENCIL_TEST_ENABLE], GL_STENCIL_TEST)) { - m_vbo.Bind(GL_ELEMENT_ARRAY_BUFFER, 1); - m_vbo.SetData(GL_ELEMENT_ARRAY_BUFFER, m_indexed_array.m_data.data(), m_indexed_array.m_data.size()); + __glcheck glStencilFunc(rsx::method_registers[NV4097_SET_STENCIL_FUNC], rsx::method_registers[NV4097_SET_STENCIL_FUNC_REF], + rsx::method_registers[NV4097_SET_STENCIL_FUNC_MASK]); + __glcheck glStencilOp(rsx::method_registers[NV4097_SET_STENCIL_OP_FAIL], rsx::method_registers[NV4097_SET_STENCIL_OP_ZFAIL], + rsx::method_registers[NV4097_SET_STENCIL_OP_ZPASS]); + + if (enable(rsx::method_registers[NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE], GL_STENCIL_TEST_TWO_SIDE_EXT)) + { + __glcheck glStencilMaskSeparate(GL_BACK, rsx::method_registers[NV4097_SET_BACK_STENCIL_MASK]); + __glcheck glStencilFuncSeparate(GL_BACK, rsx::method_registers[NV4097_SET_BACK_STENCIL_FUNC], + rsx::method_registers[NV4097_SET_BACK_STENCIL_FUNC_REF], rsx::method_registers[NV4097_SET_BACK_STENCIL_FUNC_MASK]); + __glcheck glStencilOpSeparate(GL_BACK, rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_FAIL], + rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_ZFAIL], rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_ZPASS]); + } } - checkForGlError("initializing vbo"); + __glcheck glShadeModel(rsx::method_registers[NV4097_SET_SHADE_MODE]); + + if (u32 blend_mrt = rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT]) + { + __glcheck enable(blend_mrt & 2, GL_BLEND, GL_COLOR_ATTACHMENT1); + __glcheck enable(blend_mrt & 4, GL_BLEND, GL_COLOR_ATTACHMENT2); + __glcheck enable(blend_mrt & 8, GL_BLEND, GL_COLOR_ATTACHMENT3); + } + + if (enable(rsx::method_registers[NV4097_SET_LOGIC_OP_ENABLE], GL_LOGIC_OP)) + { + __glcheck glLogicOp(rsx::method_registers[NV4097_SET_LOGIC_OP]); + } + + u32 line_width = rsx::method_registers[NV4097_SET_LINE_WIDTH]; + __glcheck glLineWidth((line_width >> 3) + (line_width & 7) / 8.f); + enable(rsx::method_registers[NV4097_SET_LINE_SMOOTH_ENABLE], GL_LINE_SMOOTH); + + //TODO + //NV4097_SET_ANISO_SPREAD + + //TODO + /* + glcheck(glFogi(GL_FOG_MODE, rsx::method_registers[NV4097_SET_FOG_MODE])); + f32 fog_p0 = (f32&)rsx::method_registers[NV4097_SET_FOG_PARAMS + 0]; + f32 fog_p1 = (f32&)rsx::method_registers[NV4097_SET_FOG_PARAMS + 1]; + + f32 fog_start = (2 * fog_p0 - (fog_p0 - 2) / fog_p1) / (fog_p0 - 1); + f32 fog_end = (2 * fog_p0 - 1 / fog_p1) / (fog_p0 - 1); + + glFogf(GL_FOG_START, fog_start); + glFogf(GL_FOG_END, fog_end); + */ + //NV4097_SET_FOG_PARAMS + + __glcheck enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_POINT_ENABLE], GL_POLYGON_OFFSET_POINT); + __glcheck enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_LINE_ENABLE], GL_POLYGON_OFFSET_LINE); + __glcheck enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_FILL_ENABLE], GL_POLYGON_OFFSET_FILL); + + __glcheck glPolygonOffset((f32&)rsx::method_registers[NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR], + (f32&)rsx::method_registers[NV4097_SET_POLYGON_OFFSET_BIAS]); + + //NV4097_SET_SPECULAR_ENABLE + //NV4097_SET_TWO_SIDE_LIGHT_EN + //NV4097_SET_FLAT_SHADE_OP + //NV4097_SET_EDGE_FLAG + + u32 clip_plane_control = rsx::method_registers[NV4097_SET_USER_CLIP_PLANE_CONTROL]; + u8 clip_plane_0 = clip_plane_control & 0xf; + u8 clip_plane_1 = (clip_plane_control >> 4) & 0xf; + u8 clip_plane_2 = (clip_plane_control >> 8) & 0xf; + u8 clip_plane_3 = (clip_plane_control >> 12) & 0xf; + u8 clip_plane_4 = (clip_plane_control >> 16) & 0xf; + u8 clip_plane_5 = (clip_plane_control >> 20) & 0xf; + + //TODO + if (enable(clip_plane_0, GL_CLIP_DISTANCE0)) {} + if (enable(clip_plane_1, GL_CLIP_DISTANCE1)) {} + if (enable(clip_plane_2, GL_CLIP_DISTANCE2)) {} + if (enable(clip_plane_3, GL_CLIP_DISTANCE3)) {} + if (enable(clip_plane_4, GL_CLIP_DISTANCE4)) {} + if (enable(clip_plane_5, GL_CLIP_DISTANCE5)) {} + + __glcheck (enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_FILL_ENABLE], GL_POLYGON_OFFSET_FILL)); + + if (enable(rsx::method_registers[NV4097_SET_POLYGON_STIPPLE], GL_POLYGON_STIPPLE)) + { + __glcheck glPolygonStipple((GLubyte*)(rsx::method_registers + NV4097_SET_POLYGON_STIPPLE_PATTERN)); + } + + __glcheck glPolygonMode(GL_FRONT, rsx::method_registers[NV4097_SET_FRONT_POLYGON_MODE]); + __glcheck glPolygonMode(GL_BACK, rsx::method_registers[NV4097_SET_BACK_POLYGON_MODE]); + + if (enable(rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE], GL_CULL_FACE)) + { + __glcheck glCullFace(rsx::method_registers[NV4097_SET_CULL_FACE]); + __glcheck glFrontFace(rsx::method_registers[NV4097_SET_FRONT_FACE]); + } + + enable(rsx::method_registers[NV4097_SET_POLY_SMOOTH_ENABLE], GL_POLYGON_SMOOTH); + + //NV4097_SET_COLOR_KEY_COLOR + //NV4097_SET_SHADER_CONTROL + //NV4097_SET_ZMIN_MAX_CONTROL + //NV4097_SET_ANTI_ALIASING_CONTROL + //NV4097_SET_CLIP_ID_TEST_ENABLE + + if (enable(rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE], GL_PRIMITIVE_RESTART)) + { + __glcheck glPrimitiveRestartIndex(rsx::method_registers[NV4097_SET_RESTART_INDEX]); + } + + if (enable(rsx::method_registers[NV4097_SET_LINE_STIPPLE], GL_LINE_STIPPLE)) + { + u32 line_stipple_pattern = rsx::method_registers[NV4097_SET_LINE_STIPPLE_PATTERN]; + u16 factor = line_stipple_pattern; + u16 pattern = line_stipple_pattern >> 16; + __glcheck glLineStipple(factor, pattern); + } +} + +template +struct apply_attrib_t; + +template +struct apply_attrib_t +{ + static void func(gl::glsl::program& program, int index, const T* data) + { + program.attribs[index] = data[0]; + } +}; + +template +struct apply_attrib_t +{ + static void func(gl::glsl::program& program, int index, const T* data) + { + program.attribs[index] = color2_base{ data[0], data[1] }; + } +}; + +template +struct apply_attrib_t +{ + static void func(gl::glsl::program& program, int index, const T* data) + { + program.attribs[index] = color3_base{ data[0], data[1], data[2] }; + } +}; +template +struct apply_attrib_t +{ + static void func(gl::glsl::program& program, int index, const T* data) + { + program.attribs[index] = color4_base{ data[0], data[1], data[2], data[3] }; + } +}; + + +template +void apply_attrib_array(gl::glsl::program& program, int index, const std::vector& data) +{ + for (size_t offset = 0; offset < data.size(); offset += count * sizeof(T)) + { + apply_attrib_t::func(program, index, (T*)(data.data() + offset)); + } +} + +void GLGSRender::end() +{ + if (!vertex_draw_count) + { + bool has_array = false; + + for (int i = 0; i < rsx::limits::vertex_count; ++i) + { + if (vertex_arrays_info[i].array) + { + has_array = true; + break; + } + } + + if (!has_array) + { + u32 min_count = ~0; + + for (int i = 0; i < rsx::limits::vertex_count; ++i) + { + if (!vertex_arrays_info[i].size) + continue; + + u32 count = u32(vertex_arrays[i].size()) / + rsx::get_vertex_type_size(vertex_arrays_info[i].type) * vertex_arrays_info[i].size; + + if (count < min_count) + min_count = count; + } + + if (min_count && min_count < ~0) + { + vertex_draw_count = min_count; + } + } + } + + if (!draw_fbo || !vertex_draw_count) + { + rsx::thread::end(); + return; + } + + draw_fbo.bind(); + m_program.use(); + + //setup textures + for (int i = 0; i < rsx::limits::textures_count; ++i) + { + if (!textures[i].enabled()) + continue; + + __glcheck m_gl_textures[i].init(textures[i]); + __glcheck m_program.uniforms.texture("tex" + std::to_string(i), i, gl::texture_view(gl::texture::target::texture2D, m_gl_textures[i].id())); + } + + //initialize vertex attributes + static const gl::buffer_pointer::type gl_types[] = + { + gl::buffer_pointer::type::f32, + + gl::buffer_pointer::type::s16, + gl::buffer_pointer::type::f32, + gl::buffer_pointer::type::f16, + gl::buffer_pointer::type::u8, + gl::buffer_pointer::type::s16, + gl::buffer_pointer::type::f32, // Needs conversion + gl::buffer_pointer::type::u8 + }; + + static const bool gl_normalized[] = + { + false, + + true, + false, + false, + true, + false, + true, + false + }; + + //merge all vertex arrays + std::vector vertex_arrays_data; + size_t vertex_arrays_offsets[rsx::limits::vertex_count]; #if DUMP_VERTEX_DATA - rFile dump("VertexDataArray.dump", rFile::write); + fs::file dump("VertexDataArray.dump", o_create | o_write); + Emu.Pause(); #endif - for (u32 i = 0; i < m_vertex_count; ++i) + for (int index = 0; index < rsx::limits::vertex_count; ++index) { - if (!m_vertex_data[i].IsEnabled()) continue; + size_t position = vertex_arrays_data.size(); + vertex_arrays_offsets[index] = position; + + if (vertex_arrays[index].empty()) + continue; + + size_t size = vertex_arrays[index].size(); + vertex_arrays_data.resize(position + size); + + memcpy(vertex_arrays_data.data() + position, vertex_arrays[index].data(), size); #if DUMP_VERTEX_DATA - dump.Write(wxString::Format("VertexData[%d]:\n", i)); - switch (m_vertex_data[i].type) + auto &vertex_info = vertex_arrays_info[index]; + dump.write(fmt::format("VertexData[%d]:\n", index)); + switch (vertex_info.type) { case CELL_GCM_VERTEX_S1: - for (u32 j = 0; j < m_vertex_data[i].data.size(); j += 2) + for (u32 j = 0; j < vertex_arrays[index].size(); j += 2) { - dump.Write(wxString::Format("%d\n", *(u16*)&m_vertex_data[i].data[j])); - if (!(((j + 2) / 2) % m_vertex_data[i].size)) dump.Write("\n"); + dump.write(fmt::format("%d\n", *(u16*)&vertex_arrays[index][j])); + if (!(((j + 2) / 2) % vertex_info.size)) dump.write("\n"); } break; case CELL_GCM_VERTEX_F: - for (u32 j = 0; j < m_vertex_data[i].data.size(); j += 4) + for (u32 j = 0; j < vertex_arrays[index].size(); j += 4) { - dump.Write(wxString::Format("%.01f\n", *(float*)&m_vertex_data[i].data[j])); - if (!(((j + 4) / 4) % m_vertex_data[i].size)) dump.Write("\n"); + dump.write(fmt::Format("%.01f\n", *(float*)&vertex_arrays[index][j])); + if (!(((j + 4) / 4) % vertex_info.size)) dump.write("\n"); } break; case CELL_GCM_VERTEX_SF: - for (u32 j = 0; j < m_vertex_data[i].data.size(); j += 2) + for (u32 j = 0; j < vertex_arrays[index].size(); j += 2) { - dump.Write(wxString::Format("%.01f\n", *(float*)&m_vertex_data[i].data[j])); - if (!(((j + 2) / 2) % m_vertex_data[i].size)) dump.Write("\n"); + dump.write(fmt::Format("%.01f\n", *(float*)&vertex_arrays[index][j])); + if (!(((j + 2) / 2) % vertex_info.size)) dump.write("\n"); } break; case CELL_GCM_VERTEX_UB: - for (u32 j = 0; j < m_vertex_data[i].data.size(); ++j) + for (u32 j = 0; j < vertex_arrays[index].size(); ++j) { - dump.Write(wxString::Format("%d\n", m_vertex_data[i].data[j])); - if (!((j + 1) % m_vertex_data[i].size)) dump.Write("\n"); + dump.write(fmt::Format("%d\n", vertex_arrays[index][j])); + if (!((j + 1) % vertex_info.size)) dump.write("\n"); } break; case CELL_GCM_VERTEX_S32K: - for (u32 j = 0; j < m_vertex_data[i].data.size(); j += 2) + for (u32 j = 0; j < vertex_arrays[index].size(); j += 2) { - dump.Write(wxString::Format("%d\n", *(u16*)&m_vertex_data[i].data[j])); - if (!(((j + 2) / 2) % m_vertex_data[i].size)) dump.Write("\n"); + dump.write(fmt::Format("%d\n", *(u16*)&vertex_arrays[index][j])); + if (!(((j + 2) / 2) % vertex_info.size)) dump.write("\n"); } break; // case CELL_GCM_VERTEX_CMP: case CELL_GCM_VERTEX_UB256: - for (u32 j = 0; j < m_vertex_data[i].data.size(); ++j) + for (u32 j = 0; j < vertex_arrays[index].size(); ++j) { - dump.Write(wxString::Format("%d\n", m_vertex_data[i].data[j])); - if (!((j + 1) % m_vertex_data[i].size)) dump.Write("\n"); + dump.write(fmt::Format("%d\n", vertex_arrays[index][j])); + if (!((j + 1) % vertex_info.size)) dump.write("\n"); } break; - - default: - LOG_ERROR(HLE, "Bad cv type! %d", m_vertex_data[i].type); - return; } - dump.Write("\n"); + dump.write("\n"); #endif + } - static const u32 gl_types[] = - { - GL_SHORT, - GL_FLOAT, - GL_HALF_FLOAT, - GL_UNSIGNED_BYTE, - GL_SHORT, - GL_FLOAT, // Needs conversion - GL_UNSIGNED_BYTE, - }; + gl::vao vao; + vao.create(); - static const bool gl_normalized[] = - { - GL_TRUE, - GL_FALSE, - GL_FALSE, - GL_TRUE, - GL_FALSE, - GL_TRUE, - GL_FALSE, - }; + gl::buffer vbo; + vbo.create(vertex_arrays_data.size(), vertex_arrays_data.data()); - if (m_vertex_data[i].type < 1 || m_vertex_data[i].type > 7) + vao.array_buffer = vbo; + vao.bind(); + + for (int index = 0; index < rsx::limits::vertex_count; ++index) + { + auto &vertex_info = vertex_arrays_info[index]; + + if (!vertex_info.size) { - LOG_ERROR(RSX, "GLGSRender::EnableVertexData: Bad vertex data type (%d)!", m_vertex_data[i].type); + //disabled + continue; } - if (!m_vertex_data[i].addr) + if (vertex_info.type < 1 || vertex_info.type > 7) { - switch (m_vertex_data[i].type) - { - case CELL_GCM_VERTEX_S32K: - case CELL_GCM_VERTEX_S1: - switch(m_vertex_data[i].size) - { - case 1: glVertexAttrib1s(i, (GLshort&)m_vertex_data[i].data[0]); break; - case 2: glVertexAttrib2sv(i, (GLshort*)&m_vertex_data[i].data[0]); break; - case 3: glVertexAttrib3sv(i, (GLshort*)&m_vertex_data[i].data[0]); break; - case 4: glVertexAttrib4sv(i, (GLshort*)&m_vertex_data[i].data[0]); break; - } - break; + LOG_ERROR(RSX, "GLGSRender::EnableVertexData: Bad vertex data type (%d)!", vertex_info.type); + continue; + } - case CELL_GCM_VERTEX_F: - switch (m_vertex_data[i].size) - { - case 1: glVertexAttrib1f(i, (GLfloat&)m_vertex_data[i].data[0]); break; - case 2: glVertexAttrib2fv(i, (GLfloat*)&m_vertex_data[i].data[0]); break; - case 3: glVertexAttrib3fv(i, (GLfloat*)&m_vertex_data[i].data[0]); break; - case 4: glVertexAttrib4fv(i, (GLfloat*)&m_vertex_data[i].data[0]); break; - } - break; - - case CELL_GCM_VERTEX_CMP: - case CELL_GCM_VERTEX_UB: - glVertexAttrib4ubv(i, (GLubyte*)&m_vertex_data[i].data[0]); - break; - } - - checkForGlError("glVertexAttrib"); + if (0 || vertex_info.array) + { + __glcheck m_program.attribs[index] = + (vao + vertex_arrays_offsets[index]) + .config(gl_types[vertex_info.type], vertex_info.size, gl_normalized[vertex_info.type]); } else { - u32 gltype = gl_types[m_vertex_data[i].type - 1]; - bool normalized = gl_normalized[m_vertex_data[i].type - 1]; + auto &vertex_data = vertex_arrays[index]; - glEnableVertexAttribArray(i); - checkForGlError("glEnableVertexAttribArray"); - glVertexAttribPointer(i, m_vertex_data[i].size, gltype, normalized, 0, reinterpret_cast(offset_list[i])); - checkForGlError("glVertexAttribPointer"); + switch (vertex_info.type) + { + case CELL_GCM_VERTEX_F: + switch (vertex_info.size) + { + case 1: apply_attrib_array(m_program, index, vertex_data); break; + case 2: apply_attrib_array(m_program, index, vertex_data); break; + case 3: apply_attrib_array(m_program, index, vertex_data); break; + case 4: apply_attrib_array(m_program, index, vertex_data); break; + } + break; + + default: + LOG_ERROR(RSX, "bad non array vertex data format (type = %d, size = %d)", vertex_info.type, vertex_info.size); + break; + } } } -} -void GLGSRender::DisableVertexData() -{ - m_vdata.clear(); - for (u32 i = 0; i < m_vertex_count; ++i) + if (vertex_index_array.empty()) { - if (!m_vertex_data[i].IsEnabled()) continue; - glDisableVertexAttribArray(i); - checkForGlError("glDisableVertexAttribArray"); + glDrawArrays(draw_mode - 1, 0, vertex_draw_count); } - m_vao.Unbind(); -} - -void GLGSRender::InitVertexData() -{ - int l; - GLfloat scaleOffsetMat[16] = + else { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - }; + gl::buffer index_buffer; + index_buffer.create(vertex_index_array.size(), vertex_index_array.data()); + vao.element_array_buffer = index_buffer; - for (const RSXTransformConstant& c : m_transform_constants) - { - const std::string name = fmt::format("vc[%u]", c.id); - l = m_program.GetLocation(name); - checkForGlError("glGetUniformLocation " + name); + u32 indexed_type = rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4; - glUniform4f(l, c.x, c.y, c.z, c.w); - checkForGlError("glUniform4f " + name + fmt::format(" %d [%f %f %f %f]", l, c.x, c.y, c.z, c.w)); + __glcheck glDrawElements(draw_mode - 1, vertex_draw_count, + (indexed_type == CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32 ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT), nullptr); } - // Scale - scaleOffsetMat[0] = (GLfloat&)methodRegisters[NV4097_SET_VIEWPORT_SCALE + (0x4 * 0)] / (RSXThread::m_width / RSXThread::m_width_scale); - scaleOffsetMat[5] = (GLfloat&)methodRegisters[NV4097_SET_VIEWPORT_SCALE + (0x4 * 1)] / (RSXThread::m_height / RSXThread::m_height_scale); - scaleOffsetMat[10] = (GLfloat&)methodRegisters[NV4097_SET_VIEWPORT_SCALE + (0x4 * 2)]; + write_buffers(); + + rsx::thread::end(); +} + +void GLGSRender::oninit() +{ + m_draw_frames = 1; + m_skip_frames = 0; + + m_frame->show(); +} + +void GLGSRender::oninit_thread() +{ + m_context = m_frame->new_context(); + m_frame->set_current(m_context); + + gl::init(); + + is_intel_vendor = strstr((const char*)glGetString(GL_VENDOR), "Intel"); + + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); +} + +void GLGSRender::onexit_thread() +{ + glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); + + if (m_program) + m_program.remove(); + + if (draw_fbo) + draw_fbo.remove(); + + for (auto &tex : m_draw_tex_color) + if (tex) tex.remove(); + + if (m_draw_tex_depth_stencil) + m_draw_tex_depth_stencil.remove(); + + if (m_flip_fbo) + m_flip_fbo.remove(); + + if (m_flip_tex_color) + m_flip_tex_color.remove(); +} + +void nv4097_clear_surface(u32 arg, GLGSRender* renderer) +{ + u16 clear_x = rsx::method_registers[NV4097_SET_CLEAR_RECT_HORIZONTAL]; + u16 clear_y = rsx::method_registers[NV4097_SET_CLEAR_RECT_VERTICAL]; + u16 clear_w = rsx::method_registers[NV4097_SET_CLEAR_RECT_HORIZONTAL] >> 16; + u16 clear_h = rsx::method_registers[NV4097_SET_CLEAR_RECT_VERTICAL] >> 16; + + //glScissor(clear_x, clear_y, clear_w, clear_h); + + GLbitfield mask = 0; + + if (arg & 0x1) + { + u32 surface_depth_format = (rsx::method_registers[NV4097_SET_SURFACE_FORMAT] >> 5) & 0x7; + u32 max_depth_value = surface_depth_format == CELL_GCM_SURFACE_Z16 ? 0x0000ffff : 0x00ffffff; + + u32 clear_depth = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] >> 8; + + glDepthMask(GL_TRUE); + glClearDepth(double(clear_depth) / max_depth_value); + mask |= GLenum(gl::buffers::depth); + } + + if (arg & 0x2) + { + u8 clear_stencil = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] & 0xff; + + glStencilMask(0xff); + glClearStencil(clear_stencil); + + mask |= GLenum(gl::buffers::stencil); + } + + if (arg & 0xf0) + { + u32 clear_color = rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE]; + u8 clear_a = clear_color >> 24; + u8 clear_r = clear_color >> 16; + u8 clear_g = clear_color >> 8; + u8 clear_b = clear_color; + + glColorMask(arg & 0x20, arg & 0x40, arg & 0x80, arg & 0x10); + glClearColor(clear_r / 255.f, clear_g / 255.f, clear_b / 255.f, clear_a / 255.f); + + mask |= GLenum(gl::buffers::color); + } + + if (mask) + { + renderer->read_buffers(); + renderer->draw_fbo.clear(gl::buffers(mask)); + renderer->write_buffers(); + } +} + +using rsx_method_impl_t = void(*)(u32, GLGSRender*); + +static const std::unordered_map g_gl_method_tbl = +{ + { NV4097_CLEAR_SURFACE, nv4097_clear_surface }, +}; + +bool GLGSRender::domethod(u32 cmd, u32 arg) +{ + auto found = g_gl_method_tbl.find(cmd); + + if (found == g_gl_method_tbl.end()) + { + return false; + } + + found->second(arg, this); + return true; +} + +bool GLGSRender::load_program() +{ +#if 1 + RSXVertexProgram vertex_program; + u32 transform_program_start = rsx::method_registers[NV4097_SET_TRANSFORM_PROGRAM_START]; + vertex_program.data.reserve((512 - transform_program_start) * 4); + + for (int i = transform_program_start; i < 512; ++i) + { + vertex_program.data.resize((i - transform_program_start) * 4 + 4); + memcpy(vertex_program.data.data() + (i - transform_program_start) * 4, transform_program + i * 4, 4 * sizeof(u32)); + + D3 d3; + d3.HEX = transform_program[i * 4 + 3]; + + if (d3.end) + break; + } + + RSXFragmentProgram fragment_program; + u32 shader_program = rsx::method_registers[NV4097_SET_SHADER_PROGRAM]; + fragment_program.offset = shader_program & ~0x3; + fragment_program.addr = rsx::get_address(fragment_program.offset, (shader_program & 0x3) - 1); + fragment_program.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL]; + + gl::glsl::program *result; + __glcheck result = m_prog_buffer.getGraphicPipelineState(&vertex_program, &fragment_program, nullptr, nullptr); + __glcheck result->use(); + + m_program.set_id(result->id()); + +#else + std::vector vertex_program; + u32 transform_program_start = rsx::method_registers[NV4097_SET_TRANSFORM_PROGRAM_START]; + vertex_program.reserve((512 - transform_program_start) * 4); + + for (int i = transform_program_start; i < 512; ++i) + { + vertex_program.resize((i - transform_program_start) * 4 + 4); + memcpy(vertex_program.data() + (i - transform_program_start) * 4, transform_program + i * 4, 4 * sizeof(u32)); + + D3 d3; + d3.HEX = transform_program[i * 4 + 3]; + + if (d3.end) + break; + } + + u32 shader_program = rsx::method_registers[NV4097_SET_SHADER_PROGRAM]; + + std::string fp_shader; ParamArray fp_parr; u32 fp_size; + GLFragmentDecompilerThread decompile_fp(fp_shader, fp_parr, + rsx::get_address(shader_program & ~0x3, (shader_program & 0x3) - 1), fp_size, rsx::method_registers[NV4097_SET_SHADER_CONTROL]); + + std::string vp_shader; ParamArray vp_parr; + GLVertexDecompilerThread decompile_vp(vertex_program, vp_shader, vp_parr); + decompile_fp.Task(); + decompile_vp.Task(); + + LOG_NOTICE(RSX, "fp: %s", fp_shader.c_str()); + LOG_NOTICE(RSX, "vp: %s", vp_shader.c_str()); + + static bool first = true; + gl::glsl::shader fp(gl::glsl::shader::type::fragment, fp_shader); + gl::glsl::shader vp(gl::glsl::shader::type::vertex, vp_shader); + + (m_program.recreate() += { fp.compile(), vp.compile() }).make(); +#endif + + int viewport_x = int(rsx::method_registers[NV4097_SET_VIEWPORT_HORIZONTAL] & 0xffff); + int viewport_y = int(rsx::method_registers[NV4097_SET_VIEWPORT_VERTICAL] & 0xffff); + int viewport_w = int(rsx::method_registers[NV4097_SET_VIEWPORT_HORIZONTAL] >> 16); + int viewport_h = int(rsx::method_registers[NV4097_SET_VIEWPORT_VERTICAL] >> 16); + + f32 viewport_offset_x = (f32&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + 0]; + f32 viewport_offset_y = (f32&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + 1]; + f32 viewport_offset_z = (f32&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + 2]; + f32 viewport_offset_w = (f32&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + 3]; + + f32 viewport_scale_x = (f32&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + 0]; + f32 viewport_scale_y = (f32&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + 1]; + f32 viewport_scale_z = (f32&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + 2]; + f32 viewport_scale_w = (f32&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + 3]; + + f32 width = f32(rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16); + f32 height = f32(rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16); + glm::mat4 scaleOffsetMat(1.f); + + //Scale + scaleOffsetMat[0][0] = viewport_scale_x * 2.f / viewport_w; + scaleOffsetMat[1][1] = viewport_scale_y * 2.f / viewport_h; + scaleOffsetMat[2][2] = viewport_scale_z; // Offset - scaleOffsetMat[3] = (GLfloat&)methodRegisters[NV4097_SET_VIEWPORT_OFFSET + (0x4 * 0)] - (RSXThread::m_width / RSXThread::m_width_scale); - scaleOffsetMat[7] = (GLfloat&)methodRegisters[NV4097_SET_VIEWPORT_OFFSET + (0x4 * 1)] - (RSXThread::m_height / RSXThread::m_height_scale); - scaleOffsetMat[11] = (GLfloat&)methodRegisters[NV4097_SET_VIEWPORT_OFFSET + (0x4 * 2)] - 1 / 2.0f; + scaleOffsetMat[0][3] = viewport_offset_x * 2.f / viewport_w - 1.f; + scaleOffsetMat[1][3] = viewport_offset_y * 2.f / viewport_h - 1.f; + scaleOffsetMat[2][3] = viewport_offset_z - .5f; - scaleOffsetMat[3] /= RSXThread::m_width / RSXThread::m_width_scale; - scaleOffsetMat[7] /= RSXThread::m_height / RSXThread::m_height_scale; + __glcheck m_program.uniforms["scaleOffsetMat"] = scaleOffsetMat; - l = m_program.GetLocation("scaleOffsetMat"); - glUniformMatrix4fv(l, 1, false, scaleOffsetMat); - checkForGlError("glUniformMatrix4fv"); -} - -void GLGSRender::InitFragmentData() -{ - if (!m_cur_fragment_prog) + for (auto &constant : transform_constants) { - LOG_ERROR(RSX, "InitFragmentData: m_cur_shader_prog == NULL"); - return; + //LOG_WARNING(RSX, "vc[%u] = (%f, %f, %f, %f)", constant.first, constant.second.r, constant.second.g, constant.second.b, constant.second.a); + __glcheck m_program.uniforms["vc[" + std::to_string(constant.first) + "]"] = constant.second; } - // Get constant from fragment program - const std::vector &fragmentOffset = m_prog_buffer.getFragmentConstantOffsetsCache(m_cur_fragment_prog); - for (size_t offsetInFP : fragmentOffset) - { - auto data = vm::ptr::make(m_cur_fragment_prog->addr + (u32)offsetInFP); - - u32 c0 = (data[0] >> 16 | data[0] << 16); - u32 c1 = (data[1] >> 16 | data[1] << 16); - u32 c2 = (data[2] >> 16 | data[2] << 16); - u32 c3 = (data[3] >> 16 | data[3] << 16); - const std::string name = fmt::format("fc%u", offsetInFP); - const int l = m_program.GetLocation(name); - checkForGlError("glGetUniformLocation " + name); - - float f0 = (float&)c0; - float f1 = (float&)c1; - float f2 = (float&)c2; - float f3 = (float&)c3; - glUniform4f(l, f0, f1, f2, f3); - checkForGlError("glUniform4f " + name + fmt::format(" %u [%f %f %f %f]", l, f0, f1, f2, f3)); - } - - for (const RSXTransformConstant& c : m_fragment_constants) - { - u32 id = c.id - m_cur_fragment_prog->offset; - - //LOG_WARNING(RSX,"fc%u[0x%x - 0x%x] = (%f, %f, %f, %f)", id, c.id, m_cur_shader_prog->offset, c.x, c.y, c.z, c.w); - - const std::string name = fmt::format("fc%u", id); - const int l = m_program.GetLocation(name); - checkForGlError("glGetUniformLocation " + name); - - glUniform4f(l, c.x, c.y, c.z, c.w); - checkForGlError("glUniform4f " + name + fmt::format(" %u [%f %f %f %f]", l, c.x, c.y, c.z, c.w)); - } - - - //if (m_fragment_constants.GetCount()) - // LOG_NOTICE(HLE, ""); -} - -bool GLGSRender::LoadProgram() -{ - if (!m_cur_fragment_prog) - { - LOG_WARNING(RSX, "LoadProgram: m_cur_shader_prog == NULL"); - return false; - } - - m_cur_fragment_prog->ctrl = m_shader_ctrl; - - if (!m_cur_vertex_prog) - { - LOG_WARNING(RSX, "LoadProgram: m_cur_vertex_prog == NULL"); - return false; - } - - GLProgram *result = m_prog_buffer.getGraphicPipelineState(m_cur_vertex_prog, m_cur_fragment_prog, nullptr, nullptr); - m_program.id = result->id; - m_program.Use(); - return true; } -void GLGSRender::WriteBuffers() +struct color_swizzle { - if (Ini.GSDumpDepthBuffer.GetValue()) - { - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[4]); - glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ); - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - WriteDepthBuffer(); - } + gl::texture::channel a = gl::texture::channel::a; + gl::texture::channel r = gl::texture::channel::r; + gl::texture::channel g = gl::texture::channel::g; + gl::texture::channel b = gl::texture::channel::b; - if (Ini.GSDumpColorBuffers.GetValue()) + color_swizzle() = default; + color_swizzle(gl::texture::channel a, gl::texture::channel r, gl::texture::channel g, gl::texture::channel b) + : a(a), r(r), g(g), b(b) { - WriteColorBuffers(); + } +}; + +struct color_format +{ + gl::texture::type type; + gl::texture::format format; + bool swap_bytes; + int channel_count; + int channel_size; + color_swizzle swizzle; +}; + +color_format surface_color_format_to_gl(int color_format) +{ + //color format + switch (color_format) + { + case CELL_GCM_SURFACE_R5G6B5: + return{ gl::texture::type::ushort_5_6_5, gl::texture::format::bgr, false, 3, 2 }; + + case CELL_GCM_SURFACE_A8R8G8B8: + return{ gl::texture::type::uint_8_8_8_8, gl::texture::format::bgra, false, 4, 1 }; + + case CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8: + return{ gl::texture::type::uint_8_8_8_8, gl::texture::format::bgra, false, 4, 1, + { gl::texture::channel::one, gl::texture::channel::r, gl::texture::channel::g, gl::texture::channel::b } }; + + case CELL_GCM_SURFACE_F_W16Z16Y16X16: + return{ gl::texture::type::f16, gl::texture::format::rgba, true, 4, 2 }; + + case CELL_GCM_SURFACE_F_W32Z32Y32X32: + return{ gl::texture::type::f32, gl::texture::format::rgba, true, 4, 4 }; + + case CELL_GCM_SURFACE_B8: + case CELL_GCM_SURFACE_X1R5G5B5_Z1R5G5B5: + case CELL_GCM_SURFACE_X1R5G5B5_O1R5G5B5: + case CELL_GCM_SURFACE_X8R8G8B8_Z8R8G8B8: + case CELL_GCM_SURFACE_G8B8: + case CELL_GCM_SURFACE_F_X32: + case CELL_GCM_SURFACE_X8B8G8R8_Z8B8G8R8: + case CELL_GCM_SURFACE_X8B8G8R8_O8B8G8R8: + case CELL_GCM_SURFACE_A8B8G8R8: + default: + LOG_ERROR(RSX, "Surface color buffer: Unsupported surface color format (0x%x)", color_format); + return{ gl::texture::type::uint_8_8_8_8, gl::texture::format::bgra, false, 4, 1 }; } } -void GLGSRender::WriteDepthBuffer() +std::pair surface_depth_format_to_gl(int depth_format) { - if (!m_set_context_dma_z) + switch (depth_format) { - return; + case CELL_GCM_SURFACE_Z16: + return std::make_pair(gl::texture::type::ushort, gl::texture::format::depth); + + default: + LOG_ERROR(RSX, "Surface depth buffer: Unsupported surface depth format (0x%x)", depth_format); + case CELL_GCM_SURFACE_Z24S8: + return std::make_pair(gl::texture::type::uint_24_8, gl::texture::format::depth_stencil); + //return std::make_pair(gl::texture::type::f32, gl::texture::format::depth); } - - u32 address = GetAddress(m_surface_offset_z, m_context_dma_z - 0xfeed0000); - - auto ptr = vm::get_ptr(address); - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[4]); - checkForGlError("WriteDepthBuffer(): glBindBuffer"); - glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0); - checkForGlError("WriteDepthBuffer(): glReadPixels"); - GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - if (packed) - { - memcpy(ptr, packed, RSXThread::m_width * RSXThread::m_height * 4); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - checkForGlError("WriteDepthBuffer(): glUnmapBuffer"); - } - - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - - checkForGlError("WriteDepthBuffer(): glReadPixels"); - glBindTexture(GL_TEXTURE_2D, g_depth_tex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, RSXThread::m_width, RSXThread::m_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, ptr); - checkForGlError("WriteDepthBuffer(): glTexImage2D"); - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ptr); - checkForGlError("WriteDepthBuffer(): glGetTexImage"); } -void GLGSRender::WriteColorBufferA() +void GLGSRender::init_buffers() { - if (!m_set_context_dma_color_a) + u32 surface_format = rsx::method_registers[NV4097_SET_SURFACE_FORMAT]; + + u32 clip_horizontal = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL]; + u32 clip_vertical = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL]; + + u32 clip_width = clip_horizontal >> 16; + u32 clip_height = clip_vertical >> 16; + u32 clip_x = clip_horizontal; + u32 clip_y = clip_vertical; + + if (!draw_fbo || m_surface.format != surface_format) { - return; - } + m_surface.unpack(surface_format); + m_surface.width = clip_width; + m_surface.height = clip_height; - u32 address = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000); + LOG_WARNING(RSX, "surface: %dx%d", clip_width, clip_height); - glReadBuffer(GL_COLOR_ATTACHMENT0); - checkForGlError("WriteColorBufferA(): glReadBuffer"); - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[0]); - checkForGlError("WriteColorBufferA(): glBindBuffer"); - glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 0); - checkForGlError("WriteColorBufferA(): glReadPixels"); - GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - if (packed) - { - memcpy(vm::get_ptr(address), packed, RSXThread::m_width * RSXThread::m_height * 4); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - checkForGlError("WriteColorBufferA(): glUnmapBuffer"); - } + draw_fbo.recreate(); + m_draw_tex_depth_stencil.recreate(gl::texture::target::texture2D); - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); -} + auto format = surface_color_format_to_gl(m_surface.color_format); -void GLGSRender::WriteColorBufferB() -{ - if (!m_set_context_dma_color_b) - { - return; - } - - u32 address = GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000); - - glReadBuffer(GL_COLOR_ATTACHMENT1); - checkForGlError("WriteColorBufferB(): glReadBuffer"); - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[1]); - checkForGlError("WriteColorBufferB(): glBindBuffer"); - glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 0); - checkForGlError("WriteColorBufferB(): glReadPixels"); - GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - if (packed) - { - memcpy(vm::get_ptr(address), packed, RSXThread::m_width * RSXThread::m_height * 4); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - checkForGlError("WriteColorBufferB(): glUnmapBuffer"); - } - - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); -} - -void GLGSRender::WriteColorBufferC() -{ - if (!m_set_context_dma_color_c) - { - return; - } - - u32 address = GetAddress(m_surface_offset_c, m_context_dma_color_c - 0xfeed0000); - - glReadBuffer(GL_COLOR_ATTACHMENT2); - checkForGlError("WriteColorBufferC(): glReadBuffer"); - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[2]); - checkForGlError("WriteColorBufferC(): glBindBuffer"); - glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 0); - checkForGlError("WriteColorBufferC(): glReadPixels"); - GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - if (packed) - { - memcpy(vm::get_ptr(address), packed, RSXThread::m_width * RSXThread::m_height * 4); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - checkForGlError("WriteColorBufferC(): glUnmapBuffer"); - } - - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); -} - -void GLGSRender::WriteColorBufferD() -{ - if (!m_set_context_dma_color_d) - { - return; - } - - u32 address = GetAddress(m_surface_offset_d, m_context_dma_color_d - 0xfeed0000); - - glReadBuffer(GL_COLOR_ATTACHMENT3); - checkForGlError("WriteColorBufferD(): glReadBuffer"); - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[3]); - checkForGlError("WriteColorBufferD(): glBindBuffer"); - glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 0); - checkForGlError("WriteColorBufferD(): glReadPixels"); - GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - if (packed) - { - memcpy(vm::get_ptr(address), packed, RSXThread::m_width * RSXThread::m_height * 4); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - checkForGlError("WriteColorBufferD(): glUnmapBuffer"); - } - - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - -} - -void GLGSRender::WriteColorBuffers() -{ - glPixelStorei(GL_PACK_ROW_LENGTH, 0); - glPixelStorei(GL_PACK_ALIGNMENT, 4); - - switch(m_surface_color_target) - { - case CELL_GCM_SURFACE_TARGET_NONE: - return; - - case CELL_GCM_SURFACE_TARGET_0: - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[0]); - glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ); - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - WriteColorBufferA(); - break; - - case CELL_GCM_SURFACE_TARGET_1: - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[1]); - glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ); - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - WriteColorBufferB(); - break; - - case CELL_GCM_SURFACE_TARGET_MRT1: - for (int i = 0; i < 2; i++) + for (int i = 0; i < rsx::limits::color_buffers_count; ++i) { - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[i]); - glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ); - } - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - WriteColorBufferA(); - WriteColorBufferB(); - break; + m_draw_tex_color[i].recreate(gl::texture::target::texture2D); + __glcheck m_draw_tex_color[i].config() + .size({ (int)m_surface.width, (int)m_surface.height }) + .type(format.type) + .format(format.format) + .swizzle(format.swizzle.r, format.swizzle.g, format.swizzle.b, format.swizzle.a); - case CELL_GCM_SURFACE_TARGET_MRT2: - for (int i = 0; i < 3; i++) - { - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[i]); - glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ); - } - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - WriteColorBufferA(); - WriteColorBufferB(); - WriteColorBufferC(); - break; + __glcheck m_draw_tex_color[i].pixel_pack_settings().swap_bytes(format.swap_bytes); + __glcheck m_draw_tex_color[i].pixel_unpack_settings().swap_bytes(format.swap_bytes); - case CELL_GCM_SURFACE_TARGET_MRT3: - for (int i = 0; i < 4; i++) - { - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[i]); - glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ); - } - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - WriteColorBufferA(); - WriteColorBufferB(); - WriteColorBufferC(); - WriteColorBufferD(); - break; - } -} - -void GLGSRender::OnInit() -{ - m_draw_frames = 1; - m_skip_frames = 0; - RSXThread::m_width = 720; - RSXThread::m_height = 576; - RSXThread::m_width_scale = 2.0f; - RSXThread::m_height_scale = 2.0f; - - last_width = 0; - last_height = 0; - last_depth_format = 0; - - m_frame->Show(); -} - -void GLGSRender::OnInitThread() -{ - m_context = m_frame->GetNewContext(); - - m_frame->SetCurrent(m_context); - - InitProcTable(); - - is_intel_vendor = strstr((const char*)glGetString(GL_VENDOR), "Intel"); - - glEnable(GL_TEXTURE_2D); - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); - - glGenTextures(1, &g_depth_tex); - glGenTextures(1, &g_flip_tex); - glGenBuffers(6, g_pbo); // 4 for color buffers + 1 for depth buffer + 1 for flip() - -#ifdef _WIN32 - glSwapInterval(Ini.GSVSyncEnable.GetValue() ? 1 : 0); -#endif - -} - -void GLGSRender::OnExitThread() -{ - glDeleteTextures(1, &g_flip_tex); - glDeleteTextures(1, &g_depth_tex); - glDeleteBuffers(6, g_pbo); - - glDisable(GL_TEXTURE_2D); - glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); - - m_program.Delete(); - m_rbo.Delete(); - m_fbo.Delete(); - m_vbo.Delete(); - m_vao.Delete(); -} - -void GLGSRender::OnReset() -{ - m_program.UnUse(); - - if (m_vbo.IsCreated()) - { - m_vbo.UnBind(); - m_vbo.Delete(); - } - - m_vao.Delete(); -} - -void GLGSRender::InitDrawBuffers() -{ - if (!m_fbo.IsCreated() || RSXThread::m_width != last_width || RSXThread::m_height != last_height || last_depth_format != m_surface_depth_format) - { - LOG_WARNING(RSX, "New FBO (%dx%d)", RSXThread::m_width, RSXThread::m_height); - last_width = RSXThread::m_width; - last_height = RSXThread::m_height; - last_depth_format = m_surface_depth_format; - - m_fbo.Create(); - checkForGlError("m_fbo.Create"); - m_fbo.Bind(); - - m_rbo.Create(4 + 1); - checkForGlError("m_rbo.Create"); - - for (int i = 0; i < 4; ++i) - { - m_rbo.Bind(i); - m_rbo.Storage(GL_RGBA, RSXThread::m_width, RSXThread::m_height); - checkForGlError("m_rbo.Storage(GL_RGBA)"); + __glcheck draw_fbo.color[i] = m_draw_tex_color[i]; + __glcheck draw_fbo.check(); } - m_rbo.Bind(4); - - switch (m_surface_depth_format) + switch (m_surface.depth_format) { - case 0: - { - // case 0 found in BLJM60410-[Suzukaze no Melt - Days in the Sanctuary] - // [E : RSXThread]: Bad depth format! (0) - // [E : RSXThread]: glEnable: opengl error 0x0506 - // [E : RSXThread]: glDrawArrays: opengl error 0x0506 - m_rbo.Storage(GL_DEPTH_COMPONENT, RSXThread::m_width, RSXThread::m_height); - checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT)"); - break; - } - case CELL_GCM_SURFACE_Z16: { - m_rbo.Storage(GL_DEPTH_COMPONENT16, RSXThread::m_width, RSXThread::m_height); - checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT16)"); + __glcheck m_draw_tex_depth_stencil.config() + .size({ (int)m_surface.width, (int)m_surface.height }) + .type(gl::texture::type::ushort) + .format(gl::texture::format::depth) + .internal_format(gl::texture::internal_format::depth16); - m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4)); - checkForGlError("m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT)"); + __glcheck draw_fbo.depth = m_draw_tex_depth_stencil; break; } - case CELL_GCM_SURFACE_Z24S8: { - m_rbo.Storage(GL_DEPTH24_STENCIL8, RSXThread::m_width, RSXThread::m_height); - checkForGlError("m_rbo.Storage(GL_DEPTH24_STENCIL8)"); - - m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4)); - checkForGlError("m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT)"); - - m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT, m_rbo.GetId(4)); - checkForGlError("m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT)"); + __glcheck m_draw_tex_depth_stencil.config() + .size({ (int)m_surface.width, (int)m_surface.height }) + .type(gl::texture::type::uint_24_8) + .format(gl::texture::format::depth_stencil) + .internal_format(gl::texture::internal_format::depth24_stencil8); + __glcheck draw_fbo.depth_stencil = m_draw_tex_depth_stencil; break; - } - + + case 0: + break; default: { - LOG_ERROR(RSX, "Bad depth format! (%d)", m_surface_depth_format); + LOG_ERROR(RSX, "Bad depth format! (%d)", m_surface.depth_format); assert(0); break; } } - for (int i = 0; i < 4; ++i) - { - m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0 + i, m_rbo.GetId(i)); - checkForGlError(fmt::format("m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT%d)", i)); - } - - //m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4)); - //checkForGlError("m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT)"); - - //if (m_surface_depth_format == 2) - //{ - // m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT, m_rbo.GetId(4)); - // checkForGlError("m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT)"); - //} + __glcheck m_draw_tex_depth_stencil.pixel_pack_settings().aligment(1); + __glcheck m_draw_tex_depth_stencil.pixel_unpack_settings().aligment(1); } - if (!m_set_surface_clip_horizontal) - { - m_surface_clip_x = 0; - m_surface_clip_w = RSXThread::m_width; - } + read_buffers(); - if (!m_set_surface_clip_vertical) - { - m_surface_clip_y = 0; - m_surface_clip_h = RSXThread::m_height; - } - - m_fbo.Bind(); - - static const GLenum draw_buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; - - switch (m_surface_color_target) + switch (rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) { case CELL_GCM_SURFACE_TARGET_NONE: break; case CELL_GCM_SURFACE_TARGET_0: - { - glDrawBuffer(draw_buffers[0]); - checkForGlError("glDrawBuffer(0)"); + __glcheck draw_fbo.draw_buffers({ draw_fbo.color[0] }); break; - } - + case CELL_GCM_SURFACE_TARGET_1: - { - glDrawBuffer(draw_buffers[1]); - checkForGlError("glDrawBuffer(1)"); + __glcheck draw_fbo.draw_buffers({ draw_fbo.color[1] }); break; - } - + case CELL_GCM_SURFACE_TARGET_MRT1: - { - glDrawBuffers(2, draw_buffers); - checkForGlError("glDrawBuffers(2)"); + __glcheck draw_fbo.draw_buffers({ draw_fbo.color[0], draw_fbo.color[1] }); break; - } - + case CELL_GCM_SURFACE_TARGET_MRT2: - { - glDrawBuffers(3, draw_buffers); - checkForGlError("glDrawBuffers(3)"); + __glcheck draw_fbo.draw_buffers({ draw_fbo.color[0], draw_fbo.color[1], draw_fbo.color[2] }); break; - } case CELL_GCM_SURFACE_TARGET_MRT3: - { - glDrawBuffers(4, draw_buffers); - checkForGlError("glDrawBuffers(4)"); + __glcheck draw_fbo.draw_buffers({ draw_fbo.color[0], draw_fbo.color[1], draw_fbo.color[2], draw_fbo.color[3] }); break; - } default: - { - LOG_ERROR(RSX, "Bad surface color target: %d", m_surface_color_target); + LOG_ERROR(RSX, "Bad surface color target: %d", rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]); break; } - - } - - if (m_read_buffer) - { - u32 format = GL_BGRA; - CellGcmDisplayInfo* buffers = vm::get_ptr(m_gcm_buffers_addr); - u32 addr = GetAddress(buffers[m_gcm_current_buffer].offset, CELL_GCM_LOCATION_LOCAL); - u32 width = buffers[m_gcm_current_buffer].width; - u32 height = buffers[m_gcm_current_buffer].height; - glDrawPixels(width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, vm::get_ptr(addr)); - } } -void GLGSRender::Clear(u32 cmd) +static const u32 mr_color_offset[rsx::limits::color_buffers_count] = { - assert(cmd == NV4097_CLEAR_SURFACE); + NV4097_SET_SURFACE_COLOR_AOFFSET, + NV4097_SET_SURFACE_COLOR_BOFFSET, + NV4097_SET_SURFACE_COLOR_COFFSET, + NV4097_SET_SURFACE_COLOR_DOFFSET +}; - InitDrawBuffers(); - - if (m_set_color_mask) - { - glColorMask(m_color_mask_r, m_color_mask_g, m_color_mask_b, m_color_mask_a); - checkForGlError("glColorMask"); - } - - if (m_set_scissor_horizontal && m_set_scissor_vertical) - { - glScissor(m_scissor_x, m_scissor_y, m_scissor_w, m_scissor_h); - checkForGlError("glScissor"); - } - - GLbitfield f = 0; - - if (m_clear_surface_mask & 0x1) - { - glClearDepth(m_clear_surface_z / (float)0xffffff); - checkForGlError("glClearDepth"); - - f |= GL_DEPTH_BUFFER_BIT; - } - - if (m_clear_surface_mask & 0x2) - { - glClearStencil(m_clear_surface_s); - checkForGlError("glClearStencil"); - - f |= GL_STENCIL_BUFFER_BIT; - } - - if (m_clear_surface_mask & 0xF0) - { - glClearColor( - m_clear_surface_color_r / 255.0f, - m_clear_surface_color_g / 255.0f, - m_clear_surface_color_b / 255.0f, - m_clear_surface_color_a / 255.0f); - checkForGlError("glClearColor"); - - f |= GL_COLOR_BUFFER_BIT; - } - - glClear(f); - checkForGlError("glClear"); - - WriteBuffers(); -} - -void GLGSRender::Draw() +static const u32 mr_color_dma[rsx::limits::color_buffers_count] = { - //return; - if (!LoadProgram()) - { - LOG_ERROR(RSX, "LoadProgram failed."); - Emu.Pause(); + NV4097_SET_CONTEXT_DMA_COLOR_A, + NV4097_SET_CONTEXT_DMA_COLOR_B, + NV4097_SET_CONTEXT_DMA_COLOR_C, + NV4097_SET_CONTEXT_DMA_COLOR_D +}; + +void GLGSRender::read_buffers() +{ + if (!draw_fbo) return; - } - InitDrawBuffers(); - - if (m_set_color_mask) + if (Ini.GSReadColorBuffers.GetValue()) { - glColorMask(m_color_mask_r, m_color_mask_g, m_color_mask_b, m_color_mask_a); - checkForGlError("glColorMask"); - } + auto color_format = surface_color_format_to_gl(m_surface.color_format); - if (!m_indexed_array.m_count && !m_draw_array_count) - { - u32 min_vertex_size = ~0; - for (auto &i : m_vertex_data) + auto read_color_buffers = [&](int index, int count) { - if (!i.size) - continue; - - u32 vertex_size = i.data.size() / (i.size * i.GetTypeSize()); - - if (min_vertex_size > vertex_size) - min_vertex_size = vertex_size; - } - - m_draw_array_count = min_vertex_size; - m_draw_array_first = 0; - } - - Enable(m_set_depth_test, GL_DEPTH_TEST); - Enable(m_set_alpha_test, GL_ALPHA_TEST); - Enable(m_set_blend || m_set_blend_mrt1 || m_set_blend_mrt2 || m_set_blend_mrt3, GL_BLEND); - Enable(m_set_scissor_horizontal && m_set_scissor_vertical, GL_SCISSOR_TEST); - Enable(m_set_logic_op, GL_LOGIC_OP); - Enable(m_set_cull_face, GL_CULL_FACE); - Enable(m_set_dither, GL_DITHER); - Enable(m_set_stencil_test, GL_STENCIL_TEST); - Enable(m_set_line_smooth, GL_LINE_SMOOTH); - Enable(m_set_poly_smooth, GL_POLYGON_SMOOTH); - Enable(m_set_point_sprite_control, GL_POINT_SPRITE); - Enable(m_set_specular, GL_LIGHTING); - Enable(m_set_poly_offset_fill, GL_POLYGON_OFFSET_FILL); - Enable(m_set_poly_offset_line, GL_POLYGON_OFFSET_LINE); - Enable(m_set_poly_offset_point, GL_POLYGON_OFFSET_POINT); - Enable(m_set_restart_index, GL_PRIMITIVE_RESTART); - Enable(m_set_line_stipple, GL_LINE_STIPPLE); - Enable(m_set_polygon_stipple, GL_POLYGON_STIPPLE); - - if (!is_intel_vendor) - { - Enable(m_set_depth_bounds_test, GL_DEPTH_BOUNDS_TEST_EXT); - } - - if (m_set_clip_plane) - { - Enable(m_clip_plane_0, GL_CLIP_PLANE0); - Enable(m_clip_plane_1, GL_CLIP_PLANE1); - Enable(m_clip_plane_2, GL_CLIP_PLANE2); - Enable(m_clip_plane_3, GL_CLIP_PLANE3); - Enable(m_clip_plane_4, GL_CLIP_PLANE4); - Enable(m_clip_plane_5, GL_CLIP_PLANE5); - - checkForGlError("m_set_clip_plane"); - } - - checkForGlError("glEnable"); - - if (m_set_front_polygon_mode) - { - glPolygonMode(GL_FRONT, m_front_polygon_mode); - checkForGlError("glPolygonMode(Front)"); - } - - if (m_set_back_polygon_mode) - { - glPolygonMode(GL_BACK, m_back_polygon_mode); - checkForGlError("glPolygonMode(Back)"); - } - - if (m_set_point_size) - { - glPointSize(m_point_size); - checkForGlError("glPointSize"); - } - - if (m_set_poly_offset_mode) - { - glPolygonOffset(m_poly_offset_scale_factor, m_poly_offset_bias); - checkForGlError("glPolygonOffset"); - } - - if (m_set_logic_op) - { - glLogicOp(m_logic_op); - checkForGlError("glLogicOp"); - } - - if (m_set_scissor_horizontal && m_set_scissor_vertical) - { - glScissor(m_scissor_x, m_scissor_y, m_scissor_w, m_scissor_h); - checkForGlError("glScissor"); - } - - if (m_set_two_sided_stencil_test_enable) - { - if (m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass) - { - glStencilOpSeparate(GL_FRONT, m_stencil_fail, m_stencil_zfail, m_stencil_zpass); - checkForGlError("glStencilOpSeparate"); - } - - if (m_set_stencil_mask) - { - glStencilMaskSeparate(GL_FRONT, m_stencil_mask); - checkForGlError("glStencilMaskSeparate"); - } - - if (m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask) - { - glStencilFuncSeparate(GL_FRONT, m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); - checkForGlError("glStencilFuncSeparate"); - } - - if (m_set_back_stencil_fail && m_set_back_stencil_zfail && m_set_back_stencil_zpass) - { - glStencilOpSeparate(GL_BACK, m_back_stencil_fail, m_back_stencil_zfail, m_back_stencil_zpass); - checkForGlError("glStencilOpSeparate(GL_BACK)"); - } - - if (m_set_back_stencil_mask) - { - glStencilMaskSeparate(GL_BACK, m_back_stencil_mask); - checkForGlError("glStencilMaskSeparate(GL_BACK)"); - } - - if (m_set_back_stencil_func && m_set_back_stencil_func_ref && m_set_back_stencil_func_mask) - { - glStencilFuncSeparate(GL_BACK, m_back_stencil_func, m_back_stencil_func_ref, m_back_stencil_func_mask); - checkForGlError("glStencilFuncSeparate(GL_BACK)"); - } - } - else - { - if (m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass) - { - glStencilOp(m_stencil_fail, m_stencil_zfail, m_stencil_zpass); - checkForGlError("glStencilOp"); - } - - if (m_set_stencil_mask) - { - glStencilMask(m_stencil_mask); - checkForGlError("glStencilMask"); - } - - if (m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask) - { - glStencilFunc(m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); - checkForGlError("glStencilFunc"); - } - } - - // TODO: Use other glLightModel functions? - glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, m_set_two_side_light_enable ? GL_TRUE : GL_FALSE); - checkForGlError("glLightModeli"); - - if (m_set_shade_mode) - { - glShadeModel(m_shade_mode); - checkForGlError("glShadeModel"); - } - - if (m_set_depth_mask) - { - glDepthMask(m_depth_mask); - checkForGlError("glDepthMask"); - } - - if (m_set_depth_func) - { - glDepthFunc(m_depth_func); - checkForGlError("glDepthFunc"); - } - - if (m_set_depth_bounds && !is_intel_vendor) - { - glDepthBoundsEXT(m_depth_bounds_min, m_depth_bounds_max); - checkForGlError("glDepthBounds"); - } - - if (m_set_clip) - { - glDepthRangef(m_clip_min, m_clip_max); - checkForGlError("glDepthRangef"); - } - - if (m_set_line_width) - { - glLineWidth(m_line_width); - checkForGlError("glLineWidth"); - } - - if (m_set_line_stipple) - { - glLineStipple(m_line_stipple_factor, m_line_stipple_pattern); - checkForGlError("glLineStipple"); - } - - if (m_set_polygon_stipple) - { - glPolygonStipple((const GLubyte*)m_polygon_stipple_pattern); - checkForGlError("glPolygonStipple"); - } - - if (m_set_blend_equation) - { - glBlendEquationSeparate(m_blend_equation_rgb, m_blend_equation_alpha); - checkForGlError("glBlendEquationSeparate"); - } - - if (m_set_blend_sfactor && m_set_blend_dfactor) - { - glBlendFuncSeparate(m_blend_sfactor_rgb, m_blend_dfactor_rgb, m_blend_sfactor_alpha, m_blend_dfactor_alpha); - checkForGlError("glBlendFuncSeparate"); - } - - if (m_set_blend_color) - { - glBlendColor(m_blend_color_r, m_blend_color_g, m_blend_color_b, m_blend_color_a); - checkForGlError("glBlendColor"); - } - - if (m_set_cull_face) - { - glCullFace(m_cull_face); - checkForGlError("glCullFace"); - } - - if (m_set_front_face) - { - glFrontFace(m_front_face); - checkForGlError("glFrontFace"); - } - - if (m_set_alpha_func && m_set_alpha_ref) - { - glAlphaFunc(m_alpha_func, m_alpha_ref); - checkForGlError("glAlphaFunc"); - } - - if (m_set_fog_mode) - { - glFogi(GL_FOG_MODE, m_fog_mode); - checkForGlError("glFogi(GL_FOG_MODE)"); - } - - if (m_set_fog_params) - { - glFogf(GL_FOG_START, m_fog_param0); - checkForGlError("glFogf(GL_FOG_START)"); - glFogf(GL_FOG_END, m_fog_param1); - checkForGlError("glFogf(GL_FOG_END)"); - } - - if (m_set_restart_index) - { - glPrimitiveRestartIndex(m_restart_index); - checkForGlError("glPrimitiveRestartIndex"); - } - - if (m_indexed_array.m_count && m_draw_array_count) - { - LOG_WARNING(RSX, "m_indexed_array.m_count && draw_array_count"); - } - - for (u32 i = 0; i < m_textures_count; ++i) - { - if (!m_textures[i].IsEnabled()) continue; - - glActiveTexture(GL_TEXTURE0 + i); - checkForGlError("glActiveTexture"); - m_gl_textures[i].Create(); - m_gl_textures[i].Bind(); - checkForGlError(fmt::format("m_gl_textures[%d].Bind", i)); - m_program.SetTex(i); - m_gl_textures[i].Init(m_textures[i]); - checkForGlError(fmt::format("m_gl_textures[%d].Init", i)); - } - - for (u32 i = 0; i < m_textures_count; ++i) - { - if (!m_vertex_textures[i].IsEnabled()) continue; - - glActiveTexture(GL_TEXTURE0 + m_textures_count + i); - checkForGlError("glActiveTexture"); - m_gl_vertex_textures[i].Create(); - m_gl_vertex_textures[i].Bind(); - checkForGlError(fmt::format("m_gl_vertex_textures[%d].Bind", i)); - m_program.SetVTex(i); - m_gl_vertex_textures[i].Init(m_vertex_textures[i]); - checkForGlError(fmt::format("m_gl_vertex_textures[%d].Init", i)); - } - - m_vao.Bind(); - - if (m_indexed_array.m_count) - LoadVertexData(m_indexed_array.index_min, m_indexed_array.index_max - m_indexed_array.index_min + 1); - else - LoadVertexData(m_draw_array_first, m_draw_array_count); - - if (m_indexed_array.m_count || m_draw_array_count) - { - EnableVertexData(m_indexed_array.m_count ? true : false); - - InitVertexData(); - InitFragmentData(); - } - - if (m_indexed_array.m_count) - { - switch(m_indexed_array.m_type) - { - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: - glDrawElements(m_draw_mode - 1, m_indexed_array.m_count, GL_UNSIGNED_INT, nullptr); - checkForGlError("glDrawElements #4"); - break; - - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: - glDrawElements(m_draw_mode - 1, m_indexed_array.m_count, GL_UNSIGNED_SHORT, nullptr); - checkForGlError("glDrawElements #2"); - break; - - default: - LOG_ERROR(RSX, "Bad indexed array type (%d)", m_indexed_array.m_type); - break; - } - - DisableVertexData(); - m_indexed_array.Reset(); - } - - if (m_draw_array_count) - { - //LOG_WARNING(RSX,"glDrawArrays(%d,%d,%d)", m_draw_mode - 1, m_draw_array_first, m_draw_array_count); - glDrawArrays(m_draw_mode - 1, 0, m_draw_array_count); - checkForGlError("glDrawArrays"); - DisableVertexData(); - } - - WriteBuffers(); -} - -void GLGSRender::Flip() -{ - // Set scissor to FBO size - if (m_set_scissor_horizontal && m_set_scissor_vertical) - { - glScissor(0, 0, RSXThread::m_width, RSXThread::m_height); - checkForGlError("glScissor"); - } - - switch (m_surface_color_target) - { - case CELL_GCM_SURFACE_TARGET_0: - case CELL_GCM_SURFACE_TARGET_1: - case CELL_GCM_SURFACE_TARGET_MRT1: - case CELL_GCM_SURFACE_TARGET_MRT2: - case CELL_GCM_SURFACE_TARGET_MRT3: - { - // Fast path for non-MRT using glBlitFramebuffer. - GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0); - // Renderbuffer is upside turn , swapped srcY0 and srcY1 - GLfbo::Blit(0, RSXThread::m_height, RSXThread::m_width, 0, 0, 0, RSXThread::m_width, RSXThread::m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST); - } - break; - - case CELL_GCM_SURFACE_TARGET_NONE: - { - // Slow path for MRT/None target using glReadPixels. - static u8* src_buffer = nullptr; - static u32 width = 0; - static u32 height = 0; - GLenum format = GL_RGBA; - - if (m_read_buffer) - { - format = GL_BGRA; - CellGcmDisplayInfo* buffers = vm::get_ptr(m_gcm_buffers_addr); - u32 addr = GetAddress(buffers[m_gcm_current_buffer].offset, CELL_GCM_LOCATION_LOCAL); - width = buffers[m_gcm_current_buffer].width; - height = buffers[m_gcm_current_buffer].height; - src_buffer = vm::get_ptr(addr); - } - else if (m_fbo.IsCreated()) - { - format = GL_RGBA; - static std::vector pixels; - pixels.resize(RSXThread::m_width * RSXThread::m_height * 4); - m_fbo.Bind(GL_READ_FRAMEBUFFER); - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[5]); - glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ); - glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 0); - checkForGlError("Flip(): glReadPixels(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8)"); - GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - if (packed) + for (int i = index; i < index + count; ++i) { - memcpy(pixels.data(), packed, RSXThread::m_width * RSXThread::m_height * 4); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - checkForGlError("Flip(): glUnmapBuffer"); + u32 color_address = rsx::get_address(rsx::method_registers[mr_color_offset[i]], rsx::method_registers[mr_color_dma[i]]); + __glcheck m_draw_tex_color[i].copy_from(vm::get_ptr(color_address), color_format.format, color_format.type); } - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + }; - src_buffer = pixels.data(); - width = RSXThread::m_width; - height = RSXThread::m_height; - } - else + switch (rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) { - src_buffer = nullptr; + case CELL_GCM_SURFACE_TARGET_NONE: + break; + + case CELL_GCM_SURFACE_TARGET_0: + read_color_buffers(0, 1); + break; + + case CELL_GCM_SURFACE_TARGET_1: + read_color_buffers(1, 1); + break; + + case CELL_GCM_SURFACE_TARGET_MRT1: + read_color_buffers(0, 2); + break; + + case CELL_GCM_SURFACE_TARGET_MRT2: + read_color_buffers(0, 3); + break; + + case CELL_GCM_SURFACE_TARGET_MRT3: + read_color_buffers(0, 4); + break; } - - if (src_buffer) + } + + if (Ini.GSReadDepthBuffer.GetValue()) + { + auto depth_format = surface_depth_format_to_gl(m_surface.depth_format); + + int pixel_size = m_surface.depth_format == CELL_GCM_SURFACE_Z16 ? 2 : 4; + + gl::buffer pbo_depth; + + __glcheck pbo_depth.create(m_surface.width * m_surface.height * pixel_size); + __glcheck pbo_depth.map([&](GLubyte* pixels) { - glDisable(GL_STENCIL_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_CLIP_PLANE0); - glDisable(GL_CLIP_PLANE1); - glDisable(GL_CLIP_PLANE2); - glDisable(GL_CLIP_PLANE3); - glDisable(GL_CLIP_PLANE4); - glDisable(GL_CLIP_PLANE5); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, g_flip_tex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, format, GL_UNSIGNED_INT_8_8_8_8, src_buffer); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + u32 depth_address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET], rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA]); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, 1, 0, 1, 0, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + if (m_surface.depth_format == CELL_GCM_SURFACE_Z16) + { + u16 *dst = (u16*)pixels; + const be_t* src = vm::get_ptr>(depth_address); + for (int i = 0, end = m_draw_tex_depth_stencil.width() * m_draw_tex_depth_stencil.height(); i < end; ++i) + { + dst[i] = src[i]; + } + } + else + { + u32 *dst = (u32*)pixels; + const be_t* src = vm::get_ptr>(depth_address); + for (int i = 0, end = m_draw_tex_depth_stencil.width() * m_draw_tex_depth_stencil.height(); i < end; ++i) + { + dst[i] = src[i]; + } + } + }, gl::buffer::access::write); - GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0); + __glcheck m_draw_tex_depth_stencil.copy_from(pbo_depth, depth_format.second, depth_format.first); + } +} - m_program.UnUse(); - m_program.Use(); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_ACCUM_BUFFER_BIT); +void GLGSRender::write_buffers() +{ + if (!draw_fbo) + return; - glColor3f(1, 1, 1); - glBegin(GL_QUADS); - glTexCoord2i(0, 1); - glVertex2i(0, 0); - glTexCoord2i(1, 1); - glVertex2i(1, 0); - glTexCoord2i(1, 0); - glVertex2i(1, 1); - glTexCoord2i(0, 0); - glVertex2i(0, 1); - glEnd(); + if (Ini.GSDumpColorBuffers.GetValue()) + { + auto color_format = surface_color_format_to_gl(m_surface.color_format); + + auto write_color_buffers = [&](int index, int count) + { + for (int i = index; i < index + count; ++i) + { + //TODO: swizzle + u32 color_address = rsx::get_address(rsx::method_registers[mr_color_offset[i]], rsx::method_registers[mr_color_dma[i]]); + __glcheck m_draw_tex_color[i].copy_to(vm::get_ptr(color_address), color_format.format, color_format.type); + } + }; + + switch (rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) + { + case CELL_GCM_SURFACE_TARGET_NONE: + break; + + case CELL_GCM_SURFACE_TARGET_0: + write_color_buffers(0, 1); + break; + + case CELL_GCM_SURFACE_TARGET_1: + write_color_buffers(1, 1); + break; + + case CELL_GCM_SURFACE_TARGET_MRT1: + write_color_buffers(0, 2); + break; + + case CELL_GCM_SURFACE_TARGET_MRT2: + write_color_buffers(0, 3); + break; + + case CELL_GCM_SURFACE_TARGET_MRT3: + write_color_buffers(0, 4); + break; } } - break; - } - // Draw Objects - for (uint i = 0; i < m_post_draw_objs.size(); ++i) + if (Ini.GSDumpDepthBuffer.GetValue()) { - m_post_draw_objs[i].Draw(); + auto depth_format = surface_depth_format_to_gl(m_surface.depth_format); + + gl::buffer pbo_depth; + + int pixel_size = m_surface.depth_format == CELL_GCM_SURFACE_Z16 ? 2 : 4; + + __glcheck pbo_depth.create(m_surface.width * m_surface.height * pixel_size); + __glcheck m_draw_tex_depth_stencil.copy_to(pbo_depth, depth_format.second, depth_format.first); + + __glcheck pbo_depth.map([&](GLubyte* pixels) + { + u32 depth_address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET], rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA]); + + if (m_surface.depth_format == CELL_GCM_SURFACE_Z16) + { + const u16 *src = (const u16*)pixels; + be_t* dst = vm::get_ptr>(depth_address); + for (int i = 0, end = m_draw_tex_depth_stencil.width() * m_draw_tex_depth_stencil.height(); i < end; ++i) + { + dst[i] = src[i]; + } + } + else + { + const u32 *src = (const u32*)pixels; + be_t* dst = vm::get_ptr>(depth_address); + for (int i = 0, end = m_draw_tex_depth_stencil.width() * m_draw_tex_depth_stencil.height(); i < end; ++i) + { + dst[i] = src[i]; + } + } + + }, gl::buffer::access::read); } +} - m_frame->Flip(m_context); +void GLGSRender::flip(int buffer) +{ + u32 buffer_width = gcm_buffers[buffer].width; + u32 buffer_height = gcm_buffers[buffer].height; + u32 buffer_pitch = gcm_buffers[buffer].pitch; + u32 buffer_address = rsx::get_address(gcm_buffers[buffer].offset, CELL_GCM_LOCATION_LOCAL); + bool skip_read = false; - // Restore scissor - if (m_set_scissor_horizontal && m_set_scissor_vertical) + if (draw_fbo && !Ini.GSDumpColorBuffers.GetValue()) { - glScissor(m_scissor_x, m_scissor_y, m_scissor_w, m_scissor_h); - checkForGlError("glScissor"); + for (uint i = 0; i < rsx::limits::color_buffers_count; ++i) + { + u32 color_address = rsx::get_address(rsx::method_registers[mr_color_offset[i]], rsx::method_registers[mr_color_dma[i]]); + + if (color_address == buffer_address) + { + skip_read = true; + __glcheck draw_fbo.draw_buffer(draw_fbo.color[i]); + break; + } + } } + if (!skip_read) + { + gl::screen.clear(gl::buffers::color_depth_stencil); + + if (!m_flip_tex_color || m_flip_tex_color.size() != sizei{ (int)buffer_width, (int)buffer_height }) + { + m_flip_tex_color.recreate(gl::texture::target::texture2D); + + __glcheck m_flip_tex_color.config() + .size({ (int)buffer_width, (int)buffer_height }) + .type(gl::texture::type::uint_8_8_8_8) + .format(gl::texture::format::bgra); + + __glcheck m_flip_fbo.recreate(); + __glcheck m_flip_fbo.color = m_flip_tex_color; + } + + __glcheck m_flip_fbo.draw_buffer(m_flip_fbo.color); + + m_flip_fbo.bind(); + + glDisable(GL_SCISSOR_TEST); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glDisable(GL_BLEND); + glDisable(GL_LOGIC_OP); + glDisable(GL_CULL_FACE); + + __glcheck m_flip_tex_color.copy_from(vm::get_ptr(buffer_address), + gl::texture::format::bgra, gl::texture::type::uint_8_8_8_8, gl::pixel_unpack_settings().row_length(buffer_pitch / 4)); + } + + areai screen_area = coordi({}, { (int)buffer_width, (int)buffer_height }); + + coordi aspect_ratio; + if (1) //enable aspect ratio + { + sizei csize = m_frame->client_size(); + sizei new_size = csize; + + const double aq = (double)buffer_width / buffer_height; + const double rq = (double)new_size.width / new_size.height; + const double q = aq / rq; + + if (q > 1.0) + { + new_size.height = int(new_size.height / q); + aspect_ratio.y = (csize.height - new_size.height) / 2; + } + else if (q < 1.0) + { + new_size.width = int(new_size.width * q); + aspect_ratio.x = (csize.width - new_size.width) / 2; + } + + aspect_ratio.size = new_size; + } + else + { + aspect_ratio.size = m_frame->client_size(); + } + + if (!skip_read) + { + __glcheck m_flip_fbo.blit(gl::screen, screen_area, areai(aspect_ratio).flipped_vertical()); + } + else + { + __glcheck draw_fbo.blit(gl::screen, screen_area, areai(aspect_ratio).flipped_vertical()); + } + + m_frame->flip(m_context); } -void GLGSRender::semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) -{ - vm::write32(m_label_addr + offset, value); -} -void GLGSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) +u64 GLGSRender::timestamp() const { - vm::write32(m_label_addr + offset, value); -} - -void GLGSRender::semaphorePFIFOAcquire(u32 offset, u32 value) -{ - + GLint64 result; + glGetInteger64v(GL_TIMESTAMP, &result); + return result; } \ No newline at end of file diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.h b/rpcs3/Emu/RSX/GL/GLGSRender.h index 31e6ac6a93..99d982eea5 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.h +++ b/rpcs3/Emu/RSX/GL/GLGSRender.h @@ -1,202 +1,110 @@ #pragma once #include "Emu/RSX/GSRender.h" #include "GLBuffers.h" +#include "gl_helpers.h" #define RSX_DEBUG 1 - #include "GLProgramBuffer.h" #pragma comment(lib, "opengl32.lib") -#if RSX_DEBUG -#define checkForGlError(sit) if((g_last_gl_error = glGetError()) != GL_NO_ERROR) printGlError(g_last_gl_error, sit) -#else -#define checkForGlError(sit) -#endif - -extern GLenum g_last_gl_error; -void printGlError(GLenum err, const char* situation); -void printGlError(GLenum err, const std::string& situation); - - class GLTexture { - u32 m_id; + u32 m_id = 0; public: - GLTexture() : m_id(0) - { - } + void create(); - void Create(); + int gl_wrap(int wrap); - int GetGlWrap(int wrap); + float max_aniso(int aniso); - float GetMaxAniso(int aniso); - - inline static u8 Convert4To8(u8 v) + inline static u8 convert_4_to_8(u8 v) { // Swizzle bits: 00001234 -> 12341234 return (v << 4) | (v); } - inline static u8 Convert5To8(u8 v) + inline static u8 convert_5_to_8(u8 v) { // Swizzle bits: 00012345 -> 12345123 return (v << 3) | (v >> 2); } - inline static u8 Convert6To8(u8 v) + inline static u8 convert_6_to_8(u8 v) { // Swizzle bits: 00123456 -> 12345612 return (v << 2) | (v >> 4); } - void Init(RSXTexture& tex); + void init(rsx::texture& tex); + void save(rsx::texture& tex, const std::string& name); + void save(rsx::texture& tex); + void bind(); + void unbind(); + void remove(); - void Save(RSXTexture& tex, const std::string& name); - - void Save(RSXTexture& tex); - - void Bind(); - - void Unbind(); - - void Delete(); + u32 id() const; }; -class PostDrawObj -{ -protected: - GLFragmentProgram m_fp; - GLVertexProgram m_vp; - GLProgram m_program; - GLfbo m_fbo; - GLrbo m_rbo; - -public: - virtual void Draw(); - - virtual void InitializeShaders() = 0; - virtual void InitializeLocations() = 0; - - void Initialize(); -}; - -class DrawCursorObj : public PostDrawObj -{ - u32 m_tex_id; - void* m_pixels; - u32 m_width, m_height; - double m_pos_x, m_pos_y, m_pos_z; - bool m_update_texture, m_update_pos; - -public: - DrawCursorObj() : PostDrawObj() - , m_tex_id(0) - , m_update_texture(false) - , m_update_pos(false) - { - } - - virtual void Draw(); - - virtual void InitializeShaders(); - - void SetTexture(void* pixels, int width, int height); - - void SetPosition(float x, float y, float z = 0.0f); - - void InitializeLocations(); -}; - -class GSFrameBase -{ -public: - GSFrameBase() {} - GSFrameBase(const GSFrameBase&) = delete; - virtual void Close() = 0; - - virtual bool IsShown() = 0; - virtual void Hide() = 0; - virtual void Show() = 0; - - virtual void* GetNewContext() = 0; - virtual void SetCurrent(void* ctx) = 0; - virtual void DeleteContext(void* ctx) = 0; - virtual void Flip(void* ctx) = 0; - -}; - -class GLGSRender final : public GSRender +class GLGSRender : public GSRender { private: - std::vector m_vdata; - std::vector m_post_draw_objs; - - GLProgram m_program; - int m_fp_buf_num; - int m_vp_buf_num; - GLProgramBuffer m_prog_buffer; - GLFragmentProgram m_fragment_prog; GLVertexProgram m_vertex_prog; - GLTexture m_gl_textures[m_textures_count]; - GLTexture m_gl_vertex_textures[m_textures_count]; + GLTexture m_gl_textures[rsx::limits::textures_count]; + GLTexture m_gl_vertex_textures[rsx::limits::vertex_textures_count]; - GLvao m_vao; - GLvbo m_vbo; - GLrbo m_rbo; - GLfbo m_fbo; + draw_context_t m_context = nullptr; - void* m_context; + //TODO: program cache + gl::glsl::program m_program; + + rsx::surface_info m_surface; public: - GSFrameBase* m_frame; + gl::fbo draw_fbo; + +private: + GLProgramBuffer m_prog_buffer; + + gl::texture m_draw_tex_color[rsx::limits::color_buffers_count]; + gl::texture m_draw_tex_depth_stencil; + + //buffer + gl::fbo m_flip_fbo; + gl::texture m_flip_tex_color; + +public: + GSFrameBase* m_frame = nullptr; u32 m_draw_frames; u32 m_skip_frames; bool is_intel_vendor; GLGSRender(); - virtual ~GLGSRender() override; + virtual ~GLGSRender(); private: - void EnableVertexData(bool indexed_draw = false); - void DisableVertexData(); - void InitVertexData(); - void InitFragmentData(); + static u32 enable(u32 enable, u32 cap); + static u32 enable(u32 enable, u32 cap, u32 index); + void close() override; - void Enable(bool enable, const u32 cap); - virtual void Close() override; - bool LoadProgram(); - void WriteBuffers(); - void WriteDepthBuffer(); - void WriteColorBuffers(); - void WriteColorBufferA(); - void WriteColorBufferB(); - void WriteColorBufferC(); - void WriteColorBufferD(); - - void DrawObjects(); - void InitDrawBuffers(); +public: + bool load_program(); + void init_buffers(); + void read_buffers(); + void write_buffers(); protected: - virtual void OnInit() override; - virtual void OnInitThread() override; - virtual void OnExitThread() override; - virtual void OnReset() override; - virtual void Clear(u32 cmd) override; - virtual void Draw() override; - virtual void Flip() override; + void begin() override; + void end() override; - virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) override; - virtual void semaphorePGRAPHBackendRelease(u32 offset, u32 value) override; - virtual void semaphorePFIFOAcquire(u32 offset, u32 value) override; - - virtual void notifyProgramChange() override {} - virtual void notifyBlendStateChange() override {} - virtual void notifyDepthStencilStateChange() override {} - virtual void notifyRasterizerStateChange() override {} + void oninit() override; + void oninit_thread() override; + void onexit_thread() override; + bool domethod(u32 id, u32 arg) override; + void flip(int buffer) override; + u64 timestamp() const override; }; diff --git a/rpcs3/Emu/RSX/GL/GLProcTable.h b/rpcs3/Emu/RSX/GL/GLProcTable.h index 22a6a004ab..83cd07262d 100644 --- a/rpcs3/Emu/RSX/GL/GLProcTable.h +++ b/rpcs3/Emu/RSX/GL/GLProcTable.h @@ -23,25 +23,12 @@ OPENGL_PROC(PFNGLATTACHSHADERPROC, AttachShader); OPENGL_PROC(PFNGLDETACHSHADERPROC, DetachShader); OPENGL_PROC(PFNGLGETATTRIBLOCATIONPROC, GetAttribLocation); OPENGL_PROC(PFNGLLINKPROGRAMPROC, LinkProgram); -//OPENGL_PROC(PFNGLBINDFRAGDATALOCATIONPROC, BindFragDataLocation); +OPENGL_PROC(PFNGLVALIDATEPROGRAMPROC, ValidateProgram); +OPENGL_PROC(PFNGLBINDFRAGDATALOCATIONPROC, BindFragDataLocation); OPENGL_PROC(PFNGLBINDATTRIBLOCATIONPROC, BindAttribLocation); OPENGL_PROC(PFNGLGETUNIFORMLOCATIONPROC, GetUniformLocation); OPENGL_PROC(PFNGLGETPROGRAMIVPROC, GetProgramiv); OPENGL_PROC(PFNGLGETPROGRAMINFOLOGPROC, GetProgramInfoLog); -OPENGL_PROC(PFNGLVERTEXATTRIB4BVPROC, VertexAttrib4bv); -OPENGL_PROC(PFNGLVERTEXATTRIB4UBVPROC, VertexAttrib4ubv); -OPENGL_PROC(PFNGLVERTEXATTRIB1SPROC, VertexAttrib1s); -OPENGL_PROC(PFNGLVERTEXATTRIB2SVPROC, VertexAttrib2sv); -OPENGL_PROC(PFNGLVERTEXATTRIB3SVPROC, VertexAttrib3sv); -OPENGL_PROC(PFNGLVERTEXATTRIB4SVPROC, VertexAttrib4sv); -OPENGL_PROC(PFNGLVERTEXATTRIB4IVPROC, VertexAttrib4iv); -OPENGL_PROC(PFNGLVERTEXATTRIB1FPROC, VertexAttrib1f); -OPENGL_PROC(PFNGLVERTEXATTRIB2FPROC, VertexAttrib2f); -OPENGL_PROC(PFNGLVERTEXATTRIB3FPROC, VertexAttrib3f); -OPENGL_PROC(PFNGLVERTEXATTRIB4FPROC, VertexAttrib4f); -OPENGL_PROC(PFNGLVERTEXATTRIB2FVPROC, VertexAttrib2fv); -OPENGL_PROC(PFNGLVERTEXATTRIB3FVPROC, VertexAttrib3fv); -OPENGL_PROC(PFNGLVERTEXATTRIB4FVPROC, VertexAttrib4fv); OPENGL_PROC(PFNGLVERTEXATTRIBPOINTERPROC, VertexAttribPointer); OPENGL_PROC(PFNGLENABLEVERTEXATTRIBARRAYPROC, EnableVertexAttribArray); OPENGL_PROC(PFNGLDISABLEVERTEXATTRIBARRAYPROC, DisableVertexAttribArray); @@ -49,36 +36,106 @@ OPENGL_PROC(PFNGLGENVERTEXARRAYSPROC, GenVertexArrays); OPENGL_PROC(PFNGLBINDVERTEXARRAYPROC, BindVertexArray); OPENGL_PROC(PFNGLDELETEVERTEXARRAYSPROC, DeleteVertexArrays); OPENGL_PROC(PFNGLDEPTHRANGEFPROC, DepthRangef); + +OPENGL_PROC(PFNGLVERTEXATTRIB1FPROC, VertexAttrib1f); +OPENGL_PROC(PFNGLVERTEXATTRIB1DPROC, VertexAttrib1d); +OPENGL_PROC(PFNGLVERTEXATTRIB1FVPROC, VertexAttrib1fv); +OPENGL_PROC(PFNGLVERTEXATTRIB1DVPROC, VertexAttrib1dv); +OPENGL_PROC(PFNGLVERTEXATTRIB2FPROC, VertexAttrib2f); +OPENGL_PROC(PFNGLVERTEXATTRIB2DPROC, VertexAttrib2d); +OPENGL_PROC(PFNGLVERTEXATTRIB2FVPROC, VertexAttrib2fv); +OPENGL_PROC(PFNGLVERTEXATTRIB2DVPROC, VertexAttrib2dv); +OPENGL_PROC(PFNGLVERTEXATTRIB3FPROC, VertexAttrib3f); +OPENGL_PROC(PFNGLVERTEXATTRIB3DPROC, VertexAttrib3d); +OPENGL_PROC(PFNGLVERTEXATTRIB3FVPROC, VertexAttrib3fv); +OPENGL_PROC(PFNGLVERTEXATTRIB3DVPROC, VertexAttrib3dv); +OPENGL_PROC(PFNGLVERTEXATTRIB4FPROC, VertexAttrib4f); +OPENGL_PROC(PFNGLVERTEXATTRIB4DPROC, VertexAttrib4d); +OPENGL_PROC(PFNGLVERTEXATTRIB4IVPROC, VertexAttrib4iv); +OPENGL_PROC(PFNGLVERTEXATTRIB4FVPROC, VertexAttrib4fv); +OPENGL_PROC(PFNGLVERTEXATTRIB4DVPROC, VertexAttrib4dv); +OPENGL_PROC(PFNGLVERTEXATTRIB4UIVPROC, VertexAttrib4uiv); + OPENGL_PROC(PFNGLUNIFORM1IPROC, Uniform1i); OPENGL_PROC(PFNGLUNIFORM1FPROC, Uniform1f); +OPENGL_PROC(PFNGLUNIFORM1DPROC, Uniform1d); OPENGL_PROC(PFNGLUNIFORM1UIPROC, Uniform1ui); OPENGL_PROC(PFNGLUNIFORM1IVPROC, Uniform1iv); OPENGL_PROC(PFNGLUNIFORM1FVPROC, Uniform1fv); +OPENGL_PROC(PFNGLUNIFORM1DVPROC, Uniform1dv); OPENGL_PROC(PFNGLUNIFORM1UIVPROC, Uniform1uiv); OPENGL_PROC(PFNGLUNIFORM2IPROC, Uniform2i); OPENGL_PROC(PFNGLUNIFORM2FPROC, Uniform2f); +OPENGL_PROC(PFNGLUNIFORM2DPROC, Uniform2d); OPENGL_PROC(PFNGLUNIFORM2UIPROC, Uniform2ui); OPENGL_PROC(PFNGLUNIFORM2IVPROC, Uniform2iv); OPENGL_PROC(PFNGLUNIFORM2FVPROC, Uniform2fv); +OPENGL_PROC(PFNGLUNIFORM2DVPROC, Uniform2dv); OPENGL_PROC(PFNGLUNIFORM2UIVPROC, Uniform2uiv); OPENGL_PROC(PFNGLUNIFORM3IPROC, Uniform3i); OPENGL_PROC(PFNGLUNIFORM3FPROC, Uniform3f); +OPENGL_PROC(PFNGLUNIFORM3DPROC, Uniform3d); OPENGL_PROC(PFNGLUNIFORM3UIPROC, Uniform3ui); OPENGL_PROC(PFNGLUNIFORM3IVPROC, Uniform3iv); OPENGL_PROC(PFNGLUNIFORM3FVPROC, Uniform3fv); +OPENGL_PROC(PFNGLUNIFORM3DVPROC, Uniform3dv); OPENGL_PROC(PFNGLUNIFORM3UIVPROC, Uniform3uiv); -OPENGL_PROC(PFNGLUNIFORM4FPROC, Uniform4i); +OPENGL_PROC(PFNGLUNIFORM4IPROC, Uniform4i); OPENGL_PROC(PFNGLUNIFORM4FPROC, Uniform4f); +OPENGL_PROC(PFNGLUNIFORM4DPROC, Uniform4d); OPENGL_PROC(PFNGLUNIFORM4UIPROC, Uniform4ui); OPENGL_PROC(PFNGLUNIFORM4IVPROC, Uniform4iv); OPENGL_PROC(PFNGLUNIFORM4FVPROC, Uniform4fv); +OPENGL_PROC(PFNGLUNIFORM4DVPROC, Uniform4dv); OPENGL_PROC(PFNGLUNIFORM4UIVPROC, Uniform4uiv); +OPENGL_PROC(PFNGLUNIFORMMATRIX2FVPROC, UniformMatrix2fv); +OPENGL_PROC(PFNGLUNIFORMMATRIX2DVPROC, UniformMatrix2dv); +OPENGL_PROC(PFNGLUNIFORMMATRIX3FVPROC, UniformMatrix3fv); +OPENGL_PROC(PFNGLUNIFORMMATRIX3DVPROC, UniformMatrix3dv); +OPENGL_PROC(PFNGLUNIFORMMATRIX4FVPROC, UniformMatrix4fv); +OPENGL_PROC(PFNGLUNIFORMMATRIX4DVPROC, UniformMatrix4dv); + OPENGL_PROC(PFNGLPROGRAMUNIFORM1IPROC, ProgramUniform1i); OPENGL_PROC(PFNGLPROGRAMUNIFORM1FPROC, ProgramUniform1f); +OPENGL_PROC(PFNGLPROGRAMUNIFORM1DPROC, ProgramUniform1d); +OPENGL_PROC(PFNGLPROGRAMUNIFORM1UIPROC, ProgramUniform1ui); +OPENGL_PROC(PFNGLPROGRAMUNIFORM1IVPROC, ProgramUniform1iv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM1FVPROC, ProgramUniform1fv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM1DVPROC, ProgramUniform1dv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM1UIVPROC, ProgramUniform1uiv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM2IPROC, ProgramUniform2i); +OPENGL_PROC(PFNGLPROGRAMUNIFORM2FPROC, ProgramUniform2f); +OPENGL_PROC(PFNGLPROGRAMUNIFORM2DPROC, ProgramUniform2d); +OPENGL_PROC(PFNGLPROGRAMUNIFORM2UIPROC, ProgramUniform2ui); +OPENGL_PROC(PFNGLPROGRAMUNIFORM2IVPROC, ProgramUniform2iv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM2FVPROC, ProgramUniform2fv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM2DVPROC, ProgramUniform2dv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM2UIVPROC, ProgramUniform2uiv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM3IPROC, ProgramUniform3i); +OPENGL_PROC(PFNGLPROGRAMUNIFORM3FPROC, ProgramUniform3f); +OPENGL_PROC(PFNGLPROGRAMUNIFORM3DPROC, ProgramUniform3d); +OPENGL_PROC(PFNGLPROGRAMUNIFORM3UIPROC, ProgramUniform3ui); +OPENGL_PROC(PFNGLPROGRAMUNIFORM3IVPROC, ProgramUniform3iv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM3FVPROC, ProgramUniform3fv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM3DVPROC, ProgramUniform3dv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM3UIVPROC, ProgramUniform3uiv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM4IPROC, ProgramUniform4i); OPENGL_PROC(PFNGLPROGRAMUNIFORM4FPROC, ProgramUniform4f); -OPENGL_PROC(PFNGLUNIFORMMATRIX4FVPROC, UniformMatrix4fv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM4DPROC, ProgramUniform4d); +OPENGL_PROC(PFNGLPROGRAMUNIFORM4UIPROC, ProgramUniform4ui); +OPENGL_PROC(PFNGLPROGRAMUNIFORM4IVPROC, ProgramUniform4iv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM4FVPROC, ProgramUniform4fv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM4DVPROC, ProgramUniform4dv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM4UIVPROC, ProgramUniform4uiv); +OPENGL_PROC(PFNGLPROGRAMUNIFORMMATRIX2FVPROC, ProgramUniformMatrix2fv); +OPENGL_PROC(PFNGLPROGRAMUNIFORMMATRIX2DVPROC, ProgramUniformMatrix2dv); +OPENGL_PROC(PFNGLPROGRAMUNIFORMMATRIX3FVPROC, ProgramUniformMatrix3fv); +OPENGL_PROC(PFNGLPROGRAMUNIFORMMATRIX3DVPROC, ProgramUniformMatrix3dv); +OPENGL_PROC(PFNGLPROGRAMUNIFORMMATRIX4FVPROC, ProgramUniformMatrix4fv); +OPENGL_PROC(PFNGLPROGRAMUNIFORMMATRIX4DVPROC, ProgramUniformMatrix4dv); + OPENGL_PROC(PFNGLUSEPROGRAMPROC, UseProgram); -OPENGL_PROC2(PFNGLDEPTHBOUNDSEXTPROC, DepthBoundsEXT, glDepthBoundsEXT); +OPENGL_PROC(PFNGLDEPTHBOUNDSEXTPROC, DepthBoundsEXT); OPENGL_PROC(PFNGLSTENCILOPSEPARATEPROC, StencilOpSeparate); OPENGL_PROC(PFNGLSTENCILFUNCSEPARATEPROC, StencilFuncSeparate); OPENGL_PROC(PFNGLSTENCILMASKSEPARATEPROC, StencilMaskSeparate); @@ -96,13 +153,25 @@ OPENGL_PROC(PFNGLFRAMEBUFFERTEXTURE3DPROC, FramebufferTexture3D); OPENGL_PROC(PFNGLFRAMEBUFFERRENDERBUFFERPROC, FramebufferRenderbuffer); OPENGL_PROC(PFNGLBLITFRAMEBUFFERPROC, BlitFramebuffer); OPENGL_PROC(PFNGLDRAWBUFFERSPROC, DrawBuffers); + +OPENGL_PROC(PFNGLENABLEIPROC, Enablei); +OPENGL_PROC(PFNGLDISABLEIPROC, Disablei); + OPENGL_PROC(PFNGLPRIMITIVERESTARTINDEXPROC, PrimitiveRestartIndex); +OPENGL_PROC(PFNGLGETINTEGER64VPROC, GetInteger64v); + +OPENGL_PROC(PFNGLCHECKFRAMEBUFFERSTATUSPROC, CheckFramebufferStatus); + +//KHR_debug +OPENGL_PROC(PFNGLDEBUGMESSAGECONTROLARBPROC, DebugMessageControlARB); +OPENGL_PROC(PFNGLDEBUGMESSAGEINSERTARBPROC, DebugMessageInsertARB); +OPENGL_PROC(PFNGLDEBUGMESSAGECALLBACKARBPROC, DebugMessageCallbackARB); +//... + #ifndef __GNUG__ OPENGL_PROC(PFNGLBLENDCOLORPROC, BlendColor); OPENGL_PROC(PFNGLBLENDEQUATIONPROC, BlendEquation); OPENGL_PROC(PFNGLCOMPRESSEDTEXIMAGE2DPROC, CompressedTexImage2D); OPENGL_PROC(PFNGLACTIVETEXTUREPROC, ActiveTexture); - -OPENGL_PROC2(PFNWGLSWAPINTERVALEXTPROC, SwapInterval, wglSwapIntervalEXT); #endif diff --git a/rpcs3/Emu/RSX/GL/GLProgram.cpp b/rpcs3/Emu/RSX/GL/GLProgram.cpp index b7f77177f7..033d1608b5 100644 --- a/rpcs3/Emu/RSX/GL/GLProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLProgram.cpp @@ -3,7 +3,7 @@ #include "Emu/Memory/Memory.h" #include "GLProgram.h" #include "GLGSRender.h" - +/* GLProgram::GLProgram() : id(0) { } @@ -116,3 +116,4 @@ void GLProgram::Delete() id = 0; m_locations.clear(); } +*/ \ No newline at end of file diff --git a/rpcs3/Emu/RSX/GL/GLProgram.h b/rpcs3/Emu/RSX/GL/GLProgram.h index 076b3ce01f..024c05b8a1 100644 --- a/rpcs3/Emu/RSX/GL/GLProgram.h +++ b/rpcs3/Emu/RSX/GL/GLProgram.h @@ -1,7 +1,8 @@ #pragma once + #include "GLVertexProgram.h" #include "GLFragmentProgram.h" - +/* struct GLProgram { private: @@ -27,3 +28,4 @@ public: void SetVTex(u32 index); void Delete(); }; +*/ diff --git a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h index 0cb5972d14..472af37a27 100644 --- a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h +++ b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h @@ -7,7 +7,7 @@ struct GLTraits { typedef GLVertexProgram VertexProgramData; typedef GLFragmentProgram FragmentProgramData; - typedef GLProgram PipelineData; + typedef gl::glsl::program PipelineData; typedef void* PipelineProperties; typedef void* ExtraData; @@ -36,12 +36,14 @@ struct GLTraits static PipelineData *BuildProgram(VertexProgramData &vertexProgramData, FragmentProgramData &fragmentProgramData, const PipelineProperties &pipelineProperties, const ExtraData& extraData) { - GLProgram *result = new GLProgram(); - result->Create(vertexProgramData.id, fragmentProgramData.id); - //checkForGlError("m_program.Create"); - result->Use(); + PipelineData *result = new PipelineData(); + __glcheck result->create() + .attach(gl::glsl::shader_view(vertexProgramData.id)) + .attach(gl::glsl::shader_view(fragmentProgramData.id)) + .make(); + __glcheck result->use(); - LOG_NOTICE(RSX, "*** prog id = %d", result->id); + LOG_NOTICE(RSX, "*** prog id = %d", result->id()); LOG_NOTICE(RSX, "*** vp id = %d", vertexProgramData.id); LOG_NOTICE(RSX, "*** fp id = %d", fragmentProgramData.id); @@ -54,7 +56,7 @@ struct GLTraits static void DeleteProgram(PipelineData *ptr) { - ptr->Delete(); + ptr->remove(); } }; diff --git a/rpcs3/Emu/RSX/GL/OpenGL.cpp b/rpcs3/Emu/RSX/GL/OpenGL.cpp index 7309fe1d7e..a4ef68af94 100644 --- a/rpcs3/Emu/RSX/GL/OpenGL.cpp +++ b/rpcs3/Emu/RSX/GL/OpenGL.cpp @@ -2,7 +2,7 @@ #include "Utilities/Log.h" #include "OpenGL.h" -void InitProcTable() +void gl::init() { #ifdef _WIN32 #define OPENGL_PROC(p, n) OPENGL_PROC2(p, n, gl##n) diff --git a/rpcs3/Emu/RSX/GL/OpenGL.h b/rpcs3/Emu/RSX/GL/OpenGL.h index ce4612c66c..9f1ca10845 100644 --- a/rpcs3/Emu/RSX/GL/OpenGL.h +++ b/rpcs3/Emu/RSX/GL/OpenGL.h @@ -25,7 +25,10 @@ typedef BOOL (WINAPI* PFNWGLSWAPINTERVALEXTPROC) (int interval); #include #endif -void InitProcTable(); +namespace gl +{ + void init(); +} struct OpenGL { diff --git a/rpcs3/Emu/RSX/GL/gl_helpers.cpp b/rpcs3/Emu/RSX/GL/gl_helpers.cpp new file mode 100644 index 0000000000..b3d06eb009 --- /dev/null +++ b/rpcs3/Emu/RSX/GL/gl_helpers.cpp @@ -0,0 +1,469 @@ +#include "stdafx.h" +#include "gl_helpers.h" + +namespace gl +{ + const fbo screen{}; + + void fbo::create() + { + glGenFramebuffers(1, &m_id); + } + + void fbo::bind() const + { + glBindFramebuffer(GL_FRAMEBUFFER, m_id); + } + + void fbo::blit(const fbo& dst, areai src_area, areai dst_area, buffers buffers_, filter filter_) const + { + bind_as(target::read_frame_buffer); + dst.bind_as(target::draw_frame_buffer); + glBlitFramebuffer( + src_area.x1, src_area.y1, src_area.x2, src_area.y2, + dst_area.x1, dst_area.y1, dst_area.x2, dst_area.y2, + (GLbitfield)buffers_, (GLenum)filter_); + } + + void fbo::bind_as(target target_) const + { + glBindFramebuffer((int)target_, id()); + } + + void fbo::remove() + { + glDeleteFramebuffers(1, &m_id); + m_id = 0; + } + + bool fbo::created() const + { + return m_id != 0; + } + + void fbo::check() const + { + save_binding_state save(*this); + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + if (status != GL_FRAMEBUFFER_COMPLETE) + { + throw std::logic_error(fmt::format("0x%04x", status)); + } + } + + void fbo::recreate() + { + if (created()) + remove(); + + create(); + } + + void fbo::draw_buffer(const attachment& buffer) const + { + save_binding_state save(*this); + GLenum buf = buffer.id(); + glDrawBuffers(1, &buf); + } + + void fbo::draw_buffers(const std::initializer_list& indexes) const + { + save_binding_state save(*this); + std::vector ids; + + for (auto &index : indexes) + ids.push_back(index.id()); + + glDrawBuffers((GLsizei)ids.size(), ids.data()); + } + + void fbo::draw_arrays(draw_mode mode, GLsizei count, GLint first) const + { + save_binding_state save(*this); + __glcheck glDrawArrays((GLenum)mode, first, count); + } + + void fbo::draw_arrays(const buffer& buffer, draw_mode mode, GLsizei count, GLint first) const + { + buffer.bind(buffer::target::array); + draw_arrays(mode, count, first); + } + + void fbo::draw_arrays(const vao& buffer, draw_mode mode, GLsizei count, GLint first) const + { + buffer.bind(); + draw_arrays(mode, count, first); + } + + void fbo::draw_elements(draw_mode mode, GLsizei count, indices_type type, const GLvoid *indices) const + { + save_binding_state save(*this); + glDrawElements((GLenum)mode, count, (GLenum)type, indices); + } + + void fbo::draw_elements(const buffer& buffer, draw_mode mode, GLsizei count, indices_type type, const GLvoid *indices) const + { + buffer.bind(buffer::target::array); + glDrawElements((GLenum)mode, count, (GLenum)type, indices); + } + + void fbo::draw_elements(draw_mode mode, GLsizei count, indices_type type, const buffer& indices, size_t indices_buffer_offset) const + { + indices.bind(buffer::target::element_array); + glDrawElements((GLenum)mode, count, (GLenum)type, (GLvoid*)indices_buffer_offset); + } + + void fbo::draw_elements(const buffer& buffer_, draw_mode mode, GLsizei count, indices_type type, const buffer& indices, size_t indices_buffer_offset) const + { + buffer_.bind(buffer::target::array); + draw_elements(mode, count, type, indices, indices_buffer_offset); + } + + void fbo::draw_elements(draw_mode mode, GLsizei count, const GLubyte *indices) const + { + draw_elements(mode, count, indices_type::ubyte, indices); + } + + void fbo::draw_elements(const buffer& buffer, draw_mode mode, GLsizei count, const GLubyte *indices) const + { + draw_elements(buffer, mode, count, indices_type::ubyte, indices); + } + + void fbo::draw_elements(draw_mode mode, GLsizei count, const GLushort *indices) const + { + draw_elements(mode, count, indices_type::ushort, indices); + } + + void fbo::draw_elements(const buffer& buffer, draw_mode mode, GLsizei count, const GLushort *indices) const + { + draw_elements(buffer, mode, count, indices_type::ushort, indices); + } + + void fbo::draw_elements(draw_mode mode, GLsizei count, const GLuint *indices) const + { + draw_elements(mode, count, indices_type::uint, indices); + } + + void fbo::draw_elements(const buffer& buffer, draw_mode mode, GLsizei count, const GLuint *indices) const + { + draw_elements(buffer, mode, count, indices_type::uint, indices); + } + + void fbo::clear(buffers buffers_) const + { + save_binding_state save(*this); + glClear((GLbitfield)buffers_); + } + + void fbo::clear(buffers buffers_, color4f color_value, double depth_value, u8 stencil_value) const + { + save_binding_state save(*this); + glClearColor(color_value.r, color_value.g, color_value.b, color_value.a); + glClearDepth(depth_value); + glClearStencil(stencil_value); + clear(buffers_); + } + + void fbo::copy_from(const void* pixels, sizei size, gl::texture::format format_, gl::texture::type type_, class pixel_unpack_settings pixel_settings) const + { + save_binding_state save(*this); + pixel_settings.apply(); + glDrawPixels(size.width, size.height, (GLenum)format_, (GLenum)type_, pixels); + } + + void fbo::copy_from(const buffer& buf, sizei size, gl::texture::format format_, gl::texture::type type_, class pixel_unpack_settings pixel_settings) const + { + save_binding_state save(*this); + buffer::save_binding_state save_buffer(buffer::target::pixel_unpack, buf); + pixel_settings.apply(); + glDrawPixels(size.width, size.height, (GLenum)format_, (GLenum)type_, nullptr); + } + + void fbo::copy_to(void* pixels, coordi coord, gl::texture::format format_, gl::texture::type type_, class pixel_pack_settings pixel_settings) const + { + save_binding_state save(*this); + pixel_settings.apply(); + glReadPixels(coord.x, coord.y, coord.width, coord.height, (GLenum)format_, (GLenum)type_, pixels); + } + + void fbo::copy_to(const buffer& buf, coordi coord, gl::texture::format format_, gl::texture::type type_, class pixel_pack_settings pixel_settings) const + { + save_binding_state save(*this); + buffer::save_binding_state save_buffer(buffer::target::pixel_pack, buf); + pixel_settings.apply(); + glReadPixels(coord.x, coord.y, coord.width, coord.height, (GLenum)format_, (GLenum)type_, nullptr); + } + + fbo fbo::get_binded_draw_buffer() + { + GLint value; + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &value); + + return{ (GLuint)value }; + } + + fbo fbo::get_binded_read_buffer() + { + GLint value; + glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &value); + + return{ (GLuint)value }; + } + + fbo fbo::get_binded_buffer() + { + GLint value; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &value); + + return{ (GLuint)value }; + } + + GLuint fbo::id() const + { + return m_id; + } + + void fbo::set_id(GLuint id) + { + m_id = id; + } + + void texture::settings::apply(const texture &texture) const + { + save_binding_state save(texture); + + texture.pixel_unpack_settings().apply(); + + if (compressed_format(m_internal_format)) + { + int compressed_image_size = m_compressed_image_size; + if (!compressed_image_size) + { + switch (m_internal_format) + { + case texture::internal_format::compressed_rgb_s3tc_dxt1: + compressed_image_size = ((m_width + 2) / 3) * ((m_height + 2) / 3) * 6; + break; + + case texture::internal_format::compressed_rgba_s3tc_dxt1: + compressed_image_size = ((m_width + 3) / 4) * ((m_height + 3) / 4) * 8; + break; + + case texture::internal_format::compressed_rgba_s3tc_dxt3: + case texture::internal_format::compressed_rgba_s3tc_dxt5: + compressed_image_size = ((m_width + 3) / 4) * ((m_height + 3) / 4) * 16; + break; + } + } + + __glcheck glCompressedTexImage2D((GLenum)m_parent->get_target(), m_level, (GLint)m_internal_format, m_width, m_height, 0, compressed_image_size, m_pixels); + } + else + { + __glcheck glTexImage2D((GLenum)m_parent->get_target(), m_level, (GLint)m_internal_format, m_width, m_height, 0, (GLint)m_format, (GLint)m_type, m_pixels); + } + + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_MAX_LEVEL, m_max_level); + + if (m_pixels) + { + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_GENERATE_MIPMAP, m_generate_mipmap ? GL_TRUE : GL_FALSE); + } + + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_WRAP_S, (GLint)m_wrap_s); + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_WRAP_T, (GLint)m_wrap_t); + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_WRAP_R, (GLint)m_wrap_r); + + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_COMPARE_MODE, (GLint)m_compare_mode); + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_COMPARE_FUNC, (GLint)m_compare_func); + + __glcheck glTexParameterf((GLenum)m_parent->get_target(), GL_TEXTURE_MIN_LOD, m_max_lod); + __glcheck glTexParameterf((GLenum)m_parent->get_target(), GL_TEXTURE_MAX_LOD, m_min_lod); + __glcheck glTexParameterf((GLenum)m_parent->get_target(), GL_TEXTURE_LOD_BIAS, m_lod); + + __glcheck glTexParameterfv((GLenum)m_parent->get_target(), GL_TEXTURE_BORDER_COLOR, m_border_color.rgba); + + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_MIN_FILTER, (GLint)m_min_filter); + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_MAG_FILTER, (GLint)m_mag_filter); + + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_SWIZZLE_R, (GLint)m_swizzle_r); + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_SWIZZLE_G, (GLint)m_swizzle_g); + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_SWIZZLE_B, (GLint)m_swizzle_b); + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_SWIZZLE_A, (GLint)m_swizzle_a); + + __glcheck glTexParameterf((GLenum)m_parent->get_target(), GL_TEXTURE_MAX_ANISOTROPY_EXT, m_aniso); + } + + void texture::settings::apply() + { + if (m_parent) + { + apply(*m_parent); + m_parent = nullptr; + } + } + + texture::settings& texture::settings::swizzle(texture::channel r, texture::channel g, texture::channel b, texture::channel a) + { + m_swizzle_r = r; + m_swizzle_g = g; + m_swizzle_b = b; + m_swizzle_a = a; + + return *this; + } + + texture::settings& texture::settings::format(texture::format format) + { + m_format = format; + return *this; + } + + texture::settings& texture::settings::type(texture::type type) + { + m_type = type; + return *this; + } + + texture::settings& texture::settings::internal_format(texture::internal_format format) + { + m_internal_format = format; + return *this; + } + + texture::settings& texture::settings::filter(min_filter min_filter, gl::filter mag_filter) + { + m_min_filter = min_filter; + m_mag_filter = mag_filter; + + return *this; + } + + texture::settings& texture::settings::width(uint width) + { + m_width = width; + return *this; + } + + texture::settings& texture::settings::height(uint height) + { + m_height = height; + return *this; + } + + texture::settings& texture::settings::size(sizei size) + { + return width(size.width).height(size.height); + } + + texture::settings& texture::settings::level(int value) + { + m_level = value; + return *this; + } + + texture::settings& texture::settings::compressed_image_size(int size) + { + m_compressed_image_size = size; + return *this; + } + + texture::settings& texture::settings::pixels(const void* pixels) + { + m_pixels = pixels; + return *this; + } + + texture::settings& texture::settings::aniso(float value) + { + m_aniso = value; + return *this; + } + + texture::settings& texture::settings::compare_mode(texture::compare_mode value) + { + m_compare_mode = value; + return *this; + } + texture::settings& texture::settings::compare_func(texture::compare_func value) + { + m_compare_func = value; + return *this; + } + texture::settings& texture::settings::compare(texture::compare_func func, texture::compare_mode mode) + { + return compare_func(func).compare_mode(mode); + } + + texture::settings& texture::settings::wrap_s(texture::wrap value) + { + m_wrap_s = value; + return *this; + } + texture::settings& texture::settings::wrap_t(texture::wrap value) + { + m_wrap_t = value; + return *this; + } + texture::settings& texture::settings::wrap_r(texture::wrap value) + { + m_wrap_r = value; + return *this; + } + texture::settings& texture::settings::wrap(texture::wrap s, texture::wrap t, texture::wrap r) + { + return wrap_s(s).wrap_t(t).wrap_r(r); + } + + texture::settings& texture::settings::max_lod(float value) + { + m_max_lod = value; + return *this; + } + texture::settings& texture::settings::min_lod(float value) + { + m_min_lod = value; + return *this; + } + texture::settings& texture::settings::lod(float value) + { + m_lod = value; + return *this; + } + texture::settings& texture::settings::max_level(int value) + { + m_max_level = value; + return *this; + } + texture::settings& texture::settings::generate_mipmap(bool value) + { + m_generate_mipmap = value; + return *this; + } + texture::settings& texture::settings::mipmap(int level, int max_level, float lod, float min_lod, float max_lod, bool generate) + { + return this->level(level).max_level(max_level).lod(lod).min_lod(min_lod).max_lod(max_lod).generate_mipmap(generate); + } + + texture::settings& texture::settings::border_color(color4f value) + { + m_border_color = value; + return *this; + } + + texture_view texture::with_level(int level) + { + return{ get_target(), id() }; + } + + texture::settings texture::config() + { + return{ this }; + } + + void texture::config(const settings& settings_) + { + settings_.apply(*this); + } +} \ No newline at end of file diff --git a/rpcs3/Emu/RSX/GL/gl_helpers.h b/rpcs3/Emu/RSX/GL/gl_helpers.h new file mode 100644 index 0000000000..766a289b5a --- /dev/null +++ b/rpcs3/Emu/RSX/GL/gl_helpers.h @@ -0,0 +1,2202 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "Utilities/types.h" +#include "OpenGL.h" + +namespace gl +{ +#ifdef _DEBUG + struct __glcheck_impl_t + { + const char* file; + const char* function; + long line; + + constexpr __glcheck_impl_t(const char* file, const char* function, long line) + : file(file) + , function(function) + , line(line) + { + } + + ~__glcheck_impl_t() noexcept(false) + { + if (GLenum err = glGetError()) + { + std::string error; + switch (err) + { + case GL_INVALID_OPERATION: error = "invalid operation"; break; + case GL_INVALID_ENUM: error = "invalid enum"; break; + case GL_INVALID_VALUE: error = "invalid value"; break; + case GL_OUT_OF_MEMORY: error = "out of memory"; break; + case GL_INVALID_FRAMEBUFFER_OPERATION: error = "invalid framebuffer operation"; break; + default: error = "unknown error"; break; + } + + throw std::runtime_error(fmt::format("OpenGL error: %s. file '%s' function '%s' line %ld", error.c_str(), file, function, line)); + } + } + }; +#define __glcheck gl::__glcheck_impl_t{ __FILE__, __FUNCTION__, __LINE__ }, +#else +#define __glcheck +#endif + + class exception : public std::exception + { + protected: + std::string m_what; + + public: + const char* what() const noexcept override + { + return m_what.c_str(); + } + }; + + template + class save_binding_state_base + { + GLint m_last_binding; + + public: + save_binding_state_base(const Type& new_state) : save_binding_state_base() + { + new_state.bind(); + } + + save_binding_state_base() + { + glGetIntegerv(GetStateId, &m_last_binding); + } + + ~save_binding_state_base() + { + glBindBuffer(BindId, m_last_binding); + } + }; + + enum class filter + { + nearest = GL_NEAREST, + linear = GL_LINEAR + }; + + enum class min_filter + { + nearest = GL_NEAREST, + linear = GL_LINEAR, + nearest_mipmap_nearest = GL_NEAREST_MIPMAP_NEAREST, + nearest_mipmap_linear = GL_NEAREST_MIPMAP_LINEAR, + linear_mipmap_nearest = GL_LINEAR_MIPMAP_NEAREST, + linear_mipmap_linear = GL_LINEAR_MIPMAP_LINEAR + }; + + enum class buffers + { + color = GL_COLOR_BUFFER_BIT, + depth = GL_DEPTH_BUFFER_BIT, + stencil = GL_STENCIL_BUFFER_BIT, + + color_depth = color | depth, + color_depth_stencil = color | depth | stencil, + color_stencil = color | stencil, + + depth_stencil = depth | stencil + }; + + class pixel_pack_settings + { + bool m_swap_bytes = false; + bool m_lsb_first = false; + int m_row_length = 0; + int m_image_height = 0; + int m_skip_rows = 0; + int m_skip_pixels = 0; + int m_skip_images = 0; + int m_aligment = 4; + + public: + void apply() const + { + glPixelStorei(GL_PACK_SWAP_BYTES, m_swap_bytes ? GL_TRUE : GL_FALSE); + glPixelStorei(GL_PACK_LSB_FIRST, m_lsb_first ? GL_TRUE : GL_FALSE); + glPixelStorei(GL_PACK_ROW_LENGTH, m_row_length); + glPixelStorei(GL_PACK_IMAGE_HEIGHT, m_image_height); + glPixelStorei(GL_PACK_SKIP_ROWS, m_skip_rows); + glPixelStorei(GL_PACK_SKIP_PIXELS, m_skip_pixels); + glPixelStorei(GL_PACK_SKIP_IMAGES, m_skip_images); + glPixelStorei(GL_PACK_ALIGNMENT, m_aligment); + } + + pixel_pack_settings& swap_bytes(bool value = true) + { + m_swap_bytes = value; + return *this; + } + pixel_pack_settings& lsb_first(bool value = true) + { + m_lsb_first = value; + return *this; + } + pixel_pack_settings& row_length(int value) + { + m_row_length = value; + return *this; + } + pixel_pack_settings& image_height(int value) + { + m_image_height = value; + return *this; + } + pixel_pack_settings& skip_rows(int value) + { + m_skip_rows = value; + return *this; + } + pixel_pack_settings& skip_pixels(int value) + { + m_skip_pixels = value; + return *this; + } + pixel_pack_settings& skip_images(int value) + { + m_skip_images = value; + return *this; + } + pixel_pack_settings& aligment(int value) + { + m_aligment = value; + return *this; + } + }; + + class pixel_unpack_settings + { + bool m_swap_bytes = false; + bool m_lsb_first = false; + int m_row_length = 0; + int m_image_height = 0; + int m_skip_rows = 0; + int m_skip_pixels = 0; + int m_skip_images = 0; + int m_aligment = 4; + + public: + void apply() const + { + glPixelStorei(GL_UNPACK_SWAP_BYTES, m_swap_bytes ? GL_TRUE : GL_FALSE); + glPixelStorei(GL_UNPACK_LSB_FIRST, m_lsb_first ? GL_TRUE : GL_FALSE); + glPixelStorei(GL_UNPACK_ROW_LENGTH, m_row_length); + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, m_image_height); + glPixelStorei(GL_UNPACK_SKIP_ROWS, m_skip_rows); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, m_skip_pixels); + glPixelStorei(GL_UNPACK_SKIP_IMAGES, m_skip_images); + glPixelStorei(GL_UNPACK_ALIGNMENT, m_aligment); + } + + pixel_unpack_settings& swap_bytes(bool value = true) + { + m_swap_bytes = value; + return *this; + } + pixel_unpack_settings& lsb_first(bool value = true) + { + m_lsb_first = value; + return *this; + } + pixel_unpack_settings& row_length(int value) + { + m_row_length = value; + return *this; + } + pixel_unpack_settings& image_height(int value) + { + m_image_height = value; + return *this; + } + pixel_unpack_settings& skip_rows(int value) + { + m_skip_rows = value; + return *this; + } + pixel_unpack_settings& skip_pixels(int value) + { + m_skip_pixels = value; + return *this; + } + pixel_unpack_settings& skip_images(int value) + { + m_skip_images = value; + return *this; + } + pixel_unpack_settings& aligment(int value) + { + m_aligment = value; + return *this; + } + }; + + class vao; + + class buffer_pointer + { + public: + enum class type + { + s8 = GL_BYTE, + u8 = GL_UNSIGNED_BYTE, + s16 = GL_SHORT, + u16 = GL_UNSIGNED_SHORT, + s32 = GL_INT, + u32 = GL_UNSIGNED_INT, + f16 = GL_HALF_FLOAT, + f32 = GL_FLOAT, + f64 = GL_DOUBLE, + fixed = GL_FIXED, + s32_2_10_10_10_rev = GL_INT_2_10_10_10_REV, + u32_2_10_10_10_rev = GL_UNSIGNED_INT_2_10_10_10_REV, + u32_10f_11f_11f_rev = GL_UNSIGNED_INT_10F_11F_11F_REV + }; + + private: + vao* m_vao; + u32 m_offset; + u32 m_stride; + u32 m_size = 4; + type m_type = type::f32; + bool m_normalize = false; + + public: + buffer_pointer(vao* vao, u32 offset = 0, u32 stride = 0) + : m_vao(vao) + , m_offset(offset) + , m_stride(stride) + { + } + + const class ::gl::vao& get_vao() const + { + return *m_vao; + } + + class ::gl::vao& get_vao() + { + return *m_vao; + } + + buffer_pointer& offset(u32 value) + { + m_offset = value; + return *this; + } + + u32 offset() const + { + return m_offset; + } + + buffer_pointer& stride(u32 value) + { + m_stride = value; + return *this; + } + + u32 stride() const + { + return m_stride; + } + + buffer_pointer& size(u32 value) + { + m_size = value; + return *this; + } + + u32 size() const + { + return m_size; + } + + buffer_pointer& set_type(type value) + { + m_type = value; + return *this; + } + + type get_type() const + { + return m_type; + } + + buffer_pointer& normalize(bool value) + { + m_normalize = value; + return *this; + } + + bool normalize() const + { + return m_normalize; + } + + buffer_pointer& operator >> (u32 value) + { + return stride(value); + } + + buffer_pointer& config(type type_ = type::f32, u32 size_ = 4, bool normalize_ = false) + { + return set_type(type_).size(size_).normalize(normalize_); + } + }; + + class buffer + { + public: + enum class target + { + pixel_pack = GL_PIXEL_PACK_BUFFER, + pixel_unpack = GL_PIXEL_UNPACK_BUFFER, + array = GL_ARRAY_BUFFER, + element_array = GL_ELEMENT_ARRAY_BUFFER + }; + enum class access + { + read = GL_READ_ONLY, + write = GL_WRITE_ONLY, + read_write = GL_READ_WRITE + }; + + private: + GLuint m_id = GL_NONE; + target m_target = target::array; + + public: + buffer() = default; + + buffer(GLuint id) + { + set_id(id); + } + + ~buffer() + { + if (created()) + remove(); + } + + class save_binding_state + { + GLint m_last_binding; + GLenum m_target; + + public: + save_binding_state(target target_, const buffer& new_state) : save_binding_state(target_) + { + new_state.bind(target_); + } + + save_binding_state(target target_) + { + GLenum pname; + switch (target_) + { + case target::pixel_pack: pname = GL_PIXEL_PACK_BUFFER_BINDING; break; + case target::pixel_unpack: pname = GL_PIXEL_UNPACK_BUFFER_BINDING; break; + case target::array: pname = GL_ARRAY_BUFFER_BINDING; break; + case target::element_array: pname = GL_ELEMENT_ARRAY_BUFFER_BINDING; break; + } + + glGetIntegerv(pname, &m_last_binding); + m_target = (GLenum)target_; + } + + + ~save_binding_state() + { + glBindBuffer(m_target, m_last_binding); + } + }; + + void recreate() + { + if (created()) + { + remove(); + } + + create(); + } + + void recreate(GLsizeiptr size, const void* data = nullptr) + { + if (created()) + { + remove(); + } + + create(size, data); + } + + void create() + { + glGenBuffers(1, &m_id); + } + + void create(GLsizeiptr size, const void* data_ = nullptr) + { + create(); + data(size, data_); + } + + void data(GLsizeiptr size, const void* data_ = nullptr) + { + target target_ = current_target(); + save_binding_state save(target_, *this); + glBufferData((GLenum)target_, size, data_, GL_STREAM_COPY); + } + + void sub_data(GLintptr offset, GLsizeiptr size, const void* data_ = nullptr) + { + target target_ = current_target(); + save_binding_state save(target_, *this); + glBufferSubData((GLenum)target_, offset, size, data_); + } + + void bind(target target_) const + { + glBindBuffer((GLenum)target_, m_id); + } + + target current_target() const + { + return m_target; + } + + void remove() + { + glDeleteBuffers(1, &m_id); + m_id = 0; + } + + uint id() const + { + return m_id; + } + + void set_id(uint id) + { + m_id = id; + } + + bool created() const + { + return m_id != 0; + } + + explicit operator bool() const + { + return created(); + } + + void map(std::function impl, access access_) + { + target target_ = current_target(); + save_binding_state save(target_, *this); + + if (GLubyte* ptr = (GLubyte*)glMapBuffer((GLenum)target_, (GLenum)access_)) + { + impl(ptr); + glUnmapBuffer((GLenum)target_); + } + } + + class mapper + { + buffer *m_parent; + GLubyte *m_data; + + public: + mapper(buffer& parent, access access_) + { + m_parent = &parent; + m_data = parent.map(access_); + } + + ~mapper() + { + m_parent->unmap(); + } + + GLubyte* get() const + { + return m_data; + } + }; + + GLubyte* map(access access_) + { + bind(current_target()); + + return (GLubyte*)glMapBuffer((GLenum)current_target(), (GLenum)access_); + } + + void unmap() + { + glUnmapBuffer((GLenum)current_target()); + } + }; + + class vao + { + template + class entry + { + vao& m_parent; + + public: + using save_binding_state = save_binding_state_base; + + entry(vao* parent) noexcept : m_parent(*parent) + { + } + + entry& operator = (const buffer& buf) noexcept + { + m_parent.bind(); + buf.bind(BindId); + + return *this; + } + }; + + GLuint m_id = GL_NONE; + + public: + entry pixel_pack_buffer{ this }; + entry pixel_unpack_buffer{ this }; + entry array_buffer{ this }; + entry element_array_buffer{ this }; + + vao() = default; + vao(vao&) = delete; + + vao(vao&& vao_) noexcept + { + swap(vao_); + } + vao(GLuint id) noexcept + { + set_id(id); + } + + ~vao() noexcept + { + if (created()) + remove(); + } + + void swap(vao& vao_) noexcept + { + auto my_old_id = id(); + set_id(vao_.id()); + vao_.set_id(my_old_id); + } + + vao& operator = (const vao& rhs) = delete; + vao& operator = (vao&& rhs) noexcept + { + swap(rhs); + return *this; + } + + void bind() const noexcept + { + glBindVertexArray(m_id); + } + + void create() noexcept + { + glGenVertexArrays(1, &m_id); + } + + void remove() noexcept + { + glDeleteVertexArrays(1, &m_id); + m_id = GL_NONE; + } + + uint id() const noexcept + { + return m_id; + } + + void set_id(uint id) noexcept + { + m_id = id; + } + + bool created() const noexcept + { + return m_id != GL_NONE; + } + + explicit operator bool() const noexcept + { + return created(); + } + + void enable_for_attributes(std::initializer_list indexes) noexcept + { + for (auto &index : indexes) + { + glEnableVertexAttribArray(index); + } + } + + void disable_for_attributes(std::initializer_list indexes) noexcept + { + for (auto &index : indexes) + { + glDisableVertexAttribArray(index); + } + } + + void enable_for_attribute(GLuint index) noexcept + { + enable_for_attributes({ index }); + } + + void disable_for_attribute(GLuint index) noexcept + { + disable_for_attributes({ index }); + } + + buffer_pointer operator + (u32 offset) const noexcept + { + return{ (vao*)this, offset }; + } + + buffer_pointer operator >> (u32 stride) const noexcept + { + return{ (vao*)this, {}, stride }; + } + + operator buffer_pointer() const noexcept + { + return{ (vao*)this }; + } + }; + + class texture_view; + class texture + { + GLuint m_id = 0; + GLuint m_level = 0; + class pixel_pack_settings m_pixel_pack_settings; + class pixel_unpack_settings m_pixel_unpack_settings; + + public: + enum class type + { + ubyte = GL_UNSIGNED_BYTE, + ushort = GL_UNSIGNED_SHORT, + uint = GL_UNSIGNED_INT, + + ubyte_3_3_2 = GL_UNSIGNED_BYTE_3_3_2, + ubyte_2_3_3_rev = GL_UNSIGNED_BYTE_2_3_3_REV, + + ushort_5_6_5 = GL_UNSIGNED_SHORT_5_6_5, + ushort_5_6_5_rev = GL_UNSIGNED_SHORT_5_6_5_REV, + ushort_4_4_4_4 = GL_UNSIGNED_SHORT_4_4_4_4, + ushort_4_4_4_4_rev = GL_UNSIGNED_SHORT_4_4_4_4_REV, + ushort_5_5_5_1 = GL_UNSIGNED_SHORT_5_5_5_1, + ushort_1_5_5_5_rev = GL_UNSIGNED_SHORT_1_5_5_5_REV, + + uint_8_8_8_8 = GL_UNSIGNED_INT_8_8_8_8, + uint_8_8_8_8_rev = GL_UNSIGNED_INT_8_8_8_8_REV, + uint_10_10_10_2 = GL_UNSIGNED_INT_10_10_10_2, + uint_2_10_10_10_rev = GL_UNSIGNED_INT_2_10_10_10_REV, + uint_24_8 = GL_UNSIGNED_INT_24_8, + + sbyte = GL_BYTE, + sshort = GL_SHORT, + sint = GL_INT, + f16 = GL_HALF_FLOAT, + f32 = GL_FLOAT, + f64 = GL_DOUBLE, + }; + + enum class channel + { + zero = GL_ZERO, + one = GL_ONE, + r = GL_RED, + g = GL_GREEN, + b = GL_BLUE, + a = GL_ALPHA, + }; + + enum class format + { + red = GL_RED, + r = GL_R, + rg = GL_RG, + rgb = GL_RGB, + rgba = GL_RGBA, + + bgr = GL_BGR, + bgra = GL_BGRA, + + stencil = GL_STENCIL_INDEX, + depth = GL_DEPTH_COMPONENT, + depth_stencil = GL_DEPTH_STENCIL + }; + + enum class internal_format + { + red = GL_RED, + r = GL_R, + rg = GL_RG, + rgb = GL_RGB, + rgba = GL_RGBA, + + bgr = GL_BGR, + bgra = GL_BGRA, + + stencil = GL_STENCIL_INDEX, + stencil8 = GL_STENCIL_INDEX8, + depth = GL_DEPTH_COMPONENT, + depth16 = GL_DEPTH_COMPONENT16, + depth_stencil = GL_DEPTH_STENCIL, + depth24_stencil8 = GL_DEPTH24_STENCIL8, + + compressed_rgb_s3tc_dxt1 = GL_COMPRESSED_RGB_S3TC_DXT1_EXT, + compressed_rgba_s3tc_dxt1 = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, + compressed_rgba_s3tc_dxt3 = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, + compressed_rgba_s3tc_dxt5 = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT + }; + + enum class wrap + { + repeat = GL_REPEAT, + mirrored_repeat = GL_MIRRORED_REPEAT, + clamp_to_edge = GL_CLAMP_TO_EDGE, + clamp_to_border = GL_CLAMP_TO_BORDER, + mirror_clamp = GL_MIRROR_CLAMP_EXT, + mirror_clamp_to_edge = GL_MIRROR_CLAMP_TO_EDGE, + mirror_clamp_to_border = GL_MIRROR_CLAMP_TO_BORDER_EXT + }; + + enum class compare_mode + { + none = GL_NONE, + ref_to_texture = GL_COMPARE_REF_TO_TEXTURE + }; + + enum class compare_func + { + never = GL_NEVER, + less = GL_LESS, + equal = GL_EQUAL, + lequal = GL_LEQUAL, + greater = GL_GREATER, + notequal = GL_NOTEQUAL, + gequal = GL_GEQUAL, + always = GL_ALWAYS + }; + + enum class target + { + texture1D = GL_TEXTURE_1D, + texture2D = GL_TEXTURE_2D, + texture3D = GL_TEXTURE_3D + }; + + enum class channel_type + { + none = GL_NONE, + signed_normalized = GL_SIGNED_NORMALIZED, + unsigned_normalized = GL_UNSIGNED_NORMALIZED, + float_ = GL_FLOAT, + int_ = GL_INT, + uint_ = GL_UNSIGNED_INT + }; + + enum class channel_name + { + red = GL_TEXTURE_RED_TYPE, + green = GL_TEXTURE_GREEN_TYPE, + blue = GL_TEXTURE_BLUE_TYPE, + alpha = GL_TEXTURE_ALPHA_TYPE, + depth = GL_TEXTURE_DEPTH_TYPE + }; + + class save_binding_state + { + GLint m_last_binding; + GLenum m_target; + + public: + save_binding_state(const texture& new_binding) noexcept + { + GLenum pname; + switch (new_binding.get_target()) + { + case target::texture1D: pname = GL_TEXTURE_1D_BINDING_EXT; break; + case target::texture2D: pname = GL_TEXTURE_2D_BINDING_EXT; break; + case target::texture3D: pname = GL_TEXTURE_3D_BINDING_EXT; break; + } + + glGetIntegerv(pname, &m_last_binding); + + new_binding.bind(); + m_target = (GLenum)new_binding.get_target(); + } + + ~save_binding_state() noexcept + { + glBindTexture(m_target, m_last_binding); + } + }; + + class settings; + + private: + target m_target = target::texture2D; + + public: + target get_target() const noexcept + { + return m_target; + } + + void set_target(target target) noexcept + { + m_target = target; + } + + static bool compressed_format(internal_format format_) noexcept + { + switch (format_) + { + case internal_format::compressed_rgb_s3tc_dxt1: + case internal_format::compressed_rgba_s3tc_dxt1: + case internal_format::compressed_rgba_s3tc_dxt3: + case internal_format::compressed_rgba_s3tc_dxt5: + return true; + } + + return false; + } + + uint id() const noexcept + { + return m_id; + } + + uint level() const noexcept + { + return m_level; + } + + void recreate() noexcept + { + if (created()) + remove(); + + create(); + } + + void recreate(target target_) noexcept + { + if (created()) + remove(); + + create(target_); + } + + void create() noexcept + { + glGenTextures(1, &m_id); + } + + void create(target target_) noexcept + { + set_target(target_); + create(); + } + + bool created() const noexcept + { + return m_id != 0; + } + + void remove() noexcept + { + glDeleteTextures(1, &m_id); + m_id = 0; + } + + void set_id(GLuint id) noexcept + { + m_id = id; + } + + void set_level(int level) noexcept + { + m_level = level; + } + + texture_view with_level(int level); + + explicit operator bool() const noexcept + { + return created(); + } + + void bind() const noexcept + { + glBindTexture((GLenum)get_target(), id()); + } + + settings config(); + + void config(const settings& settings_); + + class pixel_pack_settings& pixel_pack_settings() + { + return m_pixel_pack_settings; + } + + const class pixel_pack_settings& pixel_pack_settings() const + { + return m_pixel_pack_settings; + } + + class pixel_unpack_settings& pixel_unpack_settings() + { + return m_pixel_unpack_settings; + } + + const class pixel_unpack_settings& pixel_unpack_settings() const + { + return m_pixel_unpack_settings; + } + + int width() const + { + save_binding_state save(*this); + GLint result; + glGetTexLevelParameteriv((GLenum)get_target(), level(), GL_TEXTURE_WIDTH, &result); + return (int)result; + } + + int height() const + { + save_binding_state save(*this); + GLint result; + glGetTexLevelParameteriv((GLenum)get_target(), level(), GL_TEXTURE_HEIGHT, &result); + return (int)result; + } + + int depth() const + { + save_binding_state save(*this); + GLint result; + glGetTexLevelParameteriv((GLenum)get_target(), level(), GL_TEXTURE_DEPTH, &result); + return (int)result; + } + + sizei size() const + { + return{ width(), height() }; + } + + size3i size3d() const + { + return{ width(), height(), depth() }; + } + + texture::format get_internal_format() const + { + save_binding_state save(*this); + GLint result; + glGetTexLevelParameteriv((GLenum)get_target(), level(), GL_TEXTURE_INTERNAL_FORMAT, &result); + return (texture::format)result; + } + + texture::channel_type get_channel_type(texture::channel_name channel) const + { + save_binding_state save(*this); + GLint result; + glGetTexLevelParameteriv((GLenum)get_target(), level(), (GLenum)channel, &result); + return (texture::channel_type)result; + } + + int get_channel_count() const + { + int result = 0; + + if (get_channel_type(channel_name::red) != channel_type::none) + result++; + if (get_channel_type(channel_name::green) != channel_type::none) + result++; + if (get_channel_type(channel_name::blue) != channel_type::none) + result++; + if (get_channel_type(channel_name::alpha) != channel_type::none) + result++; + if (get_channel_type(channel_name::depth) != channel_type::none) + result++; + + return result; + } + + bool compressed() const + { + save_binding_state save(*this); + GLint result; + glGetTexLevelParameteriv((GLenum)get_target(), level(), GL_TEXTURE_COMPRESSED, &result); + return result != 0; + } + + int compressed_size() const + { + save_binding_state save(*this); + GLint result; + glGetTexLevelParameteriv((GLenum)get_target(), level(), GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &result); + return (int)result; + } + + texture() = default; + texture(texture&) = delete; + + texture(texture&& texture_) + { + swap(texture_); + } + texture(target target_, GLuint id = 0) + { + m_target = target_; + set_id(id); + } + + ~texture() + { + if (created()) + remove(); + } + + void swap(texture& texture_) + { + auto my_old_id = id(); + auto my_old_target = get_target(); + set_id(texture_.id()); + set_target(texture_.get_target()); + texture_.set_id(my_old_id); + texture_.set_target(my_old_target); + } + + texture& operator = (const texture& rhs) = delete; + texture& operator = (texture&& rhs) + { + swap(rhs); + return *this; + } + + void copy_from(const void* src, texture::format format, texture::type type, class pixel_unpack_settings pixel_settings) + { + save_binding_state save(*this); + pixel_settings.apply(); + glTexSubImage2D((GLenum)get_target(), level(), 0, 0, width(), height(), (GLenum)format, (GLenum)type, src); + } + + void copy_from(const buffer& buf, texture::format format, texture::type type, class pixel_unpack_settings pixel_settings) + { + buffer::save_binding_state save_buffer(buffer::target::pixel_unpack, buf); + copy_from(nullptr, format, type, pixel_settings); + } + + void copy_from(void* dst, texture::format format, texture::type type) + { + copy_from(dst, format, type, pixel_unpack_settings()); + } + + void copy_from(const buffer& buf, texture::format format, texture::type type) + { + copy_from(buf, format, type, pixel_unpack_settings()); + } + + void copy_to(void* dst, texture::format format, texture::type type, class pixel_pack_settings pixel_settings) const + { + save_binding_state save(*this); + pixel_settings.apply(); + glGetTexImage((GLenum)get_target(), level(), (GLenum)format, (GLenum)type, dst); + } + + void copy_to(void* dst, texture::type type, class pixel_pack_settings pixel_settings) const + { + copy_to(dst, get_internal_format(), type, pixel_settings); + } + + void copy_to(const buffer& buf, texture::format format, texture::type type, class pixel_pack_settings pixel_settings) const + { + buffer::save_binding_state save_buffer(buffer::target::pixel_pack, buf); + copy_to(nullptr, format, type, pixel_settings); + } + + void copy_to(const buffer& buf, texture::type type, class pixel_pack_settings pixel_settings) const + { + buffer::save_binding_state save_buffer(buffer::target::pixel_pack, buf); + copy_to(nullptr, get_internal_format(), type, pixel_settings); + } + + void copy_to(void* dst, texture::format format, texture::type type) const + { + copy_to(dst, format, type, pixel_pack_settings()); + } + + void copy_to(void* dst, texture::type type) const + { + copy_to(dst, get_internal_format(), type, pixel_pack_settings()); + } + + void copy_to(const buffer& buf, texture::format format, texture::type type) const + { + copy_to(buf, format, type, pixel_pack_settings()); + } + + void copy_to(const buffer& buf, texture::type type) const + { + copy_to(buf, get_internal_format(), type, pixel_pack_settings()); + } + }; + + class rbo + { + GLuint m_id = 0; + + public: + rbo() = default; + + rbo(GLuint id) + { + set_id(id); + } + + ~rbo() + { + if (created()) + remove(); + } + + class save_binding_state + { + GLint m_old_value; + + public: + save_binding_state(const rbo& new_state) + { + glGetIntegerv(GL_RENDERBUFFER_BINDING, &m_old_value); + new_state.bind(); + } + + ~save_binding_state() + { + glBindRenderbuffer(GL_RENDERBUFFER, m_old_value); + } + }; + + void recreate() + { + if (created()) + remove(); + + create(); + } + + void recreate(texture::format format, u32 width, u32 height) + { + if (created()) + remove(); + + create(format, width, height); + } + + void create() + { + glGenRenderbuffers(1, &m_id); + } + + void create(texture::format format, u32 width, u32 height) + { + create(); + storage(format, width, height); + } + + void bind() const + { + glBindRenderbuffer(GL_RENDERBUFFER, m_id); + } + + void storage(texture::format format, u32 width, u32 height) + { + save_binding_state save(*this); + glRenderbufferStorage(GL_RENDERBUFFER, (GLenum)format, width, height); + } + + void remove() + { + glDeleteRenderbuffers(1, &m_id); + m_id = 0; + } + + uint id() const + { + return m_id; + } + + void set_id(uint id) + { + m_id = id; + } + + bool created() const + { + return m_id != 0; + } + + explicit operator bool() const + { + return created(); + } + }; + + class texture::settings + { + texture *m_parent; + + texture::channel m_swizzle_r = texture::channel::r; + texture::channel m_swizzle_g = texture::channel::g; + texture::channel m_swizzle_b = texture::channel::b; + texture::channel m_swizzle_a = texture::channel::a; + + texture::format m_format = texture::format::rgba; + texture::internal_format m_internal_format = texture::internal_format::rgba; + texture::type m_type = texture::type::ubyte; + + gl::min_filter m_min_filter = gl::min_filter::nearest; + gl::filter m_mag_filter = gl::filter::nearest; + + uint m_width = 0; + uint m_height = 0; + int m_level = 0; + + int m_compressed_image_size = 0; + + const void* m_pixels = nullptr; + float m_aniso = 1.f; + texture::compare_mode m_compare_mode = texture::compare_mode::none; + texture::compare_func m_compare_func = texture::compare_func::greater; + + texture::wrap m_wrap_s = texture::wrap::repeat; + texture::wrap m_wrap_t = texture::wrap::repeat; + texture::wrap m_wrap_r = texture::wrap::repeat; + + float m_max_lod = 1000.f; + float m_min_lod = -1000.f; + float m_lod = 0.f; + int m_max_level = 1000; + bool m_generate_mipmap = false; + + color4f m_border_color; + + public: + settings(texture *parent = nullptr) : m_parent(parent) + { + } + + ~settings() + { + apply(); + } + + void apply(const texture &texture) const; + void apply(); + + settings& swizzle( + texture::channel r = texture::channel::r, + texture::channel g = texture::channel::g, + texture::channel b = texture::channel::b, + texture::channel a = texture::channel::a); + + settings& format(texture::format format); + settings& type(texture::type type); + settings& internal_format(texture::internal_format format); + settings& filter(min_filter min_filter, filter mag_filter); + settings& width(uint width); + settings& height(uint height); + settings& size(sizei size); + settings& level(int value); + settings& compressed_image_size(int size); + settings& pixels(const void* pixels); + settings& aniso(float value); + settings& compare_mode(texture::compare_mode value); + settings& compare_func(texture::compare_func value); + settings& compare(texture::compare_func func, texture::compare_mode mode); + + settings& wrap_s(texture::wrap value); + settings& wrap_t(texture::wrap value); + settings& wrap_r(texture::wrap value); + settings& wrap(texture::wrap s, texture::wrap t, texture::wrap r); + + settings& max_lod(float value); + settings& min_lod(float value); + settings& lod(float value); + settings& max_level(int value); + settings& generate_mipmap(bool value); + settings& mipmap(int level, int max_level, float lod, float min_lod, float max_lod, bool generate); + + settings& border_color(color4f value); + }; + + enum class draw_mode + { + points = GL_POINTS, + lines = GL_LINES, + line_loop = GL_LINE_LOOP, + line_strip = GL_LINE_STRIP, + triangles = GL_TRIANGLES, + triangle_strip = GL_TRIANGLE_STRIP, + triangle_fan = GL_TRIANGLE_FAN, + quads = GL_QUADS, + quad_strip = GL_QUAD_STRIP, + polygone = GL_POLYGON + }; + + enum class indices_type + { + ubyte = GL_UNSIGNED_BYTE, + ushort = GL_UNSIGNED_SHORT, + uint = GL_UNSIGNED_INT + }; + + class fbo + { + GLuint m_id = GL_NONE; + + public: + fbo() = default; + + fbo(GLuint id) + { + set_id(id); + } + + ~fbo() + { + if (created()) + remove(); + } + + class save_binding_state + { + GLint m_last_binding; + + public: + save_binding_state(const fbo& new_binding) + { + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_last_binding); + new_binding.bind(); + } + + ~save_binding_state() + { + glBindFramebuffer(GL_FRAMEBUFFER, m_last_binding); + } + }; + + class attachment + { + public: + enum class type + { + color = GL_COLOR_ATTACHMENT0, + depth = GL_DEPTH_ATTACHMENT, + stencil = GL_STENCIL_ATTACHMENT, + depth_stencil = GL_DEPTH_STENCIL_ATTACHMENT + }; + + protected: + GLuint m_id; + fbo &m_parent; + + public: + attachment(fbo& parent, type type) + : m_id((int)type) + , m_parent(parent) + { + } + + void set_id(uint id) + { + m_id = id; + } + + uint id() const + { + return m_id; + } + + void operator = (const rbo& rhs) + { + save_binding_state save(m_parent); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, m_id, GL_RENDERBUFFER, rhs.id()); + } + + void operator = (const texture& rhs) + { + save_binding_state save(m_parent); + + switch (rhs.get_target()) + { + case texture::target::texture1D: glFramebufferTexture1D(GL_FRAMEBUFFER, m_id, GL_TEXTURE_1D, rhs.id(), rhs.level()); break; + case texture::target::texture2D: glFramebufferTexture2D(GL_FRAMEBUFFER, m_id, GL_TEXTURE_2D, rhs.id(), rhs.level()); break; + case texture::target::texture3D: glFramebufferTexture3D(GL_FRAMEBUFFER, m_id, GL_TEXTURE_3D, rhs.id(), rhs.level(), 0); break; + } + } + }; + + class indexed_attachment : public attachment + { + public: + indexed_attachment(fbo& parent, type type) : attachment(parent, type) + { + } + + attachment operator[](int index) const + { + return{ m_parent, type(id() + index) }; + } + + std::vector range(int from, int count) const + { + std::vector result; + + for (int i = from; i < from + count; ++i) + result.push_back((*this)[i]); + + return result; + } + + using attachment::operator =; + }; + + indexed_attachment color{ *this, attachment::type::color }; + attachment depth{ *this, attachment::type::depth }; + attachment stencil{ *this, attachment::type::stencil }; + attachment depth_stencil{ *this, attachment::type::depth_stencil }; + + enum class target + { + read_frame_buffer = GL_READ_FRAMEBUFFER, + draw_frame_buffer = GL_DRAW_FRAMEBUFFER + }; + + void create(); + void bind() const; + void blit(const fbo& dst, areai src_area, areai dst_area, buffers buffers_ = buffers::color, filter filter_ = filter::nearest) const; + void bind_as(target target_) const; + void remove(); + bool created() const; + void check() const; + + void recreate(); + void draw_buffer(const attachment& buffer) const; + void draw_buffers(const std::initializer_list& indexes) const; + + void draw_arrays(draw_mode mode, GLsizei count, GLint first = 0) const; + void draw_arrays(const buffer& buffer, draw_mode mode, GLsizei count, GLint first = 0) const; + void draw_arrays(const vao& buffer, draw_mode mode, GLsizei count, GLint first = 0) const; + + void draw_elements(draw_mode mode, GLsizei count, indices_type type, const GLvoid *indices) const; + void draw_elements(const buffer& buffer, draw_mode mode, GLsizei count, indices_type type, const GLvoid *indices) const; + void draw_elements(draw_mode mode, GLsizei count, indices_type type, const buffer& indices, size_t indices_buffer_offset = 0) const; + void draw_elements(const buffer& buffer_, draw_mode mode, GLsizei count, indices_type type, const buffer& indices, size_t indices_buffer_offset = 0) const; + void draw_elements(draw_mode mode, GLsizei count, const GLubyte *indices) const; + void draw_elements(const buffer& buffer, draw_mode mode, GLsizei count, const GLubyte *indices) const; + void draw_elements(draw_mode mode, GLsizei count, const GLushort *indices) const; + void draw_elements(const buffer& buffer, draw_mode mode, GLsizei count, const GLushort *indices) const; + void draw_elements(draw_mode mode, GLsizei count, const GLuint *indices) const; + void draw_elements(const buffer& buffer, draw_mode mode, GLsizei count, const GLuint *indices) const; + + void clear(buffers buffers_) const; + void clear(buffers buffers_, color4f color_value, double depth_value, u8 stencil_value) const; + + void copy_from(const void* pixels, sizei size, gl::texture::format format_, gl::texture::type type_, class pixel_unpack_settings pixel_settings = pixel_unpack_settings()) const; + void copy_from(const buffer& buf, sizei size, gl::texture::format format_, gl::texture::type type_, class pixel_unpack_settings pixel_settings = pixel_unpack_settings()) const; + + void copy_to(void* pixels, coordi coord, gl::texture::format format_, gl::texture::type type_, class pixel_pack_settings pixel_settings = pixel_pack_settings()) const; + void copy_to(const buffer& buf, coordi coord, gl::texture::format format_, gl::texture::type type_, class pixel_pack_settings pixel_settings = pixel_pack_settings()) const; + + static fbo get_binded_draw_buffer(); + static fbo get_binded_read_buffer(); + static fbo get_binded_buffer(); + + GLuint id() const; + void set_id(GLuint id); + + explicit operator bool() const + { + return created(); + } + }; + + extern const fbo screen; + + namespace glsl + { + class compilation_exception : public exception + { + public: + explicit compilation_exception(const std::string& what_arg) + { + m_what = "compilation failed: '" + what_arg + "'"; + } + }; + + class link_exception : public exception + { + public: + explicit link_exception(const std::string& what_arg) + { + m_what = "linkage failed: '" + what_arg + "'"; + } + }; + + class validation_exception : public exception + { + public: + explicit validation_exception(const std::string& what_arg) + { + m_what = "compilation failed: '" + what_arg + "'"; + } + }; + + class not_found_exception : public exception + { + public: + explicit not_found_exception(const std::string& what_arg) + { + m_what = what_arg + " not found."; + } + }; + + class shader + { + GLuint m_id = GL_NONE; + + public: + enum class type + { + fragment = GL_FRAGMENT_SHADER, + vertex = GL_VERTEX_SHADER, + geometry = GL_GEOMETRY_SHADER + }; + + shader() = default; + + shader(GLuint id) + { + set_id(id); + } + + shader(type type_) + { + create(type_); + } + + shader(type type_, const std::string& src) + { + create(type_); + source(src); + } + + ~shader() + { + if (created()) + remove(); + } + + void recreate(type type_) + { + if (created()) + remove(); + + create(type_); + } + + void create(type type_) + { + m_id = glCreateShader((GLenum)type_); + } + + void source(const std::string& src) const + { + const char* str = src.c_str(); + const GLint length = (GLint)src.length(); + + glShaderSource(m_id, 1, &str, &length); + } + + shader& compile() + { + glCompileShader(m_id); + + GLint status = GL_FALSE; + glGetShaderiv(m_id, GL_COMPILE_STATUS, &status); + + if (status == GL_FALSE) + { + GLint length = 0; + glGetShaderiv(m_id, GL_INFO_LOG_LENGTH, &length); + + std::string error_msg; + if (length) + { + std::unique_ptr buf(new char[length + 1]); + glGetShaderInfoLog(m_id, length, nullptr, buf.get()); + error_msg = buf.get(); + } + + throw compilation_exception(error_msg); + } + + return *this; + } + + void remove() + { + glDeleteShader(m_id); + m_id = 0; + } + + uint id() const + { + return m_id; + } + + void set_id(uint id) + { + m_id = id; + } + + bool created() const + { + return m_id != 0; + } + + explicit operator bool() const + { + return created(); + } + }; + + class program + { + GLuint m_id = 0; + + public: + class uniform_t + { + program& m_program; + GLint m_location; + + public: + uniform_t(program& program, GLint location) + : m_program(program) + , m_location(location) + { + } + + GLint location() const + { + return m_location; + } + + void operator = (int rhs) const { m_program.use(); glUniform1i(location(), rhs); } + void operator = (float rhs) const { m_program.use(); glUniform1f(location(), rhs); } + //void operator = (double rhs) const { m_program.use(); glUniform1d(location(), rhs); } + + void operator = (const color1i& rhs) const { m_program.use(); glUniform1i(location(), rhs.r); } + void operator = (const color1f& rhs) const { m_program.use(); glUniform1f(location(), rhs.r); } + //void operator = (const color1d& rhs) const { m_program.use(); glUniform1d(location(), rhs.r); } + void operator = (const color2i& rhs) const { m_program.use(); glUniform2i(location(), rhs.r, rhs.g); } + void operator = (const color2f& rhs) const { m_program.use(); glUniform2f(location(), rhs.r, rhs.g); } + //void operator = (const color2d& rhs) const { m_program.use(); glUniform2d(location(), rhs.r, rhs.g); } + void operator = (const color3i& rhs) const { m_program.use(); glUniform3i(location(), rhs.r, rhs.g, rhs.b); } + void operator = (const color3f& rhs) const { m_program.use(); glUniform3f(location(), rhs.r, rhs.g, rhs.b); } + //void operator = (const color3d& rhs) const { m_program.use(); glUniform3d(location(), rhs.r, rhs.g, rhs.b); } + void operator = (const color4i& rhs) const { m_program.use(); glUniform4i(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + void operator = (const color4f& rhs) const { m_program.use(); glUniform4f(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + //void operator = (const color4d& rhs) const { m_program.use(); glUniform4d(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + + void operator = (const glm::ivec2& rhs) const { m_program.use(); glUniform2i(location(), rhs.r, rhs.g); } + void operator = (const glm::vec2& rhs) const { m_program.use(); glUniform2f(location(), rhs.r, rhs.g); } + //void operator = (const glm::dvec2& rhs) const { m_program.use(); glUniform2d(location(), rhs.r, rhs.g); } + void operator = (const glm::ivec3& rhs) const { m_program.use(); glUniform3i(location(), rhs.r, rhs.g, rhs.b); } + void operator = (const glm::vec3& rhs) const { m_program.use(); glUniform3f(location(), rhs.r, rhs.g, rhs.b); } + //void operator = (const glm::dvec3& rhs) const { m_program.use(); glUniform3d(location(), rhs.r, rhs.g, rhs.b); } + void operator = (const glm::ivec4& rhs) const { m_program.use(); glUniform4i(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + void operator = (const glm::vec4& rhs) const { m_program.use(); glUniform4f(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + //void operator = (const glm::dvec4& rhs) const { m_program.use(); glUniform4d(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + + void operator = (const glm::mat2& rhs) const { m_program.use(); glUniformMatrix2fv(location(), 1, GL_FALSE, glm::value_ptr(rhs)); } + //void operator = (const glm::dmat2& rhs) const { m_program.use(); glUniformMatrix2dv(location(), 1, GL_FALSE, glm::value_ptr(rhs)); } + void operator = (const glm::mat3& rhs) const { m_program.use(); glUniformMatrix3fv(location(), 1, GL_FALSE, glm::value_ptr(rhs)); } + //void operator = (const glm::dmat3& rhs) const { m_program.use(); glUniformMatrix3dv(location(), 1, GL_FALSE, glm::value_ptr(rhs)); } + void operator = (const glm::mat4& rhs) const { m_program.use(); glUniformMatrix4fv(location(), 1, GL_FALSE, glm::value_ptr(rhs)); } + //void operator = (const glm::dmat4& rhs) const { m_program.use(); glUniformMatrix4dv(location(), 1, GL_FALSE, glm::value_ptr(rhs)); } + }; + + class attrib_t + { + GLuint m_program; + GLint m_location; + + public: + attrib_t(GLuint program, GLint location) + : m_program(program) + , m_location(location) + { + } + + GLint location() const + { + return m_location; + } + + void operator = (float rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib1f(location(), rhs); } + void operator = (double rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib1d(location(), rhs); } + + void operator = (const color1f& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib1f(location(), rhs.r); } + void operator = (const color1d& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib1d(location(), rhs.r); } + void operator = (const color2f& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib2f(location(), rhs.r, rhs.g); } + void operator = (const color2d& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib2d(location(), rhs.r, rhs.g); } + void operator = (const color3f& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib3f(location(), rhs.r, rhs.g, rhs.b); } + void operator = (const color3d& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib3d(location(), rhs.r, rhs.g, rhs.b); } + void operator = (const color4f& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib4f(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + void operator = (const color4d& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib4d(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + + void operator = (const glm::vec2& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib2f(location(), rhs.r, rhs.g); } + void operator = (const glm::dvec2& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib2d(location(), rhs.r, rhs.g); } + void operator = (const glm::vec3& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib3f(location(), rhs.r, rhs.g, rhs.b); } + void operator = (const glm::dvec3& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib3d(location(), rhs.r, rhs.g, rhs.b); } + void operator = (const glm::vec4& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib4f(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + void operator = (const glm::dvec4& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib4d(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + + void operator =(buffer_pointer& pointer) const + { + pointer.get_vao().enable_for_attribute(location()); + glVertexAttribPointer(location(), pointer.size(), (GLenum)pointer.get_type(), pointer.normalize(), + pointer.stride(), (const void*)(size_t)pointer.offset()); + } + }; + + class uniforms_t + { + program& m_program; + std::unordered_map locations; + int active_texture = 0; + + public: + uniforms_t(program* program) : m_program(*program) + { + } + + void clear() + { + locations.clear(); + active_texture = 0; + } + + GLint location(const std::string &name) + { + auto finded = locations.find(name); + + if (finded != locations.end()) + { + return finded->second; + } + + int result = glGetUniformLocation(m_program.id(), name.c_str()); + + if (result < 0) + throw not_found_exception(name); + + locations[name] = result; + + return result; + } + + int texture(const std::string &name, int active_texture, const gl::texture& texture) + { + glActiveTexture(GL_TEXTURE0 + active_texture); + texture.bind(); + (*this)[name] = active_texture; + + return active_texture; + } + + int texture(const std::string &name, const gl::texture& tex) + { + int atex; + auto finded = locations.find(name); + + if (finded != locations.end()) + { + atex = finded->second; + } + else + { + atex = active_texture++; + } + + return texture(name, atex, tex); + } + + uniform_t operator[](GLint location) + { + return{ m_program, location }; + } + + uniform_t operator[](const std::string &name) + { + return{ m_program, location(name) }; + } + + void swap(uniforms_t& uniforms) + { + locations.swap(uniforms.locations); + std::swap(active_texture, uniforms.active_texture); + } + } uniforms{ this }; + + class attribs_t + { + program& m_program; + std::unordered_map m_locations; + + public: + attribs_t(program* program) : m_program(*program) + { + } + + GLint location(const std::string &name) + { + auto finded = m_locations.find(name); + + if (finded != m_locations.end()) + { + return finded->second; + } + + int result = glGetAttribLocation(m_program.id(), name.c_str()); + + if (result < 0) + throw not_found_exception(name); + + m_locations[name] = result; + + return result; + } + + attrib_t operator[](GLint location) + { + return{ m_program.id(), location }; + } + + attrib_t operator[](const std::string &name) + { + return{ m_program.id(), location(name) }; + } + + void swap(attribs_t& attribs) + { + m_locations.swap(attribs.m_locations); + } + } attribs{ this }; + + program& recreate() + { + if (created()) + remove(); + + return create(); + } + + program& create() + { + m_id = glCreateProgram(); + return *this; + } + + void remove() + { + glDeleteProgram(m_id); + m_id = 0; + uniforms.clear(); + } + + static program get_current_program() + { + GLint id; + glGetIntegerv(GL_CURRENT_PROGRAM, &id); + return{ (GLuint)id }; + } + + void use() + { + glUseProgram(m_id); + } + + void link() + { + glLinkProgram(m_id); + + GLint status = GL_FALSE; + glGetProgramiv(m_id, GL_LINK_STATUS, &status); + + if (status == GL_FALSE) + { + GLint length = 0; + glGetProgramiv(m_id, GL_INFO_LOG_LENGTH, &length); + + std::string error_msg; + if (length) + { + std::unique_ptr buf(new char[length + 1]); + glGetProgramInfoLog(m_id, length, nullptr, buf.get()); + error_msg = buf.get(); + } + + throw link_exception(error_msg); + } + } + + void validate() + { + glValidateProgram(m_id); + + GLint status = GL_FALSE; + glGetProgramiv(m_id, GL_VALIDATE_STATUS, &status); + + if (status == GL_FALSE) + { + GLint length = 0; + glGetProgramiv(m_id, GL_INFO_LOG_LENGTH, &length); + + std::string error_msg; + if (length) + { + std::unique_ptr buf(new char[length + 1]); + glGetProgramInfoLog(m_id, length, nullptr, buf.get()); + error_msg = buf.get(); + } + + throw validation_exception(error_msg); + } + } + + void make() + { + link(); + validate(); + } + + uint id() const + { + return m_id; + } + + void set_id(uint id) + { + uniforms.clear(); + m_id = id; + } + + bool created() const + { + return m_id != 0; + } + + explicit operator bool() const + { + return created(); + } + + program& attach(const shader& shader_) + { + glAttachShader(m_id, shader_.id()); + return *this; + } + + program& bind_attribute_location(const std::string& name, int index) + { + glBindAttribLocation(m_id, index, name.c_str()); + return *this; + } + + program& bind_fragment_data_location(const std::string& name, int color_number) + { + glBindFragDataLocation(m_id, color_number, name.c_str()); + return *this; + } + + int attribute_location(const std::string& name) + { + return glGetAttribLocation(m_id, name.c_str()); + } + + int uniform_location(const std::string& name) + { + return glGetUniformLocation(m_id, name.c_str()); + } + + program& operator += (const shader& rhs) + { + return attach(rhs); + } + + program& operator += (std::initializer_list shaders) + { + for (auto &shader : shaders) + *this += shader; + return *this; + } + + program() = default; + program(program&) = delete; + program(program&& program_) + { + swap(program_); + } + + program(GLuint id) + { + set_id(id); + } + + ~program() + { + if (created()) + remove(); + } + + void swap(program& program_) + { + auto my_old_id = id(); + set_id(program_.id()); + program_.set_id(my_old_id); + uniforms.swap(program_.uniforms); + attribs.swap(program_.attribs); + } + + program& operator = (const program& rhs) = delete; + program& operator = (program&& rhs) + { + swap(rhs); + return *this; + } + }; + + class shader_view : public shader + { + public: + shader_view(GLuint id) : shader(id) + { + } + + ~shader_view() + { + set_id(0); + } + }; + + class program_view : public program + { + public: + program_view(GLuint id) : program(id) + { + } + + ~program_view() + { + set_id(0); + } + }; + } + + class texture_view : public texture + { + public: + texture_view(texture::target target_, GLuint id) : texture(target_, id) + { + } + + ~texture_view() + { + set_id(0); + } + }; + + class fbo_view : public fbo + { + public: + fbo_view(GLuint id) : fbo(id) + { + } + + ~fbo_view() + { + set_id(0); + } + }; + + class rbo_view : public rbo + { + public: + rbo_view(GLuint id) : rbo(id) + { + } + + ~rbo_view() + { + set_id(0); + } + }; + + class buffer_view : public buffer + { + public: + buffer_view(GLuint id) : buffer(id) + { + } + + ~buffer_view() + { + set_id(0); + } + }; +} \ No newline at end of file diff --git a/rpcs3/Emu/RSX/GSManager.cpp b/rpcs3/Emu/RSX/GSManager.cpp index cbddef535a..592ead2c2d 100644 --- a/rpcs3/Emu/RSX/GSManager.cpp +++ b/rpcs3/Emu/RSX/GSManager.cpp @@ -48,7 +48,7 @@ void GSManager::Close() { if(m_render) { - m_render->Close(); + m_render->close(); delete m_render; m_render = nullptr; } diff --git a/rpcs3/Emu/RSX/GSRender.cpp b/rpcs3/Emu/RSX/GSRender.cpp index cebc2d08a8..93d3e6f1c4 100644 --- a/rpcs3/Emu/RSX/GSRender.cpp +++ b/rpcs3/Emu/RSX/GSRender.cpp @@ -5,26 +5,8 @@ #include "GSManager.h" #include "GSRender.h" -GSLock::GSLock(GSRender& renderer, GSLockType type) - : m_renderer(renderer) - , m_type(type) -{ - switch (m_type) - { - case GS_LOCK_NOT_WAIT: m_renderer.m_cs_main.lock(); break; - case GS_LOCK_WAIT_FLIP: m_renderer.m_sem_flip.wait(); break; - } -} -GSLock::~GSLock() -{ - switch (m_type) - { - case GS_LOCK_NOT_WAIT: m_renderer.m_cs_main.unlock(); break; - case GS_LOCK_WAIT_FLIP: m_renderer.m_sem_flip.try_post(); break; - } -} - -GSLockCurrent::GSLockCurrent(GSLockType type) : GSLock(Emu.GetGSManager().GetRender(), type) +draw_context_t GSFrameBase::new_context() { + return std::shared_ptr(make_context(), [this](void* ctxt) { delete_context(ctxt); }); } diff --git a/rpcs3/Emu/RSX/GSRender.h b/rpcs3/Emu/RSX/GSRender.h index 0aae3944df..84f5a7557c 100644 --- a/rpcs3/Emu/RSX/GSRender.h +++ b/rpcs3/Emu/RSX/GSRender.h @@ -1,34 +1,33 @@ #pragma once #include "Emu/RSX/RSXThread.h" +#include -struct GSRender : public RSXThread +using draw_context_t = std::shared_ptr; + +class GSFrameBase { - virtual ~GSRender() override - { - } - - virtual void Close()=0; -}; - -enum GSLockType -{ - GS_LOCK_NOT_WAIT, - GS_LOCK_WAIT_FLIP, -}; - -struct GSLock -{ -private: - GSRender& m_renderer; - GSLockType m_type; - public: - GSLock(GSRender& renderer, GSLockType type); + GSFrameBase() = default; + GSFrameBase(const GSFrameBase&) = delete; - ~GSLock(); + virtual void close() = 0; + virtual bool shown() = 0; + virtual void hide() = 0; + virtual void show() = 0; + + draw_context_t new_context(); + + virtual void set_current(draw_context_t ctx) = 0; + virtual void flip(draw_context_t ctx) = 0; + virtual size2i client_size() = 0; + +protected: + virtual void delete_context(void* ctx) = 0; + virtual void* make_context() = 0; }; -struct GSLockCurrent : GSLock +struct GSRender : public rsx::thread { - GSLockCurrent(GSLockType type); -}; \ No newline at end of file + virtual ~GSRender() = default; + virtual void close()=0; +}; diff --git a/rpcs3/Emu/RSX/Null/NullGSRender.h b/rpcs3/Emu/RSX/Null/NullGSRender.h index d25815fd50..53b130eb2c 100644 --- a/rpcs3/Emu/RSX/Null/NullGSRender.h +++ b/rpcs3/Emu/RSX/Null/NullGSRender.h @@ -3,67 +3,29 @@ class NullGSRender final : public GSRender { -public: - - NullGSRender() - { - } - - virtual ~NullGSRender() override - { - } - private: - virtual void OnInit() override + void oninit() override { } - virtual void OnInitThread() override + void oninit_thread() override { } - virtual void OnExitThread() override + void onexit_thread() override { } - virtual void OnReset() override + bool domethod(u32 cmd, u32 value) override + { + return false; + } + + void flip(int buffer) override { } - virtual void Clear(u32 cmd) override + void close() override { } - - virtual void Draw() override - { - } - - virtual void Flip() override - { - } - - virtual void Close() override - { - if (joinable()) - { - join(); - } - } - - virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) override - { - } - - virtual void semaphorePGRAPHBackendRelease(u32 offset, u32 value) override - { - } - - virtual void semaphorePFIFOAcquire(u32 offset, u32 value) override - { - } - - virtual void notifyProgramChange() override {} - virtual void notifyBlendStateChange() override {} - virtual void notifyDepthStencilStateChange() override {} - virtual void notifyRasterizerStateChange() override {} }; diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index ba07dfd5a3..066ac3b363 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -3,413 +3,416 @@ #include "RSXThread.h" #include "RSXTexture.h" -RSXTexture::RSXTexture() -{ - m_index = 0; -} - -RSXTexture::RSXTexture(u8 index) -{ - m_index = index; -} - -void RSXTexture::Init() -{ - // Offset - methodRegisters[NV4097_SET_TEXTURE_OFFSET + (m_index*32)] = 0; - - // Format - methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] = 0; - - // Address - methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] = - ((/*wraps*/1) | ((/*anisoBias*/0) << 4) | ((/*wrapt*/1) << 8) | ((/*unsignedRemap*/0) << 12) | - ((/*wrapr*/3) << 16) | ((/*gamma*/0) << 20) |((/*signedRemap*/0) << 24) | ((/*zfunc*/0) << 28)); - - // Control0 - methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*32)] = - (((/*alphakill*/0) << 2) | (/*maxaniso*/0) << 4) | ((/*maxlod*/0xc00) << 7) | ((/*minlod*/0) << 19) | ((/*enable*/0) << 31); - - // Control1 - methodRegisters[NV4097_SET_TEXTURE_CONTROL1 + (m_index*32)] = 0xE4; - - // Filter - methodRegisters[NV4097_SET_TEXTURE_FILTER + (m_index*32)] = - ((/*bias*/0) | ((/*conv*/1) << 13) | ((/*min*/5) << 16) | ((/*mag*/2) << 24) - | ((/*as*/0) << 28) | ((/*rs*/0) << 29) | ((/*gs*/0) << 30) | ((/*bs*/0) << 31) ); - - // Image Rect - methodRegisters[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index*32)] = (/*height*/1) | ((/*width*/1) << 16); - - // Border Color - methodRegisters[NV4097_SET_TEXTURE_BORDER_COLOR + (m_index*32)] = 0; -} - -u32 RSXTexture::GetOffset() const -{ - return methodRegisters[NV4097_SET_TEXTURE_OFFSET + (m_index*32)]; -} - -u8 RSXTexture::GetLocation() const -{ - return (methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] & 0x3) - 1; -} - -bool RSXTexture::isCubemap() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] >> 2) & 0x1); -} - -u8 RSXTexture::GetBorderType() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] >> 3) & 0x1); -} - -u8 RSXTexture::GetDimension() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] >> 4) & 0xf); -} - -u8 RSXTexture::GetFormat() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] >> 8) & 0xff); -} - -u16 RSXTexture::GetMipmap() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] >> 16) & 0xffff); -} - -u8 RSXTexture::GetWrapS() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)]) & 0xf); -} - -u8 RSXTexture::GetWrapT() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 8) & 0xf); -} - -u8 RSXTexture::GetWrapR() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 16) & 0xf); -} - -u8 RSXTexture::GetUnsignedRemap() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 12) & 0xf); -} - -u8 RSXTexture::GetZfunc() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 28) & 0xf); -} - -u8 RSXTexture::GetGamma() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 20) & 0xf); -} - -u8 RSXTexture::GetAnisoBias() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 4) & 0xf); -} - -u8 RSXTexture::GetSignedRemap() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 24) & 0xf); -} - -bool RSXTexture::IsEnabled() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*32)] >> 31) & 0x1); -} - -u16 RSXTexture::GetMinLOD() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*32)] >> 19) & 0xfff); -} - -u16 RSXTexture::GetMaxLOD() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*32)] >> 7) & 0xfff); -} - -u8 RSXTexture::GetMaxAniso() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*32)] >> 4) & 0x7); -} - -bool RSXTexture::IsAlphaKillEnabled() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*32)] >> 2) & 0x1); -} - -u32 RSXTexture::GetRemap() const -{ - return (methodRegisters[NV4097_SET_TEXTURE_CONTROL1 + (m_index*32)]); -} - -u16 RSXTexture::GetBias() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_FILTER + (m_index*32)]) & 0x1fff); -} - -u8 RSXTexture::GetMinFilter() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_FILTER + (m_index*32)] >> 16) & 0x7); -} - -u8 RSXTexture::GetMagFilter() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_FILTER + (m_index*32)] >> 24) & 0x7); -} - -u8 RSXTexture::GetConvolutionFilter() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_FILTER + (m_index*32)] >> 13) & 0xf); -} - -bool RSXTexture::isASigned() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_FILTER + (m_index*32)] >> 28) & 0x1); -} - -bool RSXTexture::isRSigned() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_FILTER + (m_index*32)] >> 29) & 0x1); -} - -bool RSXTexture::isGSigned() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_FILTER + (m_index*32)] >> 30) & 0x1); -} - -bool RSXTexture::isBSigned() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_FILTER + (m_index*32)] >> 31) & 0x1); -} - -u16 RSXTexture::GetWidth() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index*32)] >> 16) & 0xffff); -} - -u16 RSXTexture::GetHeight() const -{ - return ((methodRegisters[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index*32)]) & 0xffff); -} - -u32 RSXTexture::GetBorderColor() const -{ - return methodRegisters[NV4097_SET_TEXTURE_BORDER_COLOR + (m_index*32)]; -} - -void RSXTexture::SetControl3(u16 depth, u32 pitch) -{ - m_depth = depth; - m_pitch = pitch; -} - -RSXVertexTexture::RSXVertexTexture() : RSXTexture() -{ -} - -RSXVertexTexture::RSXVertexTexture(u8 index) : RSXTexture(index) -{ -} - -void RSXVertexTexture::Init() -{ - // Offset - methodRegisters[NV4097_SET_VERTEX_TEXTURE_OFFSET + (m_index * 32)] = 0; - - // Format - methodRegisters[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 32)] = 0; - - // Address - methodRegisters[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 32)] = - ((/*wraps*/1) | ((/*anisoBias*/0) << 4) | ((/*wrapt*/1) << 8) | ((/*unsignedRemap*/0) << 12) | - ((/*wrapr*/3) << 16) | ((/*gamma*/0) << 20) | ((/*signedRemap*/0) << 24) | ((/*zfunc*/0) << 28)); - - // Control0 - methodRegisters[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 32)] = - (((/*alphakill*/0) << 2) | (/*maxaniso*/0) << 4) | ((/*maxlod*/0xc00) << 7) | ((/*minlod*/0) << 19) | ((/*enable*/0) << 31); - - // Control1 - //methodRegisters[NV4097_SET_VERTEX_TEXTURE_CONTROL1 + (m_index * 32)] = 0xE4; - - // Filter - methodRegisters[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 32)] = - ((/*bias*/0) | ((/*conv*/1) << 13) | ((/*min*/5) << 16) | ((/*mag*/2) << 24) - | ((/*as*/0) << 28) | ((/*rs*/0) << 29) | ((/*gs*/0) << 30) | ((/*bs*/0) << 31)); - - // Image Rect - methodRegisters[NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + (m_index * 32)] = (/*height*/1) | ((/*width*/1) << 16); - - // Border Color - methodRegisters[NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + (m_index * 32)] = 0; -} - -u32 RSXVertexTexture::GetOffset() const -{ - return methodRegisters[NV4097_SET_VERTEX_TEXTURE_OFFSET + (m_index * 32)]; -} - -u8 RSXVertexTexture::GetLocation() const -{ - return (methodRegisters[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 32)] & 0x3) - 1; -} - -bool RSXVertexTexture::isCubemap() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 32)] >> 2) & 0x1); -} - -u8 RSXVertexTexture::GetBorderType() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 32)] >> 3) & 0x1); -} - -u8 RSXVertexTexture::GetDimension() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 32)] >> 4) & 0xf); -} - -u8 RSXVertexTexture::GetFormat() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 32)] >> 8) & 0xff); -} - -u16 RSXVertexTexture::GetMipmap() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 32)] >> 16) & 0xffff); -} - -u8 RSXVertexTexture::GetWrapS() const -{ - return 1; - //return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 32)]) & 0xf); -} - -u8 RSXVertexTexture::GetWrapT() const -{ - return 1; - //return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 32)] >> 8) & 0xf); -} - -u8 RSXVertexTexture::GetWrapR() const -{ - return 1; - //return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 32)] >> 16) & 0xf); -} - -u8 RSXVertexTexture::GetUnsignedRemap() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 32)] >> 12) & 0xf); -} - -u8 RSXVertexTexture::GetZfunc() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 32)] >> 28) & 0xf); -} - -u8 RSXVertexTexture::GetGamma() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 32)] >> 20) & 0xf); -} - -u8 RSXVertexTexture::GetAnisoBias() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 32)] >> 4) & 0xf); -} - -u8 RSXVertexTexture::GetSignedRemap() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 32)] >> 24) & 0xf); -} - -bool RSXVertexTexture::IsEnabled() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 32)] >> 31) & 0x1); -} - -u16 RSXVertexTexture::GetMinLOD() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 32)] >> 19) & 0xfff); -} - -u16 RSXVertexTexture::GetMaxLOD() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 32)] >> 7) & 0xfff); -} - -u8 RSXVertexTexture::GetMaxAniso() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 32)] >> 4) & 0x7); -} - -bool RSXVertexTexture::IsAlphaKillEnabled() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 32)] >> 2) & 0x1); -} - -u32 RSXVertexTexture::GetRemap() const -{ - return 0 | (1 << 2) | (2 << 4) | (3 << 6);//(methodRegisters[NV4097_SET_VERTEX_TEXTURE_CONTROL1 + (m_index * 32)]); -} - -u16 RSXVertexTexture::GetBias() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 32)]) & 0x1fff); -} - -u8 RSXVertexTexture::GetMinFilter() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 32)] >> 16) & 0x7); -} - -u8 RSXVertexTexture::GetMagFilter() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 32)] >> 24) & 0x7); -} - -u8 RSXVertexTexture::GetConvolutionFilter() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 32)] >> 13) & 0xf); -} - -bool RSXVertexTexture::isASigned() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 32)] >> 28) & 0x1); -} - -bool RSXVertexTexture::isRSigned() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 32)] >> 29) & 0x1); -} - -bool RSXVertexTexture::isGSigned() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 32)] >> 30) & 0x1); -} - -bool RSXVertexTexture::isBSigned() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 32)] >> 31) & 0x1); -} - -u16 RSXVertexTexture::GetWidth() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + (m_index * 32)] >> 16) & 0xffff); -} - -u16 RSXVertexTexture::GetHeight() const -{ - return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + (m_index * 32)]) & 0xffff); -} - -u32 RSXVertexTexture::GetBorderColor() const -{ - return methodRegisters[NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + (m_index * 32)]; +namespace rsx +{ + void texture::init(u8 index) + { + m_index = index; + + // Offset + method_registers[NV4097_SET_TEXTURE_OFFSET + (m_index * 8)] = 0; + + // Format + method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] = 0; + + // Address + method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] = + ((/*wraps*/1) | ((/*anisoBias*/0) << 4) | ((/*wrapt*/1) << 8) | ((/*unsignedRemap*/0) << 12) | + ((/*wrapr*/3) << 16) | ((/*gamma*/0) << 20) | ((/*signedRemap*/0) << 24) | ((/*zfunc*/0) << 28)); + + // Control0 + method_registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] = + (((/*alphakill*/0) << 2) | (/*maxaniso*/0) << 4) | ((/*maxlod*/0xc00) << 7) | ((/*minlod*/0) << 19) | ((/*enable*/0) << 31); + + // Control1 + method_registers[NV4097_SET_TEXTURE_CONTROL1 + (m_index * 8)] = 0xE4; + + // Filter + method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] = + ((/*bias*/0) | ((/*conv*/1) << 13) | ((/*min*/5) << 16) | ((/*mag*/2) << 24) + | ((/*as*/0) << 28) | ((/*rs*/0) << 29) | ((/*gs*/0) << 30) | ((/*bs*/0) << 31)); + + // Image Rect + method_registers[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index * 8)] = (/*height*/1) | ((/*width*/1) << 16); + + // Border Color + method_registers[NV4097_SET_TEXTURE_BORDER_COLOR + (m_index * 8)] = 0; + } + + u32 texture::offset() const + { + return method_registers[NV4097_SET_TEXTURE_OFFSET + (m_index * 8)]; + } + + u8 texture::location() const + { + return (method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] & 0x3) - 1; + } + + bool texture::cubemap() const + { + return ((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 2) & 0x1); + } + + u8 texture::border_type() const + { + return ((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 3) & 0x1); + } + + u8 texture::dimension() const + { + return ((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 4) & 0xf); + } + + u8 texture::format() const + { + return ((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 8) & 0xff); + } + + u16 texture::mipmap() const + { + return ((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 16) & 0xffff); + } + + u8 texture::wrap_s() const + { + return ((method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)]) & 0xf); + } + + u8 texture::wrap_t() const + { + return ((method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 8) & 0xf); + } + + u8 texture::wrap_r() const + { + return ((method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 16) & 0xf); + } + + u8 texture::unsigned_remap() const + { + return ((method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 12) & 0xf); + } + + u8 texture::zfunc() const + { + return ((method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 28) & 0xf); + } + + u8 texture::gamma() const + { + return ((method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 20) & 0xf); + } + + u8 texture::aniso_bias() const + { + return ((method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 4) & 0xf); + } + + u8 texture::signed_remap() const + { + return ((method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 24) & 0xf); + } + + bool texture::enabled() const + { + return location() <= 1 && ((method_registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 31) & 0x1); + } + + u16 texture::min_lod() const + { + return ((method_registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 19) & 0xfff); + } + + u16 texture::max_lod() const + { + return ((method_registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 7) & 0xfff); + } + + u8 texture::max_aniso() const + { + return ((method_registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 4) & 0x7); + } + + bool texture::alpha_kill_enabled() const + { + return ((method_registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 2) & 0x1); + } + + u32 texture::remap() const + { + return (method_registers[NV4097_SET_TEXTURE_CONTROL1 + (m_index * 8)]); + } + + u16 texture::bias() const + { + return ((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)]) & 0x1fff); + } + + u8 texture::min_filter() const + { + return ((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 16) & 0x7); + } + + u8 texture::mag_filter() const + { + return ((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 24) & 0x7); + } + + u8 texture::convolution_filter() const + { + return ((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 13) & 0xf); + } + + bool texture::a_signed() const + { + return ((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 28) & 0x1); + } + + bool texture::r_signed() const + { + return ((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 29) & 0x1); + } + + bool texture::g_signed() const + { + return ((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 30) & 0x1); + } + + bool texture::b_signed() const + { + return ((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 31) & 0x1); + } + + u16 texture::width() const + { + return ((method_registers[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index * 8)] >> 16) & 0xffff); + } + + u16 texture::height() const + { + return ((method_registers[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index * 8)]) & 0xffff); + } + + u32 texture::border_color() const + { + return method_registers[NV4097_SET_TEXTURE_BORDER_COLOR + (m_index * 8)]; + } + + u16 texture::depth() const + { + return method_registers[NV4097_SET_TEXTURE_CONTROL3] >> 20; + } + + u32 texture::pitch() const + { + return method_registers[NV4097_SET_TEXTURE_CONTROL3] & 0xfffff; + } + + void vertex_texture::init(u8 index) + { + m_index = index; + + // Offset + method_registers[NV4097_SET_VERTEX_TEXTURE_OFFSET + (m_index * 8)] = 0; + + // Format + method_registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] = 0; + + // Address + method_registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] = + ((/*wraps*/1) | ((/*anisoBias*/0) << 4) | ((/*wrapt*/1) << 8) | ((/*unsignedRemap*/0) << 12) | + ((/*wrapr*/3) << 16) | ((/*gamma*/0) << 20) | ((/*signedRemap*/0) << 24) | ((/*zfunc*/0) << 28)); + + // Control0 + method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] = + (((/*alphakill*/0) << 2) | (/*maxaniso*/0) << 4) | ((/*maxlod*/0xc00) << 7) | ((/*minlod*/0) << 19) | ((/*enable*/0) << 31); + + // Control1 + //method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL1 + (m_index * 8)] = 0xE4; + + // Filter + method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] = + ((/*bias*/0) | ((/*conv*/1) << 13) | ((/*min*/5) << 16) | ((/*mag*/2) << 24) + | ((/*as*/0) << 28) | ((/*rs*/0) << 29) | ((/*gs*/0) << 30) | ((/*bs*/0) << 31)); + + // Image Rect + method_registers[NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + (m_index * 8)] = (/*height*/1) | ((/*width*/1) << 16); + + // Border Color + method_registers[NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + (m_index * 8)] = 0; + } + + u32 vertex_texture::offset() const + { + return method_registers[NV4097_SET_VERTEX_TEXTURE_OFFSET + (m_index * 8)]; + } + + u8 vertex_texture::location() const + { + return (method_registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] & 0x3) - 1; + } + + bool vertex_texture::cubemap() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 2) & 0x1); + } + + u8 vertex_texture::border_type() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 3) & 0x1); + } + + u8 vertex_texture::dimension() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 4) & 0xf); + } + + u8 vertex_texture::format() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 8) & 0xff); + } + + u16 vertex_texture::mipmap() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 16) & 0xffff); + } + + u8 vertex_texture::wrap_s() const + { + return 1; + //return ((method_registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)]) & 0xf); + } + + u8 vertex_texture::wrap_t() const + { + return 1; + //return ((method_registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 8) & 0xf); + } + + u8 vertex_texture::wrap_r() const + { + return 1; + //return ((method_registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 16) & 0xf); + } + + u8 vertex_texture::unsigned_remap() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 12) & 0xf); + } + + u8 vertex_texture::zfunc() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 28) & 0xf); + } + + u8 vertex_texture::gamma() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 20) & 0xf); + } + + u8 vertex_texture::aniso_bias() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 4) & 0xf); + } + + u8 vertex_texture::signed_remap() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 24) & 0xf); + } + + bool vertex_texture::enabled() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 31) & 0x1); + } + + u16 vertex_texture::min_lod() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 19) & 0xfff); + } + + u16 vertex_texture::max_lod() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 7) & 0xfff); + } + + u8 vertex_texture::max_aniso() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 4) & 0x7); + } + + bool vertex_texture::alpha_kill_enabled() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 2) & 0x1); + } + + u32 vertex_texture::remap() const + { + return 0 | (1 << 2) | (2 << 4) | (3 << 6);//(method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL1 + (m_index * 8)]); + } + + u16 vertex_texture::bias() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)]) & 0x1fff); + } + + u8 vertex_texture::min_filter() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 16) & 0x7); + } + + u8 vertex_texture::mag_filter() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 24) & 0x7); + } + + u8 vertex_texture::convolution_filter() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 13) & 0xf); + } + + bool vertex_texture::a_signed() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 28) & 0x1); + } + + bool vertex_texture::r_signed() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 29) & 0x1); + } + + bool vertex_texture::g_signed() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 30) & 0x1); + } + + bool vertex_texture::b_signed() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 31) & 0x1); + } + + u16 vertex_texture::width() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + (m_index * 8)] >> 16) & 0xffff); + } + + u16 vertex_texture::height() const + { + return ((method_registers[NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + (m_index * 8)]) & 0xffff); + } + + u32 vertex_texture::border_color() const + { + return method_registers[NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + (m_index * 8)]; + } + + u16 vertex_texture::depth() const + { + return method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL3] >> 20; + } + + u32 vertex_texture::pitch() const + { + return method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL3] & 0xfffff; + } } \ No newline at end of file diff --git a/rpcs3/Emu/RSX/RSXTexture.h b/rpcs3/Emu/RSX/RSXTexture.h index c595dba082..014d862340 100644 --- a/rpcs3/Emu/RSX/RSXTexture.h +++ b/rpcs3/Emu/RSX/RSXTexture.h @@ -1,122 +1,131 @@ #pragma once +#include "Utilities/types.h" -class RSXTexture +namespace rsx { -protected: - u8 m_index; + class texture + { + protected: + u8 m_index; -public: - u32 m_pitch; - u16 m_depth; + public: + //initialize texture registers with default values + void init(u8 index); -public: - RSXTexture(); - RSXTexture(u8 index); - virtual void Init(); + // Offset + u32 offset() const; - // Offset - virtual u32 GetOffset() const; + // Format + u8 location() const; + bool cubemap() const; + u8 border_type() const; + u8 dimension() const; + u8 format() const; + u16 mipmap() const; - // Format - virtual u8 GetLocation() const; - virtual bool isCubemap() const; - virtual u8 GetBorderType() const; - virtual u8 GetDimension() const; - virtual u8 GetFormat() const; - virtual u16 GetMipmap() const; + // Address + u8 wrap_s() const; + u8 wrap_t() const; + u8 wrap_r() const; + u8 unsigned_remap() const; + u8 zfunc() const; + u8 gamma() const; + u8 aniso_bias() const; + u8 signed_remap() const; - // Address - virtual u8 GetWrapS() const; - virtual u8 GetWrapT() const; - virtual u8 GetWrapR() const; - virtual u8 GetUnsignedRemap() const; - virtual u8 GetZfunc() const; - virtual u8 GetGamma() const; - virtual u8 GetAnisoBias() const; - virtual u8 GetSignedRemap() const; + // Control0 + bool enabled() const; + u16 min_lod() const; + u16 max_lod() const; + u8 max_aniso() const; + bool alpha_kill_enabled() const; - // Control0 - virtual bool IsEnabled() const; - virtual u16 GetMinLOD() const; - virtual u16 GetMaxLOD() const; - virtual u8 GetMaxAniso() const; - virtual bool IsAlphaKillEnabled() const; + // Control1 + u32 remap() const; - // Control1 - virtual u32 GetRemap() const; + // Filter + u16 bias() const; + u8 min_filter() const; + u8 mag_filter() const; + u8 convolution_filter() const; + bool a_signed() const; + bool r_signed() const; + bool g_signed() const; + bool b_signed() const; - // Filter - virtual u16 GetBias() const; - virtual u8 GetMinFilter() const; - virtual u8 GetMagFilter() const; - virtual u8 GetConvolutionFilter() const; - virtual bool isASigned() const; - virtual bool isRSigned() const; - virtual bool isGSigned() const; - virtual bool isBSigned() const; + // Image Rect + u16 width() const; + u16 height() const; - // Image Rect - virtual u16 GetWidth() const; - virtual u16 GetHeight() const; + // Border Color + u32 border_color() const; + u16 depth() const; + u32 pitch() const; - // Border Color - virtual u32 GetBorderColor() const; + //custom info + u8 index() const; + }; - void SetControl3(u16 depth, u32 pitch); -}; + class vertex_texture + { + protected: + u8 m_index; -class RSXVertexTexture : public RSXTexture -{ -public: - RSXVertexTexture(); - RSXVertexTexture(u8 index); - void Init(); + public: + //initialize texture registers with default values + void init(u8 index); - // Offset - u32 GetOffset() const; + // Offset + u32 offset() const; - // Format - u8 GetLocation() const; - bool isCubemap() const; - u8 GetBorderType() const; - u8 GetDimension() const; - u8 GetFormat() const; - u16 GetMipmap() const; + // Format + u8 location() const; + bool cubemap() const; + u8 border_type() const; + u8 dimension() const; + u8 format() const; + u16 mipmap() const; - // Address - u8 GetWrapS() const; - u8 GetWrapT() const; - u8 GetWrapR() const; - u8 GetUnsignedRemap() const; - u8 GetZfunc() const; - u8 GetGamma() const; - u8 GetAnisoBias() const; - u8 GetSignedRemap() const; + // Address + u8 wrap_s() const; + u8 wrap_t() const; + u8 wrap_r() const; + u8 unsigned_remap() const; + u8 zfunc() const; + u8 gamma() const; + u8 aniso_bias() const; + u8 signed_remap() const; - // Control0 - bool IsEnabled() const; - u16 GetMinLOD() const; - u16 GetMaxLOD() const; - u8 GetMaxAniso() const; - bool IsAlphaKillEnabled() const; + // Control0 + bool enabled() const; + u16 min_lod() const; + u16 max_lod() const; + u8 max_aniso() const; + bool alpha_kill_enabled() const; - // Control1 - u32 GetRemap() const; + // Control1 + u32 remap() const; - // Filter - u16 GetBias() const; - u8 GetMinFilter() const; - u8 GetMagFilter() const; - u8 GetConvolutionFilter() const; - bool isASigned() const; - bool isRSigned() const; - bool isGSigned() const; - bool isBSigned() const; + // Filter + u16 bias() const; + u8 min_filter() const; + u8 mag_filter() const; + u8 convolution_filter() const; + bool a_signed() const; + bool r_signed() const; + bool g_signed() const; + bool b_signed() const; - // Image Rect - u16 GetWidth() const; - u16 GetHeight() const; + // Image Rect + u16 width() const; + u16 height() const; - // Border Color - u32 GetBorderColor() const; -}; \ No newline at end of file + // Border Color + u32 border_color() const; + u16 depth() const; + u32 pitch() const; + + //custom info + u8 index() const; + }; +} diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 623b342b4e..6f34d86d8d 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -4,252 +4,497 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/RSX/GSManager.h" -#include "Emu/RSX/GSRender.h" -#include "Emu/SysCalls/Modules/cellVideoOut.h" #include "RSXThread.h" #include "Emu/SysCalls/Callback.h" #include "Emu/SysCalls/CB_FUNC.h" +#include "Emu/SysCalls/lv2/sys_time.h" + +#include "Utilities/types.h" +#include + +using namespace std::chrono_literals; extern "C" { #include "libswscale/swscale.h" } -extern u64 get_system_time(); - -#define ARGS(x) (x >= count ? OutOfArgsCount(x, cmd, count, args.addr()) : args[x].value()) #define CMD_DEBUG 0 -u32 methodRegisters[0xffff]; +extern u64 get_system_time(); -u32 GetAddress(u32 offset, u32 location) +namespace rsx { - u32 res = 0; + using rsx_method_t = void(*)(thread*, u32); - switch (location) + u32 method_registers[0x10000 >> 2]; + rsx_method_t methods[0x10000 >> 2]{}; + + template struct vertex_data_type_from_element_type; + template<> struct vertex_data_type_from_element_type { enum { type = CELL_GCM_VERTEX_F }; }; + template<> struct vertex_data_type_from_element_type { enum { type = CELL_GCM_VERTEX_SF }; }; + template<> struct vertex_data_type_from_element_type { enum { type = CELL_GCM_VERTEX_UB }; }; + template<> struct vertex_data_type_from_element_type { enum { type = CELL_GCM_VERTEX_S1 }; }; + + namespace nv406e { - case CELL_GCM_LOCATION_LOCAL: - { - res = 0xC0000000 + offset; - break; - } - case CELL_GCM_LOCATION_MAIN: - { - res = RSXIOMem.RealAddr(offset); // TODO: Error Check? - if (res == 0) + __forceinline void set_reference(thread* rsx, u32 arg) { - throw EXCEPTION("RSXIO memory not mapped (offset=0x%x)", offset); + rsx->ctrl->ref.exchange(arg); } - if (Emu.GetGSManager().GetRender().m_strict_ordering[offset >> 20]) + __forceinline void semaphore_acquire(thread* rsx, u32 arg) { - _mm_mfence(); // probably doesn't have any effect on current implementation + //TODO: dma + while (vm::read32(rsx->label_addr + method_registers[NV406E_SEMAPHORE_OFFSET]) != arg) + { + if (Emu.IsStopped()) + break; + + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } } - break; - } - default: - { - throw EXCEPTION("Invalid location (offset=0x%x, location=0x%x)", offset, location); - } - } - - return res; -} - -RSXVertexData::RSXVertexData() - : frequency(0) - , stride(0) - , size(0) - , type(0) - , addr(0) - , data() -{ -} - -void RSXVertexData::Reset() -{ - frequency = 0; - stride = 0; - size = 0; - type = 0; - addr = 0; - data.clear(); -} - -void RSXVertexData::Load(u32 start, u32 count, u32 baseOffset, u32 baseIndex = 0) -{ - if (!addr) return; - - const u32 tsize = GetTypeSize(); - - data.resize((start + count) * tsize * size); - - for (u32 i = start; i < start + count; ++i) - { - auto src = vm::get_ptr(addr + baseOffset + stride * (i + baseIndex)); - u8* dst = &data[i * tsize * size]; - - switch (tsize) + __forceinline void semaphore_release(thread* rsx, u32 arg) { - case 1: - { - memcpy(dst, src, size); - break; - } - - case 2: - { - auto c_src = (const be_t*)src; - auto c_dst = (u16*)dst; - for (u32 j = 0; j < size; ++j) *c_dst++ = *c_src++; - break; - } - - case 4: - { - auto c_src = (const be_t*)src; - auto c_dst = (u32*)dst; - for (u32 j = 0; j < size; ++j) *c_dst++ = *c_src++; - break; - } + //TODO: dma + vm::write32(rsx->label_addr + method_registers[NV406E_SEMAPHORE_OFFSET], arg); } } -} -u32 RSXVertexData::GetTypeSize() const -{ - switch (type) + namespace nv4097 { - case CELL_GCM_VERTEX_S1: return 2; - case CELL_GCM_VERTEX_F: return 4; - case CELL_GCM_VERTEX_SF: return 2; - case CELL_GCM_VERTEX_UB: return 1; - case CELL_GCM_VERTEX_S32K: return 2; - case CELL_GCM_VERTEX_CMP: return 4; - case CELL_GCM_VERTEX_UB256: return 1; - - default: - LOG_ERROR(RSX, "RSXVertexData::GetTypeSize: Bad vertex data type (%d)!", type); - return 1; - } -} - -u32 RSXThread::OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr) -{ - auto args = vm::ptr::make(args_addr); - std::string debug = GetMethodName(cmd); - debug += "("; - for (u32 i = 0; i < count; ++i) debug += (i ? ", " : "") + fmt::format("0x%x", ARGS(i)); - debug += ")"; - LOG_NOTICE(RSX, "OutOfArgsCount(x=%d, count=%d): %s", x, count, debug.c_str()); - - return 0; -} - -#define case_2(offset, step) \ - case offset: \ - case offset + step: -#define case_4(offset, step) \ - case_2(offset, step) \ - case_2(offset + 2*step, step) -#define case_8(offset, step) \ - case_4(offset, step) \ - case_4(offset + 4*step, step) -#define case_16(offset, step) \ - case_8(offset, step) \ - case_8(offset + 8*step, step) -#define case_32(offset, step) \ - case_16(offset, step) \ - case_16(offset + 16*step, step) -#define case_range(n, offset, step) \ - case_##n(offset, step) \ - index = (cmd - offset) / step - -void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 count) -{ - auto args = vm::ptr::make(args_addr); - -#if CMD_DEBUG - std::string debug = GetMethodName(cmd); - debug += "("; - for (u32 i = 0; i < count; ++i) debug += (i ? ", " : "") + fmt::format("0x%x", ARGS(i)); - debug += ")"; - LOG_NOTICE(RSX, debug); -#endif - - u32 index = 0; - - m_used_gcm_commands.insert(cmd); - - switch (cmd) - { - // NV406E - case NV406E_SET_REFERENCE: - { - m_ctrl->ref.exchange(ARGS(0)); - break; - } - - case NV406E_SET_CONTEXT_DMA_SEMAPHORE: - { - if (ARGS(0)) + __forceinline void texture_read_semaphore_release(thread* rsx, u32 arg) { - LOG_WARNING(RSX, "TODO: NV406E_SET_CONTEXT_DMA_SEMAPHORE: 0x%x", ARGS(0)); + //TODO: dma + vm::write32(rsx->label_addr + method_registers[NV4097_SET_SEMAPHORE_OFFSET], arg); + } + + __forceinline void back_end_write_semaphore_release(thread* rsx, u32 arg) + { + //TODO: dma + vm::write32(rsx->label_addr + method_registers[NV4097_SET_SEMAPHORE_OFFSET], + (arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff)); + } + + //fire only when all data passed to rsx cmd buffer + template + __forceinline void set_vertex_data_impl(thread* rsx, u32 arg) + { + static const size_t element_size = (count * sizeof(type)); + static const size_t element_size_in_words = element_size / sizeof(u32); + + auto& info = rsx->vertex_arrays_info[index]; + + info.type = vertex_data_type_from_element_type::type; + info.size = count; + info.frequency = 0; + info.stride = 0; + info.array = false; + + auto& entry = rsx->vertex_arrays[index]; + + //find begin of data + size_t begin = id + index * element_size_in_words; + + size_t position = entry.size(); + entry.resize(position + element_size); + + memcpy(entry.data() + position, method_registers + begin, element_size); + } + + template + __forceinline void set_vertex_data4ub_m(thread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + + template + __forceinline void set_vertex_data1f_m(thread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + + template + __forceinline void set_vertex_data2f_m(thread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + + template + __forceinline void set_vertex_data3f_m(thread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + + template + __forceinline void set_vertex_data4f_m(thread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + + template + __forceinline void set_vertex_data2s_m(thread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + + template + __forceinline void set_vertex_data4s_m(thread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + + template + __forceinline void set_vertex_data_array_format(thread* rsx, u32 arg) + { + auto& info = rsx->vertex_arrays_info[index]; + info.unpack(arg); + info.array = info.size > 0; + } + + __forceinline void draw_arrays(thread* rsx, u32 arg) + { + u32 first = arg & 0xffffff; + u32 count = (arg >> 24) + 1; + + rsx->load_vertex_data(first, count); + } + + __forceinline void draw_index_array(thread* rsx, u32 arg) + { + u32 first = arg & 0xffffff; + u32 count = (arg >> 24) + 1; + + rsx->load_vertex_data(first, count); + rsx->load_vertex_index_data(first, count); + } + + template + __forceinline void set_transform_constant(thread* rsxthr, u32 arg) + { + u32& load = method_registers[NV4097_SET_TRANSFORM_CONSTANT_LOAD]; + + static const size_t count = 4; + static const size_t size = count * sizeof(f32); + + memcpy(rsxthr->transform_constants[load++].rgba, method_registers + NV4097_SET_TRANSFORM_CONSTANT + index * count, size); + } + + template + __forceinline void set_transform_program(thread* rsx, u32 arg) + { + u32& load = method_registers[NV4097_SET_TRANSFORM_PROGRAM_LOAD]; + + static const size_t count = 4; + static const size_t size = count * sizeof(u32); + + memcpy(rsx->transform_program + load++ * count, method_registers + NV4097_SET_TRANSFORM_PROGRAM + index * count, size); + } + + __forceinline void set_begin_end(thread* rsx, u32 arg) + { + if (arg) + { + rsx->begin(); + return; + } + + rsx->end(); + rsx->vertex_draw_count = 0; + } + + __forceinline void get_report(thread* rsx, u32 arg) + { + u8 type = arg >> 24; + u32 offset = arg & 0xffffff; + + u32 value; + switch (type) + { + case CELL_GCM_ZPASS_PIXEL_CNT: + case CELL_GCM_ZCULL_STATS: + case CELL_GCM_ZCULL_STATS1: + case CELL_GCM_ZCULL_STATS2: + case CELL_GCM_ZCULL_STATS3: + value = 0; + LOG_WARNING(RSX, "NV4097_GET_REPORT: Unimplemented type %d", type); + break; + + default: + value = 0; + LOG_ERROR(RSX, "NV4097_GET_REPORT: Bad type %d", type); + break; + } + + // NOTE: DMA broken, implement proper lpar mapping (sys_rsx) + //dma_write64(dma_report, offset + 0x0, rsx->timestamp()); + //dma_write32(dma_report, offset + 0x8, value); + //dma_write32(dma_report, offset + 0xc, 0); + + vm::write64(rsx->local_mem_addr + offset + 0x0, rsx->timestamp()); + vm::write32(rsx->local_mem_addr + offset + 0x8, value); + vm::write32(rsx->local_mem_addr + offset + 0xc, 0); + } + + __forceinline void clear_report_value(thread* rsx, u32 arg) + { + switch (arg) + { + case CELL_GCM_ZPASS_PIXEL_CNT: + LOG_WARNING(RSX, "TODO: NV4097_CLEAR_REPORT_VALUE: ZPASS_PIXEL_CNT"); + break; + case CELL_GCM_ZCULL_STATS: + LOG_WARNING(RSX, "TODO: NV4097_CLEAR_REPORT_VALUE: ZCULL_STATS"); + break; + default: + LOG_ERROR(RSX, "NV4097_CLEAR_REPORT_VALUE: Bad type: %d", arg); + break; + } } - break; } - case NV4097_SET_SEMAPHORE_OFFSET: + namespace nv308a { - m_PGRAPH_semaphore_offset = ARGS(0); - break; + template + __forceinline void color(u32 arg) + { + u32 point = method_registers[NV308A_POINT]; + u16 x = point; + u16 y = point >> 16; + + if (y) + { + LOG_ERROR(RSX, "%s: y is not null (0x%x)", __FUNCTION__, y); + } + + u32 address = get_address(method_registers[NV3062_SET_OFFSET_DESTIN] + (x << 2) + index, method_registers[NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN]); + vm::write32(address, arg); + } } - case NV406E_SEMAPHORE_OFFSET: + namespace nv3089 { - m_PFIFO_semaphore_offset = ARGS(0); - break; + __forceinline void image_in(u32 arg) + { + const u16 width = method_registers[NV3089_IMAGE_IN_SIZE]; + const u16 height = method_registers[NV3089_IMAGE_IN_SIZE] >> 16; + const u16 pitch = method_registers[NV3089_IMAGE_IN_FORMAT]; + const u8 origin = method_registers[NV3089_IMAGE_IN_FORMAT] >> 16; + const u8 inter = method_registers[NV3089_IMAGE_IN_FORMAT] >> 24; + + if (origin != 2 /* CELL_GCM_TRANSFER_ORIGIN_CORNER */) + { + LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown origin (%d)", origin); + } + + if (inter != 0 /* CELL_GCM_TRANSFER_INTERPOLATOR_ZOH */ && inter != 1 /* CELL_GCM_TRANSFER_INTERPOLATOR_FOH */) + { + LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown inter (%d)", inter); + } + + const u32 src_offset = method_registers[NV3089_IMAGE_IN_OFFSET]; + const u32 src_dma = method_registers[NV3089_SET_CONTEXT_DMA_IMAGE]; + + u32 dst_offset; + u32 dst_dma = 0; + + switch (method_registers[NV3089_SET_CONTEXT_SURFACE]) + { + case CELL_GCM_CONTEXT_SURFACE2D: + dst_dma = method_registers[NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN]; + dst_offset = method_registers[NV3062_SET_OFFSET_DESTIN]; + break; + + case CELL_GCM_CONTEXT_SWIZZLE2D: + dst_dma = method_registers[NV309E_SET_CONTEXT_DMA_IMAGE]; + dst_offset = method_registers[NV309E_SET_OFFSET]; + break; + + default: + LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown m_context_surface (0x%x)", method_registers[NV3089_SET_CONTEXT_SURFACE]); + break; + } + + if (!dst_dma) + return; + + LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: src = 0x%x, dst = 0x%x", src_offset, dst_offset); + + const u16 u = arg; // inX (currently ignored) + const u16 v = arg >> 16; // inY (currently ignored) + + u8* pixels_src = vm::get_ptr(get_address(src_offset, src_dma)); + u8* pixels_dst = vm::get_ptr(get_address(dst_offset, dst_dma)); + + if (method_registers[NV3062_SET_COLOR_FORMAT] != 4 /* CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5 */ && + method_registers[NV3062_SET_COLOR_FORMAT] != 10 /* CELL_GCM_TRANSFER_SURFACE_FORMAT_A8R8G8B8 */) + { + LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown m_color_format (%d)", method_registers[NV3062_SET_COLOR_FORMAT]); + } + + const u32 in_bpp = method_registers[NV3062_SET_COLOR_FORMAT] == 4 ? 2 : 4; // bytes per pixel + const u32 out_bpp = method_registers[NV3089_SET_COLOR_FORMAT] == 7 ? 2 : 4; + + const s32 out_w = (s32)(u64(width) * (1 << 20) / method_registers[NV3089_DS_DX]); + const s32 out_h = (s32)(u64(height) * (1 << 20) / method_registers[NV3089_DT_DY]); + + if (method_registers[NV3089_SET_CONTEXT_SURFACE] == CELL_GCM_CONTEXT_SWIZZLE2D) + { + u8* linear_pixels = pixels_src; + u8* swizzled_pixels = new u8[in_bpp * width * height]; + + int sw_width = 1 << (int)log2(width); + int sw_height = 1 << (int)log2(height); + + for (int y = 0; y < sw_height; y++) + { + for (int x = 0; x < sw_width; x++) + { + switch (in_bpp) + { + case 1: + swizzled_pixels[linear_to_swizzle(x, y, 0, sw_width, sw_height, 0)] = linear_pixels[y * sw_height + x]; + break; + case 2: + ((u16*)swizzled_pixels)[linear_to_swizzle(x, y, 0, sw_width, sw_height, 0)] = ((u16*)linear_pixels)[y * sw_height + x]; + break; + case 4: + ((u32*)swizzled_pixels)[linear_to_swizzle(x, y, 0, sw_width, sw_height, 0)] = ((u32*)linear_pixels)[y * sw_height + x]; + break; + } + } + } + + pixels_src = swizzled_pixels; + } + + LOG_WARNING(RSX, "NV3089_IMAGE_IN_SIZE: w=%d, h=%d, pitch=%d, offset=0x%x, inX=%f, inY=%f, scaleX=%f, scaleY=%f", + width, height, pitch, src_offset, double(u) / 16, double(v) / 16, double(1 << 20) / (method_registers[NV3089_DS_DX]), + double(1 << 20) / (method_registers[NV3089_DT_DY])); + + std::unique_ptr temp; + + if (in_bpp != out_bpp && width != out_w && height != out_h) + { + // resize/convert if necessary + + temp.reset(new u8[out_bpp * out_w * out_h]); + + AVPixelFormat in_format = method_registers[NV3062_SET_COLOR_FORMAT] == 4 ? AV_PIX_FMT_RGB565BE : AV_PIX_FMT_ARGB; // ??? + AVPixelFormat out_format = method_registers[NV3089_SET_COLOR_FORMAT] == 7 ? AV_PIX_FMT_RGB565BE : AV_PIX_FMT_ARGB; // ??? + + std::unique_ptr sws(sws_getContext(width, height, in_format, out_w, out_h, out_format, + inter ? SWS_FAST_BILINEAR : SWS_POINT, NULL, NULL, NULL), sws_freeContext); + + int in_line = in_bpp * width; + u8* out_ptr = temp.get(); + int out_line = out_bpp * out_w; + + sws_scale(sws.get(), &pixels_src, &in_line, 0, height, &out_ptr, &out_line); + + pixels_src = temp.get(); // use resized image as a source + } + + if (method_registers[NV3089_CLIP_SIZE] != method_registers[NV3089_IMAGE_OUT_SIZE] || + method_registers[NV3089_IMAGE_OUT_SIZE] != (out_w | (out_h << 16)) || + method_registers[NV3089_IMAGE_OUT_POINT] || method_registers[NV3089_CLIP_POINT]) + { + // clip if necessary + + for (s32 y = method_registers[NV3089_CLIP_POINT] >> 16, dst_y = method_registers[NV3089_IMAGE_OUT_POINT] >> 16; y < out_h; y++, dst_y++) + { + if (dst_y >= 0 && dst_y < method_registers[NV3089_IMAGE_OUT_SIZE] >> 16) + { + // destination line + u8* dst_line = pixels_dst + dst_y * out_bpp * (method_registers[NV3089_IMAGE_OUT_SIZE] & 0xffff) + + std::min(std::max(method_registers[NV3089_IMAGE_OUT_POINT] & 0xffff, 0), method_registers[NV3089_IMAGE_OUT_SIZE] & 0xffff); + + size_t dst_max = std::min( + std::max((s32)(method_registers[NV3089_IMAGE_OUT_SIZE] & 0xffff) - (method_registers[NV3089_IMAGE_OUT_POINT] & 0xffff), 0), + method_registers[NV3089_IMAGE_OUT_SIZE] & 0xffff) * out_bpp; + + if (y >= 0 && y < std::min(method_registers[NV3089_CLIP_SIZE] >> 16, out_h)) + { + // source line + u8* src_line = pixels_src + y * out_bpp * out_w + + std::min(std::max(method_registers[NV3089_CLIP_POINT] & 0xffff, 0), method_registers[NV3089_CLIP_SIZE] & 0xffff); + size_t src_max = std::min( + std::max((s32)(method_registers[NV3089_CLIP_SIZE] & 0xffff) - (method_registers[NV3089_CLIP_POINT] & 0xffff), 0), + method_registers[NV3089_CLIP_SIZE] & 0xffff) * out_bpp; + + std::pair + z0 = { src_line + 0, std::min(dst_max, std::max(0, method_registers[NV3089_CLIP_POINT] & 0xffff)) }, + d0 = { src_line + z0.second, std::min(dst_max - z0.second, src_max) }, + z1 = { src_line + d0.second, dst_max - z0.second - d0.second }; + + memset(z0.first, 0, z0.second); + memcpy(d0.first, src_line, d0.second); + memset(z1.first, 0, z1.second); + } + else + { + memset(dst_line, 0, dst_max); + } + } + } + } + else + { + memcpy(pixels_dst, pixels_src, out_w * out_h * out_bpp); + } + + if (method_registers[NV3089_SET_CONTEXT_SURFACE] == CELL_GCM_CONTEXT_SWIZZLE2D) + { + delete[] pixels_src; + } + } } - case NV406E_SEMAPHORE_ACQUIRE: + namespace nv0039 { - semaphorePFIFOAcquire(m_PFIFO_semaphore_offset, ARGS(0)); - break; + __forceinline void buffer_notify(u32 arg) + { + const u32 inPitch = method_registers[NV0039_PITCH_IN]; + const u32 outPitch = method_registers[NV0039_PITCH_OUT]; + const u32 lineLength = method_registers[NV0039_LINE_LENGTH_IN]; + const u32 lineCount = method_registers[NV0039_LINE_COUNT]; + const u8 outFormat = method_registers[NV0039_FORMAT] >> 8; + const u8 inFormat = method_registers[NV0039_FORMAT]; + const u32 notify = arg; + + // The existing GCM commands use only the value 0x1 for inFormat and outFormat + if (inFormat != 0x01 || outFormat != 0x01) + { + LOG_ERROR(RSX, "NV0039_OFFSET_IN: Unsupported format: inFormat=%d, outFormat=%d", inFormat, outFormat); + } + + if (lineCount == 1 && !inPitch && !outPitch && !notify) + { + memcpy( + vm::get_ptr(get_address(method_registers[NV0039_OFFSET_OUT], method_registers[NV0039_SET_CONTEXT_DMA_BUFFER_OUT])), + vm::get_ptr(get_address(method_registers[NV0039_OFFSET_IN], method_registers[NV0039_SET_CONTEXT_DMA_BUFFER_IN])), + lineLength); + } + else + { + LOG_ERROR(RSX, "NV0039_OFFSET_IN: bad offset(in=0x%x, out=0x%x), pitch(in=0x%x, out=0x%x), line(len=0x%x, cnt=0x%x), fmt(in=0x%x, out=0x%x), notify=0x%x", + method_registers[NV0039_OFFSET_IN], method_registers[NV0039_OFFSET_OUT], inPitch, outPitch, lineLength, lineCount, inFormat, outFormat, notify); + } + } } - case NV406E_SEMAPHORE_RELEASE: + void flip_command(thread* rsx, u32 arg) { - m_PFIFO_semaphore_release_value = ARGS(0); - break; - } + rsx->gcm_current_buffer = arg; + rsx->flip(arg); - case NV4097_TEXTURE_READ_SEMAPHORE_RELEASE: - { - semaphorePGRAPHTextureReadRelease(m_PGRAPH_semaphore_offset, ARGS(0)); - break; - } + rsx->last_flip_time = get_system_time() - 1000000; + rsx->gcm_current_buffer = arg; + rsx->flip_status = 0; - case NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE: - { - u32 value = ARGS(0); - value = (value & 0xff00ff00) | ((value & 0xff) << 16) | ((value >> 16) & 0xff); - semaphorePGRAPHBackendRelease(m_PGRAPH_semaphore_offset, value); - break; - } - - // NV4097 - case 0x0003fead: - { - Flip(); - - m_last_flip_time = get_system_time(); - m_gcm_current_buffer = ARGS(0); - m_read_buffer = true; - m_flip_status = 0; - - if (auto cb = m_flip_handler) + if (auto cb = rsx->flip_handler) { Emu.GetCallbackManager().Async([=](CPUThread& cpu) { @@ -257,2382 +502,633 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const }); } - m_sem_flip.post_and_wait(); + rsx->sem_flip.post_and_wait(); - auto sync = [&]() + //sync + double limit; + switch (Ini.GSFrameLimit.GetValue()) { - double limit; - switch (Ini.GSFrameLimit.GetValue()) - { - case 1: limit = 50.; break; - case 2: limit = 59.94; break; - case 3: limit = 30.; break; - case 4: limit = 60.; break; - case 5: limit = m_fps_limit; break; //TODO + case 1: limit = 50.; break; + case 2: limit = 59.94; break; + case 3: limit = 30.; break; + case 4: limit = 60.; break; + case 5: limit = rsx->fps_limit; break; //TODO - case 0: - default: + case 0: + default: + return; + } + + std::this_thread::sleep_for(std::chrono::milliseconds((s64)(1000.0 / limit - rsx->timer_sync.GetElapsedTimeInMilliSec()))); + rsx->timer_sync.Start(); + } + + struct __rsx_methods_t + { + using rsx_impl_method_t = void(*)(u32); + + template + __forceinline static void call_impl_func(thread *rsx, u32 arg) + { + impl_func(rsx, arg); + } + + template + __forceinline static void call_impl_func(thread *rsx, u32 arg) + { + impl_func(arg); + } + + template + static void wrapper(thread *rsx, u32 arg) + { + // try process using gpu + if (rsx->domethod(id, arg)) return; + + // not handled by renderer + // try process using cpu + if (impl_func != nullptr) + call_impl_func(rsx, arg); + } + + /* + template class T, T impl_func = nullptr, int limit = 0> + static void bind_impl() + { + bind>(); + + if (id + step < limit) + bind_impl(); + } + + template class rsx_impl_method_t impl_func = nullptr> + static void bind() { bind_impl(); } + + template class rsx_method_t impl_func = nullptr> + static void bind() { bind_impl(); } + */ + + template + static void bind_impl() + { + if (methods[id]) + { + throw std::logic_error(fmt::format("redefinition rsx method implementation (0x%04x)", id)); } - std::this_thread::sleep_for(std::chrono::milliseconds((s64)(1000.0 / limit - m_timer_sync.GetElapsedTimeInMilliSec()))); - m_timer_sync.Start(); - }; - - sync(); - - //Emu.Pause(); - break; - } - - case NV4097_NO_OPERATION: - { - // Nothing to do here - break; - } - - case NV4097_SET_CONTEXT_DMA_REPORT: - { - if (ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_CONTEXT_DMA_REPORT: 0x%x", ARGS(0)); - dma_report = ARGS(0); - } - break; - } - - case NV4097_NOTIFY: - { - if (ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_NOTIFY: 0x%x", ARGS(0)); - } - break; - } - - case NV4097_WAIT_FOR_IDLE: - { - if (ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_WAIT_FOR_IDLE: 0x%x", ARGS(0)); - } - break; - } - - case NV4097_PM_TRIGGER: - { - if (ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_PM_TRIGGER: 0x%x", ARGS(0)); - } - break; - } - - // Texture - case_range(16, NV4097_SET_TEXTURE_FORMAT, 0x20); - case_range(16, NV4097_SET_TEXTURE_OFFSET, 0x20); - case_range(16, NV4097_SET_TEXTURE_FILTER, 0x20); - case_range(16, NV4097_SET_TEXTURE_ADDRESS, 0x20); - case_range(16, NV4097_SET_TEXTURE_IMAGE_RECT, 32); - case_range(16, NV4097_SET_TEXTURE_BORDER_COLOR, 0x20); - case_range(16, NV4097_SET_TEXTURE_CONTROL0, 0x20); - case_range(16, NV4097_SET_TEXTURE_CONTROL1, 0x20); - { - // Done using methodRegisters in RSXTexture.cpp - break; - } - - case_range(16, NV4097_SET_TEX_COORD_CONTROL, 4); - { - const u32 a0 = ARGS(0); - u8 texMask2D = a0 & 1; - u8 texMaskCentroid = (a0 >> 4) & 1; - LOG_WARNING(RSX, "TODO: NV4097_SET_TEX_COORD_CONTROL(texMask2D=%d, texMaskCentroid=%d)", texMask2D, texMaskCentroid); - break; - } - - case_range(16, NV4097_SET_TEXTURE_CONTROL2, 4); - { - LOG_WARNING(RSX, "TODO: NV4097_SET_TEXTURE_CONTROL2"); - const u32 a0 = ARGS(0); - // TODO: Use these - u8 unknown = (a0 >> 8) & 0xFF; - u8 iso = (a0 >> 6) & 1; - u8 aniso = (a0 >> 7) & 1; - u8 slope = a0 & 0x1F; - break; - } - - case_range(16, NV4097_SET_TEXTURE_CONTROL3, 4); - { - RSXTexture& tex = m_textures[index]; - const u32 a0 = ARGS(0); - u32 pitch = a0 & 0xFFFFF; - u16 depth = a0 >> 20; - tex.SetControl3(depth, pitch); - break; - } - - // Vertex Texture - case_range(4, NV4097_SET_VERTEX_TEXTURE_FORMAT, 0x20); - case_range(4, NV4097_SET_VERTEX_TEXTURE_OFFSET, 0x20); - case_range(4, NV4097_SET_VERTEX_TEXTURE_FILTER, 0x20); - case_range(4, NV4097_SET_VERTEX_TEXTURE_ADDRESS, 0x20); - case_range(4, NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT, 0x20); - case_range(4, NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR, 0x20); - case_range(4, NV4097_SET_VERTEX_TEXTURE_CONTROL0, 0x20); - { - // Done using methodRegisters in RSXTexture.cpp - break; - } - - case_range(4, NV4097_SET_VERTEX_TEXTURE_CONTROL3, 0x20); - { - RSXVertexTexture& tex = m_vertex_textures[index]; - const u32 a0 = ARGS(0); - u32 pitch = a0 & 0xFFFFF; - u16 depth = a0 >> 20; - tex.SetControl3(depth, pitch); - break; - } - - // Vertex data - case_range(16, NV4097_SET_VERTEX_DATA4UB_M, 4); - { - const u32 a0 = ARGS(0); - u8 v0 = a0; - u8 v1 = a0 >> 8; - u8 v2 = a0 >> 16; - u8 v3 = a0 >> 24; - - m_vertex_data[index].Reset(); - m_vertex_data[index].size = 4; - m_vertex_data[index].type = CELL_GCM_VERTEX_UB; - m_vertex_data[index].data.push_back(v0); - m_vertex_data[index].data.push_back(v1); - m_vertex_data[index].data.push_back(v2); - m_vertex_data[index].data.push_back(v3); - - //LOG_WARNING(RSX, "NV4097_SET_VERTEX_DATA4UB_M: index = %d, v0 = 0x%x, v1 = 0x%x, v2 = 0x%x, v3 = 0x%x", index, v0, v1, v2, v3); - break; - } - - case_range(16, NV4097_SET_VERTEX_DATA2F_M, 8); - { - const u32 a0 = ARGS(0); - const u32 a1 = ARGS(1); - - float v0 = (float&)a0; - float v1 = (float&)a1; - - m_vertex_data[index].Reset(); - m_vertex_data[index].type = CELL_GCM_VERTEX_F; - m_vertex_data[index].size = 2; - u32 pos = m_vertex_data[index].data.size(); - m_vertex_data[index].data.resize(pos + sizeof(float) * 2); - (float&)m_vertex_data[index].data[pos + sizeof(float) * 0] = v0; - (float&)m_vertex_data[index].data[pos + sizeof(float) * 1] = v1; - - //LOG_WARNING(RSX, "NV4097_SET_VERTEX_DATA2F_M: index = %d, v0 = %f, v1 = %f", index, v0, v1); - break; - } - - case_range(16, NV4097_SET_VERTEX_DATA4F_M, 16); - { - const u32 a0 = ARGS(0); - const u32 a1 = ARGS(1); - const u32 a2 = ARGS(2); - const u32 a3 = ARGS(3); - - float v0 = (float&)a0; - float v1 = (float&)a1; - float v2 = (float&)a2; - float v3 = (float&)a3; - - m_vertex_data[index].Reset(); - m_vertex_data[index].type = CELL_GCM_VERTEX_F; - m_vertex_data[index].size = 4; - u32 pos = m_vertex_data[index].data.size(); - m_vertex_data[index].data.resize(pos + sizeof(float) * 4); - (float&)m_vertex_data[index].data[pos + sizeof(float) * 0] = v0; - (float&)m_vertex_data[index].data[pos + sizeof(float) * 1] = v1; - (float&)m_vertex_data[index].data[pos + sizeof(float) * 2] = v2; - (float&)m_vertex_data[index].data[pos + sizeof(float) * 3] = v3; - - //LOG_WARNING(RSX, "NV4097_SET_VERTEX_DATA4F_M: index = %d, v0 = %f, v1 = %f, v2 = %f, v3 = %f", index, v0, v1, v2, v3); - break; - } - - case_range(16, NV4097_SET_VERTEX_DATA_ARRAY_OFFSET, 4); - { - const u32 addr = GetAddress(ARGS(0) & 0x7fffffff, ARGS(0) >> 31); - - m_vertex_data[index].addr = addr; - m_vertex_data[index].data.clear(); - - //LOG_WARNING(RSX, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET: num=%d, addr=0x%x", index, addr); - break; - } - - case_range(16, NV4097_SET_VERTEX_DATA_ARRAY_FORMAT, 4); - { - const u32 a0 = ARGS(0); - u16 frequency = a0 >> 16; - u8 stride = (a0 >> 8) & 0xff; - u8 size = (a0 >> 4) & 0xf; - u8 type = a0 & 0xf; - - RSXVertexData& cv = m_vertex_data[index]; - cv.frequency = frequency; - cv.stride = stride; - cv.size = size; - cv.type = type; - - //LOG_WARNING(RSX, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT: index=%d, frequency=%d, stride=%d, size=%d, type=%d", index, frequency, stride, size, type); - - break; - } - - // Vertex Attribute - case NV4097_SET_VERTEX_ATTRIB_INPUT_MASK: - { - if (u32 mask = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_VERTEX_ATTRIB_INPUT_MASK: 0x%x", mask); + methods[id] = wrapper; } - //VertexData[0].prog.attributeInputMask = ARGS(0); - break; - } - - case NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK: - { - if (u32 mask = ARGS(0)) + template + static void bind_cpu_only_impl() { - LOG_WARNING(RSX, "TODO: NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK: 0x%x", mask); - } - - //VertexData[0].prog.attributeOutputMask = ARGS(0); - //FragmentData.prog.attributeInputMask = ARGS(0)/* & ~0x20*/; - break; - } - - // Color Mask - case NV4097_SET_COLOR_MASK: - { - const u32 a0 = ARGS(0); - - m_set_color_mask = true; - m_color_mask_a = a0 & 0x1000000 ? true : false; - m_color_mask_r = a0 & 0x0010000 ? true : false; - m_color_mask_g = a0 & 0x0000100 ? true : false; - m_color_mask_b = a0 & 0x0000001 ? true : false; - notifyRasterizerStateChange(); - break; - } - - case NV4097_SET_COLOR_MASK_MRT: - { - if (u32 mask = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_COLOR_MASK_MRT: 0x%x", mask); - } - break; - } - - // Alpha testing - case NV4097_SET_ALPHA_TEST_ENABLE: - { - m_set_alpha_test = ARGS(0) ? true : false; - break; - } - - case NV4097_SET_ALPHA_FUNC: - { - m_set_alpha_func = true; - m_alpha_func = ARGS(0); - - if (count == 2) - { - m_set_alpha_ref = true; - const u32 a1 = ARGS(1); - m_alpha_ref = (float&)a1; - } - break; - } - - case NV4097_SET_ALPHA_REF: - { - m_set_alpha_ref = true; - const u32 a0 = ARGS(0); - m_alpha_ref = (float&)a0; - break; - } - - // Cull face - case NV4097_SET_CULL_FACE_ENABLE: - { - m_set_cull_face = ARGS(0) ? true : false; - notifyRasterizerStateChange(); - break; - } - - case NV4097_SET_CULL_FACE: - { - m_cull_face = ARGS(0); - notifyRasterizerStateChange(); - break; - } - - // Front face - case NV4097_SET_FRONT_FACE: - { - m_front_face = ARGS(0); - notifyRasterizerStateChange(); - break; - } - - // Blending - case NV4097_SET_BLEND_ENABLE: - { - m_set_blend = ARGS(0) ? true : false; - notifyBlendStateChange(); - break; - } - - case NV4097_SET_BLEND_ENABLE_MRT: - { - m_set_blend_mrt1 = ARGS(0) & 0x02 ? true : false; - m_set_blend_mrt2 = ARGS(0) & 0x04 ? true : false; - m_set_blend_mrt3 = ARGS(0) & 0x08 ? true : false; - notifyBlendStateChange(); - break; - } - - case NV4097_SET_BLEND_FUNC_SFACTOR: - { - m_set_blend_sfactor = true; - m_blend_sfactor_rgb = ARGS(0) & 0xffff; - m_blend_sfactor_alpha = ARGS(0) >> 16; - - if (count == 2) - { - m_set_blend_dfactor = true; - m_blend_dfactor_rgb = ARGS(1) & 0xffff; - m_blend_dfactor_alpha = ARGS(1) >> 16; - } - notifyBlendStateChange(); - break; - } - - case NV4097_SET_BLEND_FUNC_DFACTOR: - { - m_set_blend_dfactor = true; - m_blend_dfactor_rgb = ARGS(0) & 0xffff; - m_blend_dfactor_alpha = ARGS(0) >> 16; - notifyBlendStateChange(); - break; - } - - case NV4097_SET_BLEND_COLOR: - { - m_set_blend_color = true; - m_blend_color_r = ARGS(0) & 0xff; - m_blend_color_g = (ARGS(0) >> 8) & 0xff; - m_blend_color_b = (ARGS(0) >> 16) & 0xff; - m_blend_color_a = (ARGS(0) >> 24) & 0xff; - notifyBlendStateChange(); - break; - } - - case NV4097_SET_BLEND_COLOR2: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO : NV4097_SET_BLEND_COLOR2: 0x%x", value); - } - break; - } - - case NV4097_SET_BLEND_EQUATION: - { - m_set_blend_equation = true; - m_blend_equation_rgb = ARGS(0) & 0xffff; - m_blend_equation_alpha = ARGS(0) >> 16; - notifyBlendStateChange(); - break; - } - - case NV4097_SET_REDUCE_DST_COLOR: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_REDUCE_DST_COLOR: 0x%x", value); - } - break; - } - - // Depth bound testing - case NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE: - { - m_set_depth_bounds_test = ARGS(0) ? true : false; - break; - } - - case NV4097_SET_DEPTH_BOUNDS_MIN: - { - m_set_depth_bounds = true; - const u32 a0 = ARGS(0); - m_depth_bounds_min = (float&)a0; - - if (count == 2) - { - const u32 a1 = ARGS(1); - m_depth_bounds_max = (float&)a1; - } - break; - } - - case NV4097_SET_DEPTH_BOUNDS_MAX: - { - m_set_depth_bounds = true; - const u32 a0 = ARGS(0); - m_depth_bounds_max = (float&)a0; - break; - } - - // Viewport - case NV4097_SET_VIEWPORT_HORIZONTAL: - { - m_set_viewport_horizontal = true; - m_viewport_x = ARGS(0) & 0xffff; - m_viewport_w = ARGS(0) >> 16; - - if (count == 2) - { - m_set_viewport_vertical = true; - m_viewport_y = ARGS(1) & 0xffff; - m_viewport_h = ARGS(1) >> 16; - } - - //LOG_NOTICE(RSX, "NV4097_SET_VIEWPORT_HORIZONTAL: x=%d, y=%d, w=%d, h=%d", m_viewport_x, m_viewport_y, m_viewport_w, m_viewport_h); - break; - } - - case NV4097_SET_VIEWPORT_VERTICAL: - { - m_set_viewport_vertical = true; - m_viewport_y = ARGS(0) & 0xffff; - m_viewport_h = ARGS(0) >> 16; - - //LOG_NOTICE(RSX, "NV4097_SET_VIEWPORT_VERTICAL: y=%d, h=%d", m_viewport_y, m_viewport_h); - break; - } - - case NV4097_SET_VIEWPORT_SCALE: - case NV4097_SET_VIEWPORT_OFFSET: - { - // Done in Vertex Shader - break; - } - - // Clipping - case NV4097_SET_CLIP_MIN: - { - const u32 a0 = ARGS(0); - const u32 a1 = ARGS(1); - - m_set_clip = true; - m_clip_min = (float&)a0; - m_clip_max = (float&)a1; - - //LOG_NOTICE(RSX, "NV4097_SET_CLIP_MIN: clip_min=%.01f, clip_max=%.01f", m_clip_min, m_clip_max); - break; - } - - case NV4097_SET_CLIP_MAX: - { - const u32 a0 = ARGS(0); - - m_set_clip = true; - m_clip_max = (float&)a0; - - //LOG_NOTICE(RSX, "NV4097_SET_CLIP_MAX: clip_max=%.01f", m_clip_max); - break; - } - - // Depth testing - case NV4097_SET_DEPTH_TEST_ENABLE: - { - m_set_depth_test = ARGS(0) ? true : false; - break; - } - - case NV4097_SET_DEPTH_FUNC: - { - m_set_depth_func = true; - m_depth_func = ARGS(0); - notifyDepthStencilStateChange(); - break; - } - - case NV4097_SET_DEPTH_MASK: - { - m_set_depth_mask = true; - m_depth_mask = ARGS(0); - notifyDepthStencilStateChange(); - break; - } - - // Polygon mode/offset - case NV4097_SET_FRONT_POLYGON_MODE: - { - m_set_front_polygon_mode = true; - m_front_polygon_mode = ARGS(0); - break; - } - - case NV4097_SET_BACK_POLYGON_MODE: - { - m_set_back_polygon_mode = true; - m_back_polygon_mode = ARGS(0); - break; - } - - case NV4097_SET_POLY_OFFSET_FILL_ENABLE: - { - m_set_poly_offset_fill = ARGS(0) ? true : false; - break; - } - - case NV4097_SET_POLY_OFFSET_LINE_ENABLE: - { - m_set_poly_offset_line = ARGS(0) ? true : false; - break; - } - - case NV4097_SET_POLY_OFFSET_POINT_ENABLE: - { - m_set_poly_offset_point = ARGS(0) ? true : false; - break; - } - - case NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR: - { - m_set_depth_test = true; - m_set_poly_offset_mode = true; - - const u32 a0 = ARGS(0); - m_poly_offset_scale_factor = (float&)a0; - - if (count == 2) - { - const u32 a1 = ARGS(1); - m_poly_offset_bias = (float&)a1; - } - break; - } - - case NV4097_SET_POLYGON_OFFSET_BIAS: - { - m_set_depth_test = true; - m_set_poly_offset_mode = true; - - const u32 a0 = ARGS(0); - m_poly_offset_bias = (float&)a0; - break; - } - - case NV4097_SET_CYLINDRICAL_WRAP: - { - if (ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_CYLINDRICAL_WRAP: 0x%x", ARGS(0)); - } - break; - } - - // Clearing - case NV4097_CLEAR_ZCULL_SURFACE: - { - u32 a0 = ARGS(0); - - if (a0 & 0x01) m_clear_surface_z = m_clear_z; - if (a0 & 0x02) m_clear_surface_s = m_clear_s; - - m_clear_surface_mask |= a0 & 0x3; - break; - } - - case NV4097_CLEAR_SURFACE: - { - const u32 a0 = ARGS(0); - - if (a0 & 0x01) m_clear_surface_z = m_clear_z; - if (a0 & 0x02) m_clear_surface_s = m_clear_s; - if (a0 & 0x10) m_clear_surface_color_r = m_clear_color_r; - if (a0 & 0x20) m_clear_surface_color_g = m_clear_color_g; - if (a0 & 0x40) m_clear_surface_color_b = m_clear_color_b; - if (a0 & 0x80) m_clear_surface_color_a = m_clear_color_a; - - m_clear_surface_mask = a0; - Clear(NV4097_CLEAR_SURFACE); - break; - } - - case NV4097_SET_ZSTENCIL_CLEAR_VALUE: - { - const u32 value = ARGS(0); - m_clear_s = value & 0xff; - m_clear_z = value >> 8; - break; - } - - case NV4097_SET_COLOR_CLEAR_VALUE: - { - const u32 color = ARGS(0); - m_clear_color_a = (color >> 24) & 0xff; - m_clear_color_r = (color >> 16) & 0xff; - m_clear_color_g = (color >> 8) & 0xff; - m_clear_color_b = color & 0xff; - break; - } - - case NV4097_SET_CLEAR_RECT_HORIZONTAL: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_CLEAR_RECT_HORIZONTAL: 0x%x", value); - } - break; - } - - case NV4097_SET_CLEAR_RECT_VERTICAL: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_CLEAR_RECT_VERTICAL: 0x%x", value); - } - break; - } - - // Arrays - case NV4097_INLINE_ARRAY: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_INLINE_ARRAY: 0x%x", value); - } - break; - } - - case NV4097_DRAW_ARRAYS: - { - for (u32 c = 0; c> 24) + 1; - - //LOG_WARNING(RSX, "NV4097_DRAW_ARRAYS: %d - %d", first, _count); - - if (first < m_draw_array_first) + if (methods[id]) { - m_draw_array_first = first; + throw std::logic_error(fmt::format("redefinition rsx method implementation(cpu only) (0x%04x)", id)); } - m_draw_array_count += _count; + methods[id] = call_impl_func; } - break; - } - case NV4097_SET_INDEX_ARRAY_ADDRESS: - { - m_indexed_array.m_addr = GetAddress(ARGS(0), ARGS(1) & 0xf); - m_indexed_array.m_type = ARGS(1) >> 4; - break; - } + template static void bind() { bind_impl(); } + template static void bind() { bind_impl(); } - case NV4097_DRAW_INDEX_ARRAY: - { - for (u32 c=0; c static void bind_cpu_only() { bind_cpu_only_impl(); } + //do not try process on gpu + template static void bind_cpu_only() { bind_cpu_only_impl(); } + +#define bind_2(index, offset, step, func) \ + bind>(); \ + bind>() + +#define bind_4(index, offset, step, func) \ + bind_2(index, offset, step, func); \ + bind_2(index + 2, offset + 2*step, step, func) + +#define bind_8(index, offset, step, func) \ + bind_4(index, offset, step, func); \ + bind_4(index + 4, offset + 4*step, step, func) + +#define bind_16(index, offset, step, func) \ + bind_8(index, offset, step, func); \ + bind_8(index + 8, offset + 8*step, step, func) + +#define bind_32(index, offset, step, func) \ + bind_16(index, offset, step, func); \ + bind_16(index + 16, offset + 16*step, step, func) + +#define bind_64(index, offset, step, func) \ + bind_32(index, offset, step, func); \ + bind_32(index + 32, offset + 32*step, step, func) + +#define bind_128(index, offset, step, func) \ + bind_64(index, offset, step, func); \ + bind_64(index + 64, offset + 64*step, step, func) + +#define bind_256(index, offset, step, func) \ + bind_128(index, offset, step, func); \ + bind_128(index + 128, offset + 128*step, step, func) + +#define bind_512(index, offset, step, func) \ + bind_256(index, offset, step, func); \ + bind_256(index + 256, offset + 256*step, step, func) + + __rsx_methods_t() { - const u32 first = ARGS(c) & 0xffffff; - const u32 _count = (ARGS(c) >> 24) + 1; + // NV406E + bind_cpu_only(); + bind(); + bind(); - if (first < m_indexed_array.m_first) m_indexed_array.m_first = first; + // NV4097 + bind(); + bind(); + bind(); + bind(); + bind(); + bind(); + //bind(); + bind_16(0, NV4097_SET_VERTEX_DATA_ARRAY_FORMAT, 1, nv4097::set_vertex_data_array_format); + bind_16(0, NV4097_SET_VERTEX_DATA4UB_M, 1, nv4097::set_vertex_data4ub_m); + bind_16(0, NV4097_SET_VERTEX_DATA1F_M, 1, nv4097::set_vertex_data1f_m); + bind_16(0, NV4097_SET_VERTEX_DATA2F_M + 1, 2, nv4097::set_vertex_data2f_m); + bind_16(0, NV4097_SET_VERTEX_DATA3F_M + 2, 3, nv4097::set_vertex_data3f_m); + bind_16(0, NV4097_SET_VERTEX_DATA4F_M + 3, 4, nv4097::set_vertex_data4f_m); + bind_16(0, NV4097_SET_VERTEX_DATA2S_M, 1, nv4097::set_vertex_data2s_m); + bind_16(0, NV4097_SET_VERTEX_DATA4S_M + 1, 2, nv4097::set_vertex_data4s_m); + bind_8(0, NV4097_SET_TRANSFORM_CONSTANT + 3, 4, nv4097::set_transform_constant); + bind_128(0, NV4097_SET_TRANSFORM_PROGRAM + 3, 4, nv4097::set_transform_program); + bind_cpu_only(); + bind_cpu_only(); - int pos = (int)m_indexed_array.m_data.size(); + //NV308A + bind_512(0, NV308A_COLOR, 1, nv308a::color); - switch (m_indexed_array.m_type) + //NV3089 + bind(); + + //NV0039 + bind(); + + // custom methods + bind_cpu_only(); + } + } __rsx_methods; + + u32 linear_to_swizzle(u32 x, u32 y, u32 z, u32 log2_width, u32 log2_height, u32 log2_depth) + { + u32 offset = 0; + u32 shift_count = 0; + while (log2_width | log2_height | log2_depth) + { + if (log2_width) { - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: - m_indexed_array.m_data.resize(pos + 4 * _count); - break; - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: - m_indexed_array.m_data.resize(pos + 2 * _count); - break; + offset |= (x & 0x01) << shift_count; + x >>= 1; + ++shift_count; + --log2_width; } - for (u32 i=first; i< first + _count; ++i) + if (log2_height) { - u32 index; - switch(m_indexed_array.m_type) + offset |= (y & 0x01) << shift_count; + y >>= 1; + ++shift_count; + --log2_height; + } + + if (log2_depth) + { + offset |= (z & 0x01) << shift_count; + z >>= 1; + ++shift_count; + --log2_depth; + } + } + return offset; + } + + u32 get_address(u32 offset, u32 location) + { + u32 res = 0; + + switch (location) + { + case CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER: + case CELL_GCM_LOCATION_LOCAL: + { + //TODO: don't use not named constants like 0xC0000000 + res = 0xC0000000 + offset; + break; + } + + case CELL_GCM_CONTEXT_DMA_MEMORY_HOST_BUFFER: + case CELL_GCM_LOCATION_MAIN: + { + res = (u32)RSXIOMem.RealAddr(offset); // TODO: Error Check? + if (res == 0) + { + throw fmt::format("GetAddress(offset=0x%x, location=0x%x): RSXIO memory not mapped", offset, location); + } + + //if (Emu.GetGSManager().GetRender().strict_ordering[offset >> 20]) + //{ + // _mm_mfence(); // probably doesn't have any effect on current implementation + //} + + break; + } + default: + { + throw EXCEPTION("Invalid location (offset=0x%x, location=0x%x)", offset, location); + } + } + + return res; + } + + u32 get_vertex_type_size(u32 type) + { + switch (type) + { + case CELL_GCM_VERTEX_S1: return sizeof(u16); + case CELL_GCM_VERTEX_F: return sizeof(f32); + case CELL_GCM_VERTEX_SF: return sizeof(f16); + case CELL_GCM_VERTEX_UB: return sizeof(u8); + case CELL_GCM_VERTEX_S32K: return sizeof(u32); + case CELL_GCM_VERTEX_CMP: return sizeof(u32); + case CELL_GCM_VERTEX_UB256: return sizeof(u8) * 4; + + default: + LOG_ERROR(RSX, "RSXVertexData::GetTypeSize: Bad vertex data type (%d)!", type); + assert(0); + return 1; + } + } + + void thread::load_vertex_data(u32 first, u32 count) + { + vertex_draw_count += count; + + for (int index = 0; index < limits::vertex_count; ++index) + { + auto &info = vertex_arrays_info[index]; + + if (!info.array) // disabled or not a vertex array + { + continue; + } + + auto &data = vertex_arrays[index]; + + if (info.frequency) + { + LOG_ERROR(RSX, "%s: frequency is not null (%d, index=%d)", __FUNCTION__, info.frequency, index); + } + + u32 offset = method_registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + index]; + u32 address = get_address(offset & 0x7fffffff, offset >> 31); + + u32 type_size = get_vertex_type_size(info.type); + u32 element_size = type_size * info.size; + + u32 dst_position = (u32)data.size(); + data.resize(dst_position + count * element_size); + + u32 base_offset = method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET]; + u32 base_index = method_registers[NV4097_SET_VERTEX_DATA_BASE_INDEX]; + + for (u32 i = 0; i < count; ++i) + { + auto src = vm::get_ptr(address + base_offset + info.stride * (first + i + base_index)); + u8* dst = data.data() + dst_position + i * element_size; + + switch (type_size) { - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: - index = vm::read32(m_indexed_array.m_addr + i * 4); - *(u32*)&m_indexed_array.m_data[i * 4] = index; + case 1: + memcpy(dst, src, info.size); break; - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: - index = vm::read16(m_indexed_array.m_addr + i * 2); - *(u16*)&m_indexed_array.m_data[i * 2] = index; + case 2: + { + auto* c_src = (const be_t*)src; + u16* c_dst = (u16*)dst; + + for (u32 j = 0; j < info.size; ++j) + { + *c_dst++ = *c_src++; + } break; } - if (index < m_indexed_array.index_min) m_indexed_array.index_min = index; - if (index > m_indexed_array.index_max) m_indexed_array.index_max = index; - } + case 4: + { + auto* c_src = (const be_t*)src; + u32* c_dst = (u32*)dst; - m_indexed_array.m_count += _count; - } - break; - } - - case NV4097_SET_VERTEX_DATA_BASE_OFFSET: - { - m_vertex_data_base_offset = ARGS(0); - - if (count >= 2) - { - m_vertex_data_base_index = ARGS(1); - } - - //LOG_WARNING(RSX, "NV4097_SET_VERTEX_DATA_BASE_OFFSET: 0x%x", m_vertex_data_base_offset); - break; - } - - case NV4097_SET_VERTEX_DATA_BASE_INDEX: - { - m_vertex_data_base_index = ARGS(0); - break; - } - - case NV4097_SET_BEGIN_END: - { - const u32 a0 = ARGS(0); - - //LOG_WARNING(RSX, "NV4097_SET_BEGIN_END: 0x%x", a0); - - if (!m_indexed_array.m_count && !m_draw_array_count) - { - u32 min_vertex_size = ~0; - for (auto &i : m_vertex_data) - { - if (!i.size) - continue; - - u32 vertex_size = i.data.size() / (i.size * i.GetTypeSize()); - - if (min_vertex_size > vertex_size) - min_vertex_size = vertex_size; - } - - m_draw_array_count = min_vertex_size; - m_draw_array_first = 0; - } - - m_read_buffer = Ini.GSReadColorBuffer.GetValue() || (!m_indexed_array.m_count && !m_draw_array_count); - - if (a0) - { - Begin(a0); - } - else - { - End(); - } - break; - } - - // Shader - case NV4097_SET_SHADER_PROGRAM: - { - m_cur_fragment_prog = &m_fragment_progs[m_cur_fragment_prog_num]; - - const u32 a0 = ARGS(0); - m_cur_fragment_prog->offset = a0 & ~0x3; - m_cur_fragment_prog->addr = GetAddress(m_cur_fragment_prog->offset, (a0 & 0x3) - 1); - m_cur_fragment_prog->ctrl = 0x40; - notifyProgramChange(); - break; - } - - case NV4097_SET_SHADER_CONTROL: - { - m_shader_ctrl = ARGS(0); - break; - } - - case NV4097_SET_SHADE_MODE: - { - m_set_shade_mode = true; - m_shade_mode = ARGS(0); - break; - } - - case NV4097_SET_SHADER_PACKER: - { - if (ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_SHADER_PACKER: 0x%x", ARGS(0)); - } - } - - case NV4097_SET_SHADER_WINDOW: - { - const u32 a0 = ARGS(0); - m_shader_window_height = a0 & 0xfff; - m_shader_window_origin = (a0 >> 12) & 0xf; - m_shader_window_pixel_centers = a0 >> 16; - break; - } - - // Transform - case NV4097_SET_TRANSFORM_PROGRAM_LOAD: - { - //LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM_LOAD: prog = %d", ARGS(0)); - - m_cur_vertex_prog = &m_vertex_progs[ARGS(0)]; - m_cur_vertex_prog->data.clear(); - - if (count == 2) - { - const u32 start = ARGS(1); - if (start) - { - LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM_LOAD: start = %d", start); + for (u32 j = 0; j < info.size; ++j) + { + *c_dst++ = *c_src++; + } + break; + } + } } } - notifyProgramChange(); - break; } - case NV4097_SET_TRANSFORM_PROGRAM_START: + void thread::load_vertex_index_data(u32 first, u32 count) { - const u32 start = ARGS(0); - if (start) - { - LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM_START: start = %d", start); - } - break; - } - - case_range(32, NV4097_SET_TRANSFORM_PROGRAM, 4); - { - //LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM[%d](%d)", index, count); - - if (!m_cur_vertex_prog) - { - LOG_ERROR(RSX, "NV4097_SET_TRANSFORM_PROGRAM: m_cur_vertex_prog is null"); - break; - } - - for (u32 i = 0; i < count; ++i) - { - m_cur_vertex_prog->data.push_back(ARGS(i)); - } - notifyProgramChange(); - break; - } - - case NV4097_SET_TRANSFORM_TIMEOUT: - { - // TODO: - // (cmd)[1] = CELL_GCM_ENDIAN_SWAP((count) | ((registerCount) << 16)); \ - - if (!m_cur_vertex_prog) - { - LOG_ERROR(RSX, "NV4097_SET_TRANSFORM_TIMEOUT: m_cur_vertex_prog is null"); - break; - } - - //m_cur_vertex_prog->Decompile(); - break; - } - - case NV4097_SET_TRANSFORM_BRANCH_BITS: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_TRANSFORM_BRANCH_BITS: 0x%x", value); - } - break; - } - - case NV4097_SET_TRANSFORM_CONSTANT_LOAD: - { - if ((count - 1) % 4) - { - LOG_ERROR(RSX, "NV4097_SET_TRANSFORM_CONSTANT_LOAD: bad count %d", count); - break; - } - - for (u32 id = ARGS(0), i = 1; i= 2) - { - m_set_stencil_func_ref = true; - m_stencil_func_ref = ARGS(1); - - if (count >= 3) - { - m_set_stencil_func_mask = true; - m_stencil_func_mask = ARGS(2); - } - } - notifyDepthStencilStateChange(); - break; - } - - case NV4097_SET_STENCIL_FUNC_REF: - { - m_set_stencil_func_ref = true; - m_stencil_func_ref = ARGS(0); - notifyDepthStencilStateChange(); - break; - } - - case NV4097_SET_STENCIL_FUNC_MASK: - { - m_set_stencil_func_mask = true; - m_stencil_func_mask = ARGS(0); - notifyDepthStencilStateChange(); - break; - } - - case NV4097_SET_STENCIL_OP_FAIL: - { - m_set_stencil_fail = true; - m_stencil_fail = ARGS(0); - - if (count >= 2) - { - m_set_stencil_zfail = true; - m_stencil_zfail = ARGS(1); - - if (count >= 3) - { - m_set_stencil_zpass = true; - m_stencil_zpass = ARGS(2); - } - } - notifyDepthStencilStateChange(); - break; - } - - case NV4097_SET_BACK_STENCIL_MASK: - { - m_set_back_stencil_mask = true; - m_back_stencil_mask = ARGS(0); - notifyDepthStencilStateChange(); - break; - } - - case NV4097_SET_BACK_STENCIL_FUNC: - { - m_set_back_stencil_func = true; - m_back_stencil_func = ARGS(0); - - if (count >= 2) - { - m_set_back_stencil_func_ref = true; - m_back_stencil_func_ref = ARGS(1); - - if (count >= 3) - { - m_set_back_stencil_func_mask = true; - m_back_stencil_func_mask = ARGS(2); - } - } - notifyDepthStencilStateChange(); - break; - } - - case NV4097_SET_BACK_STENCIL_FUNC_REF: - { - m_set_back_stencil_func_ref = true; - m_back_stencil_func_ref = ARGS(0); - notifyDepthStencilStateChange(); - break; - } - - case NV4097_SET_BACK_STENCIL_FUNC_MASK: - { - m_set_back_stencil_func_mask = true; - m_back_stencil_func_mask = ARGS(0); - notifyDepthStencilStateChange(); - break; - } - - case NV4097_SET_BACK_STENCIL_OP_FAIL: - { - m_set_stencil_fail = true; - m_stencil_fail = ARGS(0); - - if (count >= 2) - { - m_set_back_stencil_zfail = true; - m_back_stencil_zfail = ARGS(1); - - if (count >= 3) - { - m_set_back_stencil_zpass = true; - m_back_stencil_zpass = ARGS(2); - } - } - notifyDepthStencilStateChange(); - break; - } - - case NV4097_SET_SCULL_CONTROL: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_SCULL_CONTROL: 0x%x", value); - } - break; - } - - // Primitive restart index - case NV4097_SET_RESTART_INDEX_ENABLE: - { - m_set_restart_index = ARGS(0) ? true : false; - break; - } - - case NV4097_SET_RESTART_INDEX: - { - m_restart_index = ARGS(0); - break; - } - - // Point size - case NV4097_SET_POINT_SIZE: - { - m_set_point_size = true; - const u32 a0 = ARGS(0); - m_point_size = (float&)a0; - break; - } - - // Point sprite - case NV4097_SET_POINT_PARAMS_ENABLE: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_POINT_PARAMS_ENABLE: 0x%x", value); - } - break; - } - - case NV4097_SET_POINT_SPRITE_CONTROL: - { - m_set_point_sprite_control = ARGS(0) ? true : false; - - // TODO: - //(cmd)[1] = CELL_GCM_ENDIAN_SWAP((enable) | ((rmode) << 1) | (texcoordMask)); - break; - } - - // Lighting - case NV4097_SET_SPECULAR_ENABLE: - { - m_set_specular = ARGS(0) ? true : false; - break; - } - - // Scissor - case NV4097_SET_SCISSOR_HORIZONTAL: - { - m_set_scissor_horizontal = true; - m_scissor_x = ARGS(0) & 0xffff; - m_scissor_w = ARGS(0) >> 16; - - if (count == 2) - { - m_set_scissor_vertical = true; - m_scissor_y = ARGS(1) & 0xffff; - m_scissor_h = ARGS(1) >> 16; - } - break; - } - - case NV4097_SET_SCISSOR_VERTICAL: - { - m_set_scissor_vertical = true; - m_scissor_y = ARGS(0) & 0xffff; - m_scissor_h = ARGS(0) >> 16; - break; - } - - // Depth/Color buffer usage - case NV4097_SET_SURFACE_FORMAT: - { - const u32 a0 = ARGS(0); - m_set_surface_format = true; - m_surface_color_format = a0 & 0x1f; - m_surface_depth_format = (a0 >> 5) & 0x7; - m_surface_type = (a0 >> 8) & 0xf; - m_surface_antialias = (a0 >> 12) & 0xf; - m_surface_width = (a0 >> 16) & 0xff; - m_surface_height = (a0 >> 24) & 0xff; - - switch (std::min((u32)6, count)) - { - case 6: m_surface_pitch_b = ARGS(5); - case 5: m_surface_offset_b = ARGS(4); - case 4: m_surface_offset_z = ARGS(3); - case 3: m_surface_offset_a = ARGS(2); - case 2: m_surface_pitch_a = ARGS(1); - } - - auto buffers = vm::get_ptr(m_gcm_buffers_addr); - m_width = buffers[m_gcm_current_buffer].width; - m_height = buffers[m_gcm_current_buffer].height; - - CellVideoOutResolution res = ResolutionTable[ResolutionIdToNum(Ini.GSResolution.GetValue())]; - m_width_scale = (float)res.width / m_width * 2.0f; - m_height_scale = (float)res.height / m_height * 2.0f; - m_width = (u32)res.width; - m_height = (u32)res.height; - break; - } - - case NV4097_SET_SURFACE_COLOR_TARGET: - { - m_surface_color_target = ARGS(0); - break; - } - - case NV4097_SET_SURFACE_COLOR_AOFFSET: - { - m_surface_offset_a = ARGS(0); - break; - } - - case NV4097_SET_SURFACE_COLOR_BOFFSET: - { - m_surface_offset_b = ARGS(0); - break; - } - - case NV4097_SET_SURFACE_COLOR_COFFSET: - { - m_surface_offset_c = ARGS(0); - break; - } - - case NV4097_SET_SURFACE_COLOR_DOFFSET: - { - m_surface_offset_d = ARGS(0); - break; - } - - case NV4097_SET_SURFACE_ZETA_OFFSET: - { - m_surface_offset_z = ARGS(0); - break; - } - - case NV4097_SET_SURFACE_PITCH_A: - { - m_surface_pitch_a = ARGS(0); - break; - } - - case NV4097_SET_SURFACE_PITCH_B: - { - m_surface_pitch_b = ARGS(0); - break; - } - - case NV4097_SET_SURFACE_PITCH_C: - { - if (count != 4) - { - LOG_ERROR(RSX, "NV4097_SET_SURFACE_PITCH_C: Bad count (%d)", count); - break; - } - - m_surface_pitch_c = ARGS(0); - m_surface_pitch_d = ARGS(1); - m_surface_offset_c = ARGS(2); - m_surface_offset_d = ARGS(3); - break; - } - - case NV4097_SET_SURFACE_PITCH_D: - { - m_surface_pitch_d = ARGS(0); - - if (count != 1) - { - LOG_ERROR(RSX, "NV4097_SET_SURFACE_PITCH_D: Bad count (%d)", count); - break; - } - break; - } - - case NV4097_SET_SURFACE_PITCH_Z: - { - m_surface_pitch_z = ARGS(0); - - if (count != 1) - { - LOG_ERROR(RSX, "NV4097_SET_SURFACE_PITCH_Z: Bad count (%d)", count); - break; - } - break; - } - - case NV4097_SET_CONTEXT_DMA_COLOR_A: - { - m_set_context_dma_color_a = true; - m_context_dma_color_a = ARGS(0); - - if (count != 1) - { - LOG_ERROR(RSX, "NV4097_SET_CONTEXT_DMA_COLOR_A: Bad count (%d)", count); - break; - } - break; - } - - case NV4097_SET_CONTEXT_DMA_COLOR_B: - { - m_set_context_dma_color_b = true; - m_context_dma_color_b = ARGS(0); - break; - } - - case NV4097_SET_CONTEXT_DMA_COLOR_C: - { - m_set_context_dma_color_c = true; - m_context_dma_color_c = ARGS(0); - - if (count > 1) - { - m_set_context_dma_color_d = true; - m_context_dma_color_d = ARGS(1); - } - break; - } - - case NV4097_SET_CONTEXT_DMA_COLOR_D: - { - if (ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_CONTEXT_DMA_COLOR_D: 0x%x", ARGS(0)); - } - break; - } - - case NV4097_SET_CONTEXT_DMA_ZETA: - { - m_set_context_dma_z = true; - m_context_dma_z = ARGS(0); - break; - } - - case NV4097_SET_CONTEXT_DMA_SEMAPHORE: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_CONTEXT_DMA_SEMAPHORE: 0x%x", value); - } - break; - } + u32 address = get_address(method_registers[NV4097_SET_INDEX_ARRAY_ADDRESS], method_registers[NV4097_SET_INDEX_ARRAY_DMA] & 0xf); + u32 type = method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4; - case NV4097_SET_CONTEXT_DMA_NOTIFIES: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_CONTEXT_DMA_NOTIFIES: 0x%x", value); - } - break; - } - - case NV4097_SET_SURFACE_CLIP_HORIZONTAL: - { - const u32 a0 = ARGS(0); - - m_set_surface_clip_horizontal = true; - m_surface_clip_x = a0; - m_surface_clip_w = a0 >> 16; - - if (count == 2) - { - const u32 a1 = ARGS(1); - m_set_surface_clip_vertical = true; - m_surface_clip_y = a1; - m_surface_clip_h = a1 >> 16; - } - break; - } - - case NV4097_SET_SURFACE_CLIP_VERTICAL: - { - const u32 a0 = ARGS(0); - m_set_surface_clip_vertical = true; - m_surface_clip_y = a0; - m_surface_clip_h = a0 >> 16; - break; - } - - // Anti-aliasing - case NV4097_SET_ANTI_ALIASING_CONTROL: - { - const u32 a0 = ARGS(0); + u32 type_size = type == CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32 ? sizeof(u32) : sizeof(u16); + u32 dst_offset = (u32)vertex_index_array.size(); + vertex_index_array.resize(dst_offset + count * type_size); - const u8 enable = a0 & 0xf; - const u8 alphaToCoverage = (a0 >> 4) & 0xf; - const u8 alphaToOne = (a0 >> 8) & 0xf; - const u16 sampleMask = a0 >> 16; - - if (a0) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_ANTI_ALIASING_CONTROL: 0x%x", a0); - } - break; - } - - // Line/Polygon smoothing - case NV4097_SET_LINE_SMOOTH_ENABLE: - { - m_set_line_smooth = ARGS(0) ? true : false; - break; - } - - case NV4097_SET_POLY_SMOOTH_ENABLE: - { - m_set_poly_smooth = ARGS(0) ? true : false; - break; - } - - // Line width - case NV4097_SET_LINE_WIDTH: - { - m_set_line_width = true; - const u32 a0 = ARGS(0); - m_line_width = (float)a0 / 8.0f; - break; - } - - // Line/Polygon stipple - case NV4097_SET_LINE_STIPPLE: - { - m_set_line_stipple = ARGS(0) ? true : false; - break; - } - - case NV4097_SET_LINE_STIPPLE_PATTERN: - { - m_set_line_stipple = true; - const u32 a0 = ARGS(0); - m_line_stipple_factor = a0 & 0xffff; - m_line_stipple_pattern = a0 >> 16; - break; - } - - case NV4097_SET_POLYGON_STIPPLE: - { - m_set_polygon_stipple = ARGS(0) ? true : false; - break; - } - - case NV4097_SET_POLYGON_STIPPLE_PATTERN: - { - for (u32 i = 0; i < 32; i++) - { - m_polygon_stipple_pattern[i] = ARGS(i); - } - break; - } - - // Zcull - case NV4097_SET_ZCULL_EN: - { - const u32 a0 = ARGS(0); - - m_set_depth_test = a0 & 0x1 ? true : false; - m_set_stencil_test = a0 & 0x2 ? true : false; - notifyDepthStencilStateChange(); - break; - } - - case NV4097_SET_ZCULL_CONTROL0: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_ZCULL_CONTROL0: 0x%x", value); - } - break; - } - - case NV4097_SET_ZCULL_CONTROL1: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_ZCULL_CONTROL1: 0x%x", value); - } - break; - } - - case NV4097_SET_ZCULL_STATS_ENABLE: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_ZCULL_STATS_ENABLE: 0x%x", value); - } - break; - } - - case NV4097_ZCULL_SYNC: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_ZCULL_SYNC: 0x%x", value); - } - break; - } - - // Reports - case NV4097_GET_REPORT: - { - const u32 a0 = ARGS(0); - u8 type = a0 >> 24; - u32 offset = a0 & 0xffffff; - - u32 value; - switch(type) - { - case CELL_GCM_ZPASS_PIXEL_CNT: - case CELL_GCM_ZCULL_STATS: - case CELL_GCM_ZCULL_STATS1: - case CELL_GCM_ZCULL_STATS2: - case CELL_GCM_ZCULL_STATS3: - value = 0; - LOG_WARNING(RSX, "NV4097_GET_REPORT: Unimplemented type %d", type); - break; - - default: - value = 0; - LOG_ERROR(RSX, "NV4097_GET_REPORT: Bad type %d", type); - break; - } - - // Get timestamp, and convert it from microseconds to nanoseconds - u64 timestamp = get_system_time() * 1000; - - // NOTE: DMA broken, implement proper lpar mapping (sys_rsx) - //dma_write64(dma_report, offset + 0x0, timestamp); - //dma_write32(dma_report, offset + 0x8, value); - //dma_write32(dma_report, offset + 0xc, 0); - - vm::write64(m_local_mem_addr + offset + 0x0, timestamp); - vm::write32(m_local_mem_addr + offset + 0x8, value); - vm::write32(m_local_mem_addr + offset + 0xc, 0); - break; - } - - case NV4097_CLEAR_REPORT_VALUE: - { - const u32 type = ARGS(0); + u32 base_offset = method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET]; + u32 base_index = method_registers[NV4097_SET_VERTEX_DATA_BASE_INDEX]; switch (type) { - case CELL_GCM_ZPASS_PIXEL_CNT: - LOG_WARNING(RSX, "TODO: NV4097_CLEAR_REPORT_VALUE: ZPASS_PIXEL_CNT"); - break; - case CELL_GCM_ZCULL_STATS: - LOG_WARNING(RSX, "TODO: NV4097_CLEAR_REPORT_VALUE: ZCULL_STATS"); - break; - default: - LOG_ERROR(RSX, "NV4097_CLEAR_REPORT_VALUE: Bad type: %d", type); - break; - } - break; - } - - // Clip Plane - case NV4097_SET_USER_CLIP_PLANE_CONTROL: - { - const u32 a0 = ARGS(0); - m_set_clip_plane = true; - m_clip_plane_0 = (a0 & 0xf) ? true : false; - m_clip_plane_1 = ((a0 >> 4)) & 0xf ? true : false; - m_clip_plane_2 = ((a0 >> 8)) & 0xf ? true : false; - m_clip_plane_3 = ((a0 >> 12)) & 0xf ? true : false; - m_clip_plane_4 = ((a0 >> 16)) & 0xf ? true : false; - m_clip_plane_5 = (a0 >> 20) ? true : false; - break; - } - - // Fog - case NV4097_SET_FOG_MODE: - { - m_set_fog_mode = true; - m_fog_mode = ARGS(0); - break; - } - - case NV4097_SET_FOG_PARAMS: - { - m_set_fog_params = true; - const u32 a0 = ARGS(0); - const u32 a1 = ARGS(1); - m_fog_param0 = (float&)a0; - m_fog_param1 = (float&)a1; - break; - } - - // Zmin_max - case NV4097_SET_ZMIN_MAX_CONTROL: - { - const u8 cullNearFarEnable = ARGS(0) & 0xf; - const u8 zclampEnable = (ARGS(0) >> 4) & 0xf; - const u8 cullIgnoreW = (ARGS(0) >> 8) & 0xf; - - LOG_WARNING(RSX, "TODO: NV4097_SET_ZMIN_MAX_CONTROL: cullNearFarEnable=%d, zclampEnable=%d, cullIgnoreW=%d", cullNearFarEnable, zclampEnable, cullIgnoreW); - break; - } - - case NV4097_SET_WINDOW_OFFSET: - { - const u16 x = ARGS(0); - const u16 y = ARGS(0) >> 16; - - LOG_WARNING(RSX, "TODO: NV4097_SET_WINDOW_OFFSET: x=%d, y=%d", x, y); - break; - } - - case NV4097_SET_FREQUENCY_DIVIDER_OPERATION: - { - m_set_frequency_divider_operation = ARGS(0); - - LOG_WARNING(RSX, "TODO: NV4097_SET_FREQUENCY_DIVIDER_OPERATION: %d", m_set_frequency_divider_operation); - break; - } - - case NV4097_SET_RENDER_ENABLE: - { - const u32 offset = ARGS(0) & 0xffffff; - const u8 mode = ARGS(0) >> 24; - - LOG_WARNING(RSX, "TODO: NV4097_SET_RENDER_ENABLE: Offset=0x%06x, Mode=0x%x", offset, mode); - break; - } - - case NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE: - { - const u32 enable = ARGS(0); - - LOG_WARNING(RSX, "TODO: NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE: %d", enable); - break; - } - - // NV0039 - case NV0039_SET_CONTEXT_DMA_BUFFER_IN: - { - const u32 srcContext = ARGS(0); - const u32 dstContext = ARGS(1); - m_context_dma_buffer_in_src = srcContext; - m_context_dma_buffer_in_dst = dstContext; - break; - } - - case NV0039_OFFSET_IN: - { - const u32 inOffset = ARGS(0); - const u32 outOffset = ARGS(1); - const u32 inPitch = ARGS(2); - const u32 outPitch = ARGS(3); - const u32 lineLength = ARGS(4); - const u32 lineCount = ARGS(5); - const u8 outFormat = (ARGS(6) >> 8); - const u8 inFormat = (ARGS(6) >> 0); - const u32 notify = ARGS(7); - - // The existing GCM commands use only the value 0x1 for inFormat and outFormat - if (inFormat != 0x01 || outFormat != 0x01) - { - LOG_ERROR(RSX, "NV0039_OFFSET_IN: Unsupported format: inFormat=%d, outFormat=%d", inFormat, outFormat); - } - - if (lineCount == 1 && !inPitch && !outPitch && !notify) - { - memcpy(vm::get_ptr(GetAddress(outOffset, 0)), vm::get_ptr(GetAddress(inOffset, 0)), lineLength); - } - else - { - LOG_ERROR(RSX, "NV0039_OFFSET_IN: bad offset(in=0x%x, out=0x%x), pitch(in=0x%x, out=0x%x), line(len=0x%x, cnt=0x%x), fmt(in=0x%x, out=0x%x), notify=0x%x", - inOffset, outOffset, inPitch, outPitch, lineLength, lineCount, inFormat, outFormat, notify); - } - break; - } - - case NV0039_OFFSET_OUT: // [E : RSXThread]: TODO: unknown/illegal method [0x00002310](0x0) - { - const u32 offset = ARGS(0); - - if (!offset) - { - } - else - { - LOG_ERROR(RSX, "TODO: NV0039_OFFSET_OUT: offset=0x%x", offset); - } - break; - } - - case NV0039_PITCH_IN: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV0039_PITCH_IN: 0x%x", value); - } - break; - } - - case NV0039_BUFFER_NOTIFY: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV0039_BUFFER_NOTIFY: 0x%x", value); - } - break; - } - - // NV3062 - case NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN: - { - if (count == 1) - { - m_context_dma_img_dst = ARGS(0); - } - else - { - LOG_ERROR(RSX, "NV3062_SET_CONTEXT_DMA_IMAGE__DESTIN: unknown arg count (%d)", count); - } - break; - } - - case NV3062_SET_OFFSET_DESTIN: - { - if (count == 1) - { - m_dst_offset = ARGS(0); - } - else - { - LOG_ERROR(RSX, "NV3062_SET_OFFSET_DESTIN: unknown arg count (%d)", count); - } - break; - } - - case NV3062_SET_COLOR_FORMAT: - { - if (count == 2 || count == 4) - { - m_color_format = ARGS(0); - m_color_format_src_pitch = ARGS(1); - m_color_format_dst_pitch = ARGS(1) >> 16; - - if (count == 4) + case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: + for (u32 i = 0; i < count; ++i) { - if (ARGS(2)) + (u32&)vertex_index_array[dst_offset + i * sizeof(u32)] = vm::read32(address + (first + i) * sizeof(u32)); + } + break; + + case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: + for (u32 i = 0; i < count; ++i) + { + (u16&)vertex_index_array[dst_offset + i * sizeof(u16)] = vm::read16(address + (first + i) * sizeof(u16)); + } + break; + } + } + + void thread::begin() + { + draw_mode = method_registers[NV4097_SET_BEGIN_END]; + } + + void thread::end() + { + vertex_index_array.clear(); + for (auto &vertex_array : vertex_arrays) + vertex_array.clear(); + + fragment_constants.clear(); + transform_constants.clear(); + } + + void thread::task() + { + u8 inc; + LOG_NOTICE(RSX, "RSX thread started"); + + oninit_thread(); + + last_flip_time = get_system_time() - 1000000; + + autojoin_thread_t vblank(WRAP_EXPR("VBlank Thread"), [this]() + { + const u64 start_time = get_system_time(); + + vblank_count = 0; + + while (joinable()) + { + CHECK_EMU_STATUS; + + if (get_system_time() - start_time > vblank_count * 1000000 / 60) { - LOG_ERROR(RSX, "NV3062_SET_COLOR_FORMAT: unknown arg2 value (0x%x)", ARGS(2)); + vblank_count++; + + if (auto cb = vblank_handler) + { + Emu.GetCallbackManager().Async([=](CPUThread& cpu) + { + cb(static_cast(cpu), 1); + }); + } + + continue; } - m_dst_offset = ARGS(3); + std::this_thread::sleep_for(1ms); // hack } - } - else - { - LOG_ERROR(RSX, "NV3062_SET_COLOR_FORMAT: unknown arg count (%d)", count); - } - break; - } + }); - // NV309E - case NV309E_SET_CONTEXT_DMA_IMAGE: - { - if (count == 1) - { - m_context_dma_img_src = ARGS(0); - } - else - { - LOG_ERROR(RSX, "NV309E_SET_CONTEXT_DMA_IMAGE: unknown arg count (%d)", count); - } - break; - } - - case NV309E_SET_FORMAT: - { - if (count == 2) - { - m_swizzle_format = ARGS(0); - m_swizzle_width = ARGS(0) >> 16; - m_swizzle_height = ARGS(0) >> 24; - m_swizzle_offset = ARGS(1); - } - else - { - LOG_ERROR(RSX, "NV309E_SET_FORMAT: unknown arg count (%d)", count); - } - break; - } - - // NV308A - case NV308A_POINT: - { - const u32 a0 = ARGS(0); - m_point_x = a0 & 0xffff; - m_point_y = a0 >> 16; - break; - } - - case NV308A_COLOR: - { - RSXTransformConstant c; - c.id = m_dst_offset | ((u32)m_point_x << 2); - - if (count >= 1) - { - u32 a = ARGS(0); - a = a << 16 | a >> 16; - c.x = (float&)a; - } - - if (count >= 2) - { - u32 a = ARGS(1); - a = a << 16 | a >> 16; - c.y = (float&)a; - } - - if (count >= 3) - { - u32 a = ARGS(2); - a = a << 16 | a >> 16; - c.z = (float&)a; - } - - if (count >= 4) - { - u32 a = ARGS(3); - a = a << 16 | a >> 16; - c.w = (float&)a; - } - - if (count >= 5) - { - LOG_ERROR(RSX, "NV308A_COLOR: unknown arg count (%d)", count); - } - - m_fragment_constants.push_back(c); - - //LOG_WARNING(RSX, "NV308A_COLOR: [%d]: %f, %f, %f, %f", c.id, c.x, c.y, c.z, c.w); - break; - } - - // NV3089 - case NV3089_SET_CONTEXT_DMA_IMAGE: - { - if (count == 1) - { - m_context_dma_img_src = ARGS(0); - } - else - { - LOG_ERROR(RSX, "NV3089_SET_CONTEXT_DMA_IMAGE: unknown arg count (%d)", count); - } - break; - } - - case NV3089_SET_CONTEXT_SURFACE: - { - if (count == 1) - { - m_context_surface = ARGS(0); - - if (m_context_surface != CELL_GCM_CONTEXT_SURFACE2D && m_context_surface != CELL_GCM_CONTEXT_SWIZZLE2D) - { - LOG_ERROR(RSX, "NV3089_SET_CONTEXT_SURFACE: unknown surface (0x%x)", ARGS(0)); - } - } - else - { - LOG_ERROR(RSX, "NV3089_SET_CONTEXT_SURFACE: unknown arg count (%d)", count); - } - break; - } - - case NV3089_IMAGE_IN_SIZE: - { - const u16 width = ARGS(0); - const u16 height = ARGS(0) >> 16; - const u16 pitch = ARGS(1); - - const u8 origin = ARGS(1) >> 16; - if (origin != 2 /* CELL_GCM_TRANSFER_ORIGIN_CORNER */) - { - LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown origin (%d)", origin); - } - - const u8 inter = ARGS(1) >> 24; - if (inter != 0 /* CELL_GCM_TRANSFER_INTERPOLATOR_ZOH */ && inter != 1 /* CELL_GCM_TRANSFER_INTERPOLATOR_FOH */) - { - LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown inter (%d)", inter); - } - - const u32 offset = ARGS(2); - - const u16 u = ARGS(3); // inX (currently ignored) - const u16 v = ARGS(3) >> 16; // inY (currently ignored) - - u8* pixels_src = vm::get_ptr(GetAddress(offset, m_context_dma_img_src - 0xfeed0000)); - u8* pixels_dst = vm::get_ptr(GetAddress(m_dst_offset, m_context_dma_img_dst - 0xfeed0000)); - - if (m_context_surface == CELL_GCM_CONTEXT_SWIZZLE2D) - { - LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: Swizzle2D not implemented"); - } - else if (m_context_surface != CELL_GCM_CONTEXT_SURFACE2D) - { - LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown m_context_surface (0x%x)", m_context_surface); - } - - if (m_color_format != 4 /* CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5 */ && m_color_format != 10 /* CELL_GCM_TRANSFER_SURFACE_FORMAT_A8R8G8B8 */) - { - LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown m_color_format (%d)", m_color_format); - } - - const u32 in_bpp = m_color_format == 4 ? 2 : 4; // bytes per pixel - const u32 out_bpp = m_color_conv_fmt == 7 ? 2 : 4; - - const s32 out_w = (s32)(u64(width) * (1 << 20) / m_color_conv_dsdx); - const s32 out_h = (s32)(u64(height) * (1 << 20) / m_color_conv_dtdy); - - LOG_WARNING(RSX, "NV3089_IMAGE_IN_SIZE: w=%d, h=%d, pitch=%d, offset=0x%x, inX=%f, inY=%f, scaleX=%f, scaleY=%f", - width, height, pitch, offset, double(u) / 16, double(v) / 16, double(1 << 20) / (m_color_conv_dsdx), double(1 << 20) / (m_color_conv_dtdy)); - - std::unique_ptr temp; - - if (in_bpp != out_bpp && width != out_w && height != out_h) - { - // resize/convert if necessary - - temp.reset(new u8[out_bpp * out_w * out_h]); - - AVPixelFormat in_format = m_color_format == 4 ? AV_PIX_FMT_RGB565BE : AV_PIX_FMT_ARGB; // ??? - AVPixelFormat out_format = m_color_conv_fmt == 7 ? AV_PIX_FMT_RGB565BE : AV_PIX_FMT_ARGB; // ??? - - std::unique_ptr sws(sws_getContext(width, height, in_format, out_w, out_h, out_format, inter ? SWS_FAST_BILINEAR : SWS_POINT, NULL, NULL, NULL), sws_freeContext); - - int in_line = in_bpp * width; - u8* out_ptr = temp.get(); - int out_line = out_bpp * out_w; - - sws_scale(sws.get(), &pixels_src, &in_line, 0, height, &out_ptr, &out_line); - - pixels_src = temp.get(); // use resized image as a source - } - - if (m_color_conv_out_w != m_color_conv_clip_w || m_color_conv_out_w != out_w || - m_color_conv_out_h != m_color_conv_clip_h || m_color_conv_out_h != out_h || - m_color_conv_out_x || m_color_conv_out_y || m_color_conv_clip_x || m_color_conv_clip_y) - { - // clip if necessary - - for (s32 y = m_color_conv_clip_y, dst_y = m_color_conv_out_y; y < out_h; y++, dst_y++) - { - if (dst_y >= 0 && dst_y < m_color_conv_out_h) - { - // destination line - u8* dst_line = pixels_dst + dst_y * out_bpp * m_color_conv_out_w + std::min(std::max(m_color_conv_out_x, 0), m_color_conv_out_w); - size_t dst_max = std::min(std::max((s32)m_color_conv_out_w - m_color_conv_out_x, 0), m_color_conv_out_w) * out_bpp; - - if (y >= 0 && y < std::min(m_color_conv_clip_h, out_h)) - { - // source line - u8* src_line = pixels_src + y * out_bpp * out_w + std::min(std::max(m_color_conv_clip_x, 0), m_color_conv_clip_w); - size_t src_max = std::min(std::max((s32)m_color_conv_clip_w - m_color_conv_clip_x, 0), m_color_conv_clip_w) * out_bpp; - - std::pair - z0 = { src_line + 0, std::min(dst_max, std::max(0, m_color_conv_clip_x)) }, - d0 = { src_line + z0.second, std::min(dst_max - z0.second, src_max) }, - z1 = { src_line + d0.second, dst_max - z0.second - d0.second }; - - memset(z0.first, 0, z0.second); - memcpy(d0.first, src_line, d0.second); - memset(z1.first, 0, z1.second); - } - else - { - memset(dst_line, 0, dst_max); - } - } - } - } - else - { - memcpy(pixels_dst, pixels_src, out_w * out_h * out_bpp); - } - - break; - } - - case NV3089_SET_COLOR_CONVERSION: - { - m_color_conv = ARGS(0); - if (m_color_conv != 1 /* CELL_GCM_TRANSFER_CONVERSION_TRUNCATE */) - { - LOG_ERROR(RSX, "NV3089_SET_COLOR_CONVERSION: unknown color conv (%d)", m_color_conv); - } - - m_color_conv_fmt = ARGS(1); - if (m_color_conv_fmt != 3 /* CELL_GCM_TRANSFER_SCALE_FORMAT_A8R8G8B8 */ && m_color_conv_fmt != 7 /* CELL_GCM_TRANSFER_SCALE_FORMAT_R5G6B5 */) - { - LOG_ERROR(RSX, "NV3089_SET_COLOR_CONVERSION: unknown format (%d)", m_color_conv_fmt); - } - - m_color_conv_op = ARGS(2); - if (m_color_conv_op != 3 /* CELL_GCM_TRANSFER_OPERATION_SRCCOPY */) - { - LOG_ERROR(RSX, "NV3089_SET_COLOR_CONVERSION: unknown color conv op (%d)", m_color_conv_op); - } - - m_color_conv_clip_x = ARGS(3); - m_color_conv_clip_y = ARGS(3) >> 16; - m_color_conv_clip_w = ARGS(4); - m_color_conv_clip_h = ARGS(4) >> 16; - m_color_conv_out_x = ARGS(5); - m_color_conv_out_y = ARGS(5) >> 16; - m_color_conv_out_w = ARGS(6); - m_color_conv_out_h = ARGS(6) >> 16; - m_color_conv_dsdx = ARGS(7); - m_color_conv_dtdy = ARGS(8); - break; - } - - case GCM_SET_USER_COMMAND: - { - const u32 cause = ARGS(0); - - if (auto cb = m_user_handler) - { - Emu.GetCallbackManager().Async([=](CPUThread& cpu) - { - cb(static_cast(cpu), cause); - }); - } - else - { - throw EXCEPTION("User handler not set"); - } - - break; - } - - // Note: What is this? NV4097 offsets? - case 0x000002c8: - case 0x000002d0: - case 0x000002d8: - case 0x000002e0: - case 0x000002e8: - case 0x000002f0: - case 0x000002f8: - break; - - // The existing GCM commands don't use any of the following NV4097 / NV0039 / NV3062 / NV309E / NV308A / NV3089 methods - case NV4097_SET_WINDOW_CLIP_TYPE: - case NV4097_SET_WINDOW_CLIP_HORIZONTAL: - case NV4097_SET_WINDOW_CLIP_VERTICAL: - { - LOG_WARNING(RSX, "Unused NV4097 method 0x%x detected!", cmd); - break; - } - - case NV0039_SET_CONTEXT_DMA_BUFFER_OUT: - case NV0039_PITCH_OUT: - case NV0039_LINE_LENGTH_IN: - case NV0039_LINE_COUNT: - case NV0039_FORMAT: - case NV0039_SET_OBJECT: - case NV0039_SET_CONTEXT_DMA_NOTIFIES: - { - LOG_WARNING(RSX, "Unused NV0039 method 0x%x detected!", cmd); - break; - } - - case NV3062_SET_OBJECT: - case NV3062_SET_CONTEXT_DMA_NOTIFIES: - case NV3062_SET_CONTEXT_DMA_IMAGE_SOURCE: - case NV3062_SET_PITCH: - case NV3062_SET_OFFSET_SOURCE: - { - LOG_WARNING(RSX, "Unused NV3062 method 0x%x detected!", cmd); - break; - } - - case NV308A_SET_OBJECT: - case NV308A_SET_CONTEXT_DMA_NOTIFIES: - case NV308A_SET_CONTEXT_COLOR_KEY: - case NV308A_SET_CONTEXT_CLIP_RECTANGLE: - case NV308A_SET_CONTEXT_PATTERN: - case NV308A_SET_CONTEXT_ROP: - case NV308A_SET_CONTEXT_BETA1: - case NV308A_SET_CONTEXT_BETA4: - case NV308A_SET_CONTEXT_SURFACE: - case NV308A_SET_COLOR_CONVERSION: - case NV308A_SET_OPERATION: - case NV308A_SET_COLOR_FORMAT: - case NV308A_SIZE_OUT: - case NV308A_SIZE_IN: - { - LOG_WARNING(RSX, "Unused NV308A method 0x%x detected!", cmd); - break; - } - - case NV309E_SET_OBJECT: - case NV309E_SET_CONTEXT_DMA_NOTIFIES: - case NV309E_SET_OFFSET: - { - LOG_WARNING(RSX, "Unused NV309E method 0x%x detected!", cmd); - break; - } - - case NV3089_SET_OBJECT: - case NV3089_SET_CONTEXT_DMA_NOTIFIES: - case NV3089_SET_CONTEXT_PATTERN: - case NV3089_SET_CONTEXT_ROP: - case NV3089_SET_CONTEXT_BETA1: - case NV3089_SET_CONTEXT_BETA4: - case NV3089_SET_COLOR_FORMAT: - case NV3089_SET_OPERATION: - case NV3089_CLIP_POINT: - case NV3089_CLIP_SIZE: - case NV3089_IMAGE_OUT_POINT: - case NV3089_IMAGE_OUT_SIZE: - case NV3089_DS_DX: - case NV3089_DT_DY: - case NV3089_IMAGE_IN_FORMAT: - case NV3089_IMAGE_IN_OFFSET: - case NV3089_IMAGE_IN: - { - LOG_WARNING(RSX, "Unused NV3089 methods 0x%x detected!", cmd); - break; - } - - default: - { - std::string log = GetMethodName(cmd); - log += "("; - for (u32 i = 0; i < count; ++i) - { - log += (i ? ", " : "") + fmt::format("0x%x", ARGS(i)); - } - log += ")"; - LOG_ERROR(RSX, "TODO: %s", log.c_str()); - break; - } - } -} - -void RSXThread::Begin(u32 draw_mode) -{ - m_begin_end = 1; - m_draw_mode = draw_mode; - m_draw_array_count = 0; - m_draw_array_first = ~0; -} - -void RSXThread::End() -{ - Draw(); - - for (auto &vdata : m_vertex_data) - { - vdata.data.clear(); - } - - m_indexed_array.Reset(); - m_fragment_constants.clear(); - m_transform_constants.clear(); - m_cur_fragment_prog_num = 0; - - m_clear_surface_mask = 0; - m_begin_end = 0; - - OnReset(); -} - -void RSXThread::Task() -{ - u8 inc; - LOG_NOTICE(RSX, "RSX thread started"); - - OnInitThread(); - - m_last_flip_time = get_system_time() - 1000000; - - autojoin_thread_t vblank(WRAP_EXPR("VBlank Thread"), [this]() - { - const u64 start_time = get_system_time(); - - m_vblank_count = 0; + reset(); while (joinable()) { - CHECK_EMU_STATUS; - - if (get_system_time() - start_time > m_vblank_count * 1000000 / 60) + //TODO: async mode + if (Emu.IsStopped()) { - m_vblank_count++; - - if (auto cb = m_vblank_handler) - { - Emu.GetCallbackManager().Async([=](CPUThread& cpu) - { - cb(static_cast(cpu), 1); - }); - } + LOG_WARNING(RSX, "RSX thread aborted"); + break; } - else + std::lock_guard lock(cs_main); + + inc = 1; + + be_t get = ctrl->get; + be_t put = ctrl->put; + + if (put == get || !Emu.IsRunning()) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + continue; } - } - }); - while (joinable() && !Emu.IsStopped()) - { - std::lock_guard lock(m_cs_main); - - inc = 1; - - const be_t put = m_ctrl->put; - const be_t get = m_ctrl->get; - - if (put == get || !Emu.IsRunning()) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - continue; - } - - const u32 cmd = ReadIO32(get); - const u32 count = (cmd >> 18) & 0x7ff; - - if (Ini.RSXLogging.GetValue()) - { - LOG_NOTICE(Log::RSX, "%s (cmd=0x%x)", GetMethodName(cmd & 0xffff).c_str(), cmd); - } + const u32 cmd = ReadIO32(get); + const u32 count = (cmd >> 18) & 0x7ff; - if (cmd & CELL_GCM_METHOD_FLAG_JUMP) - { - u32 offs = cmd & 0x1fffffff; - //LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put); - m_ctrl->get.exchange(offs); - continue; - } - if (cmd & CELL_GCM_METHOD_FLAG_CALL) - { - m_call_stack.push(get + 4); - u32 offs = cmd & ~3; - //LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get); - m_ctrl->get.exchange(offs); - continue; - } - if (cmd == CELL_GCM_METHOD_FLAG_RETURN) - { - u32 get = m_call_stack.top(); - m_call_stack.pop(); - //LOG_WARNING(RSX, "rsx return(0x%x)", get); - m_ctrl->get.exchange(get); - continue; - } - if (cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT) - { - //LOG_WARNING(RSX, "rsx non increment cmd! 0x%x", cmd); - inc = 0; + if (cmd & CELL_GCM_METHOD_FLAG_JUMP) + { + u32 offs = cmd & 0x1fffffff; + //LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put); + ctrl->get.exchange(offs); + continue; + } + if (cmd & CELL_GCM_METHOD_FLAG_CALL) + { + m_call_stack.push(get + 4); + u32 offs = cmd & ~3; + //LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get); + ctrl->get.exchange(offs); + continue; + } + if (cmd == CELL_GCM_METHOD_FLAG_RETURN) + { + u32 get = m_call_stack.top(); + m_call_stack.pop(); + //LOG_WARNING(RSX, "rsx return(0x%x)", get); + ctrl->get.exchange(get); + continue; + } + if (cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT) + { + //LOG_WARNING(RSX, "rsx non increment cmd! 0x%x", cmd); + inc = 0; + } + + if (cmd == 0) //nop + { + ctrl->get.atomic_op([](be_t& value) + { + value += 4; + }); + + continue; + } + + auto args = vm::ptr::make((u32)RSXIOMem.RealAddr(get + 4)); + + u32 first_cmd = (cmd & 0xffff) >> 2; + + if (cmd & 0x3) + { + LOG_WARNING(Log::RSX, "unaligned command: %s (0x%x from 0x%x)", get_method_name(first_cmd).c_str(), first_cmd, cmd & 0xffff); + } + + for (u32 i = 0; i < count; i++) + { + u32 reg = first_cmd + (i * inc); + u32 value = args[i]; + + if (Ini.RSXLogging.GetValue()) + { + LOG_NOTICE(Log::RSX, "%s(0x%x) = 0x%x", get_method_name(reg).c_str(), reg, value); + } + + method_registers[reg] = value; + + if (auto method = methods[reg]) + method(this, value); + } + + ctrl->get.atomic_op([count](be_t& value) + { + value += (count + 1) * 4; + }); } - if (cmd == 0) //nop - { - m_ctrl->get += 4; - continue; - } + LOG_NOTICE(RSX, "RSX thread ended"); - auto args = vm::ptr::make((u32)RSXIOMem.RealAddr(get + 4)); - - for (u32 i = 0; i < count; i++) - { - methodRegisters[(cmd & 0xffff) + (i * 4 * inc)] = ARGS(i); - } - - DoCmd(cmd, cmd & 0x3ffff, args.addr(), count); - - m_ctrl->get += (count + 1) * 4; + onexit_thread(); } - OnExitThread(); -} - -void RSXThread::Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress) -{ - m_ctrl = vm::get_ptr(ctrlAddress); - m_ioAddress = ioAddress; - m_ioSize = ioSize; - m_ctrlAddress = ctrlAddress; - m_local_mem_addr = localAddress; - - m_cur_vertex_prog = nullptr; - m_cur_fragment_prog = nullptr; - m_cur_fragment_prog_num = 0; - - m_used_gcm_commands.clear(); - - OnInit(); - - start(WRAP_EXPR("RSXThread"), WRAP_EXPR(Task())); -} - -u32 RSXThread::ReadIO32(u32 addr) -{ - u32 value; - - if (!RSXIOMem.Read32(addr, &value)) + u64 thread::timestamp() const { - throw EXCEPTION("RSXIO memory not mapped (addr=0x%x)", addr); + // Get timestamp, and convert it from microseconds to nanoseconds + return get_system_time() * 1000; } - return value; -} - -void RSXThread::WriteIO32(u32 addr, u32 value) -{ - if (!RSXIOMem.Write32(addr, value)) + void thread::reset() { - throw EXCEPTION("RSXIO memory not mapped (addr=0x%x)", addr); + //setup method registers + memset(method_registers, 0, sizeof(method_registers)); + + method_registers[NV4097_SET_COLOR_MASK] = CELL_GCM_COLOR_MASK_R | CELL_GCM_COLOR_MASK_G | CELL_GCM_COLOR_MASK_B | CELL_GCM_COLOR_MASK_A; + method_registers[NV4097_SET_SCISSOR_HORIZONTAL] = (4096 << 16) | 0; + method_registers[NV4097_SET_SCISSOR_VERTICAL] = (4096 << 16) | 0; + + method_registers[NV4097_SET_ALPHA_FUNC] = CELL_GCM_ALWAYS; + method_registers[NV4097_SET_ALPHA_REF] = 0; + + method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] = (CELL_GCM_ONE << 16) | CELL_GCM_ONE; + method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] = (CELL_GCM_ZERO << 16) | CELL_GCM_ZERO; + method_registers[NV4097_SET_BLEND_COLOR] = 0; + method_registers[NV4097_SET_BLEND_COLOR2] = 0; + method_registers[NV4097_SET_BLEND_EQUATION] = (CELL_GCM_FUNC_ADD << 16) | CELL_GCM_FUNC_ADD; + + method_registers[NV4097_SET_STENCIL_MASK] = 0xff; + method_registers[NV4097_SET_STENCIL_FUNC] = CELL_GCM_ALWAYS; + method_registers[NV4097_SET_STENCIL_FUNC_REF] = 0x00; + method_registers[NV4097_SET_STENCIL_FUNC_MASK] = 0xff; + method_registers[NV4097_SET_STENCIL_OP_FAIL] = CELL_GCM_KEEP; + method_registers[NV4097_SET_STENCIL_OP_ZFAIL] = CELL_GCM_KEEP; + method_registers[NV4097_SET_STENCIL_OP_ZPASS] = CELL_GCM_KEEP; + + method_registers[NV4097_SET_BACK_STENCIL_MASK] = 0xff; + method_registers[NV4097_SET_BACK_STENCIL_FUNC] = CELL_GCM_ALWAYS; + method_registers[NV4097_SET_BACK_STENCIL_FUNC_REF] = 0x00; + method_registers[NV4097_SET_BACK_STENCIL_FUNC_MASK] = 0xff; + method_registers[NV4097_SET_BACK_STENCIL_OP_FAIL] = CELL_GCM_KEEP; + method_registers[NV4097_SET_BACK_STENCIL_OP_ZFAIL] = CELL_GCM_KEEP; + method_registers[NV4097_SET_BACK_STENCIL_OP_ZPASS] = CELL_GCM_KEEP; + + method_registers[NV4097_SET_SHADE_MODE] = CELL_GCM_SMOOTH; + + method_registers[NV4097_SET_LOGIC_OP] = CELL_GCM_COPY; + + (f32&)method_registers[NV4097_SET_DEPTH_BOUNDS_MIN] = 0.f; + (f32&)method_registers[NV4097_SET_DEPTH_BOUNDS_MAX] = 1.f; + + (f32&)method_registers[NV4097_SET_CLIP_MIN] = 0.f; + (f32&)method_registers[NV4097_SET_CLIP_MAX] = 1.f; + + method_registers[NV4097_SET_LINE_WIDTH] = 1 << 3; + + method_registers[NV4097_SET_FOG_MODE] = CELL_GCM_FOG_MODE_EXP; + + method_registers[NV4097_SET_DEPTH_FUNC] = CELL_GCM_LESS; + method_registers[NV4097_SET_DEPTH_MASK] = CELL_GCM_TRUE; + (f32&)method_registers[NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR] = 0.f; + (f32&)method_registers[NV4097_SET_POLYGON_OFFSET_BIAS] = 0.f; + method_registers[NV4097_SET_FRONT_POLYGON_MODE] = CELL_GCM_POLYGON_MODE_FILL; + method_registers[NV4097_SET_BACK_POLYGON_MODE] = CELL_GCM_POLYGON_MODE_FILL; + method_registers[NV4097_SET_CULL_FACE] = CELL_GCM_BACK; + method_registers[NV4097_SET_FRONT_FACE] = CELL_GCM_CCW; + method_registers[NV4097_SET_RESTART_INDEX] = -1; + + method_registers[NV4097_SET_CLEAR_RECT_HORIZONTAL] = (4096 << 16) | 0; + method_registers[NV4097_SET_CLEAR_RECT_VERTICAL] = (4096 << 16) | 0; + + method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] = 0xffffffff; + + // Construct Textures + for (int i = 0; i < limits::textures_count; i++) + { + textures[i].init(i); + } + } + + void thread::init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress) + { + ctrl = vm::get_ptr(ctrlAddress); + this->ioAddress = ioAddress; + this->ioSize = ioSize; + local_mem_addr = localAddress; + + m_used_gcm_commands.clear(); + + oninit(); + named_thread_t::start(WRAP_EXPR("rsx::thread"), WRAP_EXPR(task())); + } + + u32 thread::ReadIO32(u32 addr) + { + u32 value; + + if (!RSXIOMem.Read32(addr, &value)) + { + throw EXCEPTION("%s(addr=0x%x): RSXIO memory not mapped", __FUNCTION__, addr); + } + + return value; + } + + void thread::WriteIO32(u32 addr, u32 value) + { + if (!RSXIOMem.Write32(addr, value)) + { + throw EXCEPTION("%s(addr=0x%x): RSXIO memory not mapped", __FUNCTION__, addr); + } } } diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 23907e1fca..bd266e1080 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -8,721 +8,223 @@ #include "Utilities/Semaphore.h" #include "Utilities/Thread.h" #include "Utilities/Timer.h" +#include "Utilities/types.h" -enum Method +namespace rsx { - CELL_GCM_METHOD_FLAG_NON_INCREMENT = 0x40000000, - CELL_GCM_METHOD_FLAG_JUMP = 0x20000000, - CELL_GCM_METHOD_FLAG_CALL = 0x00000002, - CELL_GCM_METHOD_FLAG_RETURN = 0x00020000, -}; - -extern u32 methodRegisters[0xffff]; -u32 GetAddress(u32 offset, u32 location); - -struct RSXVertexData -{ - u32 frequency; - u32 stride; - u32 size; - u32 type; - u32 addr; - u32 constant_count; - - std::vector data; - - RSXVertexData(); - - void Reset(); - bool IsEnabled() const { return size > 0; } - void Load(u32 start, u32 count, u32 baseOffset, u32 baseIndex); - - u32 GetTypeSize() const; -}; - -struct RSXIndexArrayData -{ - std::vector m_data; - int m_type; - u32 m_first; - u32 m_count; - u32 m_addr; - u32 index_max; - u32 index_min; - - RSXIndexArrayData() + namespace limits { - Reset(); - } - - void Reset() - { - m_type = 0; - m_first = ~0; - m_count = 0; - m_addr = 0; - index_min = ~0; - index_max = 0; - m_data.clear(); - } -}; - -struct RSXTransformConstant -{ - u32 id; - float x, y, z, w; - - RSXTransformConstant() - : x(0.0f) - , y(0.0f) - , z(0.0f) - , w(0.0f) - { - } - - RSXTransformConstant(u32 id, float x, float y, float z, float w) - : id(id) - , x(x) - , y(y) - , z(z) - , w(w) - { - } -}; - -class RSXThread : protected named_thread_t -{ -public: - static const uint m_textures_count = 16; - static const uint m_vertex_count = 32; - static const uint m_fragment_count = 32; - static const uint m_tiles_count = 15; - static const uint m_zculls_count = 8; - -protected: - std::stack m_call_stack; - CellGcmControl* m_ctrl; - Timer m_timer_sync; - -public: - GcmTileInfo m_tiles[m_tiles_count]; - GcmZcullInfo m_zculls[m_zculls_count]; - RSXTexture m_textures[m_textures_count]; - RSXVertexTexture m_vertex_textures[m_textures_count]; - RSXVertexData m_vertex_data[m_vertex_count]; - RSXIndexArrayData m_indexed_array; - std::vector m_fragment_constants; - std::vector m_transform_constants; - - u32 m_shader_ctrl, m_cur_fragment_prog_num; - RSXFragmentProgram m_fragment_progs[m_fragment_count]; - RSXFragmentProgram* m_cur_fragment_prog; - RSXVertexProgram m_vertex_progs[m_vertex_count]; - RSXVertexProgram* m_cur_vertex_prog; - -public: - u32 m_ioAddress, m_ioSize, m_ctrlAddress; - int m_flip_status; - int m_flip_mode; - int m_debug_level; - int m_frequency_mode; - - u32 m_tiles_addr; - u32 m_zculls_addr; - u32 m_gcm_buffers_addr; - u32 m_gcm_buffers_count; - u32 m_gcm_current_buffer; - u32 m_ctxt_addr; - u32 m_report_main_addr; - u32 m_label_addr; - - // DMA - u32 dma_report; - - u32 m_local_mem_addr, m_main_mem_addr; - bool m_strict_ordering[0x1000]; - -public: - uint m_draw_mode; - - u32 m_width; - u32 m_height; - float m_width_scale; - float m_height_scale; - u32 m_draw_array_count; - u32 m_draw_array_first; - double m_fps_limit = 59.94; - -public: - std::mutex m_cs_main; - semaphore_t m_sem_flip; - u64 m_last_flip_time; - vm::ptr m_flip_handler; - vm::ptr m_user_handler; - u64 m_vblank_count; - vm::ptr m_vblank_handler; - -public: - // Dither - bool m_set_dither; - - // Color mask - bool m_set_color_mask; - bool m_color_mask_r; - bool m_color_mask_g; - bool m_color_mask_b; - bool m_color_mask_a; - - // Clip - bool m_set_clip; - float m_clip_min; - float m_clip_max; - - // Depth test - bool m_set_depth_test; - bool m_set_depth_func; - int m_depth_func; - bool m_set_depth_mask; - u32 m_depth_mask; - - // Depth bound test - bool m_set_depth_bounds_test; - bool m_set_depth_bounds; - float m_depth_bounds_min; - float m_depth_bounds_max; - - // Primitive restart - bool m_set_restart_index; - u32 m_restart_index; - - // Point - bool m_set_point_size; - bool m_set_point_sprite_control; - float m_point_size; - u16 m_point_x; - u16 m_point_y; - - // Line smooth - bool m_set_line_smooth; - - // Viewport & scissor - bool m_set_viewport_horizontal; - bool m_set_viewport_vertical; - u16 m_viewport_x; - u16 m_viewport_y; - u16 m_viewport_w; - u16 m_viewport_h; - bool m_set_scissor_horizontal; - bool m_set_scissor_vertical; - u16 m_scissor_x; - u16 m_scissor_y; - u16 m_scissor_w; - u16 m_scissor_h; - - // Polygon mode/offset - bool m_set_poly_smooth; - bool m_set_poly_offset_fill; - bool m_set_poly_offset_line; - bool m_set_poly_offset_point; - bool m_set_front_polygon_mode; - u32 m_front_polygon_mode; - bool m_set_back_polygon_mode; - u32 m_back_polygon_mode; - bool m_set_poly_offset_mode; - float m_poly_offset_scale_factor; - float m_poly_offset_bias; - - // Line/Polygon stipple - bool m_set_line_stipple; - u16 m_line_stipple_pattern; - u16 m_line_stipple_factor; - bool m_set_polygon_stipple; - u32 m_polygon_stipple_pattern[32]; - - // Logic Ops - bool m_set_logic_op; - u32 m_logic_op; - - // Clearing - u32 m_clear_surface_mask; - u32 m_clear_surface_z; - u8 m_clear_surface_s; - u8 m_clear_surface_color_r; - u8 m_clear_surface_color_g; - u8 m_clear_surface_color_b; - u8 m_clear_surface_color_a; - u8 m_clear_color_r; - u8 m_clear_color_g; - u8 m_clear_color_b; - u8 m_clear_color_a; - u8 m_clear_s; - u32 m_clear_z; - - // Blending - bool m_set_blend; - bool m_set_blend_dfactor; - u16 m_blend_dfactor_rgb; - u16 m_blend_dfactor_alpha; - bool m_set_blend_sfactor; - u16 m_blend_sfactor_rgb; - u16 m_blend_sfactor_alpha; - bool m_set_blend_equation; - u16 m_blend_equation_rgb; - u16 m_blend_equation_alpha; - bool m_set_blend_color; - u8 m_blend_color_r; - u8 m_blend_color_g; - u8 m_blend_color_b; - u8 m_blend_color_a; - bool m_set_blend_mrt1; - bool m_set_blend_mrt2; - bool m_set_blend_mrt3; - - // Stencil Test - bool m_set_stencil_test; - bool m_set_stencil_mask; - u32 m_stencil_mask; - bool m_set_stencil_func; - u32 m_stencil_func; - bool m_set_stencil_func_ref; - u32 m_stencil_func_ref; - bool m_set_stencil_func_mask; - u32 m_stencil_func_mask; - bool m_set_stencil_fail; - u32 m_stencil_fail; - bool m_set_stencil_zfail; - u32 m_stencil_zfail; - bool m_set_stencil_zpass; - u32 m_stencil_zpass; - bool m_set_two_sided_stencil_test_enable; - bool m_set_two_side_light_enable; - bool m_set_back_stencil_mask; - u32 m_back_stencil_mask; - bool m_set_back_stencil_func; - u32 m_back_stencil_func; - bool m_set_back_stencil_func_ref; - u32 m_back_stencil_func_ref; - bool m_set_back_stencil_func_mask; - u32 m_back_stencil_func_mask; - bool m_set_back_stencil_fail; - u32 m_back_stencil_fail; - bool m_set_back_stencil_zfail; - u32 m_back_stencil_zfail; - bool m_set_back_stencil_zpass; - u32 m_back_stencil_zpass; - bool m_set_stencil_op_fail; - - // Line width - bool m_set_line_width; - float m_line_width; - - // Shader mode - bool m_set_shade_mode; - u32 m_shade_mode; - - // Lighting - bool m_set_specular; - - // Color - u32 m_color_format; - u16 m_color_format_src_pitch; - u16 m_color_format_dst_pitch; - u32 m_color_conv; - u32 m_color_conv_fmt; - u32 m_color_conv_op; - s16 m_color_conv_clip_x; - s16 m_color_conv_clip_y; - u16 m_color_conv_clip_w; - u16 m_color_conv_clip_h; - s16 m_color_conv_out_x; - s16 m_color_conv_out_y; - u16 m_color_conv_out_w; - u16 m_color_conv_out_h; - s32 m_color_conv_dsdx; - s32 m_color_conv_dtdy; - - // Semaphore - // PGRAPH - u32 m_PGRAPH_semaphore_offset; - //PFIFO - u32 m_PFIFO_semaphore_offset; - u32 m_PFIFO_semaphore_release_value; - - // Fog - bool m_set_fog_mode; - u32 m_fog_mode; - bool m_set_fog_params; - float m_fog_param0; - float m_fog_param1; - - // Clip plane - bool m_set_clip_plane; - bool m_clip_plane_0; - bool m_clip_plane_1; - bool m_clip_plane_2; - bool m_clip_plane_3; - bool m_clip_plane_4; - bool m_clip_plane_5; - - // Surface - bool m_set_surface_format; - u8 m_surface_color_format; - u8 m_surface_depth_format; - u8 m_surface_type; - u8 m_surface_antialias; - u8 m_surface_width; - u8 m_surface_height; - bool m_set_surface_clip_horizontal; - u16 m_surface_clip_x; - u16 m_surface_clip_w; - bool m_set_surface_clip_vertical; - u16 m_surface_clip_y; - u16 m_surface_clip_h; - u32 m_surface_pitch_a; - u32 m_surface_pitch_b; - u32 m_surface_pitch_c; - u32 m_surface_pitch_d; - u32 m_surface_pitch_z; - u32 m_surface_offset_a; - u32 m_surface_offset_b; - u32 m_surface_offset_c; - u32 m_surface_offset_d; - u32 m_surface_offset_z; - u32 m_surface_color_target; - - // DMA context - bool m_set_context_dma_color_a; - u32 m_context_dma_color_a; - bool m_set_context_dma_color_b; - u32 m_context_dma_color_b; - bool m_set_context_dma_color_c; - u32 m_context_dma_color_c; - bool m_set_context_dma_color_d; - u32 m_context_dma_color_d; - bool m_set_context_dma_z; - u32 m_context_dma_z; - u32 m_context_surface; - u32 m_context_dma_img_src; - u32 m_context_dma_img_dst; - u32 m_context_dma_buffer_in_src; - u32 m_context_dma_buffer_in_dst; - u32 m_dst_offset; - - // Swizzle2D? - u16 m_swizzle_format; - u8 m_swizzle_width; - u8 m_swizzle_height; - u32 m_swizzle_offset; - - // Cull face - bool m_set_cull_face; - u32 m_cull_face; - - // Alpha test - bool m_set_alpha_test; - bool m_set_alpha_func; - u32 m_alpha_func; - bool m_set_alpha_ref; - float m_alpha_ref; - - // Shader - u16 m_shader_window_height; - u8 m_shader_window_origin; - u16 m_shader_window_pixel_centers; - - // Vertex Data - u32 m_vertex_data_base_offset; - u32 m_vertex_data_base_index; - - // Front face - bool m_set_front_face; - u32 m_front_face; - - // Frequency divider - u32 m_set_frequency_divider_operation; - - u8 m_begin_end; - bool m_read_buffer; - - std::set m_used_gcm_commands; - -protected: - RSXThread() - : m_ctrl(nullptr) - , m_shader_ctrl(0x40) - , m_flip_status(0) - , m_flip_mode(CELL_GCM_DISPLAY_VSYNC) - , m_debug_level(CELL_GCM_DEBUG_LEVEL0) - , m_frequency_mode(CELL_GCM_DISPLAY_FREQUENCY_DISABLE) - , m_report_main_addr(0) - , m_main_mem_addr(0) - , m_local_mem_addr(0) - , m_draw_mode(0) - , m_draw_array_count(0) - , m_draw_array_first(~0) - , m_gcm_current_buffer(0) - , m_read_buffer(true) - { - m_flip_handler.set(0); - m_vblank_handler.set(0); - m_user_handler.set(0); - m_set_depth_test = false; - m_set_alpha_test = false; - m_set_depth_bounds_test = false; - m_set_blend = false; - m_set_blend_mrt1 = false; - m_set_blend_mrt2 = false; - m_set_blend_mrt3 = false; - m_set_logic_op = false; - m_set_cull_face = false; - m_set_dither = false; - m_set_stencil_test = false; - m_set_scissor_horizontal = false; - m_set_scissor_vertical = false; - m_set_line_smooth = false; - m_set_poly_smooth = false; - m_set_point_sprite_control = false; - m_set_specular = false; - m_set_two_sided_stencil_test_enable = false; - m_set_two_side_light_enable = false; - m_set_surface_clip_horizontal = false; - m_set_surface_clip_vertical = false; - m_set_poly_offset_fill = false; - m_set_poly_offset_line = false; - m_set_poly_offset_point = false; - m_set_restart_index = false; - m_set_line_stipple = false; - m_set_polygon_stipple = false; - - // Default value - // TODO: Check against the default value on PS3 - m_clear_color_r = 0; - m_clear_color_g = 0; - m_clear_color_b = 0; - m_clear_color_a = 0; - m_clear_z = 0xffffff; - m_clear_s = 0; - m_poly_offset_scale_factor = 0.0; - m_poly_offset_bias = 0.0; - m_restart_index = 0xffffffff; - m_front_polygon_mode = 0x1b02; // GL_FILL - m_back_polygon_mode = 0x1b02; // GL_FILL - m_front_face = 0x0901; // GL_CCW - m_cull_face = 0x0405; // GL_BACK - m_alpha_func = 0x0207; // GL_ALWAYS - m_alpha_ref = 0.0f; - m_logic_op = 0x1503; // GL_COPY - m_shade_mode = 0x1D01; // GL_SMOOTH - m_depth_mask = 1; - m_depth_func = 0x0201; // GL_LESS - m_depth_bounds_min = 0.0; - m_depth_bounds_max = 1.0; - m_clip_min = 0.0; - m_clip_max = 1.0; - m_blend_equation_rgb = 0x8006; // GL_FUNC_ADD - m_blend_equation_alpha = 0x8006; // GL_FUNC_ADD - m_blend_sfactor_rgb = 1; // GL_ONE - m_blend_dfactor_rgb = 0; // GL_ZERO - m_blend_sfactor_alpha = 1; // GL_ONE - m_blend_dfactor_alpha = 0; // GL_ZERO - m_point_x = 0; - m_point_y = 0; - m_point_size = 1.0; - m_line_width = 1.0; - m_line_stipple_pattern = 0xffff; - m_line_stipple_factor = 1; - m_vertex_data_base_offset = 0; - m_vertex_data_base_index = 0; - - // Construct Stipple Pattern - for (size_t i = 0; i < 32; i++) + enum { - m_polygon_stipple_pattern[i] = 0xFFFFFFFF; - } - - // Construct Textures - for (int i = 0; i < 16; i++) - { - m_textures[i] = RSXTexture(i); - } - - Reset(); + textures_count = 16, + vertex_textures_count = 4, + vertex_count = 16, + fragment_count = 32, + tiles_count = 15, + zculls_count = 8, + color_buffers_count = 4 + }; } - virtual ~RSXThread() override + //TODO + union alignas(4) method_registers_t { - } - - void Reset() - { - m_set_dither = false; - m_set_color_mask = false; - m_set_clip = false; - m_set_depth_test = false; - m_set_depth_func = false; - m_set_depth_mask = false; - m_set_depth_bounds_test = false; - m_set_depth_bounds = false; - m_set_viewport_horizontal = false; - m_set_viewport_vertical = false; - m_set_scissor_horizontal = false; - m_set_scissor_vertical = false; - m_set_front_polygon_mode = false; - m_set_back_polygon_mode = false; - m_set_blend = false; - m_set_blend_mrt1 = false; - m_set_blend_mrt2 = false; - m_set_blend_mrt3 = false; - m_set_blend_sfactor = false; - m_set_blend_dfactor = false; - m_set_blend_equation = false; - m_set_blend_color = false; - m_set_stencil_test = false; - m_set_two_sided_stencil_test_enable = false; - m_set_two_side_light_enable = false; - m_set_stencil_mask = false; - m_set_stencil_func = false; - m_set_stencil_func_ref = false; - m_set_stencil_func_mask = false; - m_set_stencil_fail = false; - m_set_stencil_zfail = false; - m_set_stencil_zpass = false; - m_set_back_stencil_mask = false; - m_set_back_stencil_func = false; - m_set_back_stencil_func_ref = false; - m_set_back_stencil_func_mask = false; - m_set_back_stencil_fail = false; - m_set_back_stencil_zfail = false; - m_set_back_stencil_zpass = false; - m_set_stencil_op_fail = false; - m_set_point_sprite_control = false; - m_set_point_size = false; - m_set_line_width = false; - m_set_line_smooth = false; - m_set_shade_mode = false; - m_set_fog_mode = false; - m_set_fog_params = false; - m_set_clip_plane = false; - m_set_context_dma_color_a = false; - m_set_context_dma_color_b = false; - m_set_context_dma_color_c = false; - m_set_context_dma_color_d = false; - m_set_context_dma_z = false; - m_set_cull_face = false; - m_set_front_face = false; - m_set_alpha_test = false; - m_set_alpha_func = false; - m_set_alpha_ref = false; - m_set_poly_smooth = false; - m_set_poly_offset_fill = false; - m_set_poly_offset_line = false; - m_set_poly_offset_point = false; - m_set_poly_offset_mode = false; - m_set_restart_index = false; - m_set_specular = false; - m_set_line_stipple = false; - m_set_polygon_stipple = false; - m_set_logic_op = false; - m_set_surface_format = false; - m_set_surface_clip_horizontal = false; - m_set_surface_clip_vertical = false; - - m_clear_surface_mask = 0; - m_begin_end = 0; - - for (uint i = 0; i < m_textures_count; ++i) + u8 _u8[0x10000]; + u32 _u32[0x10000 >> 2]; +/* + struct { - m_textures[i].Init(); - } - } + u8 pad[NV4097_SET_TEXTURE_OFFSET - 4]; - void Begin(u32 draw_mode); - void End(); + struct texture_t + { + u32 offset; - u32 OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr); - void DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 count); + union format_t + { + u32 _u32; - virtual void OnInit() = 0; - virtual void OnInitThread() = 0; - virtual void OnExitThread() = 0; - virtual void OnReset() = 0; + struct + { + u32: 1; + u32 location : 1; + u32 cubemap : 1; + u32 border_type : 1; + u32 dimension : 4; + u32 format : 8; + u32 mipmap : 16; + }; + } format; - /** - * This member is called when the backend is expected to render a draw call, either - * indexed or not. - */ - virtual void Draw() = 0; + union address_t + { + u32 _u32; - /** - * This member is called when the backend is expected to clear a target surface. - */ - virtual void Clear(u32 cmd) = 0; + struct + { + u32 wrap_s : 4; + u32 aniso_bias : 4; + u32 wrap_t : 4; + u32 unsigned_remap : 4; + u32 wrap_r : 4; + u32 gamma : 4; + u32 signed_remap : 4; + u32 zfunc : 4; + }; + } address; - /** - * This member is called when the backend is expected to present a target surface in - * either local or main memory. - */ - virtual void Flip() = 0; - - /** - * This member is called when RSXThread parse a TEXTURE_READ_SEMAPHORE_RELEASE - * command. - * Backend is expected to write value at offset when current draw textures aren't - * needed anymore by the GPU and can be modified. - */ - virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) = 0; - /** - * This member is called when RSXThread parse a BACK_END_WRITE_SEMAPHORE_RELEASE - * command. - * Backend is expected to write value at offset when current draw call has completed - * and render surface can be used. - */ - virtual void semaphorePGRAPHBackendRelease(u32 offset, u32 value) = 0; - /** - * This member is called when RSXThread parse a SEMAPHORE_ACQUIRE command. - * Backend and associated GPU is expected to wait that memory at offset is the same - * as value. In particular buffer/texture buffers value can change while backend is - * waiting. - */ - virtual void semaphorePFIFOAcquire(u32 offset, u32 value) = 0; - /** - * Called when vertex or fragment shader changes. - * Backend can reuse same program if no change has been notified. - */ - virtual void notifyProgramChange() = 0; - /** - * Called when blend state changes. - * Backend can reuse same program if no change has been notified. - */ - virtual void notifyBlendStateChange() = 0; - /** - * Called when depth stencil state changes. - * Backend can reuse same program if no change has been notified. - */ - virtual void notifyDepthStencilStateChange() = 0; - /** - * Called when rasterizer state changes. - * Rasterizer state includes culling, color masking - * Backend can reuse same program if no change has been notified. - */ - virtual void notifyRasterizerStateChange() = 0; - - void LoadVertexData(u32 first, u32 count) - { - for (u32 i = 0; i < m_vertex_count; ++i) + u32 control0; + u32 control1; + u32 filter; + u32 image_rect; + u32 border_color; + } textures[limits::textures_count]; + }; +*/ + u32& operator[](int index) { - if (!m_vertex_data[i].IsEnabled()) continue; - - m_vertex_data[i].Load(first, count, m_vertex_data_base_offset, m_vertex_data_base_index); + return _u32[index >> 2]; } - } + }; - virtual void Task(); + extern u32 method_registers[0x10000 >> 2]; -public: - void Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress); + u32 get_address(u32 offset, u32 location); + u32 linear_to_swizzle(u32 x, u32 y, u32 z, u32 log2_width, u32 log2_height, u32 log2_depth); - u32 ReadIO32(u32 addr); + u32 get_vertex_type_size(u32 type); - void WriteIO32(u32 addr, u32 value); -}; + struct surface_info + { + u8 log2height; + u8 log2width; + u8 antialias; + u8 depth_format; + u8 color_format; + + u32 width; + u32 height; + u32 format; + + void unpack(u32 surface_format) + { + format = surface_format; + + log2height = surface_format >> 24; + log2width = (surface_format >> 16) & 0xff; + antialias = (surface_format >> 12) & 0xf; + depth_format = (surface_format >> 5) & 0x7; + color_format = surface_format & 0x1f; + + width = 1 << (u32(log2width) + 1); + height = 1 << (u32(log2width) + 1); + } + }; + + struct data_array_format_info + { + u16 frequency = 0; + u8 stride = 0; + u8 size = 0; + u8 type = CELL_GCM_VERTEX_F; + bool array = false; + + void unpack(u32 data_array_format) + { + frequency = data_array_format >> 16; + stride = (data_array_format >> 8) & 0xff; + size = (data_array_format >> 4) & 0xf; + type = data_array_format & 0xf; + } + }; + + class thread : protected named_thread_t + { + protected: + std::stack m_call_stack; + + public: + CellGcmControl* ctrl = nullptr; + + Timer timer_sync; + + GcmTileInfo tiles[limits::tiles_count]; + GcmZcullInfo zculls[limits::zculls_count]; + + rsx::texture textures[limits::textures_count]; + rsx::vertex_texture vertex_textures[limits::vertex_textures_count]; + + data_array_format_info vertex_arrays_info[limits::vertex_count]; + std::vector vertex_arrays[limits::vertex_count]; + std::vector vertex_index_array; + u32 vertex_draw_count = 0; + + std::unordered_map> fragment_constants; + std::unordered_map> transform_constants; + + u32 transform_program[512 * 4] = {}; + + void load_vertex_data(u32 first, u32 count); + void load_vertex_index_data(u32 first, u32 count); + + public: + u32 ioAddress, ioSize; + int flip_status; + int flip_mode; + int debug_level; + int frequency_mode; + + u32 tiles_addr; + u32 zculls_addr; + vm::ps3::ptr gcm_buffers; + u32 gcm_buffers_count; + u32 gcm_current_buffer; + u32 ctxt_addr; + u32 report_main_addr; + u32 label_addr; + u32 draw_mode; + + u32 local_mem_addr, main_mem_addr; + bool strict_ordering[0x1000]; + + public: + u32 draw_array_count; + u32 draw_array_first; + double fps_limit = 59.94; + + public: + std::mutex cs_main; + semaphore_t sem_flip; + u64 last_flip_time; + vm::ps3::ptr flip_handler = { 0 }; + vm::ps3::ptr user_handler = { 0 }; + vm::ps3::ptr vblank_handler = { 0 }; + u64 vblank_count; + + public: + std::set m_used_gcm_commands; + + protected: + virtual ~thread() {} + + public: + virtual void begin(); + virtual void end(); + + virtual void oninit() = 0; + virtual void oninit_thread() = 0; + virtual void onexit_thread() = 0; + virtual bool domethod(u32 cmd, u32 value) { return false; } + virtual void flip(int buffer) = 0; + virtual u64 timestamp() const; + + void task(); + + public: + void reset(); + void init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress); + + u32 ReadIO32(u32 addr); + void WriteIO32(u32 addr, u32 value); + }; +} diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index dc51099f92..dc1a3e2521 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -102,7 +102,7 @@ vm::ptr cellGcmGetReportDataAddressLocation(u32 index, u32 lo return vm::null; } // TODO: It seems m_report_main_addr is not initialized - return vm::ptr::make(Emu.GetGSManager().GetRender().m_report_main_addr + index * 0x10); + return vm::ptr::make(Emu.GetGSManager().GetRender().report_main_addr + index * 0x10); } cellGcmSys.Error("cellGcmGetReportDataAddressLocation: Wrong location (%d)", location); @@ -201,7 +201,7 @@ u64 cellGcmGetTimeStampLocation(u32 index, u32 location) return 0; } // TODO: It seems m_report_main_addr is not initialized - return vm::read64(Emu.GetGSManager().GetRender().m_report_main_addr + index * 0x10); + return vm::read64(Emu.GetGSManager().GetRender().report_main_addr + index * 0x10); } cellGcmSys.Error("cellGcmGetTimeStampLocation: Wrong location (%d)", location); @@ -251,14 +251,14 @@ s32 cellGcmBindTile(u8 index) { cellGcmSys.Warning("cellGcmBindTile(index=%d)", index); - if (index >= RSXThread::m_tiles_count) + if (index >= rsx::limits::tiles_count) { cellGcmSys.Error("cellGcmBindTile: CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } - auto& tile = Emu.GetGSManager().GetRender().m_tiles[index]; - tile.m_binded = true; + auto& tile = Emu.GetGSManager().GetRender().tiles[index]; + tile.binded = true; return CELL_OK; } @@ -267,14 +267,14 @@ s32 cellGcmBindZcull(u8 index) { cellGcmSys.Warning("cellGcmBindZcull(index=%d)", index); - if (index >= RSXThread::m_zculls_count) + if (index >= rsx::limits::zculls_count) { cellGcmSys.Error("cellGcmBindZcull: CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } - auto& zcull = Emu.GetGSManager().GetRender().m_zculls[index]; - zcull.m_binded = true; + auto& zcull = Emu.GetGSManager().GetRender().zculls[index]; + zcull.binded = true; return CELL_OK; } @@ -290,7 +290,7 @@ s32 cellGcmGetConfiguration(vm::ptr config) s32 cellGcmGetFlipStatus() { - s32 status = Emu.GetGSManager().GetRender().m_flip_status; + s32 status = Emu.GetGSManager().GetRender().flip_status; cellGcmSys.Log("cellGcmGetFlipStatus() -> %d", status); @@ -388,15 +388,15 @@ s32 _cellGcmInitBody(vm::pptr context, u32 cmdSize, u32 ioSi ctrl.ref = -1; auto& render = Emu.GetGSManager().GetRender(); - render.m_ctxt_addr = context.addr(); - render.m_gcm_buffers_addr = vm::alloc(sizeof(CellGcmDisplayInfo) * 8, vm::main); - render.m_zculls_addr = vm::alloc(sizeof(CellGcmZcullInfo) * 8, vm::main); - render.m_tiles_addr = vm::alloc(sizeof(CellGcmTileInfo) * 15, vm::main); - render.m_gcm_buffers_count = 0; - render.m_gcm_current_buffer = 0; - render.m_main_mem_addr = 0; - render.m_label_addr = gcm_info.label_addr; - render.Init(g_defaultCommandBufferBegin, cmdSize, gcm_info.control_addr, local_addr); + render.ctxt_addr = context.addr(); + render.gcm_buffers = { vm::alloc(sizeof(CellGcmDisplayInfo) * 8, vm::main) }; + render.zculls_addr = vm::alloc(sizeof(CellGcmZcullInfo) * 8, vm::main); + render.tiles_addr = vm::alloc(sizeof(CellGcmTileInfo) * 15, vm::main); + render.gcm_buffers_count = 0; + render.gcm_current_buffer = 0; + render.main_mem_addr = 0; + render.label_addr = gcm_info.label_addr; + render.init(g_defaultCommandBufferBegin, cmdSize, gcm_info.control_addr, local_addr); return CELL_OK; } @@ -405,7 +405,7 @@ s32 cellGcmResetFlipStatus() { cellGcmSys.Log("cellGcmResetFlipStatus()"); - Emu.GetGSManager().GetRender().m_flip_status = CELL_GCM_DISPLAY_FLIP_STATUS_WAITING; + Emu.GetGSManager().GetRender().flip_status = CELL_GCM_DISPLAY_FLIP_STATUS_WAITING; return CELL_OK; } @@ -419,7 +419,7 @@ s32 cellGcmSetDebugOutputLevel(s32 level) case CELL_GCM_DEBUG_LEVEL0: case CELL_GCM_DEBUG_LEVEL1: case CELL_GCM_DEBUG_LEVEL2: - Emu.GetGSManager().GetRender().m_debug_level = level; + Emu.GetGSManager().GetRender().debug_level = level; break; default: return CELL_EINVAL; @@ -438,16 +438,16 @@ s32 cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height return CELL_EINVAL; } - auto buffers = vm::get_ptr(Emu.GetGSManager().GetRender().m_gcm_buffers_addr); + auto buffers = Emu.GetGSManager().GetRender().gcm_buffers; buffers[id].offset = offset; buffers[id].pitch = pitch; buffers[id].width = width; buffers[id].height = height; - if (id + 1 > Emu.GetGSManager().GetRender().m_gcm_buffers_count) + if (id + 1 > Emu.GetGSManager().GetRender().gcm_buffers_count) { - Emu.GetGSManager().GetRender().m_gcm_buffers_count = id + 1; + Emu.GetGSManager().GetRender().gcm_buffers_count = id + 1; } return CELL_OK; @@ -457,7 +457,7 @@ void cellGcmSetFlipHandler(vm::ptr handler) { cellGcmSys.Warning("cellGcmSetFlipHandler(handler=*0x%x)", handler); - Emu.GetGSManager().GetRender().m_flip_handler = handler; + Emu.GetGSManager().GetRender().flip_handler = handler; } s32 cellGcmSetFlipMode(u32 mode) @@ -469,7 +469,7 @@ s32 cellGcmSetFlipMode(u32 mode) case CELL_GCM_DISPLAY_HSYNC: case CELL_GCM_DISPLAY_VSYNC: case CELL_GCM_DISPLAY_HSYNC_WITH_NOISE: - Emu.GetGSManager().GetRender().m_flip_mode = mode; + Emu.GetGSManager().GetRender().flip_mode = mode; break; default: @@ -483,7 +483,7 @@ void cellGcmSetFlipStatus() { cellGcmSys.Warning("cellGcmSetFlipStatus()"); - Emu.GetGSManager().GetRender().m_flip_status = 0; + Emu.GetGSManager().GetRender().flip_status = 0; } s32 cellGcmSetPrepareFlip(PPUThread& ppu, vm::ptr ctxt, u32 id) @@ -535,11 +535,11 @@ s32 cellGcmSetSecondVFrequency(u32 freq) switch (freq) { case CELL_GCM_DISPLAY_FREQUENCY_59_94HZ: - Emu.GetGSManager().GetRender().m_frequency_mode = freq; Emu.GetGSManager().GetRender().m_fps_limit = 59.94; break; + Emu.GetGSManager().GetRender().frequency_mode = freq; Emu.GetGSManager().GetRender().fps_limit = 59.94; break; case CELL_GCM_DISPLAY_FREQUENCY_SCANOUT: - Emu.GetGSManager().GetRender().m_frequency_mode = freq; cellGcmSys.Todo("Unimplemented display frequency: Scanout"); break; + Emu.GetGSManager().GetRender().frequency_mode = freq; cellGcmSys.Todo("Unimplemented display frequency: Scanout"); break; case CELL_GCM_DISPLAY_FREQUENCY_DISABLE: - Emu.GetGSManager().GetRender().m_frequency_mode = freq; cellGcmSys.Todo("Unimplemented display frequency: Disabled"); break; + Emu.GetGSManager().GetRender().frequency_mode = freq; cellGcmSys.Todo("Unimplemented display frequency: Disabled"); break; default: cellGcmSys.Error("Improper display frequency specified!"); return CELL_OK; } @@ -551,7 +551,7 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u cellGcmSys.Warning("cellGcmSetTileInfo(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)", index, location, offset, size, pitch, comp, base, bank); - if (index >= RSXThread::m_tiles_count || base >= 800 || bank >= 4) + if (index >= rsx::limits::tiles_count || base >= 800 || bank >= 4) { cellGcmSys.Error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; @@ -574,16 +574,16 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u cellGcmSys.Error("cellGcmSetTileInfo: bad compression mode! (%d)", comp); } - auto& tile = Emu.GetGSManager().GetRender().m_tiles[index]; - tile.m_location = location; - tile.m_offset = offset; - tile.m_size = size; - tile.m_pitch = pitch; - tile.m_comp = comp; - tile.m_base = base; - tile.m_bank = bank; + auto& tile = Emu.GetGSManager().GetRender().tiles[index]; + tile.location = location; + tile.offset = offset; + tile.size = size; + tile.pitch = pitch; + tile.comp = comp; + tile.base = base; + tile.bank = bank; - vm::get_ptr(Emu.GetGSManager().GetRender().m_tiles_addr)[index] = tile.Pack(); + vm::get_ptr(Emu.GetGSManager().GetRender().tiles_addr)[index] = tile.pack(); return CELL_OK; } @@ -591,7 +591,7 @@ void cellGcmSetUserHandler(vm::ptr handler) { cellGcmSys.Warning("cellGcmSetUserHandler(handler=*0x%x)", handler); - Emu.GetGSManager().GetRender().m_user_handler = handler; + Emu.GetGSManager().GetRender().user_handler = handler; } s32 cellGcmSetUserCommand() @@ -603,7 +603,7 @@ void cellGcmSetVBlankHandler(vm::ptr handler) { cellGcmSys.Warning("cellGcmSetVBlankHandler(handler=*0x%x)", handler); - Emu.GetGSManager().GetRender().m_vblank_handler = handler; + Emu.GetGSManager().GetRender().vblank_handler = handler; } s32 cellGcmSetWaitFlip(vm::ptr ctxt) @@ -625,26 +625,26 @@ s32 cellGcmSetZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart, cellGcmSys.Todo("cellGcmSetZcull(index=%d, offset=0x%x, width=%d, height=%d, cullStart=0x%x, zFormat=0x%x, aaFormat=0x%x, zCullDir=0x%x, zCullFormat=0x%x, sFunc=0x%x, sRef=0x%x, sMask=0x%x)", index, offset, width, height, cullStart, zFormat, aaFormat, zCullDir, zCullFormat, sFunc, sRef, sMask); - if (index >= RSXThread::m_zculls_count) + if (index >= rsx::limits::zculls_count) { cellGcmSys.Error("cellGcmSetZcull: CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } - auto& zcull = Emu.GetGSManager().GetRender().m_zculls[index]; - zcull.m_offset = offset; - zcull.m_width = width; - zcull.m_height = height; - zcull.m_cullStart = cullStart; - zcull.m_zFormat = zFormat; - zcull.m_aaFormat = aaFormat; - zcull.m_zcullDir = zCullDir; - zcull.m_zcullFormat = zCullFormat; - zcull.m_sFunc = sFunc; - zcull.m_sRef = sRef; - zcull.m_sMask = sMask; + auto& zcull = Emu.GetGSManager().GetRender().zculls[index]; + zcull.offset = offset; + zcull.width = width; + zcull.height = height; + zcull.cullStart = cullStart; + zcull.zFormat = zFormat; + zcull.aaFormat = aaFormat; + zcull.zcullDir = zCullDir; + zcull.zcullFormat = zCullFormat; + zcull.sFunc = sFunc; + zcull.sRef = sRef; + zcull.sMask = sMask; - vm::get_ptr(Emu.GetGSManager().GetRender().m_zculls_addr)[index] = zcull.Pack(); + vm::get_ptr(Emu.GetGSManager().GetRender().zculls_addr)[index] = zcull.pack(); return CELL_OK; } @@ -652,14 +652,14 @@ s32 cellGcmUnbindTile(u8 index) { cellGcmSys.Warning("cellGcmUnbindTile(index=%d)", index); - if (index >= RSXThread::m_tiles_count) + if (index >= rsx::limits::tiles_count) { cellGcmSys.Error("cellGcmUnbindTile: CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } - auto& tile = Emu.GetGSManager().GetRender().m_tiles[index]; - tile.m_binded = false; + auto& tile = Emu.GetGSManager().GetRender().tiles[index]; + tile.binded = false; return CELL_OK; } @@ -674,8 +674,8 @@ s32 cellGcmUnbindZcull(u8 index) return CELL_EINVAL; } - auto& zcull = Emu.GetGSManager().GetRender().m_zculls[index]; - zcull.m_binded = false; + auto& zcull = Emu.GetGSManager().GetRender().zculls[index]; + zcull.binded = false; return CELL_OK; } @@ -683,31 +683,31 @@ s32 cellGcmUnbindZcull(u8 index) u32 cellGcmGetTileInfo() { cellGcmSys.Warning("cellGcmGetTileInfo()"); - return Emu.GetGSManager().GetRender().m_tiles_addr; + return Emu.GetGSManager().GetRender().tiles_addr; } u32 cellGcmGetZcullInfo() { cellGcmSys.Warning("cellGcmGetZcullInfo()"); - return Emu.GetGSManager().GetRender().m_zculls_addr; + return Emu.GetGSManager().GetRender().zculls_addr; } u32 cellGcmGetDisplayInfo() { - cellGcmSys.Warning("cellGcmGetDisplayInfo() = 0x%x", Emu.GetGSManager().GetRender().m_gcm_buffers_addr); - return Emu.GetGSManager().GetRender().m_gcm_buffers_addr; + cellGcmSys.Warning("cellGcmGetDisplayInfo() = 0x%x", Emu.GetGSManager().GetRender().gcm_buffers.addr()); + return Emu.GetGSManager().GetRender().gcm_buffers.addr(); } s32 cellGcmGetCurrentDisplayBufferId(vm::ptr id) { cellGcmSys.Warning("cellGcmGetCurrentDisplayBufferId(id=*0x%x)", id); - if (Emu.GetGSManager().GetRender().m_gcm_current_buffer > UINT8_MAX) + if (Emu.GetGSManager().GetRender().gcm_current_buffer > UINT8_MAX) { throw EXCEPTION("Unexpected"); } - *id = Emu.GetGSManager().GetRender().m_gcm_current_buffer; + *id = Emu.GetGSManager().GetRender().gcm_current_buffer; return CELL_OK; } @@ -739,7 +739,7 @@ u64 cellGcmGetLastFlipTime() { cellGcmSys.Log("cellGcmGetLastFlipTime()"); - return Emu.GetGSManager().GetRender().m_last_flip_time; + return Emu.GetGSManager().GetRender().last_flip_time; } u64 cellGcmGetLastSecondVTime() @@ -752,7 +752,7 @@ u64 cellGcmGetVBlankCount() { cellGcmSys.Log("cellGcmGetVBlankCount()"); - return Emu.GetGSManager().GetRender().m_vblank_count; + return Emu.GetGSManager().GetRender().vblank_count; } s32 cellGcmSysGetLastVBlankTime() @@ -895,7 +895,7 @@ s32 gcmMapEaIoAddress(u32 ea, u32 io, u32 size, bool is_strict) { offsetTable.ioAddress[(ea >> 20) + i] = (io >> 20) + i; offsetTable.eaAddress[(io >> 20) + i] = (ea >> 20) + i; - Emu.GetGSManager().GetRender().m_strict_ordering[(io >> 20) + i] = is_strict; + Emu.GetGSManager().GetRender().strict_ordering[(io >> 20) + i] = is_strict; } } else @@ -957,7 +957,7 @@ s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr offset) { offsetTable.ioAddress[(ea >> 20) + i] = (u16)((io >> 20) + i); offsetTable.eaAddress[(io >> 20) + i] = (u16)((ea >> 20) + i); - Emu.GetGSManager().GetRender().m_strict_ordering[(io >> 20) + i] = false; + Emu.GetGSManager().GetRender().strict_ordering[(io >> 20) + i] = false; } *offset = io; @@ -968,7 +968,7 @@ s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr offset) return CELL_GCM_ERROR_NO_IO_PAGE_TABLE; } - Emu.GetGSManager().GetRender().m_main_mem_addr = Emu.GetGSManager().GetRender().m_ioAddress; + Emu.GetGSManager().GetRender().main_mem_addr = Emu.GetGSManager().GetRender().ioAddress; return CELL_OK; } @@ -1108,7 +1108,7 @@ s32 cellGcmSetCursorImageOffset(u32 offset) void cellGcmSetDefaultCommandBuffer() { cellGcmSys.Warning("cellGcmSetDefaultCommandBuffer()"); - vm::write32(Emu.GetGSManager().GetRender().m_ctxt_addr, gcm_info.context_addr); + vm::write32(Emu.GetGSManager().GetRender().ctxt_addr, gcm_info.context_addr); } s32 cellGcmSetDefaultCommandBufferAndSegmentWordSize() @@ -1142,7 +1142,7 @@ s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co index, location, offset, size, pitch, comp, base, bank); // Copied form cellGcmSetTileInfo - if (index >= RSXThread::m_tiles_count || base >= 800 || bank >= 4) + if (index >= rsx::limits::tiles_count || base >= 800 || bank >= 4) { cellGcmSys.Error("cellGcmSetTile: CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; @@ -1165,16 +1165,16 @@ s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co cellGcmSys.Error("cellGcmSetTile: bad compression mode! (%d)", comp); } - auto& tile = Emu.GetGSManager().GetRender().m_tiles[index]; - tile.m_location = location; - tile.m_offset = offset; - tile.m_size = size; - tile.m_pitch = pitch; - tile.m_comp = comp; - tile.m_base = base; - tile.m_bank = bank; + auto& tile = Emu.GetGSManager().GetRender().tiles[index]; + tile.location = location; + tile.offset = offset; + tile.size = size; + tile.pitch = pitch; + tile.comp = comp; + tile.base = base; + tile.bank = bank; - vm::get_ptr(Emu.GetGSManager().GetRender().m_tiles_addr)[index] = tile.Pack(); + vm::get_ptr(Emu.GetGSManager().GetRender().tiles_addr)[index] = tile.pack(); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index 6b898758fe..986f12d126 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -467,7 +467,7 @@ void InitMembers() void SetupRsxRenderingStates(vm::ptr& cntxt) { //TODO: use cntxt - GSRender& r = Emu.GetGSManager().GetRender(); + /*GSRender& r = Emu.GetGSManager().GetRender(); r.m_set_color_mask = true; r.m_color_mask_a = r.m_color_mask_r = r.m_color_mask_g = r.m_color_mask_b = true; r.m_set_depth_mask = true; r.m_depth_mask = 0; r.m_set_alpha_test = false; @@ -502,7 +502,7 @@ void SetupRsxRenderingStates(vm::ptr& cntxt) r.m_height = s_rescInternalInstance->m_dstHeight; r.m_surface_depth_format = 2; - r.m_surface_color_target = 1; + r.m_surface_color_target = 1;*/ if (IsPalInterpolate()) { @@ -536,32 +536,32 @@ void SetupSurfaces(vm::ptr& cntxt) dstOffset1 = s_rescInternalInstance->m_dstOffsets[s_rescInternalInstance->m_bufIdPalMidNow]; } - GSRender& r = Emu.GetGSManager().GetRender(); + //GSRender& r = Emu.GetGSManager().GetRender(); - r.m_surface_type = CELL_GCM_SURFACE_PITCH; - r.m_surface_antialias = CELL_GCM_SURFACE_CENTER_1; - r.m_surface_color_format = (u8)s_rescInternalInstance->m_pRescDsts->format; - r.m_surface_color_target = (!isMrt) ? CELL_GCM_SURFACE_TARGET_0 : CELL_GCM_SURFACE_TARGET_MRT1; - //surface.colorLocation[0] = CELL_GCM_LOCATION_LOCAL; - r.m_surface_offset_a = dstOffset0; - r.m_surface_pitch_a = s_rescInternalInstance->m_dstPitch; - //surface.colorLocation[1] = CELL_GCM_LOCATION_LOCAL; - r.m_surface_offset_b = (!isMrt) ? 0 : dstOffset1; - r.m_surface_pitch_b = (!isMrt) ? 64 : s_rescInternalInstance->m_dstPitch; - //surface.colorLocation[2] = CELL_GCM_LOCATION_LOCAL; - r.m_surface_offset_c = 0; - r.m_surface_pitch_c = 64; - //surface.colorLocation[3] = CELL_GCM_LOCATION_LOCAL; - r.m_surface_offset_d = 0; - r.m_surface_pitch_d = 64; - r.m_surface_depth_format = CELL_GCM_SURFACE_Z24S8; - //surface.depthLocation = CELL_GCM_LOCATION_LOCAL; - r.m_surface_offset_z = 0; - r.m_surface_pitch_z = 64; - r.m_surface_width = s_rescInternalInstance->m_dstWidth; - r.m_surface_height = s_rescInternalInstance->m_dstHeight; - r.m_surface_clip_x = 0; - r.m_surface_clip_y = 0; + //r.m_surface_type = CELL_GCM_SURFACE_PITCH; + //r.m_surface_antialias = CELL_GCM_SURFACE_CENTER_1; + //r.m_surface_color_format = (u8)s_rescInternalInstance->m_pRescDsts->format; + //r.m_surface_color_target = (!isMrt) ? CELL_GCM_SURFACE_TARGET_0 : CELL_GCM_SURFACE_TARGET_MRT1; + ////surface.colorLocation[0] = CELL_GCM_LOCATION_LOCAL; + //r.m_surface_offset_a = dstOffset0; + //r.m_surface_pitch_a = s_rescInternalInstance->m_dstPitch; + ////surface.colorLocation[1] = CELL_GCM_LOCATION_LOCAL; + //r.m_surface_offset_b = (!isMrt) ? 0 : dstOffset1; + //r.m_surface_pitch_b = (!isMrt) ? 64 : s_rescInternalInstance->m_dstPitch; + ////surface.colorLocation[2] = CELL_GCM_LOCATION_LOCAL; + //r.m_surface_offset_c = 0; + //r.m_surface_pitch_c = 64; + ////surface.colorLocation[3] = CELL_GCM_LOCATION_LOCAL; + //r.m_surface_offset_d = 0; + //r.m_surface_pitch_d = 64; + //r.m_surface_depth_format = CELL_GCM_SURFACE_Z24S8; + ////surface.depthLocation = CELL_GCM_LOCATION_LOCAL; + //r.m_surface_offset_z = 0; + //r.m_surface_pitch_z = 64; + //r.m_surface_width = s_rescInternalInstance->m_dstWidth; + //r.m_surface_height = s_rescInternalInstance->m_dstHeight; + //r.m_surface_clip_x = 0; + //r.m_surface_clip_y = 0; } // Module<> Functions @@ -1075,21 +1075,21 @@ void cellRescSetFlipHandler(vm::ptr handler) { cellResc.Warning("cellRescSetFlipHandler(handler=*0x%x)", handler); - Emu.GetGSManager().GetRender().m_flip_handler = handler; + Emu.GetGSManager().GetRender().flip_handler = handler; } void cellRescResetFlipStatus() { cellResc.Log("cellRescResetFlipStatus()"); - Emu.GetGSManager().GetRender().m_flip_status = 1; + Emu.GetGSManager().GetRender().flip_status = 1; } s32 cellRescGetFlipStatus() { cellResc.Log("cellRescGetFlipStatus()"); - return Emu.GetGSManager().GetRender().m_flip_status; + return Emu.GetGSManager().GetRender().flip_status; } s32 cellRescGetRegisterCount() @@ -1102,7 +1102,7 @@ u64 cellRescGetLastFlipTime() { cellResc.Log("cellRescGetLastFlipTime()"); - return Emu.GetGSManager().GetRender().m_last_flip_time; + return Emu.GetGSManager().GetRender().last_flip_time; } s32 cellRescSetRegisterCount() @@ -1115,7 +1115,7 @@ void cellRescSetVBlankHandler(vm::ptr handler) { cellResc.Warning("cellRescSetVBlankHandler(handler=*0x%x)", handler); - Emu.GetGSManager().GetRender().m_vblank_handler = handler; + Emu.GetGSManager().GetRender().vblank_handler = handler; } u16 FloatToHalf(float val) @@ -1142,7 +1142,7 @@ u16 FloatToHalf(float val) return ((s >> 16) & 0x8000) | ((e << 10) & 0x7c00) | ((m >> 13) & 0x03ff); } -static void blackman(float window[]) +static void blackman(float (&window)[4]) { const float x0 = ((1.f * 2.f*PI) / 5.f) - PI; const float x1 = ((2.f * 2.f*PI) / 5.f) - PI; diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 3a4a9017e4..dc7608d11c 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -215,7 +215,8 @@ void Emulator::Load() LOG_NOTICE(LOADER, "Resolution: %s", Ini.ResolutionIdToString(Ini.GSResolution.GetValue())); LOG_NOTICE(LOADER, "Write Depth Buffer: %s", Ini.GSDumpDepthBuffer.GetValue() ? "Yes" : "No"); LOG_NOTICE(LOADER, "Write Color Buffers: %s", Ini.GSDumpColorBuffers.GetValue() ? "Yes" : "No"); - LOG_NOTICE(LOADER, "Read Color Buffer: %s", Ini.GSReadColorBuffer.GetValue() ? "Yes" : "No"); + LOG_NOTICE(LOADER, "Read Color Buffers: %s", Ini.GSReadColorBuffers.GetValue() ? "Yes" : "No"); + LOG_NOTICE(LOADER, "Read Depth Buffer: %s", Ini.GSReadDepthBuffer.GetValue() ? "Yes" : "No"); LOG_NOTICE(LOADER, "Audio Out: %s", Ini.AudioOutIdToString(Ini.AudioOutMode.GetValue())); LOG_NOTICE(LOADER, "Log Everything: %s", Ini.HLELogging.GetValue() ? "Yes" : "No"); LOG_NOTICE(LOADER, "RSX Logging: %s", Ini.RSXLogging.GetValue() ? "Yes" : "No"); diff --git a/rpcs3/Gui/GLGSFrame.cpp b/rpcs3/Gui/GLGSFrame.cpp index def20179f3..0e48b45e49 100644 --- a/rpcs3/Gui/GLGSFrame.cpp +++ b/rpcs3/Gui/GLGSFrame.cpp @@ -21,49 +21,45 @@ GLGSFrame::GLGSFrame() canvas->Bind(wxEVT_LEFT_DCLICK, &GSFrame::OnLeftDclick, this); } -GLGSFrame::~GLGSFrame() -{ -} - -void GLGSFrame::Close() +void GLGSFrame::close() { GSFrame::Close(); } -bool GLGSFrame::IsShown() +bool GLGSFrame::shown() { return GSFrame::IsShown(); } -void GLGSFrame::Hide() +void GLGSFrame::hide() { GSFrame::Hide(); } -void GLGSFrame::Show() +void GLGSFrame::show() { GSFrame::Show(); } -void* GLGSFrame::GetNewContext() +void* GLGSFrame::make_context() { return new wxGLContext(GetCanvas()); } -void GLGSFrame::SetCurrent(void* ctx) +void GLGSFrame::set_current(draw_context_t ctx) { - GetCanvas()->SetCurrent(*(wxGLContext*)ctx); + GetCanvas()->SetCurrent(*(wxGLContext*)ctx.get()); } -void GLGSFrame::DeleteContext(void* ctx) +void GLGSFrame::delete_context(void* ctx) { delete (wxGLContext*)ctx; } -void GLGSFrame::Flip(void* context) +void GLGSFrame::flip(draw_context_t context) { if (!canvas) return; - canvas->SetCurrent(*(wxGLContext*)context); + canvas->SetCurrent(*(wxGLContext*)context.get()); static Timer fps_t; canvas->SwapBuffers(); @@ -80,6 +76,12 @@ void GLGSFrame::Flip(void* context) } } +size2i GLGSFrame::client_size() +{ + wxSize size = GetClientSize(); + return{ size.GetWidth(), size.GetHeight() }; +} + void GLGSFrame::OnSize(wxSizeEvent& event) { if (canvas) canvas->SetSize(GetClientSize()); diff --git a/rpcs3/Gui/GLGSFrame.h b/rpcs3/Gui/GLGSFrame.h index ace40928e4..9fa7ce6054 100644 --- a/rpcs3/Gui/GLGSFrame.h +++ b/rpcs3/Gui/GLGSFrame.h @@ -9,18 +9,18 @@ struct GLGSFrame : public GSFrame, public GSFrameBase u32 m_frames; GLGSFrame(); - ~GLGSFrame(); - virtual void Close() override; + void close() override; - virtual bool IsShown() override; - virtual void Hide() override; - virtual void Show() override; + bool shown() override; + void hide() override; + void show() override; - virtual void* GetNewContext() override; - virtual void SetCurrent(void* ctx) override; - virtual void DeleteContext(void* ctx) override; - virtual void Flip(void* context) override; + void* make_context() override; + void set_current(draw_context_t context) override; + void delete_context(void* context) override; + void flip(draw_context_t context) override; + size2i client_size() override; wxGLCanvas* GetCanvas() const { return canvas; } diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 8486b2bd7d..109cddcde7 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -423,27 +423,29 @@ void MainFrame::ConfigLLEModules(wxCommandEvent& event) void MainFrame::OpenELFCompiler(wxCommandEvent& WXUNUSED(event)) { - (new CompilerELF(this)) -> Show(); + (new CompilerELF(this))->Show(); } void MainFrame::OpenKernelExplorer(wxCommandEvent& WXUNUSED(event)) { - (new KernelExplorer(this)) -> Show(); + (new KernelExplorer(this))->Show(); } void MainFrame::OpenMemoryViewer(wxCommandEvent& WXUNUSED(event)) { - (new MemoryViewerPanel(this)) -> Show(); + (new MemoryViewerPanel(this))->Show(); } void MainFrame::OpenRSXDebugger(wxCommandEvent& WXUNUSED(event)) { - (new RSXDebugger(this)) -> Show(); +#if _USE_RSX_DEBUGGER + (new RSXDebugger(this))->Show(); +#endif } void MainFrame::OpenStringSearch(wxCommandEvent& WXUNUSED(event)) { - (new MemoryStringSearcher(this)) -> Show(); + (new MemoryStringSearcher(this))->Show(); } void MainFrame::OpenCgDisasm(wxCommandEvent& WXUNUSED(event)) diff --git a/rpcs3/Gui/RSXDebugger.cpp b/rpcs3/Gui/RSXDebugger.cpp index 21af469a7a..c2532e73ae 100644 --- a/rpcs3/Gui/RSXDebugger.cpp +++ b/rpcs3/Gui/RSXDebugger.cpp @@ -1,11 +1,14 @@ #include "stdafx_gui.h" + +#include "RSXDebugger.h" + +#if _USE_RSX_DEBUGGER #include "rpcs3/Ini.h" #include "Utilities/rPlatform.h" #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "RSXDebugger.h" #include "Emu/SysCalls/Modules/cellVideoOut.h" #include "Emu/RSX/GSManager.h" #include "Emu/RSX/GSRender.h" @@ -1207,3 +1210,4 @@ bool RSXDebugger::RSXReady() { return Emu.GetGSManager().IsInited(); } +#endif \ No newline at end of file diff --git a/rpcs3/Gui/RSXDebugger.h b/rpcs3/Gui/RSXDebugger.h index 733e552efb..3fa6833ef6 100644 --- a/rpcs3/Gui/RSXDebugger.h +++ b/rpcs3/Gui/RSXDebugger.h @@ -1,9 +1,10 @@ #pragma once +#define _USE_RSX_DEBUGGER 0 + +#if _USE_RSX_DEBUGGER #include - - class RSXDebugger : public wxFrame { u32 m_addr; @@ -69,3 +70,5 @@ public: bool RSXReady(); void SetPC(const uint pc) { m_addr = pc; } }; + +#endif \ No newline at end of file diff --git a/rpcs3/Gui/SettingsDialog.cpp b/rpcs3/Gui/SettingsDialog.cpp index f9762d9698..a2c8f74aaf 100644 --- a/rpcs3/Gui/SettingsDialog.cpp +++ b/rpcs3/Gui/SettingsDialog.cpp @@ -118,7 +118,8 @@ SettingsDialog::SettingsDialog(wxWindow *parent) wxCheckBox* chbox_gs_log_prog = new wxCheckBox(p_graphics, wxID_ANY, "Log shader programs"); wxCheckBox* chbox_gs_dump_depth = new wxCheckBox(p_graphics, wxID_ANY, "Write Depth Buffer"); wxCheckBox* chbox_gs_dump_color = new wxCheckBox(p_graphics, wxID_ANY, "Write Color Buffers"); - wxCheckBox* chbox_gs_read_color = new wxCheckBox(p_graphics, wxID_ANY, "Read Color Buffer"); + wxCheckBox* chbox_gs_read_color = new wxCheckBox(p_graphics, wxID_ANY, "Read Color Buffers"); + wxCheckBox* chbox_gs_read_depth = new wxCheckBox(p_graphics, wxID_ANY, "Read Depth Buffer"); wxCheckBox* chbox_gs_vsync = new wxCheckBox(p_graphics, wxID_ANY, "VSync"); wxCheckBox* chbox_gs_debug_output = new wxCheckBox(p_graphics, wxID_ANY, "Debug Output"); wxCheckBox* chbox_gs_3dmonitor = new wxCheckBox(p_graphics, wxID_ANY, "3D Monitor"); @@ -256,7 +257,8 @@ SettingsDialog::SettingsDialog(wxWindow *parent) chbox_gs_log_prog->SetValue(Ini.GSLogPrograms.GetValue()); chbox_gs_dump_depth->SetValue(Ini.GSDumpDepthBuffer.GetValue()); chbox_gs_dump_color->SetValue(Ini.GSDumpColorBuffers.GetValue()); - chbox_gs_read_color->SetValue(Ini.GSReadColorBuffer.GetValue()); + chbox_gs_read_color->SetValue(Ini.GSReadColorBuffers.GetValue()); + chbox_gs_read_depth->SetValue(Ini.GSReadDepthBuffer.GetValue()); chbox_gs_vsync->SetValue(Ini.GSVSyncEnable.GetValue()); chbox_gs_debug_output->SetValue(Ini.GSDebugOutputEnable.GetValue()); chbox_gs_3dmonitor->SetValue(Ini.GS3DTV.GetValue()); @@ -346,9 +348,10 @@ SettingsDialog::SettingsDialog(wxWindow *parent) s_subpanel_graphics1->Add(s_round_gs_render, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel_graphics1->Add(s_round_gs_res, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel_graphics1->Add(s_round_gs_d3d_adaptater, wxSizerFlags().Border(wxALL, 5).Expand()); - s_subpanel_graphics1->Add(chbox_gs_dump_depth, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel_graphics1->Add(chbox_gs_dump_color, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel_graphics1->Add(chbox_gs_read_color, wxSizerFlags().Border(wxALL, 5).Expand()); + s_subpanel_graphics1->Add(chbox_gs_dump_depth, wxSizerFlags().Border(wxALL, 5).Expand()); + s_subpanel_graphics1->Add(chbox_gs_read_depth, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel_graphics1->Add(chbox_gs_vsync, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel_graphics2->Add(s_round_gs_aspect, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel_graphics2->Add(s_round_gs_frame_limit, wxSizerFlags().Border(wxALL, 5).Expand()); @@ -437,7 +440,8 @@ SettingsDialog::SettingsDialog(wxWindow *parent) Ini.GSLogPrograms.SetValue(chbox_gs_log_prog->GetValue()); Ini.GSDumpDepthBuffer.SetValue(chbox_gs_dump_depth->GetValue()); Ini.GSDumpColorBuffers.SetValue(chbox_gs_dump_color->GetValue()); - Ini.GSReadColorBuffer.SetValue(chbox_gs_read_color->GetValue()); + Ini.GSReadColorBuffers.SetValue(chbox_gs_read_color->GetValue()); + Ini.GSReadDepthBuffer.SetValue(chbox_gs_read_depth->GetValue()); Ini.GSVSyncEnable.SetValue(chbox_gs_vsync->GetValue()); Ini.GSDebugOutputEnable.SetValue(chbox_gs_debug_output->GetValue()); Ini.GS3DTV.SetValue(chbox_gs_3dmonitor->GetValue()); diff --git a/rpcs3/Ini.h b/rpcs3/Ini.h index f1b56aadb9..197de5936d 100644 --- a/rpcs3/Ini.h +++ b/rpcs3/Ini.h @@ -111,7 +111,8 @@ public: IniEntry GSLogPrograms; IniEntry GSDumpColorBuffers; IniEntry GSDumpDepthBuffer; - IniEntry GSReadColorBuffer; + IniEntry GSReadColorBuffers; + IniEntry GSReadDepthBuffer; IniEntry GSVSyncEnable; IniEntry GS3DTV; IniEntry GSDebugOutputEnable; @@ -202,16 +203,17 @@ public: GSLogPrograms.Init("GS_LogPrograms", path); GSDumpColorBuffers.Init("GS_DumpColorBuffers", path); GSDumpDepthBuffer.Init("GS_DumpDepthBuffer", path); - GSReadColorBuffer.Init("GS_GSReadColorBuffer", path); + GSReadColorBuffers.Init("GS_ReadColorBuffer", path); + GSReadDepthBuffer.Init("GS_ReadDepthBuffer", path); GSVSyncEnable.Init("GS_VSyncEnable", path); GSDebugOutputEnable.Init("GS_DebugOutputEnable", path); GS3DTV.Init("GS_3DTV", path); GSOverlay.Init("GS_Overlay", path); // Audio - AudioOutMode.Init("Audio_AudioOutMode", path); - AudioDumpToFile.Init("Audio_AudioDumpToFile", path); - AudioConvertToU16.Init("Audio_AudioConvertToU16", path); + AudioOutMode.Init("Audio_OutMode", path); + AudioDumpToFile.Init("Audio_DumpToFile", path); + AudioConvertToU16.Init("Audio_ConvertToU16", path); // Camera Camera.Init("Camera", path); @@ -289,7 +291,8 @@ public: GSLogPrograms.Load(false); GSDumpColorBuffers.Load(false); GSDumpDepthBuffer.Load(false); - GSReadColorBuffer.Load(false); + GSReadColorBuffers.Load(false); + GSReadDepthBuffer.Load(false); GSVSyncEnable.Load(false); GSDebugOutputEnable.Load(false); GS3DTV.Load(false); @@ -376,7 +379,8 @@ public: GSLogPrograms.Save(); GSDumpColorBuffers.Save(); GSDumpDepthBuffer.Save(); - GSReadColorBuffer.Save(); + GSReadColorBuffers.Save(); + GSReadDepthBuffer.Save(); GSVSyncEnable.Save(); GSDebugOutputEnable.Save(); GS3DTV.Save(); diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index d89cf351c9..e37a5a3def 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -60,10 +60,8 @@ - - @@ -76,6 +74,7 @@ + @@ -393,6 +392,7 @@ + @@ -531,11 +531,9 @@ - - @@ -556,6 +554,7 @@ + @@ -770,55 +769,55 @@ - .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include + .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include;..\glm $(Platform)\$(Configuration)\emucore\ $(UniversalCRT_LibraryPath_x64);$(LibraryPath) $(ExcludePath) - .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include + .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include;..\glm $(Platform)\$(Configuration)\emucore\ $(UniversalCRT_LibraryPath_x64);$(LibraryPath) $(ExcludePath) - .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include + .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include;..\glm $(Platform)\$(Configuration)\emucore\ $(LibraryPath) $(ExcludePath) - .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include + .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include;..\glm $(Platform)\$(Configuration)\emucore\ $(LibraryPath) $(ExcludePath) - .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include + .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include;..\glm $(Platform)\$(Configuration)\emucore\ $(UniversalCRT_LibraryPath_x64);$(LibraryPath) $(ExcludePath) - .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include + .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include;..\glm $(Platform)\$(Configuration)\emucore\ $(UniversalCRT_LibraryPath_x64);$(LibraryPath) $(ExcludePath) - .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include + .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include;..\glm $(Platform)\$(Configuration)\emucore\ $(UniversalCRT_LibraryPath_x64);$(LibraryPath) $(ExcludePath) - .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include + .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include;..\glm $(Platform)\$(Configuration)\emucore\ $(UniversalCRT_LibraryPath_x64);$(LibraryPath) $(ExcludePath) - .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include + .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include;..\glm $(Platform)\$(Configuration)\emucore\ $(UniversalCRT_LibraryPath_x64);$(LibraryPath) $(ExcludePath) diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index c7734ec744..e0b961363d 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -989,11 +989,8 @@ Utilities - - Emu\GPU\RSX\Common - - - Emu\GPU\RSX\Common + + Emu\GPU\RSX\GL @@ -1888,11 +1885,11 @@ Emu\GPU\RSX\D3D12 - - Emu\GPU\RSX\Common + + Emu\GPU\RSX\GL - - Emu\GPU\RSX\Common + + Utilities \ No newline at end of file diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 37f0b8b2f2..271a77b197 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -139,38 +139,38 @@ - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath) + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath);..\glm $(SolutionDir)bin\ ..\libs\$(Configuration)\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath) $(ProjectName)-dbg - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath) + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath);..\glm $(SolutionDir)bin\ ..\libs\$(Configuration)\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath) $(ProjectName)-dbg - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath) + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath);..\glm $(SolutionDir)bin\ ..\libs\Debug\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath) $(ProjectName)-dbg - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath) + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath);..\glm $(SolutionDir)bin\ ..\libs\Debug\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath) $(ProjectName)-dbg - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(UniversalCRT_IncludePath);$(IncludePath) + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(UniversalCRT_IncludePath);$(IncludePath);..\glm $(SolutionDir)bin\ ..\libs\Debug\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath) $(ProjectName)-dbg false - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath) + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath);..\glm $(SolutionDir)bin\ ..\libs\$(Configuration)\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath) false @@ -178,7 +178,7 @@ false - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath) + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath);..\glm $(SolutionDir)bin\ ..\libs\$(Configuration)\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath) false @@ -186,7 +186,7 @@ false - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath) + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath);..\glm $(SolutionDir)bin\ ..\libs\Release\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath) false @@ -194,7 +194,7 @@ false - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath) + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath);..\glm $(SolutionDir)bin\ ..\libs\Release\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath) false