Play-/Source/gs/GSH_OpenGL/GSH_OpenGL.h
Jean-Philip Desjardins a8b125fe4d Removed "fix small Z values" setting.
Not a proper fix for the issues some games have.
2016-01-19 22:37:19 -05:00

360 lines
10 KiB
C++

#pragma once
#include <list>
#include <unordered_map>
#include "../GSHandler.h"
#include "../GsCachedArea.h"
#include "opengl/OpenGlDef.h"
#include "opengl/Program.h"
#include "opengl/Shader.h"
#include "opengl/Resource.h"
#define PREF_CGSH_OPENGL_FORCEBILINEARTEXTURES "renderer.opengl.forcebilineartextures"
class CGSH_OpenGL : public CGSHandler
{
public:
CGSH_OpenGL();
virtual ~CGSH_OpenGL();
virtual void LoadState(Framework::CZipArchiveReader&) override;
void ProcessHostToLocalTransfer() override;
void ProcessLocalToHostTransfer() override;
void ProcessLocalToLocalTransfer() override;
void ProcessClutTransfer(uint32, uint32) override;
void ReadFramebuffer(uint32, uint32, void*) override;
protected:
void TexCache_Flush();
void PalCache_Flush();
void LoadSettings();
virtual void InitializeImpl() override;
virtual void ReleaseImpl() override;
virtual void ResetImpl() override;
virtual void FlipImpl() override;
GLuint m_presentFramebuffer = 0;
private:
struct RENDERSTATE
{
bool isValid;
uint64 primReg;
uint64 frameReg;
uint64 testReg;
uint64 alphaReg;
uint64 zbufReg;
uint64 scissorReg;
uint64 tex0Reg;
uint64 tex1Reg;
uint64 texAReg;
uint64 clampReg;
uint64 fogColReg;
GLuint shaderHandle;
};
enum
{
MAX_TEXTURE_CACHE = 256,
MAX_PALETTE_CACHE = 256,
};
enum CVTBUFFERSIZE
{
CVTBUFFERSIZE = 0x800000,
};
typedef void (CGSH_OpenGL::*TEXTUREUPLOADER)(uint32, uint32, unsigned int, unsigned int);
typedef void (CGSH_OpenGL::*TEXTUREUPDATER)(uint32, uint32, unsigned int, unsigned int, unsigned int, unsigned int);
struct VERTEX
{
uint64 nPosition;
uint64 nRGBAQ;
uint64 nUV;
uint64 nST;
uint8 nFog;
};
enum
{
TEXTURE_SOURCE_MODE_NONE = 0,
TEXTURE_SOURCE_MODE_STD = 1,
TEXTURE_SOURCE_MODE_IDX4 = 2,
TEXTURE_SOURCE_MODE_IDX8 = 3
};
enum TEXTURE_CLAMP_MODE
{
TEXTURE_CLAMP_MODE_STD = 0,
TEXTURE_CLAMP_MODE_REGION_CLAMP = 1,
TEXTURE_CLAMP_MODE_REGION_REPEAT = 2,
TEXTURE_CLAMP_MODE_REGION_REPEAT_SIMPLE = 3
};
struct SHADERCAPS : public convertible<uint32>
{
unsigned int texFunction : 2; //0 - Modulate, 1 - Decal, 2 - Highlight, 3 - Hightlight2
unsigned int texClampS : 2;
unsigned int texClampT : 2;
unsigned int texSourceMode : 2;
unsigned int texHasAlpha : 1;
unsigned int texBilinearFilter : 1;
unsigned int texUseAlphaExpansion : 1;
unsigned int texBlackIsTransparent : 1;
unsigned int hasFog : 1;
unsigned int hasAlphaTest : 1;
unsigned int alphaTestMethod : 3;
unsigned int padding : 15;
bool isIndexedTextureSource() const { return texSourceMode == TEXTURE_SOURCE_MODE_IDX4 || texSourceMode == TEXTURE_SOURCE_MODE_IDX8; }
};
static_assert(sizeof(SHADERCAPS) == sizeof(uint32), "SHADERCAPS structure size must be 4 bytes.");
struct SHADERINFO
{
Framework::OpenGl::ProgramPtr shader;
GLint projMatrixUniform;
GLint texMatrixUniform;
GLint textureUniform;
GLint paletteUniform;
GLint textureSizeUniform;
GLint texelSizeUniform;
GLint clampMinUniform;
GLint clampMaxUniform;
GLint texA0Uniform;
GLint texA1Uniform;
GLint alphaRefUniform;
GLint fogColorUniform;
};
typedef std::unordered_map<uint32, SHADERINFO> ShaderInfoMap;
class CTexture
{
public:
CTexture();
~CTexture();
void Free();
uint64 m_tex0;
GLuint m_texture;
bool m_live;
CGsCachedArea m_cachedArea;
};
typedef std::shared_ptr<CTexture> TexturePtr;
typedef std::list<TexturePtr> TextureList;
class CPalette
{
public:
CPalette();
~CPalette();
void Invalidate(uint32);
void Free();
bool m_live;
bool m_isIDTEX4;
uint32 m_cpsm;
uint32 m_csa;
GLuint m_texture;
uint32 m_contents[256];
};
typedef std::shared_ptr<CPalette> PalettePtr;
typedef std::list<PalettePtr> PaletteList;
class CFramebuffer
{
public:
CFramebuffer(uint32, uint32, uint32, uint32);
~CFramebuffer();
uint32 m_basePtr;
uint32 m_width;
uint32 m_height;
uint32 m_psm;
GLuint m_framebuffer;
GLuint m_texture;
CGsCachedArea m_cachedArea;
};
typedef std::shared_ptr<CFramebuffer> FramebufferPtr;
typedef std::vector<FramebufferPtr> FramebufferList;
class CDepthbuffer
{
public:
CDepthbuffer(uint32, uint32, uint32, uint32);
~CDepthbuffer();
uint32 m_basePtr;
uint32 m_width;
uint32 m_height;
uint32 m_psm;
GLuint m_depthBuffer;
};
typedef std::shared_ptr<CDepthbuffer> DepthbufferPtr;
typedef std::vector<DepthbufferPtr> DepthbufferList;
struct TEXTURE_INFO
{
float offsetX = 0;
float scaleRatioX = 1;
float scaleRatioY = 1;
};
enum class PRIM_VERTEX_ATTRIB
{
POSITION = 1,
COLOR = 2,
TEXCOORD = 3,
FOG = 4,
};
struct PRIM_VERTEX
{
float x, y, z;
uint32 color;
float s, t, q;
float f;
};
enum VERTEX_BUFFER_SIZE
{
VERTEX_BUFFER_SIZE = 0x1000,
};
typedef std::vector<PRIM_VERTEX> VertexBuffer;
void WriteRegisterImpl(uint8, uint64) override;
void InitializeRC();
void SetupTextureUploaders();
virtual void PresentBackbuffer() = 0;
void MakeLinearZOrtho(float*, float, float, float, float);
unsigned int GetCurrentReadCircuit();
TEXTURE_INFO PrepareTexture(const TEX0&);
void PreparePalette(const TEX0&);
uint32 RGBA16ToRGBA32(uint16);
float GetZ(float);
void VertexKick(uint8, uint64);
Framework::OpenGl::ProgramPtr GenerateShader(const SHADERCAPS&);
Framework::OpenGl::CShader GenerateVertexShader(const SHADERCAPS&);
Framework::OpenGl::CShader GenerateFragmentShader(const SHADERCAPS&);
std::string GenerateTexCoordClampingSection(TEXTURE_CLAMP_MODE, const char*);
std::string GenerateAlphaTestSection(ALPHA_TEST_METHOD);
Framework::OpenGl::ProgramPtr GeneratePresentProgram();
Framework::OpenGl::CBuffer GeneratePresentVertexBuffer();
Framework::OpenGl::CVertexArray GeneratePresentVertexArray();
Framework::OpenGl::CVertexArray GeneratePrimVertexArray();
void Prim_Point();
void Prim_Line();
void Prim_Triangle();
void Prim_Sprite();
void FlushVertexBuffer();
void DrawToDepth(unsigned int, uint64);
void SetRenderingContext(uint64);
void SetupTestFunctions(const SHADERINFO&, uint64);
void SetupDepthBuffer(uint64, uint64);
void SetupFramebuffer(const SHADERINFO&, uint64, uint64, uint64, uint64);
void SetupBlendingFunction(uint64);
void SetupFogColor(const SHADERINFO&, uint64);
static bool CanRegionRepeatClampModeSimplified(uint32, uint32);
void FillShaderCapsFromTexture(SHADERCAPS&, const uint64&, const uint64&, const uint64&, const uint64&);
void FillShaderCapsFromTest(SHADERCAPS&, const uint64&);
void SetupTexture(const SHADERINFO&, uint64, uint64, uint64, uint64, uint64);
static bool IsCompatibleFramebufferPSM(unsigned int, unsigned int);
static uint32 GetFramebufferBitDepth(uint32);
FramebufferPtr FindFramebuffer(const FRAME&) const;
DepthbufferPtr FindDepthbuffer(const ZBUF&, const FRAME&) const;
void DumpTexture(unsigned int, unsigned int, uint32);
//Texture uploaders
void TexUploader_Invalid(uint32, uint32, unsigned int, unsigned int);
void TexUploader_Psm32(uint32, uint32, unsigned int, unsigned int);
template <typename> void TexUploader_Psm16(uint32, uint32, unsigned int, unsigned int);
template <typename> void TexUploader_Psm48(uint32, uint32, unsigned int, unsigned int);
template <uint32, uint32> void TexUploader_Psm48H(uint32, uint32, unsigned int, unsigned int);
//Texture updaters
void TexUpdater_Invalid(uint32, uint32, unsigned int, unsigned int, unsigned int, unsigned int);
void TexUpdater_Psm32(uint32, uint32, unsigned int, unsigned int, unsigned int, unsigned int);
template <typename> void TexUpdater_Psm16(uint32, uint32, unsigned int, unsigned int, unsigned int, unsigned int);
template <typename> void TexUpdater_Psm48(uint32, uint32, unsigned int, unsigned int, unsigned int, unsigned int);
template <uint32, uint32> void TexUpdater_Psm48H(uint32, uint32, unsigned int, unsigned int, unsigned int, unsigned int);
//Context variables (put this in a struct or something?)
float m_nPrimOfsX;
float m_nPrimOfsY;
uint32 m_nTexWidth;
uint32 m_nTexHeight;
float m_nMaxZ;
bool m_forceBilinearTextures = false;
uint8* m_pCvtBuffer;
CTexture* TexCache_Search(const TEX0&);
void TexCache_Insert(const TEX0&, GLuint);
void TexCache_InvalidateTextures(uint32, uint32);
GLuint PalCache_Search(const TEX0&);
GLuint PalCache_Search(unsigned int, const uint32*);
void PalCache_Insert(const TEX0&, const uint32*, GLuint);
void PalCache_Invalidate(uint32);
void PopulateFramebuffer(const FramebufferPtr&);
void CommitFramebufferDirtyPages(const FramebufferPtr&, unsigned int, unsigned int);
Framework::OpenGl::ProgramPtr m_presentProgram;
Framework::OpenGl::CBuffer m_presentVertexBuffer;
Framework::OpenGl::CVertexArray m_presentVertexArray;
GLint m_presentTextureUniform = -1;
GLint m_presentTexCoordScaleUniform = -1;
TextureList m_textureCache;
PaletteList m_paletteCache;
FramebufferList m_framebuffers;
DepthbufferList m_depthbuffers;
Framework::OpenGl::CBuffer m_primBuffer;
Framework::OpenGl::CVertexArray m_primVertexArray;
VERTEX m_VtxBuffer[3];
int m_nVtxCount;
PRMODE m_PrimitiveMode;
unsigned int m_primitiveType;
bool m_drawingToDepth = false;
static GLenum g_nativeClampModes[CGSHandler::CLAMP_MODE_MAX];
static unsigned int g_shaderClampModes[CGSHandler::CLAMP_MODE_MAX];
TEXTUREUPLOADER m_textureUploader[CGSHandler::PSM_MAX];
TEXTUREUPDATER m_textureUpdater[CGSHandler::PSM_MAX];
ShaderInfoMap m_shaderInfos;
RENDERSTATE m_renderState;
VertexBuffer m_vertexBuffer;
};