gsdx ogl:

* add a non-working hack: UserHacks_DateGL4, goal was to replace UserHacks_AlphaStencil
 + Detection of good/bad samples is based on primitive ID variable. However I'm not sure
 the behavior is always the same between draw call...Anyway let's keep a copy of the current
 work
* Dump integer texture into text csv
* add gl4.2 ARB_shader_image_load_store extension (needed by UserHacks_DateGL4)


git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5707 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gregory.hainaut 2013-07-28 14:40:43 +00:00
parent baffb9c8d9
commit e394de86dc
16 changed files with 321 additions and 39 deletions

View File

@ -40,6 +40,7 @@ PFNGLBUFFERDATAPROC gl_BufferData = NULL;
PFNGLCHECKFRAMEBUFFERSTATUSPROC gl_CheckFramebufferStatus = NULL;
PFNGLCLEARBUFFERFVPROC gl_ClearBufferfv = NULL;
PFNGLCLEARBUFFERIVPROC gl_ClearBufferiv = NULL;
PFNGLCLEARBUFFERUIVPROC gl_ClearBufferuiv = NULL;
PFNGLCOMPILESHADERPROC gl_CompileShader = NULL;
PFNGLCOPYIMAGESUBDATANVPROC gl_CopyImageSubDataNV = NULL;
PFNGLCREATEPROGRAMPROC gl_CreateProgram = NULL;
@ -99,12 +100,16 @@ PFNGLPROGRAMUNIFORM1IPROC gl_ProgramUniform1i = NULL;
PFNGLGETUNIFORMBLOCKINDEXPROC gl_GetUniformBlockIndex = NULL;
PFNGLUNIFORMBLOCKBINDINGPROC gl_UniformBlockBinding = NULL;
PFNGLGETUNIFORMLOCATIONPROC gl_GetUniformLocation = NULL;
// GL4.2
PFNGLBINDIMAGETEXTUREPROC gl_BindImageTexture = NULL;
PFNGLMEMORYBARRIERPROC gl_MemoryBarrier = NULL;
#endif
namespace GLLoader {
bool fglrx_buggy_driver = false;
bool nvidia_buggy_driver = false;
bool in_replayer = false;
bool found_GL_ARB_separate_shader_objects = false;
bool found_GL_ARB_shading_language_420pack = false;
@ -114,11 +119,15 @@ namespace GLLoader {
bool found_GL_ARB_copy_image = false;
bool found_only_gl30 = false;
bool found_GL_ARB_gpu_shader5 = false;
bool found_GL_ARB_shader_image_load_store = false;
bool check_gl_version(uint32 major, uint32 minor) {
const GLubyte* s = glGetString(GL_VERSION);
if (s == NULL) return false;
if (s == NULL) {
fprintf(stderr, "Error: GLLoader failed to get GL version\n");
return false;
}
const char* vendor = (const char*)glGetString(GL_VENDOR);
fprintf(stderr, "Supported Opengl version: %s on GPU: %s. Vendor: %s\n", s, glGetString(GL_RENDERER), vendor);
@ -183,6 +192,7 @@ namespace GLLoader {
// Replace previous extensions (when driver will be updated)
if (ext.compare("GL_ARB_copy_image") == 0) found_GL_ARB_copy_image = true;
if (ext.compare("GL_ARB_gpu_shader5") == 0) found_GL_ARB_gpu_shader5 = true;
if (ext.compare("GL_ARB_shader_image_load_store") == 0) found_GL_ARB_shader_image_load_store = true;
#ifdef ENABLE_GLES
fprintf(stderr, "DEBUG ext: %s\n", ext.c_str());
#endif
@ -203,6 +213,8 @@ namespace GLLoader {
if (!found_GL_ARB_gpu_shader5) {
fprintf(stderr, "INFO: GL_ARB_gpu_shader5 is not supported\n");
}
if (!found_GL_ARB_shader_image_load_store)
fprintf(stderr, "INFO: GL_ARB_shader_image_load_store is not supported\n");
if (theApp.GetConfig("override_GL_ARB_shading_language_420pack", -1) != -1) {
@ -213,6 +225,10 @@ namespace GLLoader {
found_GL_ARB_separate_shader_objects = !!theApp.GetConfig("override_GL_ARB_separate_shader_objects", -1);
fprintf(stderr, "Override GL_ARB_separate_shader_objects detection\n");
}
if (theApp.GetConfig("override_GL_ARB_shader_image_load_store", -1) != -1) {
found_GL_ARB_shader_image_load_store = !!theApp.GetConfig("override_GL_ARB_shader_image_load_store", -1);
fprintf(stderr, "Override GL_ARB_shader_image_load_store detection\n");
}
if (theApp.GetConfig("override_GL_ARB_copy_image", -1) != -1) {
// Same extension so override both
found_GL_ARB_copy_image = !!theApp.GetConfig("override_GL_ARB_copy_image", -1);

View File

@ -38,6 +38,7 @@ extern PFNGLBUFFERDATAPROC gl_BufferData;
extern PFNGLCHECKFRAMEBUFFERSTATUSPROC gl_CheckFramebufferStatus;
extern PFNGLCLEARBUFFERFVPROC gl_ClearBufferfv;
extern PFNGLCLEARBUFFERIVPROC gl_ClearBufferiv;
extern PFNGLCLEARBUFFERUIVPROC gl_ClearBufferuiv;
extern PFNGLCOMPILESHADERPROC gl_CompileShader;
extern PFNGLCOPYIMAGESUBDATANVPROC gl_CopyImageSubDataNV;
extern PFNGLCREATEPROGRAMPROC gl_CreateProgram;
@ -97,6 +98,9 @@ extern PFNGLPROGRAMUNIFORM1IPROC gl_ProgramUniform1i;
extern PFNGLGETUNIFORMBLOCKINDEXPROC gl_GetUniformBlockIndex;
extern PFNGLUNIFORMBLOCKBINDINGPROC gl_UniformBlockBinding;
extern PFNGLGETUNIFORMLOCATIONPROC gl_GetUniformLocation;
// GL4.2
extern PFNGLBINDIMAGETEXTUREPROC gl_BindImageTexture;
extern PFNGLMEMORYBARRIERPROC gl_MemoryBarrier;
#else
#define gl_ActiveTexture glActiveTexture
#define gl_BlendColor glBlendColor
@ -183,6 +187,7 @@ namespace GLLoader {
extern bool fglrx_buggy_driver;
extern bool nvidia_buggy_driver;
extern bool in_replayer;
extern bool found_GL_ARB_separate_shader_objects;
extern bool found_GL_ARB_shading_language_420pack;
@ -192,4 +197,5 @@ namespace GLLoader {
extern bool found_geometry_shader;
extern bool found_only_gl30;
extern bool found_GL_ARB_gpu_shader5;
extern bool found_GL_ARB_shader_image_load_store;
}

View File

@ -1417,7 +1417,7 @@ inline unsigned long timeGetTime()
// Note
EXPORT_C GSReplay(char* lpszCmdLine, int renderer)
{
GLLoader::in_replayer = true;
// lpszCmdLine:
// First parameter is the renderer.
@ -1462,7 +1462,11 @@ EXPORT_C GSReplay(char* lpszCmdLine, int renderer)
void* hWnd = NULL;
_GSopen((void**)&hWnd, "", renderer);
int err = _GSopen((void**)&hWnd, "", renderer);
if (err != 0) {
fprintf(stderr, "Error failed to GSopen\n");
return;
}
if (s_gs->m_wnd == NULL) return;
uint32 crc;

View File

@ -27,11 +27,6 @@
//#define LOUD_DEBUGGING
//#define PRINT_FRAME_NUMBER
//#define ONLY_LINES
#if 0
#ifdef _DEBUG
#define ENABLE_OGL_STENCIL_DEBUG
#endif
#endif
static uint32 g_draw_count = 0;
static uint32 g_frame_count = 1;
@ -344,10 +339,18 @@ void GSDeviceOGL::Flip()
void GSDeviceOGL::BeforeDraw()
{
m_shader->UseProgram();
//#ifdef ENABLE_OGL_STENCIL_DEBUG
// if (m_date.t)
// static_cast<GSTextureOGL*>(m_date.t)->Save(format("/tmp/date_before_%04ld.csv", g_draw_count));
//#endif
}
void GSDeviceOGL::AfterDraw()
{
//#ifdef ENABLE_OGL_STENCIL_DEBUG
// if (m_date.t)
// static_cast<GSTextureOGL*>(m_date.t)->Save(format("/tmp/date_after_%04ld.csv", g_draw_count));
//#endif
#if defined(ENABLE_OGL_DEBUG) || defined(PRINT_FRAME_NUMBER)
g_draw_count++;
#endif
@ -387,7 +390,6 @@ void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
gl_ClearBufferfv(GL_COLOR, 0, c.v);
} else {
OMSetFBO(m_fbo);
// FIXME useful
OMSetWriteBuffer();
OMAttachRt(t);
@ -402,10 +404,26 @@ void GSDeviceOGL::ClearRenderTarget(GSTexture* t, uint32 c)
ClearRenderTarget(t, color);
}
void GSDeviceOGL::ClearRenderTarget_ui(GSTexture* t, uint32 c)
{
uint32 col[4] = {c, c, c, c};
glDisable(GL_SCISSOR_TEST);
OMSetFBO(m_fbo);
OMSetWriteBuffer();
OMAttachRt(t);
gl_ClearBufferuiv(GL_COLOR, 0, col);
glEnable(GL_SCISSOR_TEST);
static_cast<GSTextureOGL*>(t)->Save(format("/tmp/date_init_%04ld.csv", g_draw_count));
}
void GSDeviceOGL::ClearDepth(GSTexture* t, float c)
{
OMSetFBO(m_fbo);
// FIXME useful
OMSetWriteBuffer();
OMAttachDs(t);
@ -423,7 +441,6 @@ void GSDeviceOGL::ClearDepth(GSTexture* t, float c)
void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c)
{
OMSetFBO(m_fbo);
// FIXME useful
OMSetWriteBuffer();
OMAttachDs(t);
GLint color = c;
@ -470,6 +487,34 @@ GLuint GSDeviceOGL::CreateSampler(bool bilinear, bool tau, bool tav)
return sampler;
}
void GSDeviceOGL::InitPrimDateTexture(int w, int h)
{
// Create a texture to avoid the useless clean@0
if (m_date.t == NULL)
m_date.t = CreateTexture(w, h, GL_R32UI);
ClearRenderTarget_ui(m_date.t, 0xFFFFFFFF);
#ifdef ENABLE_OGL_STENCIL_DEBUG
static_cast<GSTextureOGL*>(m_date.t)->EnableUnit(6);
#endif
gl_BindImageTexture(0, static_cast<GSTextureOGL*>(m_date.t)->GetID(), 0, false, 0, GL_READ_WRITE, GL_R32UI);
}
void GSDeviceOGL::RecycleDateTexture()
{
if (m_date.t) {
#ifdef ENABLE_OGL_STENCIL_DEBUG
//static_cast<GSTextureOGL*>(m_date.t)->Save(format("/tmp/date_adv_%04ld.csv", g_draw_count));
#endif
// FIXME invalidate data
Recycle(m_date.t);
m_date.t = NULL;
}
}
GLuint GSDeviceOGL::CompileVS(VSSelector sel)
{
std::string macro = format("#define VS_BPPZ %d\n", sel.bppz)

View File

@ -466,6 +466,7 @@ class GSDeviceOGL : public GSDevice
struct {
GSDepthStencilOGL* dss;
GSBlendStateOGL* bs;
GSTexture* t;
} m_date;
struct
@ -520,7 +521,6 @@ class GSDeviceOGL : public GSDevice
void OMAttachRt(GSTexture* rt);
void OMAttachDs(GSTexture* ds);
void OMSetFBO(GLuint fbo);
void OMSetWriteBuffer(GLenum buffer = GL_COLOR_ATTACHMENT0);
public:
GSDeviceOGL();
@ -545,6 +545,7 @@ class GSDeviceOGL : public GSDevice
void ClearRenderTarget(GSTexture* t, const GSVector4& c);
void ClearRenderTarget(GSTexture* t, uint32 c);
void ClearRenderTarget_ui(GSTexture* t, uint32 c);
void ClearDepth(GSTexture* t, float c);
void ClearStencil(GSTexture* t, uint8 c);
@ -552,6 +553,8 @@ class GSDeviceOGL : public GSDevice
GSTexture* CreateDepthStencil(int w, int h, bool msaa, int format = 0);
GSTexture* CreateTexture(int w, int h, int format = 0);
GSTexture* CreateOffscreen(int w, int h, int format = 0);
void InitPrimDateTexture(int w, int h);
void RecycleDateTexture();
GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0);
@ -579,7 +582,7 @@ class GSDeviceOGL : public GSDevice
void OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref);
void OMSetBlendState(GSBlendStateOGL* bs, float bf);
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL);
void OMSetWriteBuffer(GLenum buffer = GL_COLOR_ATTACHMENT0);
void CreateTextureFX();
GLuint CompileVS(VSSelector sel);

View File

@ -31,6 +31,7 @@ GSRendererOGL::GSRendererOGL()
m_fba = !!theApp.GetConfig("fba", 1);
UserHacks_AlphaHack = !!theApp.GetConfig("UserHacks_AlphaHack", 0) && !!theApp.GetConfig("UserHacks", 0);
UserHacks_AlphaStencil = !!theApp.GetConfig("UserHacks_AlphaStencil", 0) && !!theApp.GetConfig("UserHacks", 0);
UserHacks_DateGL4 = !!theApp.GetConfig("UserHacks_DateGL4", 0);
m_pixelcenter = GSVector2(-0.5f, -0.5f);
UserHacks_TCOffset = !!theApp.GetConfig("UserHacks", 0) ? theApp.GetConfig("UserHacks_TCOffset", 0) : 0;
@ -217,6 +218,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
const GSVector2& rtscale = rt->GetScale();
bool DATE = m_context->TEST.DATE && context->FRAME.PSM != PSM_PSMCT24;
bool advance_DATE = false;
ASSERT(m_dev != NULL);
@ -243,6 +245,8 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
dev->SetupDATE(rt, ds, vertices, m_context->TEST.DATM);
}
// Create an r32ui image that will containt primitive ID
dev->InitPrimDateTexture(rtsize.x, rtsize.y);
}
//
@ -298,6 +302,13 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
om_bsel.wrgba = ~GSVector4i::load((int)context->FRAME.FBMSK).eq8(GSVector4i::xffffffff()).mask();
// TODO
//if (UserHacks_DateGL4 && DATE && om_bsel.wa && (!context->TEST.ATE || context->TEST.ATST == ATST_ALWAYS)) {
if (UserHacks_DateGL4 && DATE) {
//if (!(context->FBA.FBA && context->TEST.DATM == 1))
advance_DATE = true;
}
// vs
GSDeviceOGL::VSSelector vs_sel;
@ -381,14 +392,9 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
if(DATE)
{
if(dev->HasStencil())
{
om_dssel.date = 1;
}
else
{
om_dssel.date = 1;
if (advance_DATE)
ps_sel.date = 1 + context->TEST.DATM;
}
}
if(env.COLCLAMP.CLAMP == 0 && /* hack */ !tex && PRIM->PRIM != GS_POINTLIST)
@ -512,7 +518,25 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
dev->SetupGS(gs_sel);
dev->SetupPS(ps_sel, &ps_cb);
// draw
if (advance_DATE) {
// Create an r32ui image that will containt primitive ID
// Note: do it at the beginning because the clean will dirty the state
//dev->InitPrimDateTexture(rtsize.x, rtsize.y);
// Don't write anything on the color buffer
dev->OMSetWriteBuffer(GL_NONE);
// Compute primitiveID max that pass the date test
dev->DrawIndexedPrimitive();
// Ask PS to discard shader above the primitiveID max
dev->OMSetWriteBuffer();
ps_sel.date = 3;
dev->SetupPS(ps_sel, &ps_cb);
// Be sure that first pass is finished !
gl_MemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}
if(context->TEST.DoFirstPass())
{
@ -586,6 +610,8 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
}
}
}
if (advance_DATE)
dev->RecycleDateTexture();
dev->EndScene();

View File

@ -39,6 +39,7 @@ class GSRendererOGL : public GSRendererHW
bool m_fba;
bool UserHacks_AlphaHack;
bool UserHacks_AlphaStencil;
bool UserHacks_DateGL4;
unsigned int UserHacks_TCOffset;
float UserHacks_TCO_x, UserHacks_TCO_y;

View File

@ -264,14 +264,16 @@ std::string GSShaderOGL::GenGlslHeader(const std::string& entry, GLenum type, co
if (GLLoader::found_only_gl30) {
header = "#version 130\n";
} else {
header = "#version 330\n";
header = "#version 330 core\n";
}
if (m_glsl420) {
// Need GL version 420
header += "#extension GL_ARB_shading_language_420pack: require\n";
} else {
header += "#define DISABLE_GL42\n";
}
if (m_sso) {
// Need GL version 410
header += "#extension GL_ARB_separate_shader_objects : require\n";
} else {
header += "#define DISABLE_SSO\n";
@ -285,11 +287,18 @@ std::string GSShaderOGL::GenGlslHeader(const std::string& entry, GLenum type, co
#ifdef ENABLE_OGL_STENCIL_DEBUG
header += "#define ENABLE_OGL_STENCIL_DEBUG 1\n";
#endif
if (GLLoader::found_GL_ARB_shader_image_load_store)
// Need GL version 420
header += "#extension GL_ARB_shader_image_load_store: require\n";
else
header += "#define DISABLE_GL42_image\n";
#else
header = "#version 300 es\n";
// Disable full GL features
header += "#define DISABLE_SSO\n";
header += "#define DISABLE_GL42\n";
header += "#define DISABLE_GL42_image\n";
#endif
// Allow to puts several shader in 1 files

View File

@ -144,7 +144,7 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
case GL_R16UI:
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch>>1);
format = GL_RED;
format = GL_RED_INTEGER;
type = GL_UNSIGNED_SHORT;
break;
case GL_R8:
@ -159,7 +159,7 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
}
#ifdef _LINUX
if (GLLoader::fglrx_buggy_driver) {
if (GLLoader::fglrx_buggy_driver && !GLLoader::in_replayer) {
// FIXME : it crash on colin mcrae rally 3 (others game too) when the texture is small
//if ((pitch >> 2) == 32 || r.width() < 32 || r.height() < 32) {
if ((r.width() < 32) || (pitch == 128 && r.width() == 32)) {
@ -388,6 +388,30 @@ void GSTextureOGL::Save(const string& fn, const void* image, uint32 pitch)
fclose(fp);
}
void GSTextureOGL::SaveRaw(const string& fn, const void* image, uint32 pitch)
{
// Build a raw CSV file
FILE* fp = fopen(fn.c_str(), "w");
uint32* data = (uint32*)image;
for(int h = m_size.y; h > 0; h--) {
for (int w = m_size.x; w > 0; w--, data += 1) {
if (*data == 0xffffffff)
fprintf(fp, "");
else {
fprintf(fp, "%x", *data);
}
if ( w > 1)
fprintf(fp, ",");
}
fprintf(fp, "\n");
}
fclose(fp);
}
bool GSTextureOGL::Save(const string& fn, bool dds)
{
// Collect the texture data
@ -408,10 +432,24 @@ bool GSTextureOGL::Save(const string& fn, bool dds)
glReadPixels(0, 0, m_size.x, m_size.y, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, image);
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, 0);
} else if(m_format == GL_R32UI) {
//EnableUnit(6);
gl_ActiveTexture(GL_TEXTURE0 + 6);
glBindTexture(GL_TEXTURE_2D, m_texture_id);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, image);
SaveRaw(fn, image, pitch);
// Not supported in Save function
status = false;
} else {
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
EnableUnit(6);
//EnableUnit(6);
gl_ActiveTexture(GL_TEXTURE0 + 6);
glBindTexture(GL_TEXTURE_2D, m_texture_id);
gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture_id, 0);
glReadBuffer(GL_COLOR_ATTACHMENT0);
@ -436,6 +474,10 @@ bool GSTextureOGL::Save(const string& fn, bool dds)
if (status) Save(fn, image, pitch);
free(image);
// Restore state
gl_ActiveTexture(GL_TEXTURE0 + g_state_texture_unit);
glBindTexture(GL_TEXTURE_2D, g_state_texture_id[g_state_texture_unit]);
return status;
}

View File

@ -40,6 +40,7 @@ class GSTextureOGL : public GSTexture
void Unmap();
bool Save(const string& fn, bool dds = false);
void Save(const string& fn, const void* image, uint32 pitch);
void SaveRaw(const string& fn, const void* image, uint32 pitch);
void EnableUnit(const uint32 unit);

View File

@ -41,6 +41,7 @@ void GSWndGL::PopulateGlFunction()
*(void**)&(gl_CheckFramebufferStatus) = GetProcAddress("glCheckFramebufferStatus");
*(void**)&(gl_ClearBufferfv) = GetProcAddress("glClearBufferfv");
*(void**)&(gl_ClearBufferiv) = GetProcAddress("glClearBufferiv");
*(void**)&(gl_ClearBufferuiv) = GetProcAddress("glClearBufferuiv");
*(void**)&(gl_CompileShader) = GetProcAddress("glCompileShader");
*(void**)&(gl_CopyImageSubDataNV) = GetProcAddress("glCopyImageSubDataNV");
*(void**)&(gl_CreateProgram) = GetProcAddress("glCreateProgram");
@ -100,5 +101,8 @@ void GSWndGL::PopulateGlFunction()
*(void**)&(gl_GetUniformBlockIndex) = GetProcAddress("glGetUniformBlockIndex");
*(void**)&(gl_UniformBlockBinding) = GetProcAddress("glUniformBlockBinding");
*(void**)&(gl_GetUniformLocation) = GetProcAddress("glGetUniformLocation");
// GL4.2
*(void**)&(gl_BindImageTexture) = GetProcAddress("glBindImageTexture");
*(void**)&(gl_MemoryBarrier) = GetProcAddress("glMemoryBarrier");
#endif
}

View File

@ -183,6 +183,9 @@ bool GSWndOGL::Create(const string& title, int w, int h)
m_NativeWindow = XCreateSimpleWindow(m_NativeDisplay, DefaultRootWindow(m_NativeDisplay), 0, 0, w, h, 0, 0, 0);
XMapWindow (m_NativeDisplay, m_NativeWindow);
if (m_NativeWindow == 0)
throw GSDXRecoverableError();
CreateContext(3, 3);
AttachContext();
@ -191,9 +194,6 @@ bool GSWndOGL::Create(const string& title, int w, int h)
PopulateGlFunction();
if (m_NativeWindow == 0)
throw GSDXRecoverableError();
return true;
}

View File

@ -40,3 +40,6 @@
#ifdef _DEBUG
#define ENABLE_OGL_DEBUG // Create a debug context and check opengl command status. Allow also to dump various textures/states.
#endif
// Output stencil to a color buffer
#define ENABLE_OGL_STENCIL_DEBUG

View File

@ -182,10 +182,11 @@ void ps_main6() // diagonal
#endif
// Used for DATE (stencil)
// DATM == 1
#ifdef ps_main2
void ps_main2()
{
if((sample_c().a - 127.5f / 255.0f) < 0.0f) // >= 0x80 pass
if(sample_c().a < 127.5f / 255.0f) // >= 0x80 pass
discard;
#ifdef ENABLE_OGL_STENCIL_DEBUG
@ -195,10 +196,11 @@ void ps_main2()
#endif
// Used for DATE (stencil)
// DATM == 0
#ifdef ps_main3
void ps_main3()
{
if((127.5f / 255.0f - sample_c().a) < 0.0f) // < 0x80 pass (== 0x80 should not pass)
if(127.5f / 255.0f < sample_c().a) // < 0x80 pass (== 0x80 should not pass)
discard;
#ifdef ENABLE_OGL_STENCIL_DEBUG

View File

@ -207,10 +207,11 @@ static const char* convert_glsl =
"#endif\n"
"\n"
"// Used for DATE (stencil)\n"
"// DATM == 1\n"
"#ifdef ps_main2\n"
"void ps_main2()\n"
"{\n"
" if((sample_c().a - 127.5f / 255.0f) < 0.0f) // >= 0x80 pass\n"
" if(sample_c().a < 127.5f / 255.0f) // >= 0x80 pass\n"
" discard;\n"
"\n"
"#ifdef ENABLE_OGL_STENCIL_DEBUG\n"
@ -220,10 +221,11 @@ static const char* convert_glsl =
"#endif\n"
"\n"
"// Used for DATE (stencil)\n"
"// DATM == 0\n"
"#ifdef ps_main3\n"
"void ps_main3()\n"
"{\n"
" if((127.5f / 255.0f - sample_c().a) < 0.0f) // < 0x80 pass (== 0x80 should not pass)\n"
" if(127.5f / 255.0f < sample_c().a) // < 0x80 pass (== 0x80 should not pass)\n"
" discard;\n"
"\n"
"#ifdef ENABLE_OGL_STENCIL_DEBUG\n"
@ -671,16 +673,18 @@ static const char* tfx_glsl =
"\n"
"#ifdef GEOMETRY_SHADER\n"
"in gl_PerVertex {\n"
" vec4 gl_Position;\n"
" invariant vec4 gl_Position;\n"
" float gl_PointSize;\n"
" float gl_ClipDistance[];\n"
"} gl_in[];\n"
"//in int gl_PrimitiveIDIn;\n"
"\n"
"out gl_PerVertex {\n"
" vec4 gl_Position;\n"
" float gl_PointSize;\n"
" float gl_ClipDistance[];\n"
"};\n"
"out int gl_PrimitiveID;\n"
"\n"
"in SHADER\n"
"{\n"
@ -701,6 +705,7 @@ static const char* tfx_glsl =
" GSout.t = v.t;\n"
" GSout.tp = v.tp;\n"
" GSout.c = v.c;\n"
" gl_PrimitiveID = gl_PrimitiveIDIn;\n"
" EmitVertex();\n"
"}\n"
"\n"
@ -709,6 +714,7 @@ static const char* tfx_glsl =
" GSout.t = t;\n"
" GSout.tp = tp;\n"
" GSout.c = c;\n"
" gl_PrimitiveID = gl_PrimitiveIDIn;\n"
" EmitVertex();\n"
"}\n"
"\n"
@ -874,6 +880,23 @@ static const char* tfx_glsl =
"layout(binding = 2) uniform sampler2D RTCopySampler;\n"
"#endif\n"
"\n"
"#ifndef DISABLE_GL42_image\n"
"#if PS_DATE > 0\n"
"// FIXME how to declare memory access\n"
"layout(r32ui, binding = 0) coherent uniform uimage2D img_prim_min;\n"
"#endif\n"
"#else\n"
"// use basic stencil\n"
"#endif\n"
"\n"
"#ifndef DISABLE_GL42_image\n"
"#if PS_DATE > 0\n"
"// origin_upper_left\n"
"layout(pixel_center_integer) in vec4 gl_FragCoord;\n"
"//in int gl_PrimitiveID;\n"
"#endif\n"
"#endif\n"
"\n"
"#ifdef DISABLE_GL42\n"
"layout(std140) uniform cb21\n"
"#else\n"
@ -1202,7 +1225,7 @@ static const char* tfx_glsl =
"\n"
"vec4 ps_color()\n"
"{\n"
" datst();\n"
" //datst();\n"
"\n"
" vec4 t = sample_color(PSin_t.xy, PSin_t.w);\n"
"\n"
@ -1256,12 +1279,50 @@ static const char* tfx_glsl =
" if(c.a < 0.5) c.a += 0.5;\n"
" }\n"
"\n"
" SV_Target0 = c;\n"
" SV_Target1 = vec4(alpha, alpha, alpha, alpha);\n"
"#ifndef DISABLE_GL42_image\n"
"\n"
" // Get first primitive that will write a failling alpha value\n"
"#if PS_DATE == 1\n"
" // DATM == 0\n"
" // Pixel with alpha equal to 1 will failed\n"
" if (c.a > 127.5f / 255.0f) {\n"
" imageAtomicMin(img_prim_min, ivec2(gl_FragCoord.xy), gl_PrimitiveID);\n"
" }\n"
" //memoryBarrier();\n"
"#elif PS_DATE == 2\n"
" // DATM == 1\n"
" // Pixel with alpha equal to 0 will failed\n"
" if (c.a < 127.5f / 255.0f) {\n"
" imageAtomicMin(img_prim_min, ivec2(gl_FragCoord.xy), gl_PrimitiveID);\n"
" }\n"
"#endif\n"
"\n"
" // TODO\n"
" // warning non uniform flow ???\n"
"#if PS_DATE == 3\n"
" uint stencil_ceil = imageLoad(img_prim_min, ivec2(gl_FragCoord.xy));\n"
" // Note gl_PrimitiveID == stencil_ceil will be the primitive that will update\n"
" // the bad alpha value so we must keep it.\n"
" if (gl_PrimitiveID > stencil_ceil)\n"
" discard;\n"
"#endif\n"
"\n"
"#endif\n"
"\n"
"\n"
"#if (PS_DATE == 2 || PS_DATE == 1) && !defined(DISABLE_GL42_image)\n"
" // Don't write anything on the framebuffer\n"
" // Note: you can't use discard because it will also drop\n"
" // image operation\n"
" // Note2: output will be disabled too in opengl\n"
"#else\n"
" SV_Target0 = c;\n"
" SV_Target1 = vec4(alpha, alpha, alpha, alpha);\n"
"#endif\n"
"\n"
"#endif\n"
"}\n"
"\n"
"#endif\n"
;

View File

@ -163,16 +163,18 @@ void vs_main()
#ifdef GEOMETRY_SHADER
in gl_PerVertex {
vec4 gl_Position;
invariant vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
} gl_in[];
//in int gl_PrimitiveIDIn;
out gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
};
out int gl_PrimitiveID;
in SHADER
{
@ -193,6 +195,7 @@ void out_vertex(in vertex v)
GSout.t = v.t;
GSout.tp = v.tp;
GSout.c = v.c;
gl_PrimitiveID = gl_PrimitiveIDIn;
EmitVertex();
}
@ -201,6 +204,7 @@ void out_vertex_elem(in vec4 t, in vec4 tp, in vec4 c)
GSout.t = t;
GSout.tp = tp;
GSout.c = c;
gl_PrimitiveID = gl_PrimitiveIDIn;
EmitVertex();
}
@ -366,6 +370,23 @@ layout(binding = 1) uniform sampler2D PaletteSampler;
layout(binding = 2) uniform sampler2D RTCopySampler;
#endif
#ifndef DISABLE_GL42_image
#if PS_DATE > 0
// FIXME how to declare memory access
layout(r32ui, binding = 0) coherent uniform uimage2D img_prim_min;
#endif
#else
// use basic stencil
#endif
#ifndef DISABLE_GL42_image
#if PS_DATE > 0
// origin_upper_left
layout(pixel_center_integer) in vec4 gl_FragCoord;
//in int gl_PrimitiveID;
#endif
#endif
#ifdef DISABLE_GL42
layout(std140) uniform cb21
#else
@ -694,7 +715,7 @@ vec4 fog(vec4 c, float f)
vec4 ps_color()
{
datst();
//datst();
vec4 t = sample_color(PSin_t.xy, PSin_t.w);
@ -748,10 +769,48 @@ void ps_main()
if(c.a < 0.5) c.a += 0.5;
}
#ifndef DISABLE_GL42_image
// Get first primitive that will write a failling alpha value
#if PS_DATE == 1
// DATM == 0
// Pixel with alpha equal to 1 will failed
if (c.a > 127.5f / 255.0f) {
imageAtomicMin(img_prim_min, ivec2(gl_FragCoord.xy), gl_PrimitiveID);
}
//memoryBarrier();
#elif PS_DATE == 2
// DATM == 1
// Pixel with alpha equal to 0 will failed
if (c.a < 127.5f / 255.0f) {
imageAtomicMin(img_prim_min, ivec2(gl_FragCoord.xy), gl_PrimitiveID);
}
#endif
// TODO
// warning non uniform flow ???
#if PS_DATE == 3
uint stencil_ceil = imageLoad(img_prim_min, ivec2(gl_FragCoord.xy));
// Note gl_PrimitiveID == stencil_ceil will be the primitive that will update
// the bad alpha value so we must keep it.
if (gl_PrimitiveID > stencil_ceil)
discard;
#endif
#endif
#if (PS_DATE == 2 || PS_DATE == 1) && !defined(DISABLE_GL42_image)
// Don't write anything on the framebuffer
// Note: you can't use discard because it will also drop
// image operation
// Note2: output will be disabled too in opengl
#else
SV_Target0 = c;
SV_Target1 = vec4(alpha, alpha, alpha, alpha);
#endif
#endif
}
#endif