mirror of https://github.com/PCSX2/pcsx2.git
gsdx-ogl: LINUX-ONLY
* implement offscreen and cache (mostly a copy past of dx) * add the missing macro selector of the shader... git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl@5009 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
6f5ac7b788
commit
33a9ac370a
|
@ -526,12 +526,22 @@ void GSDeviceOGL::ClearRenderTarget(GSTexture* t, uint32 c)
|
|||
|
||||
void GSDeviceOGL::ClearDepth(GSTexture* t, float c)
|
||||
{
|
||||
// FIXME I need to clarify this FBO attachment stuff
|
||||
// I would like to avoid FBO for a basic clean operation
|
||||
OMSetFBO(m_fbo);
|
||||
static_cast<GSTextureOGL*>(t)->Attach(GL_DEPTH_STENCIL_ATTACHMENT);
|
||||
// FIXME can you clean depth and stencil separately
|
||||
glClearBufferfv(GL_DEPTH, 0, &c);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c)
|
||||
{
|
||||
// FIXME I need to clarify this FBO attachment stuff
|
||||
// I would like to avoid FBO for a basic clean operation
|
||||
OMSetFBO(m_fbo);
|
||||
static_cast<GSTextureOGL*>(t)->Attach(GL_DEPTH_STENCIL_ATTACHMENT);
|
||||
GLint color = c;
|
||||
// FIXME can you clean depth and stencil separately
|
||||
glClearBufferiv(GL_STENCIL, 0, &color);
|
||||
}
|
||||
|
||||
|
@ -558,56 +568,45 @@ GSTexture* GSDeviceOGL::CreateOffscreen(int w, int h, int format)
|
|||
// blit a texture into an offscreen buffer
|
||||
GSTexture* GSDeviceOGL::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format)
|
||||
{
|
||||
// I'm not sure about the object type for offscreen buffer
|
||||
// TODO later;
|
||||
|
||||
assert(0);
|
||||
|
||||
// Need to find format equivalent. Then I think it will be straight forward
|
||||
|
||||
// A four-component, 32-bit unsigned-normalized-integer format that supports 8 bits per channel including alpha.
|
||||
// DXGI_FORMAT_R8G8B8A8_UNORM <=> GL_RGBA8
|
||||
|
||||
// A single-component, 16-bit unsigned-integer format that supports 16 bits for the red channel
|
||||
// DXGI_FORMAT_R16_UINT <=> GL_R16
|
||||
#if 0
|
||||
GSTexture* dst = NULL;
|
||||
|
||||
if(format == 0)
|
||||
{
|
||||
format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
}
|
||||
if(format == 0) format = GL_RGBA8;
|
||||
|
||||
if(format != DXGI_FORMAT_R8G8B8A8_UNORM && format != DXGI_FORMAT_R16_UINT)
|
||||
if(format != GL_RGBA8 && format != GL_R16UI)
|
||||
{
|
||||
ASSERT(0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(GSTexture* rt = CreateRenderTarget(w, h, false, format))
|
||||
// FIXME: I used directly an offscreen texture because they are the same on Opengl
|
||||
//if(GSTexture* rt = CreateRenderTarget(w, h, false, format))
|
||||
GSTexture* rt = CreateRenderTarget(w, h, false, format);
|
||||
if(rt)
|
||||
{
|
||||
GSVector4 dr(0, 0, w, h);
|
||||
|
||||
if(GSTexture* src2 = src->IsMSAA() ? Resolve(src) : src)
|
||||
{
|
||||
StretchRect(src2, sr, rt, dr, m_convert.ps[format == DXGI_FORMAT_R16_UINT ? 1 : 0], NULL);
|
||||
StretchRect(src2, sr, rt, dr, m_convert.ps[format == GL_R16UI ? 1 : 0]);
|
||||
|
||||
if(src2 != src) Recycle(src2);
|
||||
}
|
||||
|
||||
#if 0
|
||||
dst = CreateOffscreen(w, h, format);
|
||||
|
||||
if(dst)
|
||||
{
|
||||
m_ctx->CopyResource(*(GSTexture11*)dst, *(GSTexture11*)rt);
|
||||
}
|
||||
#endif
|
||||
|
||||
Recycle(rt);
|
||||
}
|
||||
|
||||
return dst;
|
||||
#endif
|
||||
//return dst;
|
||||
return rt;
|
||||
}
|
||||
|
||||
// Copy a sub part of a texture into another
|
||||
|
@ -622,12 +621,19 @@ void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
|
|||
return;
|
||||
}
|
||||
|
||||
// This function is useless on opengl. The only call I found copy the whole texture data to another one
|
||||
assert(0);
|
||||
|
||||
// GL_NV_copy_image seem like the good extension but not supported on AMD...
|
||||
// Maybe opengl 4.3 !
|
||||
// FIXME check those function work as expected
|
||||
|
||||
// Set the input of glCopyTexSubImage2D
|
||||
static_cast<GSTextureOGL*>(st)->Attach(GL_COLOR_ATTACHMENT1);
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT1);
|
||||
|
||||
// Copy the full image
|
||||
static_cast<GSTextureOGL*>(dt)->EnableUnit(0);
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, dt->GetWidth(), dt->GetHeight());
|
||||
|
||||
#if 0
|
||||
// FIXME attach the texture to the FBO
|
||||
GSTextureOGL* st_ogl = (GSTextureOGL*) st;
|
||||
GSTextureOGL* dt_ogl = (GSTextureOGL*) dt;
|
||||
|
@ -643,6 +649,7 @@ void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
|
|||
//glCopyTexSubImage2D(dt_ogl.m_texture_target, 0, 0, 0, r.left, r.bottom, r.right-r.left, r.top-r.bottom);
|
||||
// FIXME I'm not sure GL_TEXTURE_RECTANGLE is supported!!!
|
||||
//glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE, 0, 0, 0, r.left, r.bottom, r.right-r.left, r.top-r.bottom);
|
||||
#endif
|
||||
#if 0
|
||||
D3D11_BOX box = {r.left, r.top, 0, r.right, r.bottom, 1};
|
||||
m_ctx->CopySubresourceRegion(*(GSTexture11*)dt, 0, 0, 0, 0, *(GSTexture11*)st, 0, &box);
|
||||
|
@ -819,7 +826,7 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
|
|||
|
||||
// gs
|
||||
|
||||
GSSetShader(NULL);
|
||||
GSSetShader(0);
|
||||
|
||||
// ps
|
||||
|
||||
|
@ -1153,7 +1160,7 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st
|
|||
// 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;
|
||||
std::string header = version + shader_type + entry_main + macro_sel;
|
||||
|
||||
// *****************************************************
|
||||
// Read the source file
|
||||
|
|
|
@ -30,11 +30,9 @@ GSTextureCacheOGL::GSTextureCacheOGL(GSRenderer* r)
|
|||
|
||||
void GSTextureCacheOGL::Read(Target* t, const GSVector4i& r)
|
||||
{
|
||||
// Except format (CopyOffscreen method), everything else seem portable
|
||||
#if 0
|
||||
if(t->m_type != RenderTarget)
|
||||
{
|
||||
// TODO
|
||||
assert(0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -63,7 +61,10 @@ void GSTextureCacheOGL::Read(Target* t, const GSVector4i& r)
|
|||
|
||||
GSVector4 src = GSVector4(r) * GSVector4(t->m_texture->GetScale()).xyxy() / GSVector4(t->m_texture->GetSize()).xyxy();
|
||||
|
||||
GLuint format = TEX0.PSM == PSM_PSMCT16 || TEX0.PSM == PSM_PSMCT16S ? GL_R16UI : GL_RGBA8;
|
||||
#if 0
|
||||
DXGI_FORMAT format = TEX0.PSM == PSM_PSMCT16 || TEX0.PSM == PSM_PSMCT16S ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
#endif
|
||||
|
||||
if(GSTexture* offscreen = m_renderer->m_dev->CopyOffscreen(t->m_texture, src, w, h, format))
|
||||
{
|
||||
|
@ -94,8 +95,7 @@ void GSTextureCacheOGL::Read(Target* t, const GSVector4i& r)
|
|||
offscreen->Unmap();
|
||||
}
|
||||
|
||||
m_renderer->m_dev->Recycle(offscreen);
|
||||
//m_renderer->m_dev->Recycle(offscreen);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ static uint g_state_texture_id = 0;
|
|||
GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format)
|
||||
: m_texture_unit(0),
|
||||
m_extra_buffer_id(0),
|
||||
m_extra_buffer_allocated(false)
|
||||
m_pbo_size(0)
|
||||
{
|
||||
// *************************************************************
|
||||
// Opengl world
|
||||
|
@ -83,6 +83,16 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format)
|
|||
|
||||
// Generate the buffer
|
||||
switch (m_type) {
|
||||
case GSTexture::Offscreen:
|
||||
//FIXME I not sure we need a pixel buffer object. It seems more a texture
|
||||
// glGenBuffers(1, &m_texture_id);
|
||||
// m_texture_target = GL_PIXEL_UNPACK_BUFFER;
|
||||
// assert(0);
|
||||
// Note there is also a buffer texture!!!
|
||||
// http://www.opengl.org/wiki/Buffer_Texture
|
||||
// Note: in this case it must use in GLSL
|
||||
// gvec texelFetch(gsampler sampler, ivec texCoord, int lod[, int sample]);
|
||||
// corollary we can maybe use it for multisample stuff
|
||||
case GSTexture::Texture:
|
||||
case GSTexture::RenderTarget:
|
||||
glGenTextures(1, &m_texture_id);
|
||||
|
@ -92,16 +102,6 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format)
|
|||
glGenRenderbuffers(1, &m_texture_id);
|
||||
m_texture_target = GL_RENDERBUFFER;
|
||||
break;
|
||||
case GSTexture::Offscreen:
|
||||
//FIXME I not sure we need a pixel buffer object. It seems more a texture
|
||||
// glGenBuffers(1, &m_texture_id);
|
||||
// m_texture_target = GL_PIXEL_UNPACK_BUFFER;
|
||||
assert(0);
|
||||
// Note there is also a buffer texture!!!
|
||||
// http://www.opengl.org/wiki/Buffer_Texture
|
||||
// Note: in this case it must use in GLSL
|
||||
// gvec texelFetch(gsampler sampler, ivec texCoord, int lod[, int sample]);
|
||||
// corollary we can maybe use it for multisample stuff
|
||||
break;
|
||||
case GSTexture::Backbuffer:
|
||||
m_texture_target = 0;
|
||||
|
@ -140,7 +140,12 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format)
|
|||
assert(0); // TODO Later
|
||||
break;
|
||||
case GSTexture::Offscreen:
|
||||
assert(0);
|
||||
if (m_type == GL_RGBA8) m_pbo_size = m_size.x * m_size.y * 4;
|
||||
else if (m_type == GL_R16UI) m_pbo_size = m_size.x * m_size.y * 2;
|
||||
else assert(0);
|
||||
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_extra_buffer_id);
|
||||
glBufferData(GL_PIXEL_PACK_BUFFER, m_pbo_size, NULL, GL_STREAM_DRAW);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
@ -197,19 +202,18 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
|
|||
// The case appears on SW mode. Src pitch is 2x dst pitch.
|
||||
int rowbytes = r.width() << 2;
|
||||
if (pitch != rowbytes) {
|
||||
uint32 pbo_size = m_size.x * m_size.y * 4;
|
||||
uint32 map_flags = GL_MAP_WRITE_BIT;
|
||||
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_extra_buffer_id);
|
||||
if (!m_extra_buffer_allocated) {
|
||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, pbo_size, NULL, GL_STREAM_DRAW);
|
||||
m_extra_buffer_allocated = true;
|
||||
if (!m_pbo_size) {
|
||||
m_pbo_size = m_size.x * m_size.y * 4;
|
||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, m_pbo_size, NULL, GL_STREAM_DRAW);
|
||||
} else {
|
||||
GL_MAP_INVALIDATE_BUFFER_BIT;
|
||||
}
|
||||
|
||||
uint8* src = (uint8*) data;
|
||||
uint8* dst = (uint8*) glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, pbo_size, map_flags);
|
||||
uint8* dst = (uint8*) glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, m_pbo_size, map_flags);
|
||||
for(int h = r.height(); h > 0; h--, src += pitch, dst += rowbytes)
|
||||
{
|
||||
memcpy(dst, src, rowbytes);
|
||||
|
@ -274,6 +278,26 @@ bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
|
|||
//
|
||||
// glMapBuffer — map a buffer object's data store
|
||||
// Can be used on GL_PIXEL_UNPACK_BUFFER or GL_TEXTURE_BUFFER
|
||||
if (m_type == GSTexture::Offscreen) {
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_extra_buffer_id);
|
||||
// FIXME It might be possible to only map a subrange of the texture based on r object
|
||||
|
||||
// Load the PBO
|
||||
if (m_format == GL_R16UI)
|
||||
glReadPixels(0, 0, m_size.x, m_size.y, GL_RED, GL_UNSIGNED_SHORT, 0);
|
||||
else if (m_format == GL_RGBA8)
|
||||
glReadPixels(0, 0, m_size.x, m_size.y, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
else
|
||||
assert(0);
|
||||
|
||||
// Give access from the CPU
|
||||
uint32 map_flags = GL_MAP_READ_BIT;
|
||||
m.bits = (uint8*) glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, m_pbo_size, map_flags);
|
||||
m.pitch = m_size.x;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
#if 0
|
||||
if(r != NULL)
|
||||
|
@ -302,14 +326,9 @@ bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
|
|||
|
||||
void GSTextureOGL::Unmap()
|
||||
{
|
||||
// copy the texture to the GPU
|
||||
// GLboolean glUnmapBuffer(GLenum target);
|
||||
#if 0
|
||||
if(m_texture)
|
||||
{
|
||||
m_ctx->Unmap(m_texture, 0);
|
||||
if (m_type == GSTexture::Offscreen) {
|
||||
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef _WINDOWS
|
||||
|
@ -358,13 +377,13 @@ bool GSTextureOGL::Save(const string& fn, bool dds)
|
|||
|
||||
// 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 {
|
||||
if (IsBackbuffer()) {
|
||||
// TODO backbuffer
|
||||
glReadBuffer(GL_BACK);
|
||||
glReadPixels(0, 0, m_size.x, m_size.y, GL_RGBA, GL_UNSIGNED_BYTE, image);
|
||||
} else {
|
||||
EnableUnit(0);
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
|
||||
}
|
||||
|
||||
// Build a BMP file
|
||||
|
|
|
@ -30,7 +30,7 @@ class GSTextureOGL : public GSTexture
|
|||
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;
|
||||
int m_pbo_size;
|
||||
|
||||
public:
|
||||
explicit GSTextureOGL(int type, int w, int h, bool msaa, int format);
|
||||
|
|
Loading…
Reference in New Issue