gsdx-ogl:

* implement shader code (subset that seem to be used in SW mode)
* some hack to fix some alignment issue with GSVertexPT1 structure
* Lots of various opengl fixes. Remaining unsupported GL feature are inside SDL.


git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl@4974 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gregory.hainaut 2011-11-30 21:42:41 +00:00
parent 133847e8a2
commit eb3eafa090
7 changed files with 261 additions and 190 deletions

View File

@ -658,6 +658,8 @@ void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
} }
assert(0); assert(0);
// GL_NV_copy_image seem like the good extension but not supported on AMD...
// FIXME attach the texture to the FBO // FIXME attach the texture to the FBO
GSTextureOGL* st_ogl = (GSTextureOGL*) st; GSTextureOGL* st_ogl = (GSTextureOGL*) st;
GSTextureOGL* dt_ogl = (GSTextureOGL*) dt; 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 // 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) 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) if(!st || !dt)
{ {
ASSERT(0); 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 right = dr.z * 2 / ds.x - 1.0f;
float bottom = 1.0f - dr.w * 2 / ds.y; 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(left, top, 0.5f, 1.0f), GSVector2(sr.x, sr.y)},
{GSVector4(right, top, 0.5f, 1.0f), GSVector2(sr.z, 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)); IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices));
IASetInputLayout(m_convert.il); IASetInputLayout(m_convert.il, 2);
IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); IASetPrimitiveTopology(GL_TRIANGLE_STRIP);
// vs // vs
@ -736,12 +736,12 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
// gs // gs
GSSetShader(NULL); GSSetShader(0);
// ps // ps
PSSetShaderResources(st, NULL); 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); PSSetShader(ps, ps_cb);
// //
@ -753,7 +753,9 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
EndScene(); EndScene();
PSSetShaderResources(NULL, NULL); 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) 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); glGenBuffers(1, &m_vb);
// FIXME: GL_DYNAMIC_DRAW vs GL_STREAM_DRAW !!! // FIXME: GL_DYNAMIC_DRAW vs GL_STREAM_DRAW !!!
glBindBuffer(GL_ARRAY_BUFFER, m_vb); 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 // append data or go back to the beginning
@ -959,10 +961,12 @@ void GSDeviceOGL::PSSetShader(GLuint ps, GSUniformBufferOGL* ps_cb)
// glBindSampler(1 , sampler); // glBindSampler(1 , sampler);
if (m_srv_changed || m_ss_changed) { if (m_srv_changed || m_ss_changed) {
for (uint i=0 ; i < 3; i++) { for (uint i=0 ; i < 3; i++) {
if (m_state.ps_srv[i] != NULL) {
m_state.ps_srv[i]->EnableUnit(i); m_state.ps_srv[i]->EnableUnit(i);
glBindSampler(i, m_state.ps_ss[i]); glBindSampler(i, m_state.ps_ss[i]);
} }
} }
}
#if 0 #if 0
if (m_srv_changed) if (m_srv_changed)
{ {
@ -1021,6 +1025,8 @@ void GSDeviceOGL::OMSetBlendState(GSBlendStateOGL* bs, float bf)
m_state.bs = bs; m_state.bs = bs;
m_state.bf = bf; m_state.bf = bf;
if (bs->m_enable) {
glEnable(GL_BLEND);
// FIXME: double check when blend stuff is complete // 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 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) || bs->m_func_dRGB == GL_CONSTANT_COLOR || bs->m_func_dRGB == GL_ONE_MINUS_CONSTANT_COLOR)
@ -1028,6 +1034,8 @@ void GSDeviceOGL::OMSetBlendState(GSBlendStateOGL* bs, float bf)
glBlendEquationSeparate(bs->m_equation_RGB, bs->m_equation_ALPHA); 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); 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; m_state.scissor = r;
// FIXME check position // 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 #if 0
m_ctx->RSSetScissorRects(1, r); m_ctx->RSSetScissorRects(1, r);
#endif #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) 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; std::string shader_type;
switch (type) { switch (type) {
case GL_VERTEX_SHADER: case GL_VERTEX_SHADER:
shader_type = "#define VERTEX_SHADER 1\n"; shader_type = "#define VERTEX_SHADER 1\n";
break;
case GL_GEOMETRY_SHADER: case GL_GEOMETRY_SHADER:
shader_type = "#define GEOMETRY_SHADER 1\n"; shader_type = "#define GEOMETRY_SHADER 1\n";
break;
case GL_FRAGMENT_SHADER: case GL_FRAGMENT_SHADER:
shader_type = "#define FRAGMENT_SHADER 1\n"; 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 entry_main = format("#define %s main\n", entry.c_str());
std::string header = version + shader_type + entry_main;
// *****************************************************
// Read the source file // Read the source file
// *****************************************************
std::string source; std::string source;
std::string line; std::string line;
// Each linux distributions have his rules for path so we give them the possibility to // 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()); 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()); // Note it is better to separate header and source file to have the good line number
strncpy(sources, full_source.c_str(), full_source.size()); // in the glsl compiler report
sources[full_source.size()] = '\0'; 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() void GSDeviceOGL::CheckDebugLog()
@ -1199,6 +1243,9 @@ void GSDeviceOGL::DebugOutputToFile(unsigned int source, unsigned int type, unsi
strcpy(debSource, "Application"); strcpy(debSource, "Application");
else if(source == GL_DEBUG_SOURCE_OTHER_ARB) else if(source == GL_DEBUG_SOURCE_OTHER_ARB)
strcpy(debSource, "Other"); strcpy(debSource, "Other");
else
strcpy(debSource, "UNKNOW");
if(type == GL_DEBUG_TYPE_ERROR_ARB) if(type == GL_DEBUG_TYPE_ERROR_ARB)
strcpy(debType, "Error"); strcpy(debType, "Error");
@ -1212,6 +1259,8 @@ void GSDeviceOGL::DebugOutputToFile(unsigned int source, unsigned int type, unsi
strcpy(debType, "Performance"); strcpy(debType, "Performance");
else if(type == GL_DEBUG_TYPE_OTHER_ARB) else if(type == GL_DEBUG_TYPE_OTHER_ARB)
strcpy(debType, "Other"); strcpy(debType, "Other");
else
strcpy(debType, "UNKNOW");
if(severity == GL_DEBUG_SEVERITY_HIGH_ARB) if(severity == GL_DEBUG_SEVERITY_HIGH_ARB)
strcpy(debSev, "High"); strcpy(debSev, "High");

View File

@ -86,7 +86,6 @@ struct GSUniformBufferOGL {
{} {}
~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 PSSetShaderResources(GSTexture* sr0, GSTexture* sr1);
void PSSetShaderResource(int i, GSTexture* sr); 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 PSSetShader(GLuint ps, GSUniformBufferOGL* ps_cb);
void OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref); void OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref);

View File

@ -94,8 +94,12 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format)
case GSTexture::RenderTarget: case GSTexture::RenderTarget:
// FIXME what is the real use case of this texture // FIXME what is the real use case of this texture
// Maybe a texture will be better // Maybe a texture will be better
glGenRenderbuffers(1, &m_texture_id); // glGenRenderbuffers(1, &m_texture_id);
m_texture_target = GL_RENDERBUFFER; // 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; break;
case GSTexture::DepthStencil: case GSTexture::DepthStencil:
glGenRenderbuffers(1, &m_texture_id); glGenRenderbuffers(1, &m_texture_id);
@ -104,8 +108,8 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format)
case GSTexture::Texture: case GSTexture::Texture:
glGenTextures(1, &m_texture_id); glGenTextures(1, &m_texture_id);
// FIXME, do we need rectangle (or better to use 2D texture) // FIXME, do we need rectangle (or better to use 2D texture)
//m_texture_target = GL_TEXTURE_2D; m_texture_target = GL_TEXTURE_2D;
m_texture_target = GL_TEXTURE_RECTANGLE; //m_texture_target = GL_TEXTURE_RECTANGLE;
// == For texture, the Unit must be selected // == For texture, the Unit must be selected
break; break;
case GSTexture::Offscreen: case GSTexture::Offscreen:
@ -132,18 +136,25 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format)
// Allocate the buffer // Allocate the buffer
switch (m_type) { switch (m_type) {
case GSTexture::RenderTarget:
case GSTexture::DepthStencil: case GSTexture::DepthStencil:
glBindRenderbuffer(m_texture_target, m_texture_id); glBindRenderbuffer(m_texture_target, m_texture_id);
glRenderbufferStorageMultisample(m_texture_target, msaa_level, m_format, m_size.y, m_size.x); glRenderbufferStorageMultisample(m_texture_target, msaa_level, m_format, m_size.y, m_size.x);
break; break;
case GSTexture::RenderTarget:
case GSTexture::Texture: case GSTexture::Texture:
// FIXME // FIXME
// Howto allocate the texture unit !!! // Howto allocate the texture unit !!!
// In worst case the HW renderer seems to use 3 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 // For the moment SW renderer only use 1 so don't bother
EnableUnit(0); 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; break;
case GSTexture::Offscreen: case GSTexture::Offscreen:
assert(0); 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: // To update only a part of the texture you can use:
// glTexSubImage2D — specify a two-dimensional texture subimage // glTexSubImage2D — specify a two-dimensional texture subimage
switch (m_type) { switch (m_type) {
case GSTexture::RenderTarget:
case GSTexture::Texture: case GSTexture::Texture:
// glTexSubImage2D specifies a two-dimensional subtexture for the current texture unit, specified with glActiveTexture. // 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 // 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 I'm not confident with GL_UNSIGNED_BYTE type
// FIXME add a state check // FIXME add a state check
glBindTexture(m_texture_target, m_texture_id); 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; break;
case GSTexture::RenderTarget:
case GSTexture::DepthStencil: case GSTexture::DepthStencil:
case GSTexture::Offscreen: case GSTexture::Offscreen:
assert(0); assert(0);
@ -204,11 +220,11 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
void GSTextureOGL::EnableUnit(uint unit) void GSTextureOGL::EnableUnit(uint unit)
{ {
switch (m_type) { switch (m_type) {
case GSTexture::RenderTarget:
case GSTexture::DepthStencil: case GSTexture::DepthStencil:
case GSTexture::Offscreen: case GSTexture::Offscreen:
assert(0); assert(0);
break; break;
case GSTexture::RenderTarget:
case GSTexture::Texture: case GSTexture::Texture:
// FIXME // FIXME
// Howto allocate the texture unit !!! // Howto allocate the texture unit !!!

View File

@ -50,6 +50,10 @@ struct GSVertexPT1
{ {
GSVector4 p; GSVector4 p;
GSVector2 t; GSVector2 t;
#ifdef _LINUX
//FIXME aligment issue
GSVector2 pad;
#endif
}; };
struct GSVertexPT2 struct GSVertexPT2

View File

@ -1,142 +1,137 @@
#if 0 //#version 420 // Keep it for editor detection
struct VS_INPUT
{
float4 p : POSITION;
float2 t : TEXCOORD0;
};
struct VS_OUTPUT #ifdef VERTEX_SHADER
{
float4 p : SV_Position;
float2 t : TEXCOORD0;
};
Texture2D Texture; layout(location = 0) in vec4 POSITION;
SamplerState TextureSampler; 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; return texture(TextureSampler, uv);
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;
} }
PS_OUTPUT ps_main0(PS_INPUT input) vec4 ps_crt(vec2 uv, uint i)
{ {
PS_OUTPUT output; vec4 mask[4] =
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] =
{ {
float4(1, 0, 0, 0), vec4(1, 0, 0, 0),
float4(0, 1, 0, 0), vec4(0, 1, 0, 0),
float4(0, 0, 1, 0), vec4(0, 0, 1, 0),
float4(1, 1, 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); SV_Target0 = sample_c(TEXCOORD0);
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) void ps_main7()
{ {
PS_OUTPUT output; vec4 c = sample_c(TEXCOORD0);
clip(sample_c(input.t).a - 128.0f / 255); // >= 0x80 pass c.a = dot(c.rgb, vec3(0.299, 0.587, 0.114));
output.c = 0; SV_Target0 = c;
return output;
} }
PS_OUTPUT ps_main3(PS_INPUT input) void ps_main5() // triangular
{ {
PS_OUTPUT output; //uint4 p = (uint4)input.p;
highp uvec4 p = uvec4(SV_Position);
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;
// output.c = ps_crt(input, ((p.x + (p.y & 1) * 3) >> 1) % 3); // 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; uvec4 p = uvec4(SV_Position);
uint4 p = (uint4)input.p; vec4 c = ps_crt(TEXCOORD0, (p.x + (p.y % 3)) % 3);
output.c = ps_crt(input, (p.x + (p.y % 3)) % 3); SV_Target0 = c;
return output;
} }
// 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 #endif

View File

@ -1,46 +1,54 @@
#if 0 //#version 420 // Keep it for editor detection
Texture2D Texture; #ifdef FRAGMENT_SHADER
SamplerState Sampler; 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; vec2 ZrH;
float hH; float hH;
}; };
struct PS_INPUT layout(binding = 0) uniform sampler2D TextureSampler;
{
float4 p : SV_Position;
float2 t : TEXCOORD0;
};
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); vec4 c0 = texture(TextureSampler, TEXCOORD0 - ZrH);
float4 c1 = Texture.Sample(Sampler, input.t); vec4 c1 = texture(TextureSampler, TEXCOORD0);
float4 c2 = Texture.Sample(Sampler, input.t + ZrH); 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 #endif

View File

@ -1,31 +1,31 @@
#if 0 //#version 420 // Keep it for editor detection
Texture2D Texture; #ifdef FRAGMENT_SHADER
SamplerState Sampler;
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 layout(binding = 0) uniform sampler2D TextureSampler;
{
float4 p : SV_Position;
float2 t : TEXCOORD0;
};
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); 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; c.a = BGColor.a;
return c; SV_Target0 = c;
} }
#endif #endif