diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index c0ba73f696..e3248b8dd7 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -658,6 +658,8 @@ void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r) } assert(0); + // GL_NV_copy_image seem like the good extension but not supported on AMD... + // FIXME attach the texture to the FBO GSTextureOGL* st_ogl = (GSTextureOGL*) st; GSTextureOGL* dt_ogl = (GSTextureOGL*) dt; @@ -692,9 +694,6 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, // probably no difficult to convert when all helpers function will be done void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, GLuint ps, GSUniformBufferOGL* ps_cb, GSBlendStateOGL* bs, bool linear) { - //TODO later - assert(0); -#if 0 if(!st || !dt) { ASSERT(0); @@ -718,7 +717,8 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, float right = dr.z * 2 / ds.x - 1.0f; float bottom = 1.0f - dr.w * 2 / ds.y; - GSVertexPT1 vertices[] = + //FIXME aligment issue + GSVertexPT1 vertices[] __attribute__ ((aligned (16))) = { {GSVector4(left, top, 0.5f, 1.0f), GSVector2(sr.x, sr.y)}, {GSVector4(right, top, 0.5f, 1.0f), GSVector2(sr.z, sr.y)}, @@ -727,8 +727,8 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, }; IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices)); - IASetInputLayout(m_convert.il); - IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + IASetInputLayout(m_convert.il, 2); + IASetPrimitiveTopology(GL_TRIANGLE_STRIP); // vs @@ -736,12 +736,12 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, // gs - GSSetShader(NULL); + GSSetShader(0); // ps PSSetShaderResources(st, NULL); - PSSetSamplerState(linear ? m_convert.ln : m_convert.pt, NULL); + PSSetSamplerState(linear ? m_convert.ln : m_convert.pt, 0); PSSetShader(ps, ps_cb); // @@ -753,7 +753,9 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, EndScene(); PSSetShaderResources(NULL, NULL); -#endif + + // FIXME: disable it when code is working + CheckDebugLog(); } void GSDeviceOGL::DoMerge(GSTexture* st[2], GSVector4* sr, GSTexture* dt, GSVector4* dr, bool slbg, bool mmod, const GSVector4& c) @@ -847,7 +849,7 @@ void GSDeviceOGL::IASetVertexBuffer(const void* vertices, size_t stride, size_t glGenBuffers(1, &m_vb); // FIXME: GL_DYNAMIC_DRAW vs GL_STREAM_DRAW !!! glBindBuffer(GL_ARRAY_BUFFER, m_vb); - glBufferData(GL_ARRAY_BUFFER, m_vertices.limit, NULL, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, m_vertices.limit * stride, NULL, GL_DYNAMIC_DRAW); } // append data or go back to the beginning @@ -959,8 +961,10 @@ void GSDeviceOGL::PSSetShader(GLuint ps, GSUniformBufferOGL* ps_cb) // glBindSampler(1 , sampler); if (m_srv_changed || m_ss_changed) { for (uint i=0 ; i < 3; i++) { - m_state.ps_srv[i]->EnableUnit(i); - glBindSampler(i, m_state.ps_ss[i]); + if (m_state.ps_srv[i] != NULL) { + m_state.ps_srv[i]->EnableUnit(i); + glBindSampler(i, m_state.ps_ss[i]); + } } } #if 0 @@ -1021,13 +1025,17 @@ void GSDeviceOGL::OMSetBlendState(GSBlendStateOGL* bs, float bf) m_state.bs = bs; m_state.bf = bf; - // FIXME: double check when blend stuff is complete - if (bs->m_func_sRGB == GL_CONSTANT_COLOR || bs->m_func_sRGB == GL_ONE_MINUS_CONSTANT_COLOR - || bs->m_func_dRGB == GL_CONSTANT_COLOR || bs->m_func_dRGB == GL_ONE_MINUS_CONSTANT_COLOR) - glBlendColor(bf, bf, bf, 0); + if (bs->m_enable) { + glEnable(GL_BLEND); + // FIXME: double check when blend stuff is complete + if (bs->m_func_sRGB == GL_CONSTANT_COLOR || bs->m_func_sRGB == GL_ONE_MINUS_CONSTANT_COLOR + || bs->m_func_dRGB == GL_CONSTANT_COLOR || bs->m_func_dRGB == GL_ONE_MINUS_CONSTANT_COLOR) + glBlendColor(bf, bf, bf, 0); - glBlendEquationSeparate(bs->m_equation_RGB, bs->m_equation_ALPHA); - glBlendFuncSeparate(bs->m_func_sRGB, bs->m_func_dRGB, bs->m_func_sALPHA, bs->m_func_dALPHA); + glBlendEquationSeparate(bs->m_equation_RGB, bs->m_equation_ALPHA); + glBlendFuncSeparate(bs->m_func_sRGB, bs->m_func_dRGB, bs->m_func_sALPHA, bs->m_func_dALPHA); + } else + glDisable(GL_BLEND); } } @@ -1087,7 +1095,11 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto { m_state.scissor = r; // FIXME check position - glScissor(r.x, r.w, r.z-r.x, r.y-r.w); + // x = 0, + // y = 0, + // z = 512, + // w = 512 + glScissor(r.x, r.y, r.z-r.x, r.w-r.y); #if 0 m_ctx->RSSetScissorRects(1, r); #endif @@ -1096,21 +1108,35 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const std::string& entry, GLenum type, GLuint* program) { - // Could be useful to filter ubber shader + // ***************************************************** + // Build a header string + // ***************************************************** + // First select the version (must be the first line so we need to generate it + std::string version = "#version 410\n#extension GL_ARB_shading_language_420pack: enable\n"; + + // Allow to puts several shader in 1 files std::string shader_type; switch (type) { case GL_VERTEX_SHADER: shader_type = "#define VERTEX_SHADER 1\n"; + break; case GL_GEOMETRY_SHADER: shader_type = "#define GEOMETRY_SHADER 1\n"; + break; case GL_FRAGMENT_SHADER: shader_type = "#define FRAGMENT_SHADER 1\n"; + break; + default: assert(0); } - // Select the entry point + // Select the entry point ie the main function std::string entry_main = format("#define %s main\n", entry.c_str()); + std::string header = version + shader_type + entry_main; + + // ***************************************************** // Read the source file + // ***************************************************** std::string source; std::string line; // Each linux distributions have his rules for path so we give them the possibility to @@ -1135,16 +1161,34 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st fprintf(stderr, "Error opening %s: ", shader_file.c_str()); } - // Create a giant string with everythings - std::string full_source = shader_type + entry_main + source; - char* sources = (char*)malloc(full_source.size()); - strncpy(sources, full_source.c_str(), full_source.size()); - sources[full_source.size()] = '\0'; + // Note it is better to separate header and source file to have the good line number + // in the glsl compiler report + const char** sources_array = (const char**)malloc(2*sizeof(char*)); + char* source_str = (char*)malloc(source.size() + 1); + char* header_str = (char*)malloc(header.size() + 1); + sources_array[0] = header_str; + sources_array[1] = source_str; - *program = glCreateShaderProgramv(type, 1, (const char**)&sources); + source.copy(source_str, source.size(), 0); + source_str[source.size()] = '\0'; + header.copy(header_str, header.size(), 0); + header_str[header.size()] = '\0'; - free(sources); + *program = glCreateShaderProgramv(type, 2, sources_array); + free(source_str); + free(header_str); + free(sources_array); + + // Print a nice debug log + GLint log_length = 0; + glGetProgramiv(*program, GL_INFO_LOG_LENGTH, &log_length); + + char* log = (char*)malloc(log_length); + glGetProgramInfoLog(*program, log_length, NULL, log); + + fprintf(stderr, "%s", log); + free(log); } void GSDeviceOGL::CheckDebugLog() @@ -1199,6 +1243,9 @@ void GSDeviceOGL::DebugOutputToFile(unsigned int source, unsigned int type, unsi strcpy(debSource, "Application"); else if(source == GL_DEBUG_SOURCE_OTHER_ARB) strcpy(debSource, "Other"); + else + strcpy(debSource, "UNKNOW"); + if(type == GL_DEBUG_TYPE_ERROR_ARB) strcpy(debType, "Error"); @@ -1212,6 +1259,8 @@ void GSDeviceOGL::DebugOutputToFile(unsigned int source, unsigned int type, unsi strcpy(debType, "Performance"); else if(type == GL_DEBUG_TYPE_OTHER_ARB) strcpy(debType, "Other"); + else + strcpy(debType, "UNKNOW"); if(severity == GL_DEBUG_SEVERITY_HIGH_ARB) strcpy(debSev, "High"); diff --git a/plugins/GSdx/GSDeviceOGL.h b/plugins/GSdx/GSDeviceOGL.h index a8fbaddc15..d131fe6db0 100644 --- a/plugins/GSdx/GSDeviceOGL.h +++ b/plugins/GSdx/GSDeviceOGL.h @@ -86,8 +86,7 @@ struct GSUniformBufferOGL { {} ~GSUniformBufferOGL() { - if (buffer) - glDeleteBuffers(1, &buffer); + glDeleteBuffers(1, &buffer); } }; @@ -280,7 +279,7 @@ class GSDeviceOGL : public GSDevice void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1); void PSSetShaderResource(int i, GSTexture* sr); - void PSSetSamplerState(GLuint ss0, GLuint ss1, GLuint ss2); + void PSSetSamplerState(GLuint ss0, GLuint ss1, GLuint ss2 = 0); void PSSetShader(GLuint ps, GSUniformBufferOGL* ps_cb); void OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref); diff --git a/plugins/GSdx/GSTextureOGL.cpp b/plugins/GSdx/GSTextureOGL.cpp index ebc782440f..9c3a679e38 100644 --- a/plugins/GSdx/GSTextureOGL.cpp +++ b/plugins/GSdx/GSTextureOGL.cpp @@ -94,8 +94,12 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format) case GSTexture::RenderTarget: // FIXME what is the real use case of this texture // Maybe a texture will be better - glGenRenderbuffers(1, &m_texture_id); - m_texture_target = GL_RENDERBUFFER; + // glGenRenderbuffers(1, &m_texture_id); + // m_texture_target = GL_RENDERBUFFER; + // Buffer can not be read by shader and must be blit before. I see no point to use a render buffer + // when you can directly render on the texture. It said it could be faster... + glGenTextures(1, &m_texture_id); + m_texture_target = GL_TEXTURE_2D; break; case GSTexture::DepthStencil: glGenRenderbuffers(1, &m_texture_id); @@ -104,8 +108,8 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format) case GSTexture::Texture: glGenTextures(1, &m_texture_id); // FIXME, do we need rectangle (or better to use 2D texture) - //m_texture_target = GL_TEXTURE_2D; - m_texture_target = GL_TEXTURE_RECTANGLE; + m_texture_target = GL_TEXTURE_2D; + //m_texture_target = GL_TEXTURE_RECTANGLE; // == For texture, the Unit must be selected break; case GSTexture::Offscreen: @@ -132,18 +136,25 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format) // Allocate the buffer switch (m_type) { - case GSTexture::RenderTarget: case GSTexture::DepthStencil: glBindRenderbuffer(m_texture_target, m_texture_id); glRenderbufferStorageMultisample(m_texture_target, msaa_level, m_format, m_size.y, m_size.x); break; + case GSTexture::RenderTarget: case GSTexture::Texture: // FIXME // Howto allocate the texture unit !!! // 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(0); - glTexStorage2D_glew17(m_texture_target, 0, m_format, m_size.y, m_size.x); + // FIXME glTexStorage2D does not work yet on my system (4.2) extension but glTexImage2D seems ok + // glTexStorage2D_glew17(m_texture_target, 1, m_format, m_size.y, m_size.x); + // fprintf(stderr, "texture storage %d, %d\n", w, h); + if (m_format == GL_RGBA8) { + glTexImage2D(m_texture_target, 0, m_format, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + } + else + assert(0); break; case GSTexture::Offscreen: assert(0); @@ -170,6 +181,7 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch) // To update only a part of the texture you can use: // glTexSubImage2D — specify a two-dimensional texture subimage switch (m_type) { + case GSTexture::RenderTarget: case GSTexture::Texture: // glTexSubImage2D specifies a two-dimensional subtexture for the current texture unit, specified with glActiveTexture. // If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target @@ -179,9 +191,13 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch) // FIXME I'm not confident with GL_UNSIGNED_BYTE type // FIXME add a state check glBindTexture(m_texture_target, m_texture_id); - glTexSubImage2D(m_texture_target, 0, r.left, r.bottom, r.right-r.left, r.top-r.bottom, m_format, GL_UNSIGNED_BYTE, data); + //void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * data); + // fprintf(stderr, "texture coord %d, %d, %d, %d\n", r.x, r.y, r.z, r.w); + if (m_format == GL_RGBA8) + glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.z-r.x, r.w-r.y, GL_RGBA, GL_UNSIGNED_BYTE, data); + else + assert(0); break; - case GSTexture::RenderTarget: case GSTexture::DepthStencil: case GSTexture::Offscreen: assert(0); @@ -204,11 +220,11 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch) void GSTextureOGL::EnableUnit(uint unit) { switch (m_type) { - case GSTexture::RenderTarget: case GSTexture::DepthStencil: case GSTexture::Offscreen: assert(0); break; + case GSTexture::RenderTarget: case GSTexture::Texture: // FIXME // Howto allocate the texture unit !!! diff --git a/plugins/GSdx/GSVertex.h b/plugins/GSdx/GSVertex.h index 6df8fcd3aa..4daa85bdd5 100644 --- a/plugins/GSdx/GSVertex.h +++ b/plugins/GSdx/GSVertex.h @@ -50,6 +50,10 @@ struct GSVertexPT1 { GSVector4 p; GSVector2 t; +#ifdef _LINUX + //FIXME aligment issue + GSVector2 pad; +#endif }; struct GSVertexPT2 diff --git a/plugins/GSdx/res/convert.glsl b/plugins/GSdx/res/convert.glsl index 62adf6dbe4..33a1b1113a 100644 --- a/plugins/GSdx/res/convert.glsl +++ b/plugins/GSdx/res/convert.glsl @@ -1,142 +1,137 @@ -#if 0 -struct VS_INPUT -{ - float4 p : POSITION; - float2 t : TEXCOORD0; -}; +//#version 420 // Keep it for editor detection -struct VS_OUTPUT -{ - float4 p : SV_Position; - float2 t : TEXCOORD0; -}; +#ifdef VERTEX_SHADER -Texture2D Texture; -SamplerState TextureSampler; +layout(location = 0) in vec4 POSITION; +layout(location = 1) in vec2 TEXCOORD0; -float4 sample_c(float2 uv) +// FIXME set the interpolation (don't know what dx do) +// flat means that there is no interpolation. The value given to the fragment shader is based on the provoking vertex conventions. +// +// noperspective means that there will be linear interpolation in window-space. This is usually not what you want, but it can have its uses. +// +// smooth, the default, means to do perspective-correct interpolation. +// +// The centroid qualifier only matters when multisampling. If this qualifier is not present, then the value is interpolated to the pixel's center, anywhere in the pixel, or to one of the pixel's samples. This sample may lie outside of the actual primitive being rendered, since a primitive can cover only part of a pixel's area. The centroid qualifier is used to prevent this; the interpolation point must fall within both the pixel's area and the primitive's area. +// FIXME gl_Position +smooth layout(location = 0) out vec4 POSITION_OUT; +smooth layout(location = 1) out vec2 TEXCOORD0_OUT; + +void vs_main() { - return Texture.Sample(TextureSampler, uv); + POSITION_OUT = POSITION; + TEXCOORD0_OUT = TEXCOORD0_OUT; + gl_Position = POSITION; // NOTE I don't know if it is possible to merge POSITION_OUT and gl_Position } -struct PS_INPUT +#endif + +#ifdef FRAGMENT_SHADER +// NOTE: pixel can be clip with "discard" + +layout(location = 0) in vec4 SV_Position; +layout(location = 1) in vec2 TEXCOORD0; + +out vec4 SV_Target0; + +layout(binding = 0) uniform sampler2D TextureSampler; + +vec4 sample_c(vec2 uv) { - float4 p : SV_Position; - float2 t : TEXCOORD0; -}; - -struct PS_OUTPUT -{ - float4 c : SV_Target0; -}; - -VS_OUTPUT vs_main(VS_INPUT input) -{ - VS_OUTPUT output; - - output.p = input.p; - output.t = input.t; - - return output; + return texture(TextureSampler, uv); } -PS_OUTPUT ps_main0(PS_INPUT input) +vec4 ps_crt(vec2 uv, uint i) { - PS_OUTPUT output; - - output.c = sample_c(input.t); - - return output; -} - -PS_OUTPUT ps_main7(PS_INPUT input) -{ - PS_OUTPUT output; - - float4 c = sample_c(input.t); - - c.a = dot(c.rgb, float3(0.299, 0.587, 0.114)); - - output.c = c; - - return output; -} - -float4 ps_crt(PS_INPUT input, int i) -{ - float4 mask[4] = + vec4 mask[4] = { - float4(1, 0, 0, 0), - float4(0, 1, 0, 0), - float4(0, 0, 1, 0), - float4(1, 1, 1, 0) + vec4(1, 0, 0, 0), + vec4(0, 1, 0, 0), + vec4(0, 0, 1, 0), + vec4(1, 1, 1, 0) }; - - return sample_c(input.t) * saturate(mask[i] + 0.5f); + + return sample_c(uv) * clamp((mask[i] + 0.5f), 0.0f, 1.0f); } -uint ps_main1(PS_INPUT input) : SV_Target0 +void ps_main0() { - float4 c = sample_c(input.t); - - c.a *= 256.0f / 127; // hm, 0.5 won't give us 1.0 if we just multiply with 2 - - uint4 i = c * float4(0x001f, 0x03e0, 0x7c00, 0x8000); - - return (i.x & 0x001f) | (i.y & 0x03e0) | (i.z & 0x7c00) | (i.w & 0x8000); + SV_Target0 = sample_c(TEXCOORD0); } -PS_OUTPUT ps_main2(PS_INPUT input) +void ps_main7() { - PS_OUTPUT output; - - clip(sample_c(input.t).a - 128.0f / 255); // >= 0x80 pass - - output.c = 0; + vec4 c = sample_c(TEXCOORD0); - return output; + c.a = dot(c.rgb, vec3(0.299, 0.587, 0.114)); + + SV_Target0 = c; } -PS_OUTPUT ps_main3(PS_INPUT input) +void ps_main5() // triangular { - PS_OUTPUT output; - - clip(127.95f / 255 - sample_c(input.t).a); // < 0x80 pass (== 0x80 should not pass) - - output.c = 0; - - return output; -} - -PS_OUTPUT ps_main4(PS_INPUT input) -{ - PS_OUTPUT output; - - output.c = fmod(sample_c(input.t) * 255 + 0.5f, 256) / 255; - - return output; -} - -PS_OUTPUT ps_main5(PS_INPUT input) // triangular -{ - PS_OUTPUT output; - - uint4 p = (uint4)input.p; + //uint4 p = (uint4)input.p; + highp uvec4 p = uvec4(SV_Position); // output.c = ps_crt(input, ((p.x + (p.y & 1) * 3) >> 1) % 3); - output.c = ps_crt(input, ((p.x + ((p.y >> 1) & 1) * 3) >> 1) % 3); + vec4 c = ps_crt(TEXCOORD0, ((p.x + ((p.y >> 1) & 1) * 3) >> 1) % 3); - return output; + SV_Target0 = c; } -PS_OUTPUT ps_main6(PS_INPUT input) // diagonal +void ps_main6() // diagonal { - PS_OUTPUT output; - - uint4 p = (uint4)input.p; + uvec4 p = uvec4(SV_Position); - output.c = ps_crt(input, (p.x + (p.y % 3)) % 3); + vec4 c = ps_crt(TEXCOORD0, (p.x + (p.y % 3)) % 3); - return output; + SV_Target0 = c; } + +// Texture2D Texture; +// SamplerState TextureSampler; +// +// uint ps_main1(PS_INPUT input) : SV_Target0 +// { +// float4 c = sample_c(input.t); +// +// c.a *= 256.0f / 127; // hm, 0.5 won't give us 1.0 if we just multiply with 2 +// +// uint4 i = c * float4(0x001f, 0x03e0, 0x7c00, 0x8000); +// +// return (i.x & 0x001f) | (i.y & 0x03e0) | (i.z & 0x7c00) | (i.w & 0x8000); +// } +// +// PS_OUTPUT ps_main2(PS_INPUT input) +// { +// PS_OUTPUT output; +// +// clip(sample_c(input.t).a - 128.0f / 255); // >= 0x80 pass +// +// output.c = 0; +// +// return output; +// } +// +// PS_OUTPUT ps_main3(PS_INPUT input) +// { +// PS_OUTPUT output; +// +// clip(127.95f / 255 - sample_c(input.t).a); // < 0x80 pass (== 0x80 should not pass) +// +// output.c = 0; +// +// return output; +// } +// +// PS_OUTPUT ps_main4(PS_INPUT input) +// { +// PS_OUTPUT output; +// +// output.c = fmod(sample_c(input.t) * 255 + 0.5f, 256) / 255; +// +// return output; +// } +// + #endif diff --git a/plugins/GSdx/res/interlace.glsl b/plugins/GSdx/res/interlace.glsl index b7245a7f32..9933fe3b5e 100644 --- a/plugins/GSdx/res/interlace.glsl +++ b/plugins/GSdx/res/interlace.glsl @@ -1,46 +1,54 @@ -#if 0 +//#version 420 // Keep it for editor detection -Texture2D Texture; -SamplerState Sampler; +#ifdef FRAGMENT_SHADER +layout(location = 0) in vec4 SV_Position; +layout(location = 1) in vec2 TEXCOORD0; -cbuffer cb0 +out vec4 SV_Target0; + +layout(std140, binding = 1) uniform cb0 { - float2 ZrH; - float hH; + vec2 ZrH; + float hH; }; -struct PS_INPUT -{ - float4 p : SV_Position; - float2 t : TEXCOORD0; -}; +layout(binding = 0) uniform sampler2D TextureSampler; -float4 ps_main0(PS_INPUT input) : SV_Target0 +// TODO ensure that clip (discard) is < 0 and not <= 0 ??? +void ps_main0() { - clip(frac(input.t.y * hH) - 0.5); + // I'm not sure it impact us but be safe to lookup texture before conditional if + // see: http://www.opengl.org/wiki/GLSL_Sampler#Non-uniform_flow_control + vec4 c = texture(TextureSampler, TEXCOORD0); + if (fract(TEXCOORD0.y * hH) - 0.5 < 0.0) + discard; - return Texture.Sample(Sampler, input.t); + SV_Target0 = c; } -float4 ps_main1(PS_INPUT input) : SV_Target0 +void ps_main1() { - clip(0.5 - frac(input.t.y * hH)); + // I'm not sure it impact us but be safe to lookup texture before conditional if + // see: http://www.opengl.org/wiki/GLSL_Sampler#Non-uniform_flow_control + vec4 c = texture(TextureSampler, TEXCOORD0); + if (0.5 - fract(TEXCOORD0.y * hH) < 0.0) + discard; - return Texture.Sample(Sampler, input.t); + SV_Target0 = c; } -float4 ps_main2(PS_INPUT input) : SV_Target0 +void ps_main2() { - float4 c0 = Texture.Sample(Sampler, input.t - ZrH); - float4 c1 = Texture.Sample(Sampler, input.t); - float4 c2 = Texture.Sample(Sampler, input.t + ZrH); + vec4 c0 = texture(TextureSampler, TEXCOORD0 - ZrH); + vec4 c1 = texture(TextureSampler, TEXCOORD0); + vec4 c2 = texture(TextureSampler, TEXCOORD0 + ZrH); - return (c0 + c1 * 2 + c2) / 4; + SV_Target0 = (c0 + c1 * 2 + c2) / 4; } -float4 ps_main3(PS_INPUT input) : SV_Target0 +void ps_main3() { - return Texture.Sample(Sampler, input.t); + SV_Target0 = texture(TextureSampler, TEXCOORD0); } #endif diff --git a/plugins/GSdx/res/merge.glsl b/plugins/GSdx/res/merge.glsl index 74f47377ad..b46ac7d4ed 100644 --- a/plugins/GSdx/res/merge.glsl +++ b/plugins/GSdx/res/merge.glsl @@ -1,31 +1,31 @@ -#if 0 +//#version 420 // Keep it for editor detection -Texture2D Texture; -SamplerState Sampler; +#ifdef FRAGMENT_SHADER -cbuffer cb0 +layout(location = 0) in vec4 SV_Position; +layout(location = 1) in vec2 TEXCOORD0; + +out vec4 SV_Target0; + +layout(std140, binding = 1) uniform cb0 { - float4 BGColor; + vec4 BGColor; }; -struct PS_INPUT -{ - float4 p : SV_Position; - float2 t : TEXCOORD0; -}; +layout(binding = 0) uniform sampler2D TextureSampler; -float4 ps_main0(PS_INPUT input) : SV_Target0 +void ps_main0() { - float4 c = Texture.Sample(Sampler, input.t); + vec4 c = texture(TextureSampler, TEXCOORD0); c.a = min(c.a * 2, 1); - return c; + SV_Target0 = c; } -float4 ps_main1(PS_INPUT input) : SV_Target0 +void ps_main1() { - float4 c = Texture.Sample(Sampler, input.t); + vec4 c = texture(TextureSampler, TEXCOORD0); c.a = BGColor.a; - return c; + SV_Target0 = c; } #endif