mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
133847e8a2
commit
eb3eafa090
|
@ -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,8 +961,10 @@ 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++) {
|
||||||
m_state.ps_srv[i]->EnableUnit(i);
|
if (m_state.ps_srv[i] != NULL) {
|
||||||
glBindSampler(i, m_state.ps_ss[i]);
|
m_state.ps_srv[i]->EnableUnit(i);
|
||||||
|
glBindSampler(i, m_state.ps_ss[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -1021,13 +1025,17 @@ void GSDeviceOGL::OMSetBlendState(GSBlendStateOGL* bs, float bf)
|
||||||
m_state.bs = bs;
|
m_state.bs = bs;
|
||||||
m_state.bf = bf;
|
m_state.bf = bf;
|
||||||
|
|
||||||
// FIXME: double check when blend stuff is complete
|
if (bs->m_enable) {
|
||||||
if (bs->m_func_sRGB == GL_CONSTANT_COLOR || bs->m_func_sRGB == GL_ONE_MINUS_CONSTANT_COLOR
|
glEnable(GL_BLEND);
|
||||||
|| bs->m_func_dRGB == GL_CONSTANT_COLOR || bs->m_func_dRGB == GL_ONE_MINUS_CONSTANT_COLOR)
|
// FIXME: double check when blend stuff is complete
|
||||||
glBlendColor(bf, bf, bf, 0);
|
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);
|
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");
|
||||||
|
|
|
@ -86,8 +86,7 @@ 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);
|
||||||
|
|
|
@ -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 !!!
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue