mirror of https://github.com/PCSX2/pcsx2.git
GSdx-ogl: LINUX only
* Use the new map interface/separate texture coordinate inside shader * support new format on texture Note: it is quite instable with various crashes and GL error but at least it compiles now :p git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl@5094 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
4a00648d9f
commit
92f2ab38ae
|
@ -246,7 +246,7 @@ static int _GSopen(void** dsp, char* title, int renderer, int threads = -1)
|
|||
case 2: dev = new GSDeviceSDL(); break;
|
||||
#endif
|
||||
case 3: dev = new GSDeviceNull(); break;
|
||||
case 5: dev = new GSDeviceOGL(); break;
|
||||
case 4: dev = new GSDeviceOGL(); break;
|
||||
}
|
||||
|
||||
if(dev == NULL)
|
||||
|
@ -429,11 +429,15 @@ EXPORT_C GSreadFIFO(uint8* mem)
|
|||
#ifdef _LINUX
|
||||
// FIXME: double check which thread call this function
|
||||
// See fifo2 issue below
|
||||
if (theApp.GetConfig("renderer", 0) == 12) {
|
||||
if (theApp.GetConfig("renderer", 0) / 3 == 4) {
|
||||
fprintf(stderr, "Disable FIFO1 on opengl\n");
|
||||
}
|
||||
#endif
|
||||
s_gs->m_wnd.AttachContext();
|
||||
|
||||
s_gs->ReadFIFO(mem, 1);
|
||||
|
||||
s_gs->m_wnd.DetachContext();
|
||||
}
|
||||
|
||||
EXPORT_C GSreadFIFO2(uint8* mem, uint32 size)
|
||||
|
@ -441,14 +445,18 @@ EXPORT_C GSreadFIFO2(uint8* mem, uint32 size)
|
|||
#ifdef _LINUX
|
||||
// FIXME called from EE core thread not MTGS which cause
|
||||
// invalidate data for opengl
|
||||
if (theApp.GetConfig("renderer", 0) == 12) {
|
||||
if (theApp.GetConfig("renderer", 0) / 3 == 4) {
|
||||
#ifdef OGL_DEBUG
|
||||
fprintf(stderr, "Disable FIFO2(%d) on opengl\n", size);
|
||||
#endif
|
||||
//return;
|
||||
}
|
||||
#endif
|
||||
s_gs->m_wnd.AttachContext();
|
||||
|
||||
s_gs->ReadFIFO(mem, size);
|
||||
|
||||
s_gs->m_wnd.DetachContext();
|
||||
}
|
||||
|
||||
EXPORT_C GSgifTransfer(const uint8* mem, uint32 size)
|
||||
|
|
|
@ -536,6 +536,7 @@ void GSDeviceOGL::DebugOutput()
|
|||
fprintf(stderr, "\n");
|
||||
|
||||
}
|
||||
CheckDebugLog();
|
||||
}
|
||||
|
||||
void GSDeviceOGL::DrawPrimitive()
|
||||
|
@ -566,6 +567,20 @@ void GSDeviceOGL::DrawIndexedPrimitive()
|
|||
#endif
|
||||
}
|
||||
|
||||
void GSDeviceOGL::DrawIndexedPrimitive(int offset, int count)
|
||||
{
|
||||
ASSERT(offset + count <= m_index.count);
|
||||
#ifdef OGL_DEBUG
|
||||
DebugInput();
|
||||
#endif
|
||||
|
||||
m_state.vb->DrawIndexedPrimitive(offset, count);
|
||||
#ifdef OGL_DEBUG
|
||||
DebugOutput();
|
||||
g_draw_count++;
|
||||
#endif
|
||||
}
|
||||
|
||||
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
||||
{
|
||||
GLuint fbo_old = m_state.fbo;
|
||||
|
@ -578,9 +593,15 @@ void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
|||
// glClearColor(c.x, c.y, c.z, c.w);
|
||||
// glClear(GL_COLOR_BUFFER_BIT);
|
||||
} else {
|
||||
// FIXME I need to clarify this FBO attachment stuff
|
||||
// FIXME1 I need to clarify this FBO attachment stuff
|
||||
// I would like to avoid FBO for a basic clean operation
|
||||
OMSetFBO(m_fbo);
|
||||
// FIXME2:
|
||||
// it would be better to attach the texture to another slot (like 3)
|
||||
// but it crash for an unknow reason
|
||||
// The following error appears "glClearBufferfv failed because the currently set GL_DRAW_FRAMEBUFFER binding has incomplete status"
|
||||
// Maybe glDrawBuffer must be updated but it does not solve the crash...
|
||||
// FIXME3: I still have another crash on GOW...
|
||||
static_cast<GSTextureOGL*>(t)->Attach(GL_COLOR_ATTACHMENT0);
|
||||
glClearBufferfv(GL_COLOR, 0, c.v);
|
||||
}
|
||||
|
@ -970,6 +991,8 @@ void GSDeviceOGL::SetUniformBuffer(GSUniformBufferOGL* cb)
|
|||
|
||||
void GSDeviceOGL::IASetVertexState(GSVertexBufferStateOGL* vb)
|
||||
{
|
||||
if (vb == NULL) vb = m_vb;
|
||||
|
||||
if (m_state.vb != vb) {
|
||||
m_state.vb = vb;
|
||||
vb->bind();
|
||||
|
@ -981,6 +1004,16 @@ void GSDeviceOGL::IASetVertexBuffer(const void* vertices, size_t count)
|
|||
m_state.vb->UploadVB(vertices, count);
|
||||
}
|
||||
|
||||
bool GSDeviceOGL::IAMapVertexBuffer(void** vertex, size_t stride, size_t count)
|
||||
{
|
||||
return m_state.vb->MapVB(vertex, count);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::IAUnmapVertexBuffer()
|
||||
{
|
||||
m_state.vb->UnmapVB();
|
||||
}
|
||||
|
||||
void GSDeviceOGL::IASetIndexBuffer(const void* index, size_t count)
|
||||
{
|
||||
m_state.vb->UploadIB(index, count);
|
||||
|
@ -1073,6 +1106,8 @@ void GSDeviceOGL::OMSetFBO(GLuint fbo)
|
|||
if (m_state.fbo != fbo) {
|
||||
m_state.fbo = fbo;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
// FIXME DEBUG
|
||||
//if (fbo) fprintf(stderr, "FB status %x\n", glCheckFramebufferStatus(GL_FRAMEBUFFER));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1277,6 +1312,7 @@ void GSDeviceOGL::CheckDebugLog()
|
|||
void GSDeviceOGL::DebugOutputToFile(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, const char* message)
|
||||
{
|
||||
char debType[20], debSev[5];
|
||||
static int sev_counter = 0;
|
||||
|
||||
if(type == GL_DEBUG_TYPE_ERROR_ARB)
|
||||
strcpy(debType, "Error");
|
||||
|
@ -1293,23 +1329,26 @@ void GSDeviceOGL::DebugOutputToFile(unsigned int source, unsigned int type, unsi
|
|||
else
|
||||
strcpy(debType, "UNKNOWN");
|
||||
|
||||
if(severity == GL_DEBUG_SEVERITY_HIGH_ARB)
|
||||
if(severity == GL_DEBUG_SEVERITY_HIGH_ARB) {
|
||||
strcpy(debSev, "High");
|
||||
sev_counter++;
|
||||
}
|
||||
else if(severity == GL_DEBUG_SEVERITY_MEDIUM_ARB)
|
||||
strcpy(debSev, "Med");
|
||||
else if(severity == GL_DEBUG_SEVERITY_LOW_ARB)
|
||||
strcpy(debSev, "Low");
|
||||
|
||||
#ifdef LOUD_DEBUGGING
|
||||
fprintf(stderr,"Type:%s\tID:%d\tSeverity:%s\tMessage:%s\n", debType,id,debSev,message);
|
||||
fprintf(stderr,"Type:%s\tID:%d\tSeverity:%s\tMessage:%s\n", debType, g_draw_count, debSev,message);
|
||||
#endif
|
||||
|
||||
FILE* f = fopen("Debug.txt","a");
|
||||
if(f)
|
||||
{
|
||||
fprintf(f,"Type:%s\tID:%d\tSeverity:%s\tMessage:%s\n", debType,id,debSev,message);
|
||||
fprintf(f,"Type:%s\tID:%d\tSeverity:%s\tMessage:%s\n", debType, g_draw_count, debSev,message);
|
||||
fclose(f);
|
||||
}
|
||||
//if (sev_counter > 2) assert(0);
|
||||
}
|
||||
|
||||
// (A - B) * C + D
|
||||
|
|
|
@ -323,11 +323,22 @@ class GSVertexBufferStateOGL {
|
|||
|
||||
void upload(const void* src, uint32 count)
|
||||
{
|
||||
// Upload the data to the buffer
|
||||
void* dst;
|
||||
if (Map(&dst, count)) {
|
||||
// FIXME which one to use
|
||||
// GSVector4i::storent(dst, src, m_count * m_stride);
|
||||
memcpy(dst, src, m_stride*m_count);
|
||||
Unmap();
|
||||
}
|
||||
}
|
||||
|
||||
bool Map(void** pointer, uint32 count ) {
|
||||
#ifdef OGL_DEBUG
|
||||
GLint b_size = -1;
|
||||
glGetBufferParameteriv(m_target, GL_BUFFER_SIZE, &b_size);
|
||||
|
||||
if (b_size <= 0) return;
|
||||
if (b_size <= 0) return false;
|
||||
#endif
|
||||
|
||||
m_count = count;
|
||||
|
@ -338,7 +349,7 @@ class GSVertexBufferStateOGL {
|
|||
|
||||
// Current GPU buffer is really too small need to allocate a new one
|
||||
if (m_count > m_limit) {
|
||||
allocate(std::max<int>(count * 3 / 2, m_default_size));
|
||||
allocate(std::max<int>(m_count * 3 / 2, m_default_size));
|
||||
|
||||
} else if (m_count > (m_limit - m_start) ) {
|
||||
// Not enough left free room. Just go back at the beginning
|
||||
|
@ -354,17 +365,19 @@ class GSVertexBufferStateOGL {
|
|||
}
|
||||
|
||||
// Upload the data to the buffer
|
||||
uint8* dst = (uint8*) glMapBufferRange(m_target, m_stride*m_start, m_stride*m_count, map_flags);
|
||||
*pointer = (uint8*) glMapBufferRange(m_target, m_stride*m_start, m_stride*m_count, map_flags);
|
||||
//fprintf(stderr, "Map %x from %d to %d\n", *pointer, m_start, m_start+m_count);
|
||||
#ifdef OGL_DEBUG
|
||||
if (dst == NULL) {
|
||||
if (*pointer == NULL) {
|
||||
fprintf(stderr, "CRITICAL ERROR map failed for vb!!!\n");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
memcpy(dst, src, m_stride*m_count);
|
||||
glUnmapBuffer(m_target);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Unmap() { glUnmapBuffer(m_target); }
|
||||
|
||||
void EndScene()
|
||||
{
|
||||
m_start += m_count;
|
||||
|
@ -381,6 +394,11 @@ class GSVertexBufferStateOGL {
|
|||
glDrawElementsBaseVertex(mode, m_count, GL_UNSIGNED_INT, (void*)(m_start * m_stride), basevertex);
|
||||
}
|
||||
|
||||
void Draw(GLenum mode, GLint basevertex, int offset, int count)
|
||||
{
|
||||
glDrawElementsBaseVertex(mode, count, GL_UNSIGNED_INT, (void*)((m_start + offset) * m_stride), basevertex);
|
||||
}
|
||||
|
||||
size_t GetStart() { return m_start; }
|
||||
|
||||
void debug()
|
||||
|
@ -416,52 +434,6 @@ public:
|
|||
m_vb->bind();
|
||||
}
|
||||
|
||||
#if 0
|
||||
void upload(const void* src, uint32 count)
|
||||
{
|
||||
#ifdef OGL_DEBUG
|
||||
GLint b_size = -1;
|
||||
glGetBufferParameteriv(m_target, GL_BUFFER_SIZE, &b_size);
|
||||
|
||||
if (b_size <= 0) return;
|
||||
#endif
|
||||
|
||||
m_count = count;
|
||||
|
||||
// Note: For an explanation of the map flag
|
||||
// see http://www.opengl.org/wiki/Buffer_Object_Streaming
|
||||
uint32 map_flags = GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
|
||||
|
||||
// Current GPU buffer is really too small need to allocate a new one
|
||||
if (m_count > m_limit) {
|
||||
allocate(std::max<int>(count * 3 / 2, 60000));
|
||||
|
||||
} else if (m_count > (m_limit - m_start) ) {
|
||||
// Not enough left free room. Just go back at the beginning
|
||||
m_start = 0;
|
||||
|
||||
// Tell the driver that it can orphan previous buffer and restart from a scratch buffer.
|
||||
// Technically the buffer will not be accessible by the application anymore but the
|
||||
// GL will effectively remove it when draws call are finised.
|
||||
map_flags |= GL_MAP_INVALIDATE_BUFFER_BIT;
|
||||
} else {
|
||||
// Tell the driver that it doesn't need to contain any valid buffer data, and that you promise to write the entire range you map
|
||||
map_flags |= GL_MAP_INVALIDATE_RANGE_BIT;
|
||||
}
|
||||
|
||||
// Upload the data to the buffer
|
||||
uint8* dst = (uint8*) glMapBufferRange(m_target, m_stride*m_start, m_stride*m_count, map_flags);
|
||||
#ifdef OGL_DEBUG
|
||||
if (dst == NULL) {
|
||||
fprintf(stderr, "CRITICAL ERROR map failed for vb!!!\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
memcpy(dst, src, m_stride*m_count);
|
||||
glUnmapBuffer(m_target);
|
||||
}
|
||||
#endif
|
||||
|
||||
void set_internal_format(GSInputLayoutOGL* layout, uint32 layout_nbr)
|
||||
{
|
||||
for (int i = 0; i < layout_nbr; i++) {
|
||||
|
@ -490,17 +462,17 @@ public:
|
|||
|
||||
void DrawIndexedPrimitive() { m_ib->Draw(m_topology, m_vb->GetStart() ); }
|
||||
|
||||
void DrawIndexedPrimitive(int offset, int count) { m_ib->Draw(m_topology, m_vb->GetStart(), offset, count ); }
|
||||
|
||||
void SetTopology(GLenum topology) { m_topology = topology; }
|
||||
|
||||
void UploadVB(const void* vertices, size_t count)
|
||||
{
|
||||
m_vb->upload(vertices, count);
|
||||
}
|
||||
void UploadVB(const void* vertices, size_t count) { m_vb->upload(vertices, count); }
|
||||
|
||||
void UploadIB(const void* index, size_t count)
|
||||
{
|
||||
m_ib->upload(index, count);
|
||||
}
|
||||
void UploadIB(const void* index, size_t count) { m_ib->upload(index, count); }
|
||||
|
||||
bool MapVB(void **pointer, size_t count) { return m_vb->Map(pointer, count); }
|
||||
|
||||
void UnmapVB() { m_vb->Unmap(); }
|
||||
|
||||
~GSVertexBufferStateOGL()
|
||||
{
|
||||
|
@ -878,6 +850,7 @@ class GSDeviceOGL : public GSDevice
|
|||
|
||||
void DrawPrimitive();
|
||||
void DrawIndexedPrimitive();
|
||||
void DrawIndexedPrimitive(int offset, int count);
|
||||
|
||||
void ClearRenderTarget(GSTexture* t, const GSVector4& c);
|
||||
void ClearRenderTarget(GSTexture* t, uint32 c);
|
||||
|
@ -906,8 +879,10 @@ class GSDeviceOGL : public GSDevice
|
|||
|
||||
void IASetPrimitiveTopology(GLenum topology);
|
||||
void IASetVertexBuffer(const void* vertices, size_t count);
|
||||
bool IAMapVertexBuffer(void** vertex, size_t stride, size_t count);
|
||||
void IAUnmapVertexBuffer();
|
||||
void IASetIndexBuffer(const void* index, size_t count);
|
||||
void IASetVertexState(GSVertexBufferStateOGL* vb);
|
||||
void IASetVertexState(GSVertexBufferStateOGL* vb = NULL);
|
||||
|
||||
void SetUniformBuffer(GSUniformBufferOGL* cb);
|
||||
|
||||
|
|
|
@ -76,8 +76,8 @@ GtkWidget* CreateRenderComboBox()
|
|||
case 8 : renderer_box_position = 1; break;
|
||||
case 10: renderer_box_position = 2; break;
|
||||
case 11: renderer_box_position = 3; break;
|
||||
case 15: renderer_box_position = 4; break;
|
||||
case 16: renderer_box_position = 5; break;
|
||||
case 12: renderer_box_position = 4; break;
|
||||
case 13: renderer_box_position = 5; break;
|
||||
}
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(render_combo_box), renderer_box_position);
|
||||
return render_combo_box;
|
||||
|
@ -375,8 +375,8 @@ bool RunLinuxDialog()
|
|||
case 1: theApp.SetConfig("renderer", 8); break;
|
||||
case 2: theApp.SetConfig("renderer", 10); break;
|
||||
case 3: theApp.SetConfig("renderer", 11); break;
|
||||
case 4: theApp.SetConfig("renderer", 15); break;
|
||||
case 5: theApp.SetConfig("renderer", 16); break;
|
||||
case 4: theApp.SetConfig("renderer", 12); break;
|
||||
case 5: theApp.SetConfig("renderer", 13); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,15 +24,12 @@
|
|||
|
||||
|
||||
GSRendererOGL::GSRendererOGL()
|
||||
: GSRendererHW(new GSVertexTraceDX11(this), sizeof(GSVertexHW11), new GSTextureCacheOGL(this))
|
||||
, m_topology(0)
|
||||
: GSRendererHW(new GSTextureCacheOGL(this))
|
||||
{
|
||||
m_logz = !!theApp.GetConfig("logz", 0);
|
||||
m_fba = !!theApp.GetConfig("fba", 1);
|
||||
UserHacks_AlphaHack = !!theApp.GetConfig("UserHacks_AlphaHack", 0);
|
||||
m_pixelcenter = GSVector2(-0.5f, -0.5f);
|
||||
|
||||
InitConvertVertex(GSRendererOGL);
|
||||
}
|
||||
|
||||
bool GSRendererOGL::CreateDevice(GSDevice* dev)
|
||||
|
@ -43,44 +40,47 @@ bool GSRendererOGL::CreateDevice(GSDevice* dev)
|
|||
return true;
|
||||
}
|
||||
|
||||
template<uint32 prim, uint32 tme, uint32 fst>
|
||||
void GSRendererOGL::ConvertVertex(size_t dst_index, size_t src_index)
|
||||
void GSRendererOGL::SetupIA()
|
||||
{
|
||||
GSVertex* s = (GSVertex*)((GSVertexHW11*)m_vertex.buff + src_index);
|
||||
GSVertexHW11* d = (GSVertexHW11*)m_vertex.buff + dst_index;
|
||||
GSDeviceOGL* dev = (GSDeviceOGL*)m_dev;
|
||||
|
||||
GSVector4i v0 = ((GSVector4i*)s)[0];
|
||||
GSVector4i v1 = ((GSVector4i*)s)[1];
|
||||
void* ptr = NULL;
|
||||
|
||||
if(tme && fst)
|
||||
dev->IASetVertexState();
|
||||
|
||||
if(dev->IAMapVertexBuffer(&ptr, sizeof(GSVertex), m_vertex.next))
|
||||
{
|
||||
// TODO: modify VertexTrace and the shaders to read uv from v1.u16[0], v1.u16[1], then this step is not needed
|
||||
GSVector4i::storent(ptr, m_vertex.buff, sizeof(GSVertex) * m_vertex.next);
|
||||
|
||||
v0 = GSVector4i::cast(GSVector4(v1.uph16()).xyzw(GSVector4::cast(v0))); // uv => st
|
||||
dev->IAUnmapVertexBuffer();
|
||||
}
|
||||
|
||||
((GSVector4i*)d)[0] = v0;
|
||||
((GSVector4i*)d)[1] = v1;
|
||||
}
|
||||
dev->IASetIndexBuffer(m_index.buff, m_index.tail);
|
||||
|
||||
void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex)
|
||||
{
|
||||
switch(m_vt->m_primclass)
|
||||
GLenum t;
|
||||
|
||||
switch(m_vt.m_primclass)
|
||||
{
|
||||
case GS_POINT_CLASS:
|
||||
m_topology = GL_POINTS;
|
||||
t = GL_POINTS;
|
||||
break;
|
||||
case GS_LINE_CLASS:
|
||||
case GS_SPRITE_CLASS:
|
||||
m_topology = GL_LINES;
|
||||
t = GL_LINES;
|
||||
break;
|
||||
case GS_TRIANGLE_CLASS:
|
||||
m_topology = GL_TRIANGLES;
|
||||
t = GL_TRIANGLES;
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
|
||||
dev->IASetPrimitiveTopology(t);
|
||||
}
|
||||
|
||||
|
||||
void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex)
|
||||
{
|
||||
GSDrawingEnvironment& env = m_env;
|
||||
GSDrawingContext* context = m_context;
|
||||
|
||||
|
@ -103,7 +103,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
GSVector4 s = GSVector4(rtscale.x / rtsize.x, rtscale.y / rtsize.y);
|
||||
GSVector4 o = GSVector4(-1.0f, 1.0f);
|
||||
|
||||
GSVector4 src = ((m_vt->m_min.p.xyxy(m_vt->m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy());
|
||||
GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy());
|
||||
GSVector4 dst = src * 2.0f + o.xxxx();
|
||||
|
||||
GSVertexPT1 vertices[] =
|
||||
|
@ -163,7 +163,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
|
||||
if(!IsOpaque())
|
||||
{
|
||||
om_bsel.abe = PRIM->ABE || PRIM->AA1 && m_vt->m_primclass == GS_LINE_CLASS;
|
||||
om_bsel.abe = PRIM->ABE || PRIM->AA1 && m_vt.m_primclass == GS_LINE_CLASS;
|
||||
|
||||
om_bsel.a = context->ALPHA.A;
|
||||
om_bsel.b = context->ALPHA.B;
|
||||
|
@ -207,11 +207,11 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
{
|
||||
if(context->ZBUF.PSM == PSM_PSMZ24)
|
||||
{
|
||||
if(m_vt->m_max.p.z > 0xffffff)
|
||||
if(m_vt.m_max.p.z > 0xffffff)
|
||||
{
|
||||
ASSERT(m_vt->m_min.p.z > 0xffffff);
|
||||
ASSERT(m_vt.m_min.p.z > 0xffffff);
|
||||
// Fixme :Following conditional fixes some dialog frame in Wild Arms 3, but may not be what was intended.
|
||||
if (m_vt->m_min.p.z > 0xffffff)
|
||||
if (m_vt.m_min.p.z > 0xffffff)
|
||||
{
|
||||
vs_sel.bppz = 1;
|
||||
om_dssel.ztst = ZTST_ALWAYS;
|
||||
|
@ -220,11 +220,11 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
}
|
||||
else if(context->ZBUF.PSM == PSM_PSMZ16 || context->ZBUF.PSM == PSM_PSMZ16S)
|
||||
{
|
||||
if(m_vt->m_max.p.z > 0xffff)
|
||||
if(m_vt.m_max.p.z > 0xffff)
|
||||
{
|
||||
ASSERT(m_vt->m_min.p.z > 0xffff); // sfex capcom logo
|
||||
ASSERT(m_vt.m_min.p.z > 0xffff); // sfex capcom logo
|
||||
// Fixme : Same as above, I guess.
|
||||
if (m_vt->m_min.p.z > 0xffff)
|
||||
if (m_vt.m_min.p.z > 0xffff)
|
||||
{
|
||||
vs_sel.bppz = 2;
|
||||
om_dssel.ztst = ZTST_ALWAYS;
|
||||
|
@ -268,7 +268,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
GSDeviceOGL::GSSelector gs_sel;
|
||||
|
||||
gs_sel.iip = PRIM->IIP;
|
||||
gs_sel.prim = m_vt->m_primclass;
|
||||
gs_sel.prim = m_vt.m_primclass;
|
||||
|
||||
// ps
|
||||
|
||||
|
@ -288,7 +288,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
}
|
||||
}
|
||||
|
||||
if (env.COLCLAMP.CLAMP == 0 && /* hack */ !tex && PRIM->PRIM != GS_POINTLIST)
|
||||
if(env.COLCLAMP.CLAMP == 0 && /* hack */ !tex && PRIM->PRIM != GS_POINTLIST)
|
||||
{
|
||||
ps_sel.colclip = 1;
|
||||
}
|
||||
|
@ -336,7 +336,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
ps_sel.aem = env.TEXA.AEM;
|
||||
ps_sel.tfx = context->TEX0.TFX;
|
||||
ps_sel.tcc = context->TEX0.TCC;
|
||||
ps_sel.ltf = m_filter == 2 ? m_vt->IsLinear() : m_filter;
|
||||
ps_sel.ltf = m_filter == 2 ? m_vt.IsLinear() : m_filter;
|
||||
ps_sel.rt = tex->m_target;
|
||||
|
||||
int w = tex->m_texture->GetWidth();
|
||||
|
@ -385,8 +385,9 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
|
||||
uint8 afix = context->ALPHA.FIX;
|
||||
|
||||
SetupIA();
|
||||
|
||||
dev->SetupOM(om_dssel, om_bsel, afix);
|
||||
dev->SetupIA(m_vertex.buff, m_vertex.next, m_index.buff, m_index.tail, m_topology);
|
||||
dev->SetupVS(vs_sel, &vs_cb);
|
||||
dev->SetupGS(gs_sel);
|
||||
dev->SetupPS(ps_sel, &ps_cb, ps_ssel);
|
||||
|
|
|
@ -40,22 +40,12 @@ class GSRendererOGL : public GSRendererHW
|
|||
bool UserHacks_AlphaHack;
|
||||
|
||||
protected:
|
||||
GLenum m_topology;
|
||||
|
||||
template<uint32 prim, uint32 tme, uint32 fst>
|
||||
void ConvertVertex(size_t dst_index, size_t src_index);
|
||||
|
||||
int GetPosX(const void* vertex) const {return (int)((const GSVertexHW11*)vertex)->p.x;}
|
||||
int GetPosY(const void* vertex) const {return (int)((const GSVertexHW11*)vertex)->p.y;}
|
||||
uint32 GetColor(const void* vertex) const {return ((const GSVertexHW11*)vertex)->c0;}
|
||||
void SetColor(void* vertex, uint32 c) const {((GSVertexHW11*)vertex)->c0 = c;}
|
||||
void SetupIA();
|
||||
|
||||
public:
|
||||
GSRendererOGL();
|
||||
virtual ~GSRendererOGL() {};
|
||||
|
||||
template<uint32 prim, uint32 tme, uint32 fst> void VertexKick(bool skip);
|
||||
|
||||
bool CreateDevice(GSDevice* dev);
|
||||
|
||||
void UpdateFBA(GSTexture* rt) {}
|
||||
|
|
|
@ -62,6 +62,7 @@ void GSTextureCacheOGL::Read(Target* t, const GSVector4i& r)
|
|||
GSVector4 src = GSVector4(r) * GSVector4(t->m_texture->GetScale()).xyxy() / GSVector4(t->m_texture->GetSize()).xyxy();
|
||||
|
||||
GLuint format = TEX0.PSM == PSM_PSMCT16 || TEX0.PSM == PSM_PSMCT16S ? GL_R16UI : GL_RGBA8;
|
||||
//if (format == GL_R16UI) fprintf(stderr, "Format 16 bits integer\n");
|
||||
#if 0
|
||||
DXGI_FORMAT format = TEX0.PSM == PSM_PSMCT16 || TEX0.PSM == PSM_PSMCT16S ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
#endif
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
class GSTextureCacheOGL : public GSTextureCache
|
||||
{
|
||||
protected:
|
||||
int Get8bitFormat() {/* TODO return DXGI_FORMAT_A8_UNORM;*/}
|
||||
int Get8bitFormat() { return GL_R8; /* TODO return DXGI_FORMAT_A8_UNORM;*/}
|
||||
|
||||
void Read(Target* t, const GSVector4i& r);
|
||||
|
||||
|
|
|
@ -61,26 +61,19 @@ void GSDeviceOGL::CreateTextureFX()
|
|||
//float4 c : COLOR0;
|
||||
//float4 f : COLOR1;
|
||||
|
||||
GSInputLayoutOGL vert_format[6] =
|
||||
GSInputLayoutOGL vert_format[] =
|
||||
{
|
||||
// FIXME
|
||||
{0 , 2 , GL_FLOAT , GL_FALSE , sizeof(GSVertexHW11) , (const GLvoid*)(0) } ,
|
||||
{1 , 4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(GSVertexHW11) , (const GLvoid*)(8) } ,
|
||||
{2 , 1 , GL_FLOAT , GL_FALSE , sizeof(GSVertexHW11) , (const GLvoid*)(12) } ,
|
||||
{3 , 2 , GL_UNSIGNED_SHORT , GL_FALSE , sizeof(GSVertexHW11) , (const GLvoid*)(16) } ,
|
||||
{4 , 1 , GL_UNSIGNED_INT , GL_FALSE , sizeof(GSVertexHW11) , (const GLvoid*)(20) } ,
|
||||
{0 , 2 , GL_FLOAT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(0) } ,
|
||||
{1 , 4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(GSVertex) , (const GLvoid*)(8) } ,
|
||||
{2 , 1 , GL_FLOAT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(12) } ,
|
||||
{3 , 2 , GL_UNSIGNED_SHORT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(16) } ,
|
||||
{4 , 1 , GL_UNSIGNED_INT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(20) } ,
|
||||
// note: there is a 32 bits pad
|
||||
{5 , 4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(GSVertexHW11) , (const GLvoid*)(28) } ,
|
||||
{5 , 2 , GL_UNSIGNED_SHORT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(24) } ,
|
||||
{6 , 4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(GSVertex) , (const GLvoid*)(28) } ,
|
||||
};
|
||||
m_vb = new GSVertexBufferStateOGL(sizeof(GSVertexHW11), vert_format, countof(vert_format));
|
||||
}
|
||||
|
||||
void GSDeviceOGL::SetupIA(const void* vertex, int vertex_count, const uint32* index, int index_count, int prim)
|
||||
{
|
||||
IASetVertexState(m_vb);
|
||||
IASetVertexBuffer(vertex, vertex_count);
|
||||
IASetIndexBuffer(index, index_count);
|
||||
IASetPrimitiveTopology(prim);
|
||||
m_vb = new GSVertexBufferStateOGL(sizeof(GSVertex), vert_format, countof(vert_format));
|
||||
}
|
||||
|
||||
void GSDeviceOGL::SetupVS(VSSelector sel, const VSConstantBuffer* cb)
|
||||
|
|
|
@ -103,11 +103,16 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format, GLuint
|
|||
// In worst case the HW renderer seems to use 3 texture unit
|
||||
// For the moment SW renderer only use 1 so don't bother
|
||||
EnableUnit(2);
|
||||
if (m_format == GL_RGBA8) {
|
||||
if (m_format == GL_RGBA8)
|
||||
glTexImage2D(m_texture_target, 0, m_format, m_size.x, m_size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
}
|
||||
else
|
||||
else if (m_format == GL_R16UI)
|
||||
glTexImage2D(m_texture_target, 0, m_format, m_size.x, m_size.y, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, NULL);
|
||||
else if (m_format == GL_R8)
|
||||
glTexImage2D(m_texture_target, 0, m_format, m_size.x, m_size.y, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
|
||||
else {
|
||||
fprintf(stderr, "wrong texture pixel format :%x\n", m_format);
|
||||
assert(0); // TODO Later
|
||||
}
|
||||
break;
|
||||
case GSTexture::Offscreen:
|
||||
if (m_type == GL_RGBA8) m_pbo_size = m_size.x * m_size.y * 4;
|
||||
|
@ -130,7 +135,10 @@ GSTextureOGL::~GSTextureOGL()
|
|||
|
||||
void GSTextureOGL::Attach(GLenum attachment)
|
||||
{
|
||||
//fprintf(stderr, "format %d,%x\n", m_type, m_format);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, m_texture_target, m_texture_id, 0);
|
||||
// FIXME DEBUG
|
||||
//fprintf(stderr, "FB status %x\n", glCheckFramebufferStatus(GL_FRAMEBUFFER));
|
||||
}
|
||||
|
||||
bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
|
||||
|
@ -142,18 +150,22 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
|
|||
|
||||
EnableUnit(2);
|
||||
|
||||
if (m_format != GL_RGBA8) {
|
||||
fprintf(stderr, "wrong pixel format\n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
// pitch could be different of width*element_size
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch>>2);
|
||||
// FIXME : it crash on colin mcrae rally 3 (others game too) when the size is 16
|
||||
//fprintf(stderr, "Texture %dx%d with a pitch of %d\n", m_size.x, m_size.y, pitch >>2);
|
||||
//fprintf(stderr, "Box (%d,%d)x(%d,%d)\n", r.x, r.y, r.width(), r.height());
|
||||
|
||||
if (m_format == GL_RGBA8)
|
||||
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
else if (m_format == GL_R16UI)
|
||||
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RED_INTEGER, GL_R16UI, data);
|
||||
else if (m_format == GL_R8)
|
||||
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RED, GL_R8, data);
|
||||
else {
|
||||
fprintf(stderr, "wrong texture pixel format :%x\n", m_format);
|
||||
assert(0);
|
||||
}
|
||||
#if 0
|
||||
//if (m_size.x != 16)
|
||||
if (r.width() > 16 && r.height() > 16)
|
||||
|
@ -216,12 +228,16 @@ bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
|
|||
// FIXME It might be possible to only map a subrange of the texture based on r object
|
||||
|
||||
// Load the PBO
|
||||
if (m_format == GL_R16UI)
|
||||
glReadPixels(0, 0, m_size.x, m_size.y, GL_RED, GL_UNSIGNED_SHORT, 0);
|
||||
else if (m_format == GL_RGBA8)
|
||||
if (m_format == GL_RGBA8)
|
||||
glReadPixels(0, 0, m_size.x, m_size.y, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
else
|
||||
else if (m_format == GL_R16UI)
|
||||
glReadPixels(0, 0, m_size.x, m_size.y, GL_RED_INTEGER, GL_UNSIGNED_SHORT, 0);
|
||||
else if (m_format == GL_R8)
|
||||
glReadPixels(0, 0, m_size.x, m_size.y, GL_RED, GL_UNSIGNED_BYTE, 0);
|
||||
else {
|
||||
fprintf(stderr, "wrong texture pixel format :%x\n", m_format);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
// Give access from the CPU
|
||||
uint32 map_flags = GL_MAP_READ_BIT;
|
||||
|
|
|
@ -182,6 +182,8 @@ public:
|
|||
void Lock() {pthread_mutex_lock(&m_mutex);}
|
||||
bool TryLock() {return pthread_mutex_trylock(&m_mutex) == 0;}
|
||||
void Unlock() {pthread_mutex_unlock(&m_mutex);}
|
||||
|
||||
operator pthread_mutex_t* () {return &m_mutex;}
|
||||
};
|
||||
|
||||
class GSEvent : public IGSEvent
|
||||
|
|
|
@ -48,12 +48,13 @@ struct vertex
|
|||
};
|
||||
|
||||
#ifdef VERTEX_SHADER
|
||||
layout(location = 0) in vec2 i_t;
|
||||
layout(location = 0) in vec2 i_st;
|
||||
layout(location = 1) in vec4 i_c;
|
||||
layout(location = 2) in float i_q;
|
||||
layout(location = 3) in uvec2 i_p;
|
||||
layout(location = 4) in uint i_z;
|
||||
layout(location = 5) in vec4 i_f;
|
||||
layout(location = 5) in uvec2 i_uv;
|
||||
layout(location = 6) in vec4 i_f;
|
||||
|
||||
layout(location = 0) out vertex VSout;
|
||||
|
||||
|
@ -101,12 +102,14 @@ void vs_main()
|
|||
{
|
||||
if(VS_FST != 0)
|
||||
{
|
||||
VSout.t.xy = i_t * TextureScale;
|
||||
//VSout.t.xy = i_t * TextureScale;
|
||||
VSout.t.xy = i_uv * TextureScale;
|
||||
VSout.t.w = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
VSout.t.xy = i_t;
|
||||
//VSout.t.xy = i_t;
|
||||
VSout.t.xy = i_st;
|
||||
VSout.t.w = i_q;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue