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)
|
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);
|
glClearBufferfv(GL_DEPTH, 0, &c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 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;
|
GLint color = c;
|
||||||
|
// FIXME can you clean depth and stencil separately
|
||||||
glClearBufferiv(GL_STENCIL, 0, &color);
|
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
|
// blit a texture into an offscreen buffer
|
||||||
GSTexture* GSDeviceOGL::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format)
|
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;
|
GSTexture* dst = NULL;
|
||||||
|
|
||||||
if(format == 0)
|
if(format == 0) format = GL_RGBA8;
|
||||||
{
|
|
||||||
format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(format != DXGI_FORMAT_R8G8B8A8_UNORM && format != DXGI_FORMAT_R16_UINT)
|
if(format != GL_RGBA8 && format != GL_R16UI)
|
||||||
{
|
{
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
|
|
||||||
return false;
|
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);
|
GSVector4 dr(0, 0, w, h);
|
||||||
|
|
||||||
if(GSTexture* src2 = src->IsMSAA() ? Resolve(src) : src)
|
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(src2 != src) Recycle(src2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
dst = CreateOffscreen(w, h, format);
|
dst = CreateOffscreen(w, h, format);
|
||||||
|
|
||||||
if(dst)
|
if(dst)
|
||||||
{
|
{
|
||||||
m_ctx->CopyResource(*(GSTexture11*)dst, *(GSTexture11*)rt);
|
m_ctx->CopyResource(*(GSTexture11*)dst, *(GSTexture11*)rt);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Recycle(rt);
|
Recycle(rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dst;
|
//return dst;
|
||||||
#endif
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy a sub part of a texture into another
|
// Copy a sub part of a texture into another
|
||||||
|
@ -622,12 +621,19 @@ void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
|
||||||
return;
|
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...
|
// GL_NV_copy_image seem like the good extension but not supported on AMD...
|
||||||
// Maybe opengl 4.3 !
|
// 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
|
// 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;
|
||||||
|
@ -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);
|
//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!!!
|
// 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);
|
//glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE, 0, 0, 0, r.left, r.bottom, r.right-r.left, r.top-r.bottom);
|
||||||
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
D3D11_BOX box = {r.left, r.top, 0, r.right, r.bottom, 1};
|
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);
|
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
|
// gs
|
||||||
|
|
||||||
GSSetShader(NULL);
|
GSSetShader(0);
|
||||||
|
|
||||||
// ps
|
// ps
|
||||||
|
|
||||||
|
@ -1153,7 +1160,7 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st
|
||||||
// Select the entry point ie the main function
|
// 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;
|
std::string header = version + shader_type + entry_main + macro_sel;
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// Read the source file
|
// Read the source file
|
||||||
|
|
|
@ -30,11 +30,9 @@ GSTextureCacheOGL::GSTextureCacheOGL(GSRenderer* r)
|
||||||
|
|
||||||
void GSTextureCacheOGL::Read(Target* t, const GSVector4i& r)
|
void GSTextureCacheOGL::Read(Target* t, const GSVector4i& r)
|
||||||
{
|
{
|
||||||
// Except format (CopyOffscreen method), everything else seem portable
|
|
||||||
#if 0
|
|
||||||
if(t->m_type != RenderTarget)
|
if(t->m_type != RenderTarget)
|
||||||
{
|
{
|
||||||
// TODO
|
assert(0);
|
||||||
|
|
||||||
return;
|
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();
|
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;
|
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))
|
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();
|
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)
|
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_id(0),
|
||||||
m_extra_buffer_allocated(false)
|
m_pbo_size(0)
|
||||||
{
|
{
|
||||||
// *************************************************************
|
// *************************************************************
|
||||||
// Opengl world
|
// Opengl world
|
||||||
|
@ -83,6 +83,16 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format)
|
||||||
|
|
||||||
// Generate the buffer
|
// Generate the buffer
|
||||||
switch (m_type) {
|
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::Texture:
|
||||||
case GSTexture::RenderTarget:
|
case GSTexture::RenderTarget:
|
||||||
glGenTextures(1, &m_texture_id);
|
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);
|
glGenRenderbuffers(1, &m_texture_id);
|
||||||
m_texture_target = GL_RENDERBUFFER;
|
m_texture_target = GL_RENDERBUFFER;
|
||||||
break;
|
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;
|
break;
|
||||||
case GSTexture::Backbuffer:
|
case GSTexture::Backbuffer:
|
||||||
m_texture_target = 0;
|
m_texture_target = 0;
|
||||||
|
@ -140,7 +140,12 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format)
|
||||||
assert(0); // TODO Later
|
assert(0); // TODO Later
|
||||||
break;
|
break;
|
||||||
case GSTexture::Offscreen:
|
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;
|
break;
|
||||||
default: 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.
|
// The case appears on SW mode. Src pitch is 2x dst pitch.
|
||||||
int rowbytes = r.width() << 2;
|
int rowbytes = r.width() << 2;
|
||||||
if (pitch != rowbytes) {
|
if (pitch != rowbytes) {
|
||||||
uint32 pbo_size = m_size.x * m_size.y * 4;
|
|
||||||
uint32 map_flags = GL_MAP_WRITE_BIT;
|
uint32 map_flags = GL_MAP_WRITE_BIT;
|
||||||
|
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_extra_buffer_id);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_extra_buffer_id);
|
||||||
if (!m_extra_buffer_allocated) {
|
if (!m_pbo_size) {
|
||||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, pbo_size, NULL, GL_STREAM_DRAW);
|
m_pbo_size = m_size.x * m_size.y * 4;
|
||||||
m_extra_buffer_allocated = true;
|
glBufferData(GL_PIXEL_UNPACK_BUFFER, m_pbo_size, NULL, GL_STREAM_DRAW);
|
||||||
} else {
|
} else {
|
||||||
GL_MAP_INVALIDATE_BUFFER_BIT;
|
GL_MAP_INVALIDATE_BUFFER_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8* src = (uint8*) data;
|
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)
|
for(int h = r.height(); h > 0; h--, src += pitch, dst += rowbytes)
|
||||||
{
|
{
|
||||||
memcpy(dst, src, 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
|
// glMapBuffer — map a buffer object's data store
|
||||||
// Can be used on GL_PIXEL_UNPACK_BUFFER or GL_TEXTURE_BUFFER
|
// 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;
|
return false;
|
||||||
#if 0
|
#if 0
|
||||||
if(r != NULL)
|
if(r != NULL)
|
||||||
|
@ -302,14 +326,9 @@ bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
|
||||||
|
|
||||||
void GSTextureOGL::Unmap()
|
void GSTextureOGL::Unmap()
|
||||||
{
|
{
|
||||||
// copy the texture to the GPU
|
if (m_type == GSTexture::Offscreen) {
|
||||||
// GLboolean glUnmapBuffer(GLenum target);
|
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
||||||
#if 0
|
|
||||||
if(m_texture)
|
|
||||||
{
|
|
||||||
m_ctx->Unmap(m_texture, 0);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WINDOWS
|
#ifndef _WINDOWS
|
||||||
|
@ -358,13 +377,13 @@ bool GSTextureOGL::Save(const string& fn, bool dds)
|
||||||
|
|
||||||
// Collect the texture data
|
// Collect the texture data
|
||||||
char* image = (char*)malloc(4 * m_size.x * m_size.y);
|
char* image = (char*)malloc(4 * m_size.x * m_size.y);
|
||||||
if (m_type) {
|
if (IsBackbuffer()) {
|
||||||
EnableUnit(0);
|
|
||||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
|
|
||||||
} else {
|
|
||||||
// TODO backbuffer
|
// TODO backbuffer
|
||||||
glReadBuffer(GL_BACK);
|
glReadBuffer(GL_BACK);
|
||||||
glReadPixels(0, 0, m_size.x, m_size.y, GL_RGBA, GL_UNSIGNED_BYTE, image);
|
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
|
// Build a BMP file
|
||||||
|
|
|
@ -30,7 +30,7 @@ class GSTextureOGL : public GSTexture
|
||||||
GLuint m_texture_id; // the texture id
|
GLuint m_texture_id; // the texture id
|
||||||
uint m_texture_unit; // the texture unit offset
|
uint m_texture_unit; // the texture unit offset
|
||||||
uint m_extra_buffer_id;
|
uint m_extra_buffer_id;
|
||||||
bool m_extra_buffer_allocated;
|
int m_pbo_size;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GSTextureOGL(int type, int w, int h, bool msaa, int format);
|
explicit GSTextureOGL(int type, int w, int h, bool msaa, int format);
|
||||||
|
|
Loading…
Reference in New Issue