mirror of https://github.com/PCSX2/pcsx2.git
gsdx-ogl: LINUX-ONLY
* fix vertex shader for HW renderer :) Remains the fragment part... * add some dumping infrastucture (DUMP_START and DUMP_LENGTH) git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl@5030 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
720a841cb2
commit
aa499f4bfd
|
@ -53,6 +53,15 @@
|
|||
// glUniformBlockBinding(program, block_index, block_binding_point);
|
||||
|
||||
//#define LOUD_DEBUGGING
|
||||
//#define DUMP_START (380)
|
||||
#define DUMP_LENGTH (20)
|
||||
|
||||
#ifdef DUMP_START
|
||||
static uint32 g_draw_count = 0;
|
||||
static uint32 g_frame_count = 0;
|
||||
#endif
|
||||
|
||||
|
||||
GSDeviceOGL::GSDeviceOGL()
|
||||
: m_free_window(false)
|
||||
, m_window(NULL)
|
||||
|
@ -492,11 +501,43 @@ void GSDeviceOGL::Flip()
|
|||
// FIXME: disable it when code is working
|
||||
CheckDebugLog();
|
||||
m_wnd->Flip();
|
||||
#ifdef DUMP_START
|
||||
g_frame_count++;
|
||||
#endif
|
||||
}
|
||||
|
||||
void GSDeviceOGL::DrawPrimitive()
|
||||
{
|
||||
glDrawArrays(m_state.topology, m_state.vb_state->start, m_state.vb_state->count);
|
||||
#ifdef DUMP_START
|
||||
if (g_draw_count > DUMP_START && g_draw_count < (DUMP_START+DUMP_LENGTH)) {
|
||||
for (auto i = 0 ; i < 3 ; i++) {
|
||||
if (m_state.ps_srv[i] != NULL) {
|
||||
m_state.ps_srv[i]->Save(format("/tmp/in_%d__%d.bmp", g_draw_count, i),false);
|
||||
}
|
||||
}
|
||||
if (m_state.rtv != NULL) m_state.rtv->Save(format("/tmp/out_%d.bmp", g_draw_count),false);
|
||||
if (m_state.dsv != NULL) m_state.dsv->Save(format("/tmp/out_%d_ds.bmp", g_draw_count),false);
|
||||
|
||||
string topo;
|
||||
switch (m_state.topology) {
|
||||
case GL_TRIANGLE_STRIP: topo = "triangle_strip"; break;
|
||||
case GL_TRIANGLES: topo = "triangle"; break;
|
||||
case GL_LINES: topo = "line"; break;
|
||||
case GL_POINTS: topo = "point"; break;
|
||||
default: topo = "!!!!";
|
||||
}
|
||||
fprintf(stderr, "Draw %d (Frame %d), %d elem of %s\n", g_draw_count, g_frame_count, m_state.vb_state->count, topo.c_str() );
|
||||
fprintf(stderr, "vs: %d ; gs: %d ; ps: %d\n", m_state.vs, m_state.gs, m_state.ps);
|
||||
fprintf(stderr, "Blend: %d, Depth: %d, Stencil: %d \n",m_state.bs->m_enable, m_state.dss->m_depth_enable, m_state.dss->m_stencil_enable);
|
||||
|
||||
//fprintf(stderr, "type: %d, format: 0x%x\n", m_state.rtv->GetType(), m_state.rtv->GetFormat());
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
}
|
||||
|
||||
g_draw_count++;
|
||||
#endif
|
||||
}
|
||||
|
||||
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
||||
|
@ -941,6 +982,7 @@ void GSDeviceOGL::GSSetShader(GLuint gs)
|
|||
if(m_state.gs != gs)
|
||||
{
|
||||
m_state.gs = gs;
|
||||
// FIXME AMD driver bug !!!!!!!!
|
||||
glUseProgramStages(m_pipeline, GL_GEOMETRY_SHADER_BIT, gs);
|
||||
}
|
||||
}
|
||||
|
@ -954,9 +996,7 @@ void GSDeviceOGL::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
|
|||
|
||||
void GSDeviceOGL::PSSetShaderResource(int i, GSTexture* sr)
|
||||
{
|
||||
GSTextureOGL* srv = NULL;
|
||||
|
||||
if(sr) srv = (GSTextureOGL*)sr;
|
||||
GSTextureOGL* srv = static_cast<GSTextureOGL*>(sr);
|
||||
|
||||
if(m_state.ps_srv[i] != srv)
|
||||
{
|
||||
|
@ -1082,24 +1122,11 @@ void GSDeviceOGL::OMSetBlendState(GSBlendStateOGL* bs, float bf)
|
|||
|
||||
void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor)
|
||||
{
|
||||
// attach render&depth to the FBO
|
||||
// Hum, need to separate 2 case, Render target fbo and render target backbuffer
|
||||
// Or maybe blit final result to the backbuffer
|
||||
#if 0
|
||||
ID3D11RenderTargetView* rtv = NULL;
|
||||
ID3D11DepthStencilView* dsv = NULL;
|
||||
m_state.rtv = static_cast<GSTextureOGL*>(rt);
|
||||
m_state.dsv = static_cast<GSTextureOGL*>(ds);
|
||||
|
||||
if(rt) rtv = *(GSTexture11*)rt;
|
||||
if(ds) dsv = *(GSTexture11*)ds;
|
||||
|
||||
if(m_state.rtv != rtv || m_state.dsv != dsv)
|
||||
{
|
||||
m_state.rtv = rtv;
|
||||
m_state.dsv = dsv;
|
||||
|
||||
m_ctx->OMSetRenderTargets(1, &rtv, dsv);
|
||||
}
|
||||
#endif
|
||||
if (static_cast<GSTextureOGL*>(rt)->IsBackbuffer()) {
|
||||
OMSetFBO(0);
|
||||
|
||||
|
@ -1108,7 +1135,16 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto
|
|||
OMSetFBO(m_fbo);
|
||||
|
||||
assert(rt != NULL); // a render target must exists
|
||||
static_cast<GSTextureOGL*>(rt)->Attach(GL_COLOR_ATTACHMENT0);
|
||||
|
||||
// FIXME DEBUG special case for GL_R16UI
|
||||
if (rt->GetFormat() == GL_R16UI) {
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT1);
|
||||
static_cast<GSTextureOGL*>(rt)->Attach(GL_COLOR_ATTACHMENT1);
|
||||
} else {
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
static_cast<GSTextureOGL*>(rt)->Attach(GL_COLOR_ATTACHMENT0);
|
||||
}
|
||||
|
||||
if (ds != NULL)
|
||||
static_cast<GSTextureOGL*>(ds)->Attach(GL_DEPTH_STENCIL_ATTACHMENT);
|
||||
}
|
||||
|
@ -1215,7 +1251,8 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st
|
|||
char* log = (char*)malloc(log_length);
|
||||
glGetProgramInfoLog(*program, log_length, NULL, log);
|
||||
|
||||
fprintf(stderr, "%s (%s) :", glsl_file.c_str(), entry.c_str());
|
||||
fprintf(stderr, "%s (entry %s, prog %d) :", glsl_file.c_str(), entry.c_str(), *program);
|
||||
fprintf(stderr, "\n%s", macro_sel.c_str());
|
||||
fprintf(stderr, "%s\n", log);
|
||||
free(log);
|
||||
}
|
||||
|
|
|
@ -87,10 +87,12 @@ class GSUniformBufferOGL {
|
|||
GLuint buffer; // data object
|
||||
GLuint index; // GLSL slot
|
||||
uint size; // size of the data
|
||||
const GLenum target;
|
||||
|
||||
public:
|
||||
GSUniformBufferOGL(GLuint index, uint size) : index(index)
|
||||
, size(size)
|
||||
, size(size)
|
||||
,target(GL_UNIFORM_BUFFER)
|
||||
{
|
||||
glGenBuffers(1, &buffer);
|
||||
bind();
|
||||
|
@ -100,25 +102,25 @@ public:
|
|||
|
||||
void bind()
|
||||
{
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, buffer);
|
||||
glBindBuffer(target, buffer);
|
||||
}
|
||||
|
||||
void allocate()
|
||||
{
|
||||
glBufferData(GL_UNIFORM_BUFFER, size, NULL, GL_STREAM_DRAW);
|
||||
glBufferData(target, size, NULL, GL_STREAM_DRAW);
|
||||
}
|
||||
|
||||
void attach()
|
||||
{
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, index, buffer);
|
||||
glBindBufferBase(target, index, buffer);
|
||||
}
|
||||
|
||||
void upload(const void* src)
|
||||
{
|
||||
uint32 flags = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT;
|
||||
uint8* dst = (uint8*) glMapBufferRange(GL_UNIFORM_BUFFER, 0, size, flags);
|
||||
uint8* dst = (uint8*) glMapBufferRange(target, 0, size, flags);
|
||||
memcpy(dst, src, size);
|
||||
glUnmapBuffer(GL_UNIFORM_BUFFER);
|
||||
glUnmapBuffer(target);
|
||||
}
|
||||
|
||||
~GSUniformBufferOGL() {
|
||||
|
@ -178,7 +180,10 @@ struct GSVertexBufferState {
|
|||
for (int i = 0; i < layout_nbr; i++) {
|
||||
// Note this function need both a vertex array object and a GL_ARRAY_BUFFER buffer
|
||||
glEnableVertexAttribArray(layout[i].index);
|
||||
glVertexAttribPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].normalize, layout[i].stride, layout[i].offset);
|
||||
if (layout[i].type == GL_UNSIGNED_INT || layout[i].type == GL_UNSIGNED_SHORT)
|
||||
glVertexAttribIPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].stride, layout[i].offset);
|
||||
else
|
||||
glVertexAttribPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].normalize, layout[i].stride, layout[i].offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -215,6 +215,7 @@ class GSRendererOGL : public GSRendererHW<GSVertexHW11>
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME Opengl support half pixel center (as dx10). Code could be easier!!!
|
||||
GSDeviceOGL::VSConstantBuffer vs_cb;
|
||||
|
||||
float sx = 2.0f * rtscale.x / (rtsize.x << 4);
|
||||
|
@ -242,6 +243,7 @@ class GSRendererOGL : public GSRendererHW<GSVertexHW11>
|
|||
|
||||
vs_cb.VertexScale = GSVector4(sx, -sy, ldexpf(1, -32), 0.0f);
|
||||
vs_cb.VertexOffset = GSVector4(ox * sx + ox2 + 1, -(oy * sy + oy2 + 1), 0.0f, -1.0f);
|
||||
// END of FIXME
|
||||
|
||||
// gs
|
||||
|
||||
|
|
|
@ -106,10 +106,9 @@ void GSDeviceOGL::SetupVS(VSSelector sel, const VSConstantBuffer* cb)
|
|||
// *************************************************************
|
||||
// Dynamic
|
||||
// *************************************************************
|
||||
if(m_vs_cb_cache.Update(cb))
|
||||
{
|
||||
if(m_vs_cb_cache.Update(cb)) {
|
||||
SetUniformBuffer(m_vs_cb);
|
||||
m_vs_cb->upload(&cb);
|
||||
m_vs_cb->upload(cb);
|
||||
}
|
||||
|
||||
VSSetShader(i->second);
|
||||
|
@ -178,10 +177,9 @@ void GSDeviceOGL::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerS
|
|||
// *************************************************************
|
||||
// Dynamic
|
||||
// *************************************************************
|
||||
if(m_ps_cb_cache.Update(cb))
|
||||
{
|
||||
if(m_ps_cb_cache.Update(cb)) {
|
||||
SetUniformBuffer(m_ps_cb);
|
||||
m_ps_cb->upload(&cb);
|
||||
m_ps_cb->upload(cb);
|
||||
}
|
||||
|
||||
GLuint ss0, ss1;
|
||||
|
|
|
@ -146,6 +146,7 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format)
|
|||
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_extra_buffer_id);
|
||||
glBufferData(GL_PIXEL_PACK_BUFFER, m_pbo_size, NULL, GL_STREAM_DRAW);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
@ -295,6 +296,8 @@ bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
|
|||
m.bits = (uint8*) glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, m_pbo_size, map_flags);
|
||||
m.pitch = m_size.x;
|
||||
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -367,20 +370,21 @@ struct BITMAPINFOHEADER
|
|||
|
||||
bool GSTextureOGL::Save(const string& fn, bool dds)
|
||||
{
|
||||
switch (m_type) {
|
||||
case GSTexture::DepthStencil:
|
||||
case GSTexture::Offscreen:
|
||||
ASSERT(0);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
// Code not yet working
|
||||
if (IsDss()) return false;
|
||||
|
||||
// Collect the texture data
|
||||
char* image = (char*)malloc(4 * m_size.x * m_size.y);
|
||||
uint32 pitch = 4 * m_size.x;
|
||||
if (IsDss()) pitch *= 2;
|
||||
char* image = (char*)malloc(pitch * m_size.y);
|
||||
|
||||
if (IsBackbuffer()) {
|
||||
// TODO backbuffer
|
||||
glReadBuffer(GL_BACK);
|
||||
glReadPixels(0, 0, m_size.x, m_size.y, GL_RGBA, GL_UNSIGNED_BYTE, image);
|
||||
} else if(IsDss()) {
|
||||
Attach(GL_DEPTH_STENCIL_ATTACHMENT);
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, image);
|
||||
} else {
|
||||
EnableUnit(0);
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
|
||||
|
@ -417,12 +421,29 @@ bool GSTextureOGL::Save(const string& fn, bool dds)
|
|||
fwrite(&bfh, 1, sizeof(bfh), fp);
|
||||
fwrite(&bih, 1, sizeof(bih), fp);
|
||||
|
||||
uint32 pitch = 4 * m_size.x;
|
||||
uint8* data = (uint8*)image + (m_size.y - 1) * pitch;
|
||||
|
||||
for(int h = m_size.y; h > 0; h--, data -= pitch)
|
||||
{
|
||||
fwrite(data, 1, m_size.x << 2, fp); // TODO: swap red-blue?
|
||||
if (IsDss()) {
|
||||
// Only get the depth and convert it to an integer
|
||||
uint8* better_data = data;
|
||||
for (int w = m_size.x; w > 0; w--, better_data += 8) {
|
||||
float* input = (float*)better_data;
|
||||
uint32 depth = (uint32)ldexpf(*input, 32);
|
||||
fwrite(&depth, 1, 4, fp);
|
||||
}
|
||||
} else {
|
||||
// swap red and blue
|
||||
uint8* better_data = data;
|
||||
for (int w = m_size.x; w > 0; w--, better_data += 4) {
|
||||
uint8 red = better_data[2];
|
||||
better_data[2] = better_data[0];
|
||||
better_data[0] = red;
|
||||
fwrite(better_data, 1, 4, fp);
|
||||
}
|
||||
}
|
||||
// fwrite(data, 1, m_size.x << 2, fp); // TODO: swap red-blue?
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
|
|
@ -45,4 +45,5 @@ class GSTextureOGL : public GSTexture
|
|||
void Attach(GLenum attachment);
|
||||
|
||||
bool IsBackbuffer() { return (m_type == GSTexture::Backbuffer); }
|
||||
bool IsDss() { return (m_type == GSTexture::DepthStencil); }
|
||||
};
|
||||
|
|
|
@ -39,6 +39,7 @@ layout(location = 0) in vec4 SV_Position;
|
|||
layout(location = 1) in vec2 TEXCOORD0;
|
||||
|
||||
layout(location = 0) out vec4 SV_Target0;
|
||||
layout(location = 1) out uint SV_Target1;
|
||||
|
||||
layout(binding = 0) uniform sampler2D TextureSampler;
|
||||
|
||||
|
@ -65,6 +66,17 @@ void ps_main0()
|
|||
SV_Target0 = sample_c();
|
||||
}
|
||||
|
||||
void ps_main1()
|
||||
{
|
||||
vec4 c = sample_c();
|
||||
|
||||
c.a *= 256.0f / 127.0f; // hm, 0.5 won't give us 1.0 if we just multiply with 2
|
||||
|
||||
highp uvec4 i = uvec4(c * vec4(0x001f, 0x03e0, 0x7c00, 0x8000));
|
||||
|
||||
SV_Target1 = (i.x & 0x001f) | (i.y & 0x03e0) | (i.z & 0x7c00) | (i.w & 0x8000);
|
||||
}
|
||||
|
||||
void ps_main7()
|
||||
{
|
||||
vec4 c = sample_c();
|
||||
|
@ -93,9 +105,6 @@ void ps_main6() // diagonal
|
|||
}
|
||||
|
||||
// Avoid to log useless error compilation failure
|
||||
void ps_main1()
|
||||
{
|
||||
}
|
||||
void ps_main2()
|
||||
{
|
||||
}
|
||||
|
@ -106,20 +115,6 @@ void ps_main4()
|
|||
{
|
||||
}
|
||||
|
||||
//void ps_main1()
|
||||
//{
|
||||
// vec4 c = sample_c();
|
||||
//
|
||||
// c.a *= 256.0f / 127; // hm, 0.5 won't give us 1.0 if we just multiply with 2
|
||||
//
|
||||
// uvec4 i = uvec4(c * vec4(0x001f, 0x03e0, 0x7c00, 0x8000));
|
||||
//
|
||||
//#ifdef DEBUG_FRAG
|
||||
// SV_Target0 = vec4(0.5,0.5,0.5,1.0);
|
||||
//#else
|
||||
// SV_Target0 = (i.x & 0x001f) | (i.y & 0x03e0) | (i.z & 0x7c00) | (i.w & 0x8000);
|
||||
//#endif
|
||||
//}
|
||||
|
||||
// Texture2D Texture;
|
||||
// SamplerState TextureSampler;
|
||||
|
|
|
@ -86,12 +86,13 @@ void vs_main()
|
|||
// example: 133.0625 (133 + 1/16) should start from line 134, ceil(133.0625 - 0.05) still above 133
|
||||
|
||||
vec4 p = vec4(i_p, z, 0) - vec4(0.05f, 0.05f, 0, 0);
|
||||
vec4 final_p = p * VertexScale - VertexOffset;
|
||||
|
||||
OUT.p = p * VertexScale - VertexOffset;
|
||||
OUT.p = final_p;
|
||||
gl_Position = final_p; // NOTE I don't know if it is possible to merge POSITION_OUT and gl_Position
|
||||
#if VS_RTCOPY
|
||||
OUT.tp = (p * VertexScale - VertexOffset) * vec4(0.5, -0.5, 0, 0) + 0.5;
|
||||
OUT.tp = final_p * vec4(0.5, -0.5, 0, 0) + 0.5;
|
||||
#endif
|
||||
gl_Position = p; // NOTE I don't know if it is possible to merge POSITION_OUT and gl_Position
|
||||
|
||||
if(VS_TME != 0)
|
||||
{
|
||||
|
@ -237,8 +238,13 @@ void gs_main()
|
|||
layout(location = 0) in vertex PSin;
|
||||
|
||||
// Same buffer but 2 colors for dual source blending
|
||||
layout(location = 0, index = 0) out vec4 SV_Target0;
|
||||
layout(location = 0, index = 1) out vec4 SV_Target1;
|
||||
//FIXME
|
||||
#if 1
|
||||
layout(location = 0, index = 0) out vec4 SV_Target0;
|
||||
layout(location = 0, index = 1) out vec4 SV_Target1;
|
||||
#else
|
||||
layout(location = 0) out vec4 SV_Target;
|
||||
#endif
|
||||
|
||||
layout(binding = 0) uniform sampler2D TextureSampler;
|
||||
layout(binding = 1) uniform sampler2D PaletteSampler;
|
||||
|
@ -583,8 +589,6 @@ vec4 ps_color()
|
|||
|
||||
if(PS_CLR1 != 0) // needed for Cd * (As/Ad/F + 1) blending modes
|
||||
{
|
||||
// FIXME: I'm not sure about the value of others field
|
||||
//c.rgb = 1.0f;
|
||||
c.rgb = vec3(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
|
@ -593,6 +597,8 @@ vec4 ps_color()
|
|||
|
||||
void ps_main()
|
||||
{
|
||||
//FIXME
|
||||
#if 1
|
||||
vec4 c = ps_color();
|
||||
|
||||
// FIXME: I'm not sure about the value of others field
|
||||
|
@ -611,5 +617,11 @@ void ps_main()
|
|||
}
|
||||
|
||||
SV_Target0 = c;
|
||||
|
||||
//SV_Target0 = vec4(1.0f,0.0f,0.0f, 1.0f);
|
||||
//SV_Target1 = vec4(1.0f,0.0f,0.0f, 1.0f);
|
||||
#else
|
||||
SV_Target = vec4(1.0f,0.0f,0.0f, 1.0f);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue