zzogl-pg:

* bump minimal requirement to  opengl 2! Basically any Dx9 class hardware. On intel you will need a gen4+ GPU.
* remove the bad quality integer texture to use only texture float. Again need an gen4+ Intel GPU. Opensource users: Mesa must be built with support of texture float (stupid patents)



git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5603 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gregory.hainaut 2013-03-25 18:49:29 +00:00
parent 51fc6dbd07
commit 9cc306c74f
9 changed files with 140 additions and 181 deletions

View File

@ -249,12 +249,9 @@ void TransferLocalHost24Z(void* pbyMem, u32 nQWordSize) {FUNCLOG}
void TransferLocalHost16Z(void* pbyMem, u32 nQWordSize) {FUNCLOG} void TransferLocalHost16Z(void* pbyMem, u32 nQWordSize) {FUNCLOG}
void TransferLocalHost16SZ(void* pbyMem, u32 nQWordSize) {FUNCLOG} void TransferLocalHost16SZ(void* pbyMem, u32 nQWordSize) {FUNCLOG}
void fill_block(BLOCK b, vector<char>& vBlockData, vector<char>& vBilinearData, int floatfmt) void fill_block(BLOCK b, vector<char>& vBlockData, vector<char>& vBilinearData)
{ {
float* psrcf = (float*)&vBlockData[0] + b.ox + b.oy * BLOCK_TEXWIDTH; float* psrcf = (float*)&vBlockData[0] + b.ox + b.oy * BLOCK_TEXWIDTH;
u16* psrcw = NULL;
if (!floatfmt)
psrcw = (u16*)&vBlockData[0] + b.ox + b.oy * BLOCK_TEXWIDTH;
for(int i = 0; i < b.height; ++i) for(int i = 0; i < b.height; ++i)
{ {
@ -266,43 +263,33 @@ void fill_block(BLOCK b, vector<char>& vBlockData, vector<char>& vBilinearData,
u32 ct = b.columnTable[(i%b.colheight)*b.colwidth + (j%b.colwidth)]; u32 ct = b.columnTable[(i%b.colheight)*b.colwidth + (j%b.colwidth)];
u32 u = bt * 64 * b.mult + ct; u32 u = bt * 64 * b.mult + ct;
b.pageTable[i * b.width + j] = u; b.pageTable[i * b.width + j] = u;
if (floatfmt) psrcf[i_width + j] = (float)(u) / (float)(GPU_TEXWIDTH * b.mult);
psrcf[i_width + j] = (float)(u) / (float)(GPU_TEXWIDTH * b.mult);
else
psrcw[i_width + j] = u;
} }
} }
if (floatfmt) { float4* psrcv = (float4*)&vBilinearData[0] + b.ox + b.oy * BLOCK_TEXWIDTH;
float4* psrcv = (float4*)&vBilinearData[0] + b.ox + b.oy * BLOCK_TEXWIDTH;
for(int i = 0; i < b.height; ++i) for(int i = 0; i < b.height; ++i)
{ {
u32 i_width = i*BLOCK_TEXWIDTH; u32 i_width = i*BLOCK_TEXWIDTH;
u32 i_width2 = ((i+1)%b.height)*BLOCK_TEXWIDTH; u32 i_width2 = ((i+1)%b.height)*BLOCK_TEXWIDTH;
for(int j = 0; j < b.width; ++j) for(int j = 0; j < b.width; ++j)
{ {
u32 temp = ((j + 1) % b.width); u32 temp = ((j + 1) % b.width);
float4* pv = &psrcv[i_width + j]; float4* pv = &psrcv[i_width + j];
pv->x = psrcf[i_width + j]; pv->x = psrcf[i_width + j];
pv->y = psrcf[i_width + temp]; pv->y = psrcf[i_width + temp];
pv->z = psrcf[i_width2 + j]; pv->z = psrcf[i_width2 + j];
pv->w = psrcf[i_width2 + temp]; pv->w = psrcf[i_width2 + temp];
} }
} }
}
} }
void BLOCK::FillBlocks(vector<char>& vBlockData, vector<char>& vBilinearData, int floatfmt) void BLOCK::FillBlocks(vector<char>& vBlockData, vector<char>& vBilinearData)
{ {
FUNCLOG FUNCLOG
if (floatfmt) { vBlockData.resize(BLOCK_TEXWIDTH * BLOCK_TEXHEIGHT * 4);
vBlockData.resize(BLOCK_TEXWIDTH * BLOCK_TEXHEIGHT * 4); vBilinearData.resize(BLOCK_TEXWIDTH * BLOCK_TEXHEIGHT * sizeof(float4));
vBilinearData.resize(BLOCK_TEXWIDTH * BLOCK_TEXHEIGHT * sizeof(float4));
} else {
vBlockData.resize(BLOCK_TEXWIDTH * BLOCK_TEXHEIGHT * 2);
}
BLOCK b; BLOCK b;
@ -311,7 +298,7 @@ void BLOCK::FillBlocks(vector<char>& vBlockData, vector<char>& vBilinearData, in
// 32 // 32
b.SetDim(64, 32, 0, 0, 1); b.SetDim(64, 32, 0, 0, 1);
b.SetTable(PSMCT32); b.SetTable(PSMCT32);
fill_block(b, vBlockData, vBilinearData, floatfmt); fill_block(b, vBlockData, vBilinearData);
m_Blocks[PSMCT32] = b; m_Blocks[PSMCT32] = b;
m_Blocks[PSMCT32].SetFun(PSMCT32); m_Blocks[PSMCT32].SetFun(PSMCT32);
@ -332,7 +319,7 @@ void BLOCK::FillBlocks(vector<char>& vBlockData, vector<char>& vBilinearData, in
// 32z // 32z
b.SetDim(64, 32, 64, 0, 1); b.SetDim(64, 32, 64, 0, 1);
b.SetTable(PSMT32Z); b.SetTable(PSMT32Z);
fill_block(b, vBlockData, vBilinearData, floatfmt); fill_block(b, vBlockData, vBilinearData);
m_Blocks[PSMT32Z] = b; m_Blocks[PSMT32Z] = b;
m_Blocks[PSMT32Z].SetFun(PSMT32Z); m_Blocks[PSMT32Z].SetFun(PSMT32Z);
@ -343,42 +330,42 @@ void BLOCK::FillBlocks(vector<char>& vBlockData, vector<char>& vBilinearData, in
// 16 // 16
b.SetDim(64, 64, 0, 32, 2); b.SetDim(64, 64, 0, 32, 2);
b.SetTable(PSMCT16); b.SetTable(PSMCT16);
fill_block(b, vBlockData, vBilinearData, floatfmt); fill_block(b, vBlockData, vBilinearData);
m_Blocks[PSMCT16] = b; m_Blocks[PSMCT16] = b;
m_Blocks[PSMCT16].SetFun(PSMCT16); m_Blocks[PSMCT16].SetFun(PSMCT16);
// 16s // 16s
b.SetDim(64, 64, 64, 32, 2); b.SetDim(64, 64, 64, 32, 2);
b.SetTable(PSMCT16S); b.SetTable(PSMCT16S);
fill_block(b, vBlockData, vBilinearData, floatfmt); fill_block(b, vBlockData, vBilinearData);
m_Blocks[PSMCT16S] = b; m_Blocks[PSMCT16S] = b;
m_Blocks[PSMCT16S].SetFun(PSMCT16S); m_Blocks[PSMCT16S].SetFun(PSMCT16S);
// 16z // 16z
b.SetDim(64, 64, 0, 96, 2); b.SetDim(64, 64, 0, 96, 2);
b.SetTable(PSMT16Z); b.SetTable(PSMT16Z);
fill_block(b, vBlockData, vBilinearData, floatfmt); fill_block(b, vBlockData, vBilinearData);
m_Blocks[PSMT16Z] = b; m_Blocks[PSMT16Z] = b;
m_Blocks[PSMT16Z].SetFun(PSMT16Z); m_Blocks[PSMT16Z].SetFun(PSMT16Z);
// 16sz // 16sz
b.SetDim(64, 64, 64, 96, 2); b.SetDim(64, 64, 64, 96, 2);
b.SetTable(PSMT16SZ); b.SetTable(PSMT16SZ);
fill_block(b, vBlockData, vBilinearData, floatfmt); fill_block(b, vBlockData, vBilinearData);
m_Blocks[PSMT16SZ] = b; m_Blocks[PSMT16SZ] = b;
m_Blocks[PSMT16SZ].SetFun(PSMT16SZ); m_Blocks[PSMT16SZ].SetFun(PSMT16SZ);
// 8 // 8
b.SetDim(128, 64, 0, 160, 4); b.SetDim(128, 64, 0, 160, 4);
b.SetTable(PSMT8); b.SetTable(PSMT8);
fill_block(b, vBlockData, vBilinearData, floatfmt); fill_block(b, vBlockData, vBilinearData);
m_Blocks[PSMT8] = b; m_Blocks[PSMT8] = b;
m_Blocks[PSMT8].SetFun(PSMT8); m_Blocks[PSMT8].SetFun(PSMT8);
// 4 // 4
b.SetDim(128, 128, 0, 224, 8); b.SetDim(128, 128, 0, 224, 8);
b.SetTable(PSMT4); b.SetTable(PSMT4);
fill_block(b, vBlockData, vBilinearData, floatfmt); fill_block(b, vBlockData, vBilinearData);
m_Blocks[PSMT4] = b; m_Blocks[PSMT4] = b;
m_Blocks[PSMT4].SetFun(PSMT4); m_Blocks[PSMT4].SetFun(PSMT4);
} }

View File

@ -150,7 +150,7 @@ struct BLOCK
_TransferLocalHost TransferLocalHost; _TransferLocalHost TransferLocalHost;
// texture must be of dims BLOCK_TEXWIDTH and BLOCK_TEXHEIGHT // texture must be of dims BLOCK_TEXWIDTH and BLOCK_TEXHEIGHT
static void FillBlocks(std::vector<char>& vBlockData, std::vector<char>& vBilinearData, int floatfmt); static void FillBlocks(std::vector<char>& vBlockData, std::vector<char>& vBilinearData);
void SetDim(u32 bw, u32 bh, u32 ox2, u32 oy2, u32 mult2) void SetDim(u32 bw, u32 bh, u32 ox2, u32 oy2, u32 mult2)
{ {

View File

@ -95,9 +95,6 @@ static __forceinline void SET_STREAM()
#endif #endif
} }
// global alpha blending settings
extern GLenum g_internalRGBAFloat16Fmt;
//static __forceinline void SAFE_RELEASE_TEX(u32& x) //static __forceinline void SAFE_RELEASE_TEX(u32& x)
//{ //{
// if (x != 0) // if (x != 0)
@ -148,7 +145,6 @@ extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
extern PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT; extern PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT;
extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT; extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT; extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT;
extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;
extern PFNGLDRAWBUFFERSPROC glDrawBuffers; extern PFNGLDRAWBUFFERSPROC glDrawBuffers;
#ifdef GLSL4_API #ifdef GLSL4_API

View File

@ -96,10 +96,6 @@ GLenum s_srcrgb, s_dstrgb, s_srcalpha, s_dstalpha; // set by zgsBlendFuncSeparat
u32 s_stencilfunc, s_stencilref, s_stencilmask; u32 s_stencilfunc, s_stencilref, s_stencilmask;
GLenum s_drawbuffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT }; GLenum s_drawbuffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
GLenum g_internalFloatFmt = GL_ALPHA_FLOAT32_ATI;
GLenum g_internalRGBAFloatFmt = GL_RGBA_FLOAT32_ATI;
GLenum g_internalRGBAFloat16Fmt = GL_RGBA_FLOAT16_ATI;
u32 ptexLogo = 0; u32 ptexLogo = 0;
int nLogoWidth, nLogoHeight; int nLogoWidth, nLogoHeight;
u32 s_ptexInterlace = 0; // holds interlace fields u32 s_ptexInterlace = 0; // holds interlace fields
@ -136,35 +132,55 @@ bool IsGLExt(const char* szTargetExtension)
return mapGLExtensions.find(string(szTargetExtension)) != mapGLExtensions.end(); return mapGLExtensions.find(string(szTargetExtension)) != mapGLExtensions.end();
} }
inline bool check_gl_version(uint32 major, uint32 minor) {
const GLubyte* s;
s = glGetString(GL_VERSION);
if (s == NULL) return false;
ZZLog::Error_Log("Supported Opengl version: %s on GPU: %s. Vendor: %s\n", s, glGetString(GL_RENDERER), glGetString(GL_VENDOR));
// Could be useful to detect the GPU vendor:
// if ( strcmp((const char*)glGetString(GL_VENDOR), "ATI Technologies Inc.") == 0 )
GLuint dot = 0;
while (s[dot] != '\0' && s[dot] != '.') dot++;
if (dot == 0) return false;
GLuint major_gl = s[dot-1]-'0';
GLuint minor_gl = s[dot+1]-'0';
if ( (major_gl < major) || ( major_gl == major && minor_gl < minor ) ) {
ZZLog::Error_Log("OPENGL %d.%d is not supported\n", major, minor);
return false;
}
return true;
}
// Function asks about different OGL extensions, that are required to setup accordingly. Return false if checks failed // Function asks about different OGL extensions, that are required to setup accordingly. Return false if checks failed
inline bool CreateImportantCheck() inline bool CreateImportantCheck()
{ {
bool bSuccess = true; bool bSuccess = true;
#ifndef _WIN32 #ifndef _WIN32
int const glew_ok = glewInit(); int const glew_ok = glewInit();
if (glew_ok != GLEW_OK) { if (glew_ok != GLEW_OK) {
ZZLog::Error_Log("glewInit() is not ok!"); ZZLog::Error_Log("glewInit() is not ok!");
bSuccess = false; // Better exit now, any openGL call will segfault.
} else { return false;
const GLubyte* gl_version = glGetString(GL_VERSION);
ZZLog::Error_Log("Supported Opengl version : %s\n", gl_version);
} }
#endif #endif
// Require a minimum of openGL2.0 (first version that support hardware shader)
bSuccess &= check_gl_version(2, 0);
// GL_EXT_framebuffer_object -> GL3.0
// Opensource driver -> Intel OK. Radeon need EXT_packed_depth_stencil
if (!IsGLExt("GL_EXT_framebuffer_object")) if (!IsGLExt("GL_EXT_framebuffer_object"))
{ {
ZZLog::Error_Log("*********\nZZogl: ERROR: Need GL_EXT_framebuffer_object for multiple render targets\nZZogl: *********"); ZZLog::Error_Log("*********\nZZogl: ERROR: Need GL_EXT_framebuffer_object for multiple render targets\nZZogl: *********");
bSuccess = false; bSuccess = false;
} }
if (!IsGLExt("GL_EXT_secondary_color"))
{
ZZLog::Error_Log("*********\nZZogl: OGL WARNING: Need GL_EXT_secondary_color\nZZogl: *********");
bSuccess = false;
}
bSuccess &= ZZshCheckProfilesSupport(); bSuccess &= ZZshCheckProfilesSupport();
return bSuccess; return bSuccess;
@ -173,39 +189,21 @@ inline bool CreateImportantCheck()
// This is a check for less important open gl extensions. // This is a check for less important open gl extensions.
inline void CreateOtherCheck() inline void CreateOtherCheck()
{ {
if (!IsGLExt("GL_EXT_blend_equation_separate") || glBlendEquationSeparateEXT == NULL) // GL_EXT_blend_equation_separate -> GL2.0
{ // Opensource driver -> Intel OK. Radeon OK.
ZZLog::Error_Log("*********\nZZogl: OGL WARNING: Need GL_EXT_blend_equation_separate\nZZogl: *********"); zgsBlendEquationSeparateEXT = glBlendEquationSeparateEXT;
zgsBlendEquationSeparateEXT = glBlendEquationSeparateDummy;
}
else
zgsBlendEquationSeparateEXT = glBlendEquationSeparateEXT;
if (!IsGLExt("GL_EXT_blend_func_separate") || glBlendFuncSeparateEXT == NULL) // GL_EXT_blend_func_separate -> GL1.4
{ // Opensource driver -> Intel OK. Radeon OK.
ZZLog::Error_Log("*********\nZZogl: OGL WARNING: Need GL_EXT_blend_func_separate\nZZogl: *********"); zgsBlendFuncSeparateEXT = glBlendFuncSeparateEXT;
zgsBlendFuncSeparateEXT = glBlendFuncSeparateDummy;
}
else
zgsBlendFuncSeparateEXT = glBlendFuncSeparateEXT;
if (!IsGLExt("GL_ARB_draw_buffers") && !IsGLExt("GL_ATI_draw_buffers")) // GL_ARB_draw_buffers -> GL2.0
{ // Opensource driver -> Intel (need gen4). Radeon OK.
ZZLog::Error_Log("*********\nZZogl: OGL WARNING: multiple render targets not supported, some effects might look bad\nZZogl: *********"); if (glDrawBuffers == NULL) {
ZZLog::Error_Log("*********\nZZogl: OGL ERROR: multiple render targets not supported, some effects might look bad\nZZogl: *********");
conf.mrtdepth = 0; conf.mrtdepth = 0;
} }
if (IsGLExt("GL_ARB_draw_buffers"))
glDrawBuffers = (PFNGLDRAWBUFFERSPROC)GLWin.GetProcAddress("glDrawBuffers");
else if (IsGLExt("GL_ATI_draw_buffers"))
glDrawBuffers = (PFNGLDRAWBUFFERSPROC)GLWin.GetProcAddress("glDrawBuffersATI");
if (!IsGLExt("GL_ARB_multitexture"))
ZZLog::Error_Log("No multitexturing.");
else
ZZLog::Error_Log("Using multitexturing.");
GLint Max_Texture_Size_NV = 0; GLint Max_Texture_Size_NV = 0;
GLint Max_Texture_Size_2d = 0; GLint Max_Texture_Size_2d = 0;
@ -396,6 +394,8 @@ inline bool CreateFillExtensionsMap()
void LoadglFunctions() void LoadglFunctions()
{ {
// GL_EXT_framebuffer_object
// CORE -> 3.0 and replaced by GL_ARB_framebuffer_object
GL_LOADFN(glIsRenderbufferEXT); GL_LOADFN(glIsRenderbufferEXT);
GL_LOADFN(glBindRenderbufferEXT); GL_LOADFN(glBindRenderbufferEXT);
GL_LOADFN(glDeleteRenderbuffersEXT); GL_LOADFN(glDeleteRenderbuffersEXT);
@ -412,23 +412,21 @@ void LoadglFunctions()
GL_LOADFN(glFramebufferTexture3DEXT); GL_LOADFN(glFramebufferTexture3DEXT);
GL_LOADFN(glFramebufferRenderbufferEXT); GL_LOADFN(glFramebufferRenderbufferEXT);
GL_LOADFN(glGetFramebufferAttachmentParameterivEXT); GL_LOADFN(glGetFramebufferAttachmentParameterivEXT);
GL_LOADFN(glGenerateMipmapEXT);
// CORE -> 2.0
GL_LOADFN(glDrawBuffers);
} }
inline bool TryBlockFormat(GLint fmt, const GLvoid* vBlockData) { inline bool TryBlockFormat(GLint fmt, const GLvoid* vBlockData) {
g_internalFloatFmt = fmt; glTexImage2D(GL_TEXTURE_2D, 0, fmt, BLOCK_TEXWIDTH, BLOCK_TEXHEIGHT, 0, GL_ALPHA, GL_FLOAT, vBlockData);
glTexImage2D(GL_TEXTURE_2D, 0, g_internalFloatFmt, BLOCK_TEXWIDTH, BLOCK_TEXHEIGHT, 0, GL_ALPHA, GL_FLOAT, vBlockData);
return (glGetError() == GL_NO_ERROR); return (glGetError() == GL_NO_ERROR);
} }
inline bool TryBlinearFormat(GLint fmt32, GLint fmt16, const GLvoid* vBilinearData) { inline bool TryBlinearFormat(GLint fmt32, const GLvoid* vBilinearData) {
g_internalRGBAFloatFmt = fmt32; glTexImage2D(GL_TEXTURE_2D, 0, fmt32, BLOCK_TEXWIDTH, BLOCK_TEXHEIGHT, 0, GL_RGBA, GL_FLOAT, vBilinearData);
g_internalRGBAFloat16Fmt = fmt16;
glTexImage2D(GL_TEXTURE_2D, 0, g_internalRGBAFloatFmt, BLOCK_TEXWIDTH, BLOCK_TEXHEIGHT, 0, GL_RGBA, GL_FLOAT, vBilinearData);
return (glGetError() == GL_NO_ERROR); return (glGetError() == GL_NO_ERROR);
} }
bool ZZCreate(int _width, int _height) bool ZZCreate(int _width, int _height)
{ {
GLenum err = GL_NO_ERROR; GLenum err = GL_NO_ERROR;
@ -584,7 +582,6 @@ bool ZZCreate(int _width, int _height)
// create the blocks texture // create the blocks texture
g_fBlockMult = 1; g_fBlockMult = 1;
bool do_not_use_billinear = false;
#ifndef ZZNORMAL_MEMORY #ifndef ZZNORMAL_MEMORY
FillAlowedPsnTable(); FillAlowedPsnTable();
@ -592,58 +589,54 @@ bool ZZCreate(int _width, int _height)
#endif #endif
vector<char> vBlockData, vBilinearData; vector<char> vBlockData, vBilinearData;
BLOCK::FillBlocks(vBlockData, vBilinearData, 1); BLOCK::FillBlocks(vBlockData, vBilinearData);
glGenTextures(1, &ptexBlocks); glGenTextures(1, &ptexBlocks);
glBindTexture(GL_TEXTURE_2D, ptexBlocks); glBindTexture(GL_TEXTURE_2D, ptexBlocks);
// Opensource driver -> Intel (need gen4) (enabled by default on mesa 9). Radeon depends on the HW capability
#ifdef GLSL4_API
// texture float -> GL3.0
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, BLOCK_TEXWIDTH, BLOCK_TEXHEIGHT, 0, GL_RED, GL_FLOAT, &vBlockData[0]);
if (glGetError() != GL_NO_ERROR) {
ZZLog::Error_Log("ZZogl ERROR: could not fill blocks");
return false;
}
#else
if (TryBlockFormat(GL_RGBA32F, &vBlockData[0])) if (TryBlockFormat(GL_RGBA32F, &vBlockData[0]))
ZZLog::Error_Log("Use GL_RGBA32F for blockdata."); ZZLog::Error_Log("Use GL_RGBA32F for blockdata.");
else if (TryBlockFormat(GL_ALPHA_FLOAT32_ATI, &vBlockData[0])) else if (TryBlockFormat(GL_ALPHA_FLOAT32_ATI, &vBlockData[0]))
ZZLog::Error_Log("Use ATI_texture_float for blockdata."); ZZLog::Error_Log("Use ATI_texture_float for blockdata.");
else if (TryBlockFormat(GL_ALPHA32F_ARB, &vBlockData[0])) else {
ZZLog::Error_Log("Use ARB_texture_float for blockdata."); ZZLog::Error_Log("ZZogl ERROR: float texture not supported. If you use opensource driver (aka Mesa), you probably need to compile it with texture float support.");
else ZZLog::Error_Log("ZZogl ERROR: Otherwise you probably have a very very old GPU, either use an older version of the plugin or upgrade your computer");
{ // This case is bad. But for really old cards it could be nice. return false;
g_fBlockMult = 65535.0f*(float)g_fiGPU_TEXWIDTH;
BLOCK::FillBlocks(vBlockData, vBilinearData, 0);
g_internalFloatFmt = GL_ALPHA16;
// We store block data on u16 rather float numbers. It's not so preciese, but ALPHA16 is OpenGL 2.0 standart
// and use only 16 bit. Old zerogs use red channel, but it does not work.
glTexImage2D(GL_TEXTURE_2D, 0, g_internalFloatFmt, BLOCK_TEXWIDTH, BLOCK_TEXHEIGHT, 0, GL_ALPHA, GL_UNSIGNED_SHORT, &vBlockData[0]);
if( glGetError() != GL_NO_ERROR ) {
ZZLog::Error_Log("ZZogl ERROR: could not fill blocks");
return false;
}
do_not_use_billinear = true;
conf.bilinear = 0;
ZZLog::Error_Log("Using non-bilinear fill, quallity is outdated!");
} }
#endif
setTex2DFilters(GL_NEAREST); setTex2DFilters(GL_NEAREST);
setTex2DWrap(GL_REPEAT); setTex2DWrap(GL_REPEAT);
if (!do_not_use_billinear) // fill in the bilinear blocks (main variant).
{ glGenTextures(1, &ptexBilinearBlocks);
// fill in the bilinear blocks (main variant). glBindTexture(GL_TEXTURE_2D, ptexBilinearBlocks);
glGenTextures(1, &ptexBilinearBlocks);
glBindTexture(GL_TEXTURE_2D, ptexBilinearBlocks);
if (TryBlinearFormat(GL_RGBA32F, GL_RGBA16F, &vBilinearData[0]))
ZZLog::Error_Log("Fill bilinear blocks OK.!");
else if (TryBlinearFormat(GL_RGBA_FLOAT32_ATI, GL_RGBA_FLOAT16_ATI, &vBilinearData[0]))
ZZLog::Error_Log("Fill bilinear blocks with ATI_texture_float.");
else if (TryBlinearFormat(GL_FLOAT_RGBA32_NV, GL_FLOAT_RGBA16_NV, &vBilinearData[0]))
ZZLog::Error_Log("ZZogl Fill bilinear blocks with NVidia_float.");
else
ZZLog::Error_Log("Fill bilinear blocks failed.");
setTex2DFilters(GL_NEAREST); #ifdef GLSL4_API
setTex2DWrap(GL_REPEAT); if (!TryBlinearFormat(GL_RGBA32F, &vBilinearData[0]))
} ZZLog::Error_Log("Fill bilinear blocks failed.");
#else
if (TryBlinearFormat(GL_RGBA32F, &vBilinearData[0]))
ZZLog::Error_Log("Fill bilinear blocks OK.!");
else if (TryBlinearFormat(GL_RGBA_FLOAT32_ATI, &vBilinearData[0]))
ZZLog::Error_Log("Fill bilinear blocks with ATI_texture_float.");
else if (TryBlinearFormat(GL_FLOAT_RGBA32_NV, &vBilinearData[0]))
ZZLog::Error_Log("ZZogl Fill bilinear blocks with NVidia_float.");
else
ZZLog::Error_Log("Fill bilinear blocks failed.");
#endif
setTex2DFilters(GL_NEAREST);
setTex2DWrap(GL_REPEAT);
float fpri = 1; float fpri = 1;
@ -688,11 +681,6 @@ bool ZZCreate(int _width, int _height)
GL_REPORT_ERROR(); GL_REPORT_ERROR();
#endif #endif
// some cards don't support this
// glClientActiveTexture(GL_TEXTURE0);
// glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// glTexCoordPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexGPU), (void*)12);
// create the conversion textures // create the conversion textures
glGenTextures(1, &ptexConv16to32); glGenTextures(1, &ptexConv16to32);
glBindTexture(GL_TEXTURE_2D, ptexConv16to32); glBindTexture(GL_TEXTURE_2D, ptexConv16to32);
@ -746,6 +734,7 @@ bool ZZCreate(int _width, int _height)
GL_REPORT_ERROR(); GL_REPORT_ERROR();
if (err != GL_NO_ERROR) bSuccess = false; if (err != GL_NO_ERROR) bSuccess = false;
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
@ -773,10 +762,6 @@ bool ZZCreate(int _width, int _height)
g_vsprog = g_psprog = sZero; g_vsprog = g_psprog = sZero;
#ifdef OGL4_LOG
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
#endif
if (glGetError() == GL_NO_ERROR) if (glGetError() == GL_NO_ERROR)
{ {
return bSuccess; return bSuccess;

View File

@ -428,7 +428,7 @@ void TransferLocalHost24Z(void* pbyMem, u32 nQWordSize) { FUNCLOG }
void TransferLocalHost16Z(void* pbyMem, u32 nQWordSize) { FUNCLOG } void TransferLocalHost16Z(void* pbyMem, u32 nQWordSize) { FUNCLOG }
void TransferLocalHost16SZ(void* pbyMem, u32 nQWordSize) { FUNCLOG } void TransferLocalHost16SZ(void* pbyMem, u32 nQWordSize) { FUNCLOG }
inline void FILL_BLOCK(BLOCK& b, int floatfmt, vector<char>& vBlockData, vector<char>& vBilinearData, int ox, int oy, int psmX) { inline void FILL_BLOCK(BLOCK& b, vector<char>& vBlockData, vector<char>& vBilinearData, int ox, int oy, int psmX) {
int bw = ZZ_DT[psmX][4] + 1; int bw = ZZ_DT[psmX][4] + 1;
int bh = ZZ_DT[psmX][3] + 1; int bh = ZZ_DT[psmX][3] + 1;
int mult = 1 << ZZ_DT[psmX][0]; int mult = 1 << ZZ_DT[psmX][0];
@ -448,36 +448,28 @@ inline void FILL_BLOCK(BLOCK& b, int floatfmt, vector<char>& vBlockData, vector<
// This is never true. // This is never true.
//assert( sizeof(g_pageTable[psmX]) == bw*bh*sizeof(g_pageTable[psmX][0][0]) ); //assert( sizeof(g_pageTable[psmX]) == bw*bh*sizeof(g_pageTable[psmX][0][0]) );
float* psrcf = (float*)&vBlockData[0] + ox + oy * BLOCK_TEXWIDTH; float* psrcf = (float*)&vBlockData[0] + ox + oy * BLOCK_TEXWIDTH;
u16* psrcw = (u16*)&vBlockData[0] + ox + oy * BLOCK_TEXWIDTH;
for(int i = 0; i < bh; ++i) { for(int i = 0; i < bh; ++i) {
for(int j = 0; j < bw; ++j) { for(int j = 0; j < bw; ++j) {
/* fill the table */ /* fill the table */
u32 u = g_blockTable[psmX][(i / b.colheight)][(j / b.colwidth)] * 64 * mult + g_columnTable[psmX][i%b.colheight][j%b.colwidth]; u32 u = g_blockTable[psmX][(i / b.colheight)][(j / b.colwidth)] * 64 * mult + g_columnTable[psmX][i%b.colheight][j%b.colwidth];
b.pageTable[i][j] = u; b.pageTable[i][j] = u;
if( floatfmt ) { psrcf[i*BLOCK_TEXWIDTH+j] = (float)(u) / (float)(GPU_TEXWIDTH*mult);
psrcf[i*BLOCK_TEXWIDTH+j] = (float)(u) / (float)(GPU_TEXWIDTH*mult);
}
else {
psrcw[i*BLOCK_TEXWIDTH+j] = u;
}
} }
} }
if( floatfmt ) { float4* psrcv = (float4*)&vBilinearData[0] + ox + oy * BLOCK_TEXWIDTH;
float4* psrcv = (float4*)&vBilinearData[0] + ox + oy * BLOCK_TEXWIDTH; for(int i = 0; i < bh; ++i) {
for(int i = 0; i < bh; ++i) { for(int j = 0; j < bw; ++j) {
for(int j = 0; j < bw; ++j) { float4* pv = &psrcv[i*BLOCK_TEXWIDTH+j];
float4* pv = &psrcv[i*BLOCK_TEXWIDTH+j]; pv->x = psrcf[i*BLOCK_TEXWIDTH+j];
pv->x = psrcf[i*BLOCK_TEXWIDTH+j]; pv->y = psrcf[i*BLOCK_TEXWIDTH+((j+1)%bw)];
pv->y = psrcf[i*BLOCK_TEXWIDTH+((j+1)%bw)]; pv->z = psrcf[((i+1)%bh)*BLOCK_TEXWIDTH+j];
pv->z = psrcf[((i+1)%bh)*BLOCK_TEXWIDTH+j]; pv->w = psrcf[((i+1)%bh)*BLOCK_TEXWIDTH+((j+1)%bw)];
pv->w = psrcf[((i+1)%bh)*BLOCK_TEXWIDTH+((j+1)%bw)];
}
} }
} }
} }
void BLOCK::FillBlocks(vector<char>& vBlockData, vector<char>& vBilinearData, int floatfmt) void BLOCK::FillBlocks(vector<char>& vBlockData, vector<char>& vBilinearData)
{ {
FUNCLOG FUNCLOG
vBlockData.resize(BLOCK_TEXWIDTH * BLOCK_TEXHEIGHT * (floatfmt ? 4 : 2)); vBlockData.resize(BLOCK_TEXWIDTH * BLOCK_TEXHEIGHT * (floatfmt ? 4 : 2));
@ -490,7 +482,7 @@ void BLOCK::FillBlocks(vector<char>& vBlockData, vector<char>& vBilinearData, in
memset(m_Blocks, 0, sizeof(m_Blocks)); memset(m_Blocks, 0, sizeof(m_Blocks));
// 32 // 32
FILL_BLOCK(b, floatfmt, vBlockData, vBilinearData, 0, 0, PSMCT32); FILL_BLOCK(b, vBlockData, vBilinearData, 0, 0, PSMCT32);
b.TransferHostLocal = TransferHostLocal32; b.TransferHostLocal = TransferHostLocal32;
b.TransferLocalHost = TransferLocalHost32; b.TransferLocalHost = TransferLocalHost32;
m_Blocks[PSMCT32] = b; m_Blocks[PSMCT32] = b;
@ -514,7 +506,7 @@ void BLOCK::FillBlocks(vector<char>& vBlockData, vector<char>& vBilinearData, in
m_Blocks[PSMT4HH] = b; m_Blocks[PSMT4HH] = b;
// 32z // 32z
FILL_BLOCK(b, floatfmt, vBlockData, vBilinearData, 64, 0, PSMT32Z); FILL_BLOCK(b, vBlockData, vBilinearData, 64, 0, PSMT32Z);
b.TransferHostLocal = TransferHostLocal32Z; b.TransferHostLocal = TransferHostLocal32Z;
b.TransferLocalHost = TransferLocalHost32Z; b.TransferLocalHost = TransferLocalHost32Z;
m_Blocks[PSMT32Z] = b; m_Blocks[PSMT32Z] = b;
@ -525,37 +517,37 @@ void BLOCK::FillBlocks(vector<char>& vBlockData, vector<char>& vBilinearData, in
m_Blocks[PSMT24Z] = b; m_Blocks[PSMT24Z] = b;
// 16 // 16
FILL_BLOCK(b, floatfmt, vBlockData, vBilinearData, 0, 32, PSMCT16); FILL_BLOCK(b, vBlockData, vBilinearData, 0, 32, PSMCT16);
b.TransferHostLocal = TransferHostLocal16; b.TransferHostLocal = TransferHostLocal16;
b.TransferLocalHost = TransferLocalHost16; b.TransferLocalHost = TransferLocalHost16;
m_Blocks[PSMCT16] = b; m_Blocks[PSMCT16] = b;
// 16s // 16s
FILL_BLOCK(b, floatfmt, vBlockData, vBilinearData, 64, 32, PSMCT16S); FILL_BLOCK(b, vBlockData, vBilinearData, 64, 32, PSMCT16S);
b.TransferHostLocal = TransferHostLocal16S; b.TransferHostLocal = TransferHostLocal16S;
b.TransferLocalHost = TransferLocalHost16S; b.TransferLocalHost = TransferLocalHost16S;
m_Blocks[PSMCT16S] = b; m_Blocks[PSMCT16S] = b;
// 16z // 16z
FILL_BLOCK(b, floatfmt, vBlockData, vBilinearData, 0, 96, PSMT16Z); FILL_BLOCK(b, vBlockData, vBilinearData, 0, 96, PSMT16Z);
b.TransferHostLocal = TransferHostLocal16Z; b.TransferHostLocal = TransferHostLocal16Z;
b.TransferLocalHost = TransferLocalHost16Z; b.TransferLocalHost = TransferLocalHost16Z;
m_Blocks[PSMT16Z] = b; m_Blocks[PSMT16Z] = b;
// 16sz // 16sz
FILL_BLOCK(b, floatfmt, vBlockData, vBilinearData, 64, 96, PSMT16SZ); FILL_BLOCK(b, vBlockData, vBilinearData, 64, 96, PSMT16SZ);
b.TransferHostLocal = TransferHostLocal16SZ; b.TransferHostLocal = TransferHostLocal16SZ;
b.TransferLocalHost = TransferLocalHost16SZ; b.TransferLocalHost = TransferLocalHost16SZ;
m_Blocks[PSMT16SZ] = b; m_Blocks[PSMT16SZ] = b;
// 8 // 8
FILL_BLOCK(b, floatfmt, vBlockData, vBilinearData, 0, 160, PSMT8); FILL_BLOCK(b, vBlockData, vBilinearData, 0, 160, PSMT8);
b.TransferHostLocal = TransferHostLocal8; b.TransferHostLocal = TransferHostLocal8;
b.TransferLocalHost = TransferLocalHost8; b.TransferLocalHost = TransferLocalHost8;
m_Blocks[PSMT8] = b; m_Blocks[PSMT8] = b;
// 4 // 4
FILL_BLOCK(b, floatfmt, vBlockData, vBilinearData, 0, 224, PSMT4); FILL_BLOCK(b, vBlockData, vBilinearData, 0, 224, PSMT4);
b.TransferHostLocal = TransferHostLocal4; b.TransferHostLocal = TransferHostLocal4;
b.TransferLocalHost = TransferLocalHost4; b.TransferLocalHost = TransferLocalHost4;
m_Blocks[PSMT4] = b; m_Blocks[PSMT4] = b;

View File

@ -95,7 +95,7 @@ struct BLOCK
void (*TransferLocalHost)(void* pbyMem, u32 nQWordSize); void (*TransferLocalHost)(void* pbyMem, u32 nQWordSize);
// texture must be of dims BLOCK_TEXWIDTH and BLOCK_TEXHEIGHT // texture must be of dims BLOCK_TEXWIDTH and BLOCK_TEXHEIGHT
static void FillBlocks(std::vector<char>& vBlockData, std::vector<char>& vBilinearData, int floatfmt); static void FillBlocks(std::vector<char>& vBlockData, std::vector<char>& vBilinearData);
}; };
void FillBlockTables(); void FillBlockTables();

View File

@ -96,7 +96,7 @@ float2 ps2memcoord(float2 realtex)
off.xy = realtex.xy-fblock.xy; off.xy = realtex.xy-fblock.xy;
#ifdef ACCURATE_DECOMPRESSION #ifdef ACCURATE_DECOMPRESSION
off.zw = tex2D(g_sBlocks, g_fTexBlock.xy*fblock + g_fTexBlock.zw).ar; off.z = tex2D(g_sBlocks, g_fTexBlock.xy*fblock + g_fTexBlock.zw).a;
off.x = dot(off.xy, g_fTexOffset.xy); off.x = dot(off.xy, g_fTexOffset.xy);
float r = g_fTexOffset.w; float r = g_fTexOffset.w;
float f = frac(off.x); float f = frac(off.x);

View File

@ -193,7 +193,7 @@ float2 ps2memcoord(float2 realtex)
off.xy = realtex.xy-fblock.xy; off.xy = realtex.xy-fblock.xy;
#ifdef ACCURATE_DECOMPRESSION #ifdef ACCURATE_DECOMPRESSION
off.zw = texture(g_sBlocks, g_fTexBlock.xy*fblock + g_fTexBlock.zw).ar; off.z = texture(g_sBlocks, g_fTexBlock.xy*fblock + g_fTexBlock.zw).r;
off.x = dot(off.xy, g_fTexOffset.xy); off.x = dot(off.xy, g_fTexOffset.xy);
float r = g_fTexOffset.w; float r = g_fTexOffset.w;
float f = fract(off.x); float f = fract(off.x);
@ -202,7 +202,7 @@ float2 ps2memcoord(float2 realtex)
off.x = fract(f + fadd + r); off.x = fract(f + fadd + r);
off.w -= off.x ; off.w -= off.x ;
#else #else
off.z = texture(g_sBlocks, g_fTexBlock.xy*fblock + g_fTexBlock.zw).a; off.z = texture(g_sBlocks, g_fTexBlock.xy*fblock + g_fTexBlock.zw).r;
// combine the two // combine the two
off.x = dot(off.xyz, g_fTexOffset.xyz)+g_fTexOffset.w; off.x = dot(off.xyz, g_fTexOffset.xyz)+g_fTexOffset.w;
@ -232,10 +232,10 @@ void ps2memcoord4(float4 orgtex, out float4 off0, out float4 off1)
float4 colors;// = texture(g_sBilinearBlocks, ftransblock.xy); float4 colors;// = texture(g_sBilinearBlocks, ftransblock.xy);
// this is faster on ffx ingame // this is faster on ffx ingame
colors.x = texture(g_sBlocks, ftransblock.xy).a; colors.x = texture(g_sBlocks, ftransblock.xy).r;
colors.y = texture(g_sBlocks, ftransblock.zy).a; colors.y = texture(g_sBlocks, ftransblock.zy).r;
colors.z = texture(g_sBlocks, ftransblock.xw).a; colors.z = texture(g_sBlocks, ftransblock.xw).r;
colors.w = texture(g_sBlocks, ftransblock.zw).a; colors.w = texture(g_sBlocks, ftransblock.zw).r;
float4 fr, rem; float4 fr, rem;

View File

@ -63,7 +63,6 @@ PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT = NULL;
PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT = NULL; PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT = NULL;
PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT = NULL; PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT = NULL;
PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT = NULL; PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT = NULL;
PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT = NULL;
PFNGLDRAWBUFFERSPROC glDrawBuffers = NULL; PFNGLDRAWBUFFERSPROC glDrawBuffers = NULL;
#ifndef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT #ifndef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT