gsdx-ogl: LINUX-ONLY

* implement the saving of texture (take bmp SW code)
* fix the missing "enable attribute code" and the typo in glsl. It works now !!!
* rework a little texture to pack texture into a temporay buffer when src pitch != dst pitch
* try to replace sdl with pure xlib (not yet enabled by default but it seems to work)

Note there still a minor issue, coordinate are different between DX and OGL (upper-left vs lower-left) so the image is inversed.


git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl@4981 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gregory.hainaut 2011-12-07 22:05:46 +00:00
parent eb3eafa090
commit a835de0af7
12 changed files with 358 additions and 85 deletions

View File

@ -119,7 +119,7 @@ set(CMAKE_SHARED_LIBRARY_CXX_FLAGS "")
#-------------------------------------------------------------------------------
# Set some default compiler flags
#-------------------------------------------------------------------------------
set(DEFAULT_WARNINGS "-Wno-write-strings -Wno-format -Wno-unused-parameter -Wno-unused-value -Wstrict-aliasing")
set(DEFAULT_WARNINGS "-w -Wno-write-strings -Wno-format -Wno-unused-parameter -Wno-unused-value -Wstrict-aliasing")
set(DEFAULT_GCC_FLAG "-m32 -msse -msse2 -march=i686 -pthread ${DEFAULT_WARNINGS}")
set(DEFAULT_CPP_FLAG "${DEFAULT_GCC_FLAG} -Wno-invalid-offsetof")

View File

@ -16,6 +16,7 @@ set(CommonFlags
-mfpmath=sse
#-Wstrict-aliasing # Allow to track strict aliasing issue.
-Wunused-variable
-DKEEP_SDL
)
set(OptimizationFlags
@ -196,6 +197,12 @@ endif(NOT USER_CMAKE_LD_FLAGS STREQUAL "")
if(PACKAGE_MODE)
install(TARGETS ${Output} DESTINATION ${PLUGIN_DIR})
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/convert.glsl DESTINATION ${PLUGIN_DIR})
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/interlace.glsl DESTINATION ${PLUGIN_DIR})
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/merge.glsl DESTINATION ${PLUGIN_DIR})
else(PACKAGE_MODE)
install(TARGETS ${Output} DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/convert.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/interlace.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/merge.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
endif(PACKAGE_MODE)

View File

@ -62,8 +62,13 @@ GSDeviceOGL::GSDeviceOGL()
, m_pipeline(0)
, m_srv_changed(false)
, m_ss_changed(false)
, m_vb_changed(false)
{
m_msaa = theApp.GetConfig("msaa", 0);
m_frag_back_buffer[0] = GL_BACK_LEFT;
m_frag_rt_buffer[0] = GL_COLOR_ATTACHMENT0;
memset(&m_merge, 0, sizeof(m_merge));
memset(&m_interlace, 0, sizeof(m_interlace));
memset(&m_convert, 0, sizeof(m_convert));
@ -102,13 +107,17 @@ GSDeviceOGL::~GSDeviceOGL()
glDeleteProgramPipelines(1, &m_pipeline);
glDeleteFramebuffers(1, &m_fbo);
// glXMakeCurrent(m_XDisplay, m_Xwindow, 0);
// if (m_context) glXDestroyContext(m_XDisplay, m_context);
// if(m_context)
// SDL_GL_DeleteContext(m_context);
#ifdef KEEP_SDL
if(m_dummy_renderer)
SDL_DestroyRenderer(m_dummy_renderer);
if(m_window != NULL && m_free_window)
SDL_DestroyWindow(m_window);
#endif
}
GSTexture* GSDeviceOGL::CreateSurface(int type, int w, int h, bool msaa, int format)
@ -149,11 +158,8 @@ PFNGLTEXSTORAGE2DPROC glTexStorage2D_glew17 = NULL;
bool GSDeviceOGL::Create(GSWnd* wnd)
{
if (m_window == NULL) {
#if SDL_VERSION_ATLEAST(1,3,0)
#ifdef KEEP_SDL
m_window = SDL_CreateWindowFrom(wnd->GetHandle());
#else
assert(0);
#endif
m_free_window = true;
// If the user request OpenGL acceleration, we take recent OGL version (4.2)
@ -168,7 +174,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
// Ask for an advance opengl version
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 4 );
// FIXME AMD does not support yet 4.2...
//SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 1 );
//SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 2 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 1 );
// Window must be recreated to gain Opengl feature...
@ -177,7 +183,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
m_dummy_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_ACCELERATED); // SDL_RENDERER_PRESENTVSYNC
// At least create the opengl context
// m_context = SDL_GL_CreateContext(m_window);
#endif
// FIXME......
// GLEW's problem is that it calls glGetString(GL_EXTENSIONS) which causes GL_INVALID_ENUM on GL 3.2 forward compatible context as soon as glewInit() is called. It also doesn't fetch the function pointers. The solution is for GLEW to use glGetStringi instead.
@ -202,10 +208,12 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
glTexStorage2D_glew17 = (PFNGLTEXSTORAGE2DPROC)glXGetProcAddressARB((const GLubyte*)"glTexStorage2D");
}
#ifdef __LINUX__
#ifdef KEEP_SDL
// In GSopen2, sdl failed to received any resize event. GSWnd::GetClientRect need to manually
// set the window size... So we send the m_window to the wnd object to allow some manipulation on it.
wnd->SetWindow(m_window);
#else
m_window = wnd;
#endif
// FIXME disable it when code is ready
@ -529,13 +537,7 @@ void GSDeviceOGL::Flip()
{
// FIXME: disable it when code is working
CheckDebugLog();
// Warning it is not OGL dependent but application dependant (glx and so not portable)
#if SDL_VERSION_ATLEAST(1,3,0)
SDL_GL_SwapWindow(m_window);
#else
SDL_GL_SwapBuffers();
#endif
m_wnd->Flip();
}
void GSDeviceOGL::DrawPrimitive()
@ -546,18 +548,29 @@ void GSDeviceOGL::DrawPrimitive()
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
{
GSTextureOGL* t_ogl = (GSTextureOGL*)t;
// FIXME I need to clarify this FBO attachment stuff
// I would like to avoid FBO for a basic clean operation
//glClearBufferfv(GL_COLOR, t_ogl->attachment(), c.v);
if (t == m_backbuffer) {
// FIXME need an assert
if (m_state.fbo) {
m_state.fbo = 0;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
glClearBufferfv(GL_COLOR, GL_BACK, c.v);
} else {
// FIXME I need to clarify this FBO attachment stuff
// I would like to avoid FBO for a basic clean operation
if (!m_state.fbo) {
m_state.fbo = m_fbo;
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
}
t_ogl->Attach(GL_COLOR_ATTACHMENT0);
glClearBufferfv(GL_COLOR, 0, c.v);
}
}
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, uint32 c)
{
GSTextureOGL* t_ogl = (GSTextureOGL*)t;
GSVector4 color = GSVector4::rgba32(c) * (1.0f / 255);
// FIXME I need to clarify this FBO attachment stuff
// I would like to avoid FBO for a basic clean operation
//glClearBufferfv(GL_COLOR, t_ogl->attachment(), color.v);
ClearRenderTarget(t, color);
}
void GSDeviceOGL::ClearDepth(GSTexture* t, float c)
@ -691,9 +704,9 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
StretchRect(st, sr, dt, dr, ps, ps_cb, m_convert.bs, linear);
}
// 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)
{
if(!st || !dt)
{
ASSERT(0);
@ -717,8 +730,7 @@ 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;
//FIXME aligment issue
GSVertexPT1 vertices[] __attribute__ ((aligned (16))) =
GSVertexPT1 vertices[] =
{
{GSVector4(left, top, 0.5f, 1.0f), GSVector2(sr.x, sr.y)},
{GSVector4(right, top, 0.5f, 1.0f), GSVector2(sr.z, sr.y)},
@ -745,6 +757,12 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
PSSetShader(ps, ps_cb);
//
// FIXME: disable it when code is working
glValidateProgramPipeline(m_pipeline);
GLint status;
glGetProgramPipelineiv(m_pipeline, GL_VALIDATE_STATUS, &status);
if (status != GL_TRUE)
fprintf(stderr, "Failed to validate the pipeline\n");
DrawPrimitive();
@ -797,7 +815,6 @@ void GSDeviceOGL::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool lin
m_state.cb = m_interlace.cb->buffer;
glBindBuffer(GL_UNIFORM_BUFFER, m_interlace.cb->buffer);
}
// FIXME I'm not sure it will be happy with InterlaceConstantBuffer type
glBufferSubData(GL_UNIFORM_BUFFER, 0, m_interlace.cb->byte_size, &cb);
#if 0
m_ctx->UpdateSubresource(m_interlace.cb, 0, NULL, &cb, 0, 0);
@ -842,6 +859,7 @@ void GSDeviceOGL::IASetVertexBuffer(const void* vertices, size_t stride, size_t
m_vertices.start = 0;
m_vertices.count = 0;
m_vertices.limit = std::max<int>(count * 3 / 2, 11000);
}
if(!m_vb)
@ -850,6 +868,7 @@ void GSDeviceOGL::IASetVertexBuffer(const void* vertices, size_t stride, size_t
// FIXME: GL_DYNAMIC_DRAW vs GL_STREAM_DRAW !!!
glBindBuffer(GL_ARRAY_BUFFER, m_vb);
glBufferData(GL_ARRAY_BUFFER, m_vertices.limit * stride, NULL, GL_DYNAMIC_DRAW);
m_vb_changed = true;
}
// append data or go back to the beginning
@ -867,12 +886,21 @@ void GSDeviceOGL::IASetVertexBuffer(const void* vertices, size_t stride, size_t
void GSDeviceOGL::IASetInputLayout(GSInputLayout* layout, int layout_nbr)
{
if(m_state.layout != layout)
if(m_state.layout != layout || m_state.layout_nbr != layout_nbr || m_vb_changed)
{
m_state.layout = layout;
// Remove old configuration.
for (int i = m_state.layout_nbr ; i > (m_state.layout_nbr - layout_nbr) ; i--) {
glDisableVertexAttribArray(i);
}
for (int i = 0; i < layout_nbr; i++)
glVertexAttribPointer(layout->index, layout->size, layout->type, GL_FALSE, layout->stride, layout->offset);
for (int i = 0; i < layout_nbr; i++) {
glEnableVertexAttribArray(layout[i].index);
glVertexAttribPointer(layout[i].index, layout[i].size, layout[i].type, GL_FALSE, layout[i].stride, layout[i].offset);
}
m_vb_changed = false;
m_state.layout = layout;
m_state.layout_nbr = layout_nbr;
}
}
@ -1066,6 +1094,7 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto
if (m_state.fbo) {
m_state.fbo = 0;
glBindFramebuffer(GL_FRAMEBUFFER, 0); // render in the backbuffer
glDrawBuffers(1, m_frag_back_buffer);
}
assert(ds_ogl == NULL); // no depth-stencil without FBO
@ -1073,6 +1102,7 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto
if (m_state.fbo != m_fbo) {
m_state.fbo = m_fbo;
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
glDrawBuffers(1, m_frag_rt_buffer);
}
assert(rt_ogl != NULL); // a render target must exists
@ -1094,12 +1124,7 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto
if(!m_state.scissor.eq(r))
{
m_state.scissor = r;
// FIXME check position
// x = 0,
// y = 0,
// z = 512,
// w = 512
glScissor(r.x, r.y, r.z-r.x, r.w-r.y);
glScissor( r.x, r.y, r.width(), r.height() );
#if 0
m_ctx->RSSetScissorRects(1, r);
#endif
@ -1187,7 +1212,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", log);
fprintf(stderr, "%s (%s) :", glsl_file.c_str(), entry.c_str());
fprintf(stderr, "%s\n", log);
free(log);
}

View File

@ -103,7 +103,11 @@ class GSDeviceOGL : public GSDevice
uint32 m_msaa; // Level of Msaa
bool m_free_window;
#ifdef KEEP_SDL
SDL_Window* m_window; // pointer to the SDL window
#else
GSWnd* m_window; // pointer to the SDL window
#endif
//SDL_GLContext m_context; // current opengl context
SDL_Renderer* m_dummy_renderer; // ... crappy API ...
@ -111,6 +115,9 @@ class GSDeviceOGL : public GSDevice
GLuint m_pipeline; // pipeline to attach program shader
GLuint m_fbo; // frame buffer container
GLenum m_frag_back_buffer[1];
GLenum m_frag_rt_buffer[1];
struct {
GLuint ps[2]; // program object
GSUniformBufferOGL* cb; // uniform buffer object
@ -170,6 +177,7 @@ class GSDeviceOGL : public GSDevice
// size_t vb_stride;
// ID3D11InputLayout* layout;
GSInputLayout* layout;
uint32 layout_nbr;
GLenum topology; // (ie GL_TRIANGLES...)
GLuint vs; // program
GLuint cb; // uniform current buffer
@ -197,6 +205,7 @@ class GSDeviceOGL : public GSDevice
bool m_srv_changed;
bool m_ss_changed;
bool m_vb_changed;
#if 0
CComPtr<ID3D11Device> m_dev;
@ -229,6 +238,8 @@ class GSDeviceOGL : public GSDevice
PSConstantBuffer m_ps_cb_cache;
#endif
//GLenum frag_back[1] = { GL_BACK };
//GLenum frag_target[1] = { GL_COLOR_ATTACHMENT0 }:
void CheckDebugLog();
void DebugOutputToFile(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, const char* message);

View File

@ -24,7 +24,9 @@
#include "GSTextureOGL.h"
GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format)
: m_texture_unit(0)
: m_texture_unit(0),
m_extra_buffer_id(0),
m_extra_buffer_allocated(false)
{
// *************************************************************
// Opengl world
@ -123,8 +125,11 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format)
// gvec texelFetch(gsampler sampler, ivec texCoord, int lod[, int sample]);
// corollary we can maybe use it for multisample stuff
break;
default: break;
default:
break;
}
// Extra buffer to handle various pixel transfer
glGenBuffers(1, &m_extra_buffer_id);
uint msaa_level;
if (m_msaa) {
@ -178,31 +183,51 @@ void GSTextureOGL::Attach(GLenum attachment)
bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
{
// static int update_count = 0;
// update_count++;
// 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
//(see glBindBuffer) while a texture image is
// specified, data is treated as a byte offset into the buffer object's data store
// FIXME warning order of the y axis
// FIXME I'm not confident with GL_UNSIGNED_BYTE type
// FIXME add a state check
glBindTexture(m_texture_target, m_texture_id);
//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::DepthStencil:
case GSTexture::Offscreen:
assert(0);
break;
if (m_type == GSTexture::DepthStencil || m_type == GSTexture::Offscreen) assert(0);
// 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
//(see glBindBuffer) while a texture image is
// specified, data is treated as a byte offset into the buffer object's data store
// FIXME warning order of the y axis
// FIXME I'm not confident with GL_UNSIGNED_BYTE type
// FIXME add a state check
EnableUnit(0);
if (m_format != GL_RGBA8) assert(0);
// FIXME. That suck but I don't know how to do better for now. I think we need to create a texture buffer and directly upload the copy
// The case appears on SW mode. Src pitch is 2x dst pitch.
int rowbytes = r.width() << 2;
if (pitch != rowbytes) {
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_extra_buffer_id);
if (!m_extra_buffer_allocated) {
glBufferData(GL_PIXEL_UNPACK_BUFFER, m_size.x * m_size.y * 4, NULL, GL_STREAM_DRAW);
m_extra_buffer_allocated = true;
}
uint8* src = (uint8*) data;
uint8* dst = (uint8*) glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
for(int h = r.height(); h > 0; h--, src += pitch, dst += rowbytes)
{
memcpy(dst, src, rowbytes);
}
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RGBA, GL_UNSIGNED_BYTE, 0 /* offset in UNPACK BUFFER */);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
} else {
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RGBA, GL_UNSIGNED_BYTE, data);
}
#if 0
if(m_dev && m_texture)
{
@ -283,10 +308,107 @@ void GSTextureOGL::Unmap()
#endif
}
// If I'm correct, this function only dump some buffer. Debug only, still very useful!
// Note: check zzogl implementation
#ifndef _WINDOWS
#pragma pack(push, 1)
struct BITMAPFILEHEADER
{
uint16 bfType;
uint32 bfSize;
uint16 bfReserved1;
uint16 bfReserved2;
uint32 bfOffBits;
};
struct BITMAPINFOHEADER
{
uint32 biSize;
int32 biWidth;
int32 biHeight;
uint16 biPlanes;
uint16 biBitCount;
uint32 biCompression;
uint32 biSizeImage;
int32 biXPelsPerMeter;
int32 biYPelsPerMeter;
uint32 biClrUsed;
uint32 biClrImportant;
};
#define BI_RGB 0
#pragma pack(pop)
#endif
bool GSTextureOGL::Save(const string& fn, bool dds)
{
switch (m_type) {
case GSTexture::DepthStencil:
case GSTexture::Offscreen:
ASSERT(0);
break;
default: break;
}
// Collect the texture data
char* image = (char*)malloc(4 * m_size.x * m_size.y);
if (m_type) {
EnableUnit(0);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
} else {
// TODO backbuffer
glReadBuffer(GL_BACK);
glReadPixels(0, 0, m_size.x, m_size.y, GL_RGBA, GL_UNSIGNED_BYTE, image);
}
// Build a BMP file
if(FILE* fp = fopen(fn.c_str(), "wb"))
{
BITMAPINFOHEADER bih;
memset(&bih, 0, sizeof(bih));
bih.biSize = sizeof(bih);
bih.biWidth = m_size.x;
bih.biHeight = m_size.y;
bih.biPlanes = 1;
bih.biBitCount = 32;
bih.biCompression = BI_RGB;
bih.biSizeImage = m_size.x * m_size.y << 2;
BITMAPFILEHEADER bfh;
memset(&bfh, 0, sizeof(bfh));
uint8* bfType = (uint8*)&bfh.bfType;
// bfh.bfType = 'MB';
bfType[0] = 0x42;
bfType[1] = 0x4d;
bfh.bfOffBits = sizeof(bfh) + sizeof(bih);
bfh.bfSize = bfh.bfOffBits + bih.biSizeImage;
bfh.bfReserved1 = bfh.bfReserved2 = 0;
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?
}
fclose(fp);
free(image);
return true;
}
return false;
#if 0
CComPtr<ID3D11Resource> res;

View File

@ -29,6 +29,8 @@ class GSTextureOGL : public GSTexture
GLenum m_texture_target; // texture target: 2D, rectangle etc...
GLuint m_texture_id; // the texture id
uint m_texture_unit; // the texture unit offset
uint m_extra_buffer_id;
bool m_extra_buffer_allocated;
public:
explicit GSTextureOGL(int type, int w, int h, bool msaa, int format);

View File

@ -46,14 +46,10 @@ struct GSVertexP
GSVector4 p;
};
struct GSVertexPT1
__aligned(struct, 32) GSVertexPT1
{
GSVector4 p;
GSVector2 t;
#ifdef _LINUX
//FIXME aligment issue
GSVector2 pad;
#endif
};
struct GSVertexPT2

View File

@ -314,6 +314,11 @@ void GSWnd::HideFrame()
GSWnd::GSWnd()
: m_window(NULL), m_Xwindow(0), m_XDisplay(NULL)
{
#ifdef KEEP_SDL
m_renderer = 2;
#else
m_renderer = theApp.GetConfig("renderer", 0) / 3;
#endif
}
GSWnd::~GSWnd()
@ -334,6 +339,53 @@ bool GSWnd::Attach(void* handle, bool managed)
m_Xwindow = *(Window*)handle;
m_managed = managed;
if (m_renderer != 2) {
m_XDisplay = XOpenDisplay(NULL);
// Get visual information
int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_DEPTH_SIZE, 24,
None
};
PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) glXGetProcAddress((GLubyte *) "glXChooseFBConfig");
int fbcount = 0;
GLXFBConfig *fbc = glXChooseFBConfig(m_XDisplay, DefaultScreen(m_XDisplay), attrListDbl, &fbcount);
if (!fbc || fbcount < 1) return false;
glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddress((const GLubyte*) "glXCreateContextAttribsARB");
if (!glXCreateContextAttribsARB) return false;
// Create a context
int context_attribs[] =
{
GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
GLX_CONTEXT_MINOR_VERSION_ARB, 1,
// FIXME : Request a debug context to ease opengl development
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
0
};
m_context = glXCreateContextAttribsARB(m_XDisplay, fbc[0], 0, true, context_attribs);
XSync( m_XDisplay, false);
if (!m_context) return false;
glXMakeCurrent(m_XDisplay, m_Xwindow, m_context);
// Check the status
int glxMajorVersion, glxMinorVersion;
glXQueryVersion(m_XDisplay, &glxMajorVersion, &glxMinorVersion);
if (glXIsDirect(m_XDisplay, m_context))
fprintf(stderr, "glX-Version %d.%d with Direct Rendering\n", glxMajorVersion, glxMinorVersion);
else
fprintf(stderr, "glX-Version %d.%d with Indirect Rendering !!! It will be slow\n", glxMajorVersion, glxMinorVersion);
}
return true;
}
@ -341,10 +393,15 @@ void GSWnd::Detach()
{
// Actually the destructor is not called when there is only a GSclose/GSshutdown
// The window still need to be closed
if(m_window != NULL && m_managed)
{
SDL_DestroyWindow(m_window);
m_window = NULL;
if (m_renderer == 2) {
if(m_window != NULL && m_managed)
{
SDL_DestroyWindow(m_window);
m_window = NULL;
}
} else {
glXMakeCurrent(m_XDisplay, m_Xwindow, 0);
if (m_context) glXDestroyContext(m_XDisplay, m_context);
}
if (m_XDisplay) {
XCloseDisplay(m_XDisplay);
@ -425,7 +482,8 @@ GSVector4i GSWnd::GetClientRect()
// In real world...:
if (!m_XDisplay) m_XDisplay = XOpenDisplay(NULL);
XGetGeometry(m_XDisplay, m_Xwindow, &winDummy, &xDummy, &yDummy, &w, &h, &borderDummy, &depthDummy);
SDL_SetWindowSize(m_window, w, h);
if (m_renderer == 2)
SDL_SetWindowSize(m_window, w, h);
return GSVector4i(0, 0, (int)w, (int)h);
}
@ -445,23 +503,48 @@ bool GSWnd::SetWindowText(const char* title)
// but we not use this function anyway.
// FIXME: it does not feel a good solution -- Gregory
// NOte: it might be more thread safe to use a call to XGetGeometry
SDL_PumpEvents();
int x,y = 0;
SDL_GetWindowPosition(m_window, &x, &y);
if ( x && y )
SDL_SetWindowTitle(m_window, title);
if (m_renderer == 2) {
SDL_PumpEvents();
SDL_GetWindowPosition(m_window, &x, &y);
if ( x && y )
SDL_SetWindowTitle(m_window, title);
}
return true;
}
void GSWnd::Flip()
{
if (m_renderer == 2) {
#if SDL_VERSION_ATLEAST(1,3,0)
SDL_GL_SwapWindow(m_window);
#else
SDL_GL_SwapBuffers();
#endif
} else {
glXSwapBuffers(m_XDisplay, m_Xwindow);
}
}
void GSWnd::Show()
{
SDL_ShowWindow(m_window);
if (m_renderer == 2) {
SDL_ShowWindow(m_window);
} else {
XMapRaised(m_XDisplay, m_Xwindow);
XFlush(m_XDisplay);
}
}
void GSWnd::Hide()
{
SDL_HideWindow(m_window);
if (m_renderer == 2) {
SDL_HideWindow(m_window);
} else {
XUnmapWindow(m_XDisplay, m_Xwindow);
XFlush(m_XDisplay);
}
}
void GSWnd::HideFrame()

View File

@ -91,12 +91,16 @@ public:
#include "../../3rdparty/SDL-1.3.0-5387/include/SDL.h"
#include "../../3rdparty/SDL-1.3.0-5387/include/SDL_syswm.h"
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, bool, const int*);
class GSWnd
{
SDL_Window* m_window;
Window m_Xwindow;
Display* m_XDisplay;
bool m_managed;
int m_renderer;
GLXContext m_context;
public:
GSWnd();
@ -116,6 +120,7 @@ public:
void Show();
void Hide();
void HideFrame();
void Flip();
};
#endif

View File

@ -2,6 +2,12 @@
#ifdef VERTEX_SHADER
out gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
};
layout(location = 0) in vec4 POSITION;
layout(location = 1) in vec2 TEXCOORD0;
@ -20,7 +26,7 @@ smooth layout(location = 1) out vec2 TEXCOORD0_OUT;
void vs_main()
{
POSITION_OUT = POSITION;
TEXCOORD0_OUT = TEXCOORD0_OUT;
TEXCOORD0_OUT = TEXCOORD0;
gl_Position = POSITION; // NOTE I don't know if it is possible to merge POSITION_OUT and gl_Position
}
@ -32,7 +38,7 @@ void vs_main()
layout(location = 0) in vec4 SV_Position;
layout(location = 1) in vec2 TEXCOORD0;
out vec4 SV_Target0;
layout(location = 0) out vec4 SV_Target0;
layout(binding = 0) uniform sampler2D TextureSampler;
@ -88,6 +94,21 @@ void ps_main6() // diagonal
SV_Target0 = c;
}
//void ps_main1()
//{
// vec4 c = sample_c(TEXCOORD);
//
// 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;
//

View File

@ -4,7 +4,7 @@
layout(location = 0) in vec4 SV_Position;
layout(location = 1) in vec2 TEXCOORD0;
out vec4 SV_Target0;
layout(location = 0) out vec4 SV_Target0;
layout(std140, binding = 1) uniform cb0
{

View File

@ -1,11 +1,10 @@
//#version 420 // Keep it for editor detection
#ifdef FRAGMENT_SHADER
layout(location = 0) in vec4 SV_Position;
layout(location = 1) in vec2 TEXCOORD0;
out vec4 SV_Target0;
layout(location = 0) out vec4 SV_Target0;
layout(std140, binding = 1) uniform cb0
{
@ -16,8 +15,9 @@ layout(binding = 0) uniform sampler2D TextureSampler;
void ps_main0()
{
vec4 c = texture(TextureSampler, TEXCOORD0);
c.a = min(c.a * 2, 1);
c.a = min(c.a * 2, 1.0);
SV_Target0 = c;
}