mirror of https://github.com/PCSX2/pcsx2.git
gsdx ogl:
* allow to switch renderer with F9 * skip first frame in stat of the replayer * drop msaa. Fxaa and internal resolution will do the job * move texture attachment from texture object into device object (allow to keep sanely the state) * split the write buffer and attachment setup * completely split sampler and texture input setup * redo GSDeviceOGL::CopyOffscreen to avoid an extra copy. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5704 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
92487e2618
commit
d3e1e4da0d
|
@ -429,9 +429,17 @@ EXPORT_C_(int) GSopen2(void** dsp, uint32 flags)
|
||||||
case 0: renderer = 1; break; // DX9: HW to SW
|
case 0: renderer = 1; break; // DX9: HW to SW
|
||||||
case 4: renderer = 3; break; // DX11: SW to HW
|
case 4: renderer = 3; break; // DX11: SW to HW
|
||||||
case 3: renderer = 4; break; // DX11: HW to SW
|
case 3: renderer = 4; break; // DX11: HW to SW
|
||||||
|
case 13: renderer = 12; break; // OGL: SW to HW
|
||||||
|
case 12: renderer = 13; break; // OGL: HW to SW
|
||||||
default: renderer = best_sw_renderer; // If wasn't using DX (e.g. SDL), use best SW renderer.
|
default: renderer = best_sw_renderer; // If wasn't using DX (e.g. SDL), use best SW renderer.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#ifdef _LINUX
|
||||||
|
switch(renderer) {
|
||||||
|
case 13: renderer = 12; break; // OGL: SW to HW
|
||||||
|
case 12: renderer = 13; break; // OGL: HW to SW
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1594,15 +1602,18 @@ EXPORT_C GSReplay(char* lpszCmdLine, int renderer)
|
||||||
finished--;
|
finished--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (theApp.GetConfig("linux_replay", 1) > 1) {
|
||||||
// Print some nice stats
|
// Print some nice stats
|
||||||
float n = (float)theApp.GetConfig("linux_replay", 1);
|
// Skip first frame (shader compilation populate the result)
|
||||||
|
// it divides by 10 the standard deviation...
|
||||||
|
float n = (float)theApp.GetConfig("linux_replay", 1) - 1.0f;
|
||||||
float mean = 0;
|
float mean = 0;
|
||||||
float sd = 0;
|
float sd = 0;
|
||||||
for (auto i = stats.begin(); i != stats.end(); i++) {
|
for (auto i = stats.begin()+1; i != stats.end(); i++) {
|
||||||
mean += *i;
|
mean += *i;
|
||||||
}
|
}
|
||||||
mean = mean/n;
|
mean = mean/n;
|
||||||
for (auto i = stats.begin(); i != stats.end(); i++) {
|
for (auto i = stats.begin()+1; i != stats.end(); i++) {
|
||||||
sd += pow((*i)-mean, 2);
|
sd += pow((*i)-mean, 2);
|
||||||
}
|
}
|
||||||
sd = sqrt(sd/n);
|
sd = sqrt(sd/n);
|
||||||
|
@ -1611,6 +1622,7 @@ EXPORT_C GSReplay(char* lpszCmdLine, int renderer)
|
||||||
fprintf(stderr, "Standard deviation: %fms\n", sd);
|
fprintf(stderr, "Standard deviation: %fms\n", sd);
|
||||||
fprintf(stderr, "Mean by frame: %fms (%ffps)\n", mean/(float)frame_number, 1000.0f*frame_number/mean);
|
fprintf(stderr, "Mean by frame: %fms (%ffps)\n", mean/(float)frame_number, 1000.0f*frame_number/mean);
|
||||||
fprintf(stderr, "Standard deviatin by frame: %fms\n", sd/(float)frame_number);
|
fprintf(stderr, "Standard deviatin by frame: %fms\n", sd/(float)frame_number);
|
||||||
|
}
|
||||||
|
|
||||||
for(auto i = packets.begin(); i != packets.end(); i++)
|
for(auto i = packets.begin(); i != packets.end(); i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,10 +24,6 @@
|
||||||
|
|
||||||
#include "res/glsl_source.h"
|
#include "res/glsl_source.h"
|
||||||
|
|
||||||
// TODO performance cost to investigate
|
|
||||||
// Texture attachment/glDrawBuffer. For the moment it set every draw and potentially multiple time (first time in clear, second time in rendering)
|
|
||||||
// Attachment 1 is only used with the GL_16UI format
|
|
||||||
|
|
||||||
//#define LOUD_DEBUGGING
|
//#define LOUD_DEBUGGING
|
||||||
//#define PRINT_FRAME_NUMBER
|
//#define PRINT_FRAME_NUMBER
|
||||||
//#define ONLY_LINES
|
//#define ONLY_LINES
|
||||||
|
@ -54,8 +50,6 @@ GSDeviceOGL::GSDeviceOGL()
|
||||||
, m_vb_sr(NULL)
|
, m_vb_sr(NULL)
|
||||||
, m_shader(NULL)
|
, m_shader(NULL)
|
||||||
{
|
{
|
||||||
m_msaa = !!theApp.GetConfig("UserHacks", 0) ? theApp.GetConfig("UserHacks_MSAA", 0) : 0;
|
|
||||||
|
|
||||||
memset(&m_merge_obj, 0, sizeof(m_merge_obj));
|
memset(&m_merge_obj, 0, sizeof(m_merge_obj));
|
||||||
memset(&m_interlace, 0, sizeof(m_interlace));
|
memset(&m_interlace, 0, sizeof(m_interlace));
|
||||||
memset(&m_convert, 0, sizeof(m_convert));
|
memset(&m_convert, 0, sizeof(m_convert));
|
||||||
|
@ -143,7 +137,7 @@ GSTexture* GSDeviceOGL::CreateSurface(int type, int w, int h, bool msaa, int for
|
||||||
{
|
{
|
||||||
// A wrapper to call GSTextureOGL, with the different kind of parameter
|
// A wrapper to call GSTextureOGL, with the different kind of parameter
|
||||||
GSTextureOGL* t = NULL;
|
GSTextureOGL* t = NULL;
|
||||||
t = new GSTextureOGL(type, w, h, msaa, format, m_fbo_read);
|
t = new GSTextureOGL(type, w, h, format, m_fbo_read);
|
||||||
|
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
|
@ -152,7 +146,7 @@ GSTexture* GSDeviceOGL::CreateSurface(int type, int w, int h, bool msaa, int for
|
||||||
break;
|
break;
|
||||||
case GSTexture::DepthStencil:
|
case GSTexture::DepthStencil:
|
||||||
ClearDepth(t, 0);
|
ClearDepth(t, 0);
|
||||||
//FIXME might be need to clear the stencil too
|
// No need to clear the stencil now.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
|
@ -160,16 +154,7 @@ GSTexture* GSDeviceOGL::CreateSurface(int type, int w, int h, bool msaa, int for
|
||||||
|
|
||||||
GSTexture* GSDeviceOGL::FetchSurface(int type, int w, int h, bool msaa, int format)
|
GSTexture* GSDeviceOGL::FetchSurface(int type, int w, int h, bool msaa, int format)
|
||||||
{
|
{
|
||||||
// FIXME: keep DX code. Do not know how work msaa but not important for the moment
|
return GSDevice::FetchSurface(type, w, h, false, format);
|
||||||
// Current config give only 0 or 1
|
|
||||||
#if 0
|
|
||||||
if(m_msaa < 2) {
|
|
||||||
msaa = false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
msaa = false;
|
|
||||||
|
|
||||||
return GSDevice::FetchSurface(type, w, h, msaa, format);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GSDeviceOGL::Create(GSWnd* wnd)
|
bool GSDeviceOGL::Create(GSWnd* wnd)
|
||||||
|
@ -180,9 +165,6 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
||||||
if (!GLLoader::check_gl_supported_extension()) return false;
|
if (!GLLoader::check_gl_supported_extension()) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME disable it when code is ready
|
|
||||||
// glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
|
|
||||||
|
|
||||||
m_window = wnd;
|
m_window = wnd;
|
||||||
|
|
||||||
// ****************************************************************
|
// ****************************************************************
|
||||||
|
@ -281,7 +263,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ****************************************************************
|
// ****************************************************************
|
||||||
// fxaa (bonus)
|
// fxaa
|
||||||
// ****************************************************************
|
// ****************************************************************
|
||||||
std::string fxaa_macro = "#define FXAA_GLSL_130 1\n";
|
std::string fxaa_macro = "#define FXAA_GLSL_130 1\n";
|
||||||
if (GLLoader::found_GL_ARB_gpu_shader5) {
|
if (GLLoader::found_GL_ARB_gpu_shader5) {
|
||||||
|
@ -320,59 +302,6 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
||||||
GSVector4i rect = wnd->GetClientRect();
|
GSVector4i rect = wnd->GetClientRect();
|
||||||
Reset(rect.z, rect.w);
|
Reset(rect.z, rect.w);
|
||||||
|
|
||||||
#if 0
|
|
||||||
HRESULT hr = E_FAIL;
|
|
||||||
|
|
||||||
DXGI_SWAP_CHAIN_DESC scd;
|
|
||||||
D3D11_BUFFER_DESC bd;
|
|
||||||
D3D11_SAMPLER_DESC sd;
|
|
||||||
D3D11_DEPTH_STENCIL_DESC dsd;
|
|
||||||
D3D11_RASTERIZER_DESC rd;
|
|
||||||
D3D11_BLEND_DESC bsd;
|
|
||||||
|
|
||||||
memset(&scd, 0, sizeof(scd));
|
|
||||||
|
|
||||||
scd.BufferCount = 2;
|
|
||||||
scd.BufferDesc.Width = 1;
|
|
||||||
scd.BufferDesc.Height = 1;
|
|
||||||
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
||||||
//scd.BufferDesc.RefreshRate.Numerator = 60;
|
|
||||||
//scd.BufferDesc.RefreshRate.Denominator = 1;
|
|
||||||
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
|
||||||
scd.OutputWindow = (HWND)m_wnd->GetHandle();
|
|
||||||
scd.SampleDesc.Count = 1;
|
|
||||||
scd.SampleDesc.Quality = 0;
|
|
||||||
|
|
||||||
// Always start in Windowed mode. According to MS, DXGI just "prefers" this, and it's more or less
|
|
||||||
// required if we want to add support for dual displays later on. The fullscreen/exclusive flip
|
|
||||||
// will be issued after all other initializations are complete.
|
|
||||||
|
|
||||||
scd.Windowed = TRUE;
|
|
||||||
|
|
||||||
// NOTE : D3D11_CREATE_DEVICE_SINGLETHREADED
|
|
||||||
// This flag is safe as long as the DXGI's internal message pump is disabled or is on the
|
|
||||||
// same thread as the GS window (which the emulator makes sure of, if it utilizes a
|
|
||||||
// multithreaded GS). Setting the flag is a nice and easy 5% speedup on GS-intensive scenes.
|
|
||||||
|
|
||||||
uint32 flags = D3D11_CREATE_DEVICE_SINGLETHREADED;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
flags |= D3D11_CREATE_DEVICE_DEBUG;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
D3D_FEATURE_LEVEL level;
|
|
||||||
|
|
||||||
const D3D_FEATURE_LEVEL levels[] =
|
|
||||||
{
|
|
||||||
D3D_FEATURE_LEVEL_11_0,
|
|
||||||
D3D_FEATURE_LEVEL_10_1,
|
|
||||||
D3D_FEATURE_LEVEL_10_0,
|
|
||||||
};
|
|
||||||
|
|
||||||
hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, levels, countof(levels), D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &level, &m_ctx);
|
|
||||||
// hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, flags, NULL, 0, D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &level, &m_ctx);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,7 +314,7 @@ bool GSDeviceOGL::Reset(int w, int h)
|
||||||
// Opengl allocate the backbuffer with the window. The render is done in the backbuffer when
|
// Opengl allocate the backbuffer with the window. The render is done in the backbuffer when
|
||||||
// there isn't any FBO. Only a dummy texture is created to easily detect when the rendering is done
|
// there isn't any FBO. Only a dummy texture is created to easily detect when the rendering is done
|
||||||
// in the backbuffer
|
// in the backbuffer
|
||||||
m_backbuffer = new GSTextureOGL(GSTextureOGL::Backbuffer, w, h, false, 0, m_fbo_read);
|
m_backbuffer = new GSTextureOGL(GSTextureOGL::Backbuffer, w, h, 0, m_fbo_read);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -458,7 +387,9 @@ void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
||||||
gl_ClearBufferfv(GL_COLOR, 0, c.v);
|
gl_ClearBufferfv(GL_COLOR, 0, c.v);
|
||||||
} else {
|
} else {
|
||||||
OMSetFBO(m_fbo);
|
OMSetFBO(m_fbo);
|
||||||
static_cast<GSTextureOGL*>(t)->Attach(GL_COLOR_ATTACHMENT0);
|
// FIXME useful
|
||||||
|
OMSetWriteBuffer();
|
||||||
|
OMAttachRt(t);
|
||||||
|
|
||||||
gl_ClearBufferfv(GL_COLOR, 0, c.v);
|
gl_ClearBufferfv(GL_COLOR, 0, c.v);
|
||||||
}
|
}
|
||||||
|
@ -474,7 +405,9 @@ void GSDeviceOGL::ClearRenderTarget(GSTexture* t, uint32 c)
|
||||||
void GSDeviceOGL::ClearDepth(GSTexture* t, float c)
|
void GSDeviceOGL::ClearDepth(GSTexture* t, float c)
|
||||||
{
|
{
|
||||||
OMSetFBO(m_fbo);
|
OMSetFBO(m_fbo);
|
||||||
static_cast<GSTextureOGL*>(t)->Attach(GL_DEPTH_STENCIL_ATTACHMENT);
|
// FIXME useful
|
||||||
|
OMSetWriteBuffer();
|
||||||
|
OMAttachDs(t);
|
||||||
|
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
if (m_state.dss != NULL && m_state.dss->IsMaskEnable()) {
|
if (m_state.dss != NULL && m_state.dss->IsMaskEnable()) {
|
||||||
|
@ -490,7 +423,9 @@ void GSDeviceOGL::ClearDepth(GSTexture* t, float c)
|
||||||
void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c)
|
void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c)
|
||||||
{
|
{
|
||||||
OMSetFBO(m_fbo);
|
OMSetFBO(m_fbo);
|
||||||
static_cast<GSTextureOGL*>(t)->Attach(GL_DEPTH_STENCIL_ATTACHMENT);
|
// FIXME useful
|
||||||
|
OMSetWriteBuffer();
|
||||||
|
OMAttachDs(t);
|
||||||
GLint color = c;
|
GLint color = c;
|
||||||
|
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
@ -608,48 +543,19 @@ 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)
|
||||||
{
|
{
|
||||||
GSTexture* dst = NULL;
|
ASSERT(src);
|
||||||
|
ASSERT(format == GL_RGBA8 || format == GL_R16UI);
|
||||||
|
|
||||||
if(format == 0) format = GL_RGBA8;
|
if(format == 0) format = GL_RGBA8;
|
||||||
|
|
||||||
if(format != GL_RGBA8 && format != GL_R16UI)
|
if(format != GL_RGBA8 && format != GL_R16UI) return NULL;
|
||||||
{
|
|
||||||
ASSERT(0);
|
|
||||||
|
|
||||||
return NULL;
|
GSTexture* dst = CreateOffscreen(w, h, format);
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: It is possible to bypass completely offscreen-buffer on opengl but it needs some re-thinking of the code.
|
|
||||||
// For the moment mimic dx11
|
|
||||||
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)
|
StretchRect(src, sr, dst, dr, m_convert.ps[format == GL_R16UI ? 1 : 0]);
|
||||||
{
|
|
||||||
StretchRect(src2, sr, rt, dr, m_convert.ps[format == GL_R16UI ? 1 : 0]);
|
|
||||||
|
|
||||||
if(src2 != src) Recycle(src2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GSVector4i dor(0, 0, w, h);
|
|
||||||
dst = CreateOffscreen(w, h, format);
|
|
||||||
|
|
||||||
if (dst) CopyRect(rt, dst, dor);
|
|
||||||
#if 0
|
|
||||||
if(dst)
|
|
||||||
{
|
|
||||||
m_ctx->CopyResource(*(GSTexture11*)dst, *(GSTexture11*)rt);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Recycle(rt);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dst;
|
return dst;
|
||||||
//return rt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy a sub part of a texture into another
|
// Copy a sub part of a texture into another
|
||||||
|
@ -658,32 +564,23 @@ GSTexture* GSDeviceOGL::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w
|
||||||
// From a sub-part to a full texture
|
// From a sub-part to a full texture
|
||||||
void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
|
void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
|
||||||
{
|
{
|
||||||
if(!st || !dt)
|
ASSERT(st && dt);
|
||||||
{
|
|
||||||
ASSERT(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: the extension was integrated in opengl 4.3 (now we need driver that support OGL4.3)
|
// FIXME: the extension was integrated in opengl 4.3 (now we need driver that support OGL4.3)
|
||||||
// FIXME check those function work as expected
|
|
||||||
// void CopyImageSubDataNV(
|
|
||||||
// uint32 srcName, enum srcTarget, int srcLevel, int srcX, int srcY, int srcZ,
|
|
||||||
// uint32 dstName, enum dstTarget, int dstLevel, int dstX, int dstY, int dstZ,
|
|
||||||
// sizei width, sizei height, sizei depth);
|
|
||||||
if (GLLoader::found_GL_NV_copy_image) {
|
if (GLLoader::found_GL_NV_copy_image) {
|
||||||
#ifndef ENABLE_GLES
|
#ifndef ENABLE_GLES
|
||||||
gl_CopyImageSubDataNV( static_cast<GSTextureOGL*>(st)->GetID(), static_cast<GSTextureOGL*>(st)->GetTarget(),
|
gl_CopyImageSubDataNV( static_cast<GSTextureOGL*>(st)->GetID(), GL_TEXTURE_2D,
|
||||||
0, r.x, r.y, 0,
|
0, r.x, r.y, 0,
|
||||||
static_cast<GSTextureOGL*>(dt)->GetID(), static_cast<GSTextureOGL*>(dt)->GetTarget(),
|
static_cast<GSTextureOGL*>(dt)->GetID(), GL_TEXTURE_2D,
|
||||||
0, r.x, r.y, 0,
|
0, r.x, r.y, 0,
|
||||||
r.width(), r.height(), 1);
|
r.width(), r.height(), 1);
|
||||||
#endif
|
#endif
|
||||||
} else if (GLLoader::found_GL_ARB_copy_image) {
|
} else if (GLLoader::found_GL_ARB_copy_image) {
|
||||||
// Would need an update of GL definition. For the moment it isn't supported by driver anyway.
|
// Would need an update of GL definition. For the moment it isn't supported by driver anyway.
|
||||||
#if 0
|
#if 0
|
||||||
gl_CopyImageSubData( static_cast<GSTextureOGL*>(st)->GetID(), static_cast<GSTextureOGL*>(st)->GetTarget(),
|
gl_CopyImageSubData( static_cast<GSTextureOGL*>(st)->GetID(), GL_TEXTURE_2D,
|
||||||
0, r.x, r.y, 0,
|
0, r.x, r.y, 0,
|
||||||
static_cast<GSTextureOGL*>(dt)->GetID(), static_cast<GSTextureOGL*>(dt)->GetTarget(),
|
static_cast<GSTextureOGL*>(dt)->GetID(), GL_TEXTURE_2D,
|
||||||
0, r.x, r.y, 0,
|
0, r.x, r.y, 0,
|
||||||
r.width(), r.height(), 1);
|
r.width(), r.height(), 1);
|
||||||
#endif
|
#endif
|
||||||
|
@ -694,17 +591,14 @@ void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
|
||||||
|
|
||||||
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
|
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
|
||||||
|
|
||||||
st_ogl->AttachRead(GL_COLOR_ATTACHMENT0);
|
gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, static_cast<GSTextureOGL*>(st_ogl)->GetID(), 0);
|
||||||
|
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
|
|
||||||
dt_ogl->EnableUnit(6);
|
dt_ogl->EnableUnit(6);
|
||||||
glCopyTexSubImage2D(dt_ogl->GetTarget(), 0, r.x, r.y, r.x, r.y, r.width(), r.height());
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, r.x, r.y, r.x, r.y, r.width(), r.height());
|
||||||
|
|
||||||
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#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);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader, bool linear)
|
void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader, bool linear)
|
||||||
|
@ -801,8 +695,8 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
|
||||||
// ps
|
// ps
|
||||||
// ************************************
|
// ************************************
|
||||||
|
|
||||||
PSSetShaderResources(st, NULL);
|
PSSetShaderResource(0, st);
|
||||||
PSSetSamplerState(linear ? m_convert.ln : m_convert.pt, 0);
|
PSSetSamplerState(0, linear ? m_convert.ln : m_convert.pt);
|
||||||
m_shader->PS(ps);
|
m_shader->PS(ps);
|
||||||
|
|
||||||
// ************************************
|
// ************************************
|
||||||
|
@ -815,8 +709,6 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
|
||||||
// ************************************
|
// ************************************
|
||||||
|
|
||||||
EndScene();
|
EndScene();
|
||||||
|
|
||||||
PSSetShaderResources(NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
@ -896,7 +788,7 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_OGL_STENCIL_DEBUG
|
#ifdef ENABLE_OGL_STENCIL_DEBUG
|
||||||
const GSVector2i& size = rt->GetSize();
|
const GSVector2i& size = rt->GetSize();
|
||||||
GSTexture* t = CreateRenderTarget(size.x, size.y, rt->IsMSAA());
|
GSTexture* t = CreateRenderTarget(size.x, size.y, false);
|
||||||
#else
|
#else
|
||||||
GSTexture* t = NULL;
|
GSTexture* t = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -928,10 +820,8 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
|
||||||
|
|
||||||
// ps
|
// ps
|
||||||
|
|
||||||
GSTexture* rt2 = rt->IsMSAA() ? Resolve(rt) : rt;
|
PSSetShaderResource(0, rt);
|
||||||
|
PSSetSamplerState(0, m_convert.pt);
|
||||||
PSSetShaderResources(rt2, NULL);
|
|
||||||
PSSetSamplerState(m_convert.pt, 0);
|
|
||||||
m_shader->PS(m_convert.ps[datm ? 2 : 3]);
|
m_shader->PS(m_convert.ps[datm ? 2 : 3]);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -943,31 +833,9 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
|
||||||
EndScene();
|
EndScene();
|
||||||
|
|
||||||
#ifdef ENABLE_OGL_STENCIL_DEBUG
|
#ifdef ENABLE_OGL_STENCIL_DEBUG
|
||||||
|
// FIXME invalidate data
|
||||||
Recycle(t);
|
Recycle(t);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(rt2 != rt) Recycle(rt2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy a multisample texture to a non-texture multisample. On opengl you need 2 FBO with different level of
|
|
||||||
// sample and then do a blit. Headach expected to for the moment just drop MSAA...
|
|
||||||
GSTexture* GSDeviceOGL::Resolve(GSTexture* t)
|
|
||||||
{
|
|
||||||
ASSERT(t != NULL && t->IsMSAA());
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
if(GSTexture* dst = CreateRenderTarget(t->GetWidth(), t->GetHeight(), false, t->GetFormat()))
|
|
||||||
{
|
|
||||||
dst->SetScale(t->GetScale());
|
|
||||||
|
|
||||||
m_ctx->ResolveSubresource(*(GSTexture11*)dst, 0, *(GSTexture11*)t, 0, (DXGI_FORMAT)t->GetFormat());
|
|
||||||
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::EndScene()
|
void GSDeviceOGL::EndScene()
|
||||||
|
@ -1018,53 +886,54 @@ void GSDeviceOGL::IASetPrimitiveTopology(GLenum topology)
|
||||||
m_state.vb->SetTopology(topology);
|
m_state.vb->SetTopology(topology);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
|
void GSDeviceOGL::PSSetShaderResource(const int i, GSTexture* sr)
|
||||||
{
|
{
|
||||||
PSSetShaderResource(0, sr0);
|
ASSERT(sr);
|
||||||
PSSetShaderResource(1, sr1);
|
|
||||||
//PSSetShaderResource(2, NULL);
|
static_cast<GSTextureOGL*>(sr)->EnableUnit(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::PSSetShaderResource(int i, GSTexture* sr)
|
void GSDeviceOGL::PSSetSamplerState(const int i, GLuint ss)
|
||||||
{
|
{
|
||||||
GSTextureOGL* srv = static_cast<GSTextureOGL*>(sr);
|
if (m_state.ps_ss[i] != ss) {
|
||||||
|
m_state.ps_ss[i] = ss;
|
||||||
if (m_state.ps_srv[i] != srv)
|
gl_BindSampler(i, ss);
|
||||||
{
|
|
||||||
m_state.ps_srv[i] = srv;
|
|
||||||
if (srv != NULL)
|
|
||||||
m_state.ps_srv[i]->EnableUnit(i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::PSSetSamplerState(GLuint ss0, GLuint ss1, GLuint ss2)
|
void GSDeviceOGL::OMAttachRt(GSTexture* rt)
|
||||||
{
|
{
|
||||||
if (m_state.ps_ss[0] != ss0) {
|
if (m_state.rt != rt) {
|
||||||
m_state.ps_ss[0] = ss0;
|
m_state.rt = rt;
|
||||||
gl_BindSampler(0, ss0);
|
gl_FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, static_cast<GSTextureOGL*>(rt)->GetID(), 0);
|
||||||
}
|
|
||||||
if (m_state.ps_ss[1] != ss1) {
|
|
||||||
m_state.ps_ss[1] = ss1;
|
|
||||||
gl_BindSampler(1, ss1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::OMSetFBO(GLuint fbo, GLenum buffer)
|
void GSDeviceOGL::OMAttachDs(GSTexture* ds)
|
||||||
|
{
|
||||||
|
if (m_state.ds != ds) {
|
||||||
|
m_state.ds = ds;
|
||||||
|
gl_FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, static_cast<GSTextureOGL*>(ds)->GetID(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSDeviceOGL::OMSetFBO(GLuint fbo)
|
||||||
{
|
{
|
||||||
if (m_state.fbo != fbo) {
|
if (m_state.fbo != fbo) {
|
||||||
m_state.fbo = fbo;
|
m_state.fbo = fbo;
|
||||||
gl_BindFramebuffer(GL_FRAMEBUFFER, fbo);
|
gl_BindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||||
// FIXME DEBUG
|
}
|
||||||
//if (fbo) fprintf(stderr, "FB status %x\n", gl_CheckFramebufferStatus(GL_FRAMEBUFFER));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note if m_fbo is 0, standard GL_BACK will be used instead
|
void GSDeviceOGL::OMSetWriteBuffer(GLenum buffer)
|
||||||
if (m_fbo && m_state.draw != buffer) {
|
{
|
||||||
|
// Note if fbo is 0, standard GL_BACK will be used instead
|
||||||
|
if (m_state.fbo && m_state.draw != buffer) {
|
||||||
m_state.draw = buffer;
|
m_state.draw = buffer;
|
||||||
|
|
||||||
GLenum target[1] = {buffer};
|
GLenum target[1] = {buffer};
|
||||||
gl_DrawBuffers(1, target);
|
gl_DrawBuffers(1, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref)
|
void GSDeviceOGL::OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref)
|
||||||
|
@ -1093,16 +962,18 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto
|
||||||
if (rt == NULL || !static_cast<GSTextureOGL*>(rt)->IsBackbuffer()) {
|
if (rt == NULL || !static_cast<GSTextureOGL*>(rt)->IsBackbuffer()) {
|
||||||
if (rt) {
|
if (rt) {
|
||||||
OMSetFBO(m_fbo);
|
OMSetFBO(m_fbo);
|
||||||
static_cast<GSTextureOGL*>(rt)->Attach(GL_COLOR_ATTACHMENT0);
|
OMSetWriteBuffer();
|
||||||
|
OMAttachRt(rt);
|
||||||
} else {
|
} else {
|
||||||
// Note: NULL rt is only used in DATE so far. Color writing is disabled
|
// Note: NULL rt is only used in DATE so far. Color writing is disabled
|
||||||
// on the blend setup
|
// on the blend setup
|
||||||
OMSetFBO(m_fbo, GL_NONE);
|
OMSetFBO(m_fbo);
|
||||||
|
OMSetWriteBuffer(GL_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: it must be done after OMSetFBO
|
// Note: it must be done after OMSetFBO
|
||||||
if (ds)
|
if (ds)
|
||||||
static_cast<GSTextureOGL*>(ds)->Attach(GL_DEPTH_STENCIL_ATTACHMENT);
|
OMAttachDs(ds);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Render in the backbuffer
|
// Render in the backbuffer
|
||||||
|
|
|
@ -43,7 +43,6 @@ class GSBlendStateOGL {
|
||||||
bool m_g_msk;
|
bool m_g_msk;
|
||||||
bool m_a_msk;
|
bool m_a_msk;
|
||||||
bool constant_factor;
|
bool constant_factor;
|
||||||
float debug_factor;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -104,7 +103,6 @@ public:
|
||||||
if (m_enable) {
|
if (m_enable) {
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
if (HasConstantFactor()) {
|
if (HasConstantFactor()) {
|
||||||
debug_factor = factor;
|
|
||||||
gl_BlendColor(factor, factor, factor, 0);
|
gl_BlendColor(factor, factor, factor, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,38 +112,6 @@ public:
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char* NameOfParam(GLenum p)
|
|
||||||
{
|
|
||||||
switch (p) {
|
|
||||||
case GL_FUNC_ADD: return "ADD";
|
|
||||||
case GL_FUNC_SUBTRACT: return "SUB";
|
|
||||||
case GL_FUNC_REVERSE_SUBTRACT: return "REV SUB";
|
|
||||||
case GL_ONE: return "ONE";
|
|
||||||
case GL_ZERO: return "ZERO";
|
|
||||||
#ifndef ENABLE_GLES
|
|
||||||
case GL_SRC1_ALPHA: return "SRC1 ALPHA";
|
|
||||||
case GL_ONE_MINUS_SRC1_ALPHA: return "1 - SRC1 ALPHA";
|
|
||||||
#endif
|
|
||||||
case GL_SRC_ALPHA: return "SRC ALPHA";
|
|
||||||
case GL_ONE_MINUS_DST_ALPHA: return "1 - DST ALPHA";
|
|
||||||
case GL_DST_ALPHA: return "DST ALPHA";
|
|
||||||
case GL_DST_COLOR: return "DST COLOR";
|
|
||||||
case GL_ONE_MINUS_SRC_ALPHA: return "1 - SRC ALPHA";
|
|
||||||
case GL_CONSTANT_COLOR: return "CST";
|
|
||||||
case GL_ONE_MINUS_CONSTANT_COLOR: return "1 - CST";
|
|
||||||
default: return "UKN";
|
|
||||||
}
|
|
||||||
return "UKN";
|
|
||||||
}
|
|
||||||
|
|
||||||
void debug()
|
|
||||||
{
|
|
||||||
if (!m_enable) return;
|
|
||||||
fprintf(stderr,"Blend op: %s; src:%s; dst:%s\n", NameOfParam(m_equation_RGB), NameOfParam(m_func_sRGB), NameOfParam(m_func_dRGB));
|
|
||||||
if (HasConstantFactor()) fprintf(stderr, "Blend constant: %f\n", debug_factor);
|
|
||||||
fprintf(stderr,"Mask. R:%d B:%d G:%d A:%d\n", m_r_msk, m_b_msk, m_g_msk, m_a_msk);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class GSDepthStencilOGL {
|
class GSDepthStencilOGL {
|
||||||
|
@ -161,21 +127,6 @@ class GSDepthStencilOGL {
|
||||||
const GLuint m_stencil_spass_dfail_op;
|
const GLuint m_stencil_spass_dfail_op;
|
||||||
GLuint m_stencil_spass_dpass_op;
|
GLuint m_stencil_spass_dpass_op;
|
||||||
|
|
||||||
char* NameOfParam(GLenum p)
|
|
||||||
{
|
|
||||||
switch(p) {
|
|
||||||
case GL_NEVER: return "NEVER";
|
|
||||||
case GL_ALWAYS: return "ALWAYS";
|
|
||||||
case GL_GEQUAL: return "GEQUAL";
|
|
||||||
case GL_GREATER: return "GREATER";
|
|
||||||
case GL_KEEP: return "KEEP";
|
|
||||||
case GL_EQUAL: return "EQUAL";
|
|
||||||
case GL_REPLACE: return "REPLACE";
|
|
||||||
default: return "UKN";
|
|
||||||
}
|
|
||||||
return "UKN";
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GSDepthStencilOGL() : m_depth_enable(false)
|
GSDepthStencilOGL() : m_depth_enable(false)
|
||||||
|
@ -188,7 +139,11 @@ public:
|
||||||
, m_stencil_sfail_op(GL_KEEP)
|
, m_stencil_sfail_op(GL_KEEP)
|
||||||
, m_stencil_spass_dfail_op(GL_KEEP)
|
, m_stencil_spass_dfail_op(GL_KEEP)
|
||||||
, m_stencil_spass_dpass_op(GL_KEEP)
|
, m_stencil_spass_dpass_op(GL_KEEP)
|
||||||
{}
|
{
|
||||||
|
// Only needed once since m_stencil_mask is constant
|
||||||
|
// Control which stencil bitplane are written
|
||||||
|
glStencilMask(m_stencil_mask);
|
||||||
|
}
|
||||||
|
|
||||||
void EnableDepth() { m_depth_enable = true; }
|
void EnableDepth() { m_depth_enable = true; }
|
||||||
void EnableStencil() { m_stencil_enable = true; }
|
void EnableStencil() { m_stencil_enable = true; }
|
||||||
|
@ -213,27 +168,10 @@ public:
|
||||||
// Note: here the mask control which bitplane is considered by the operation
|
// Note: here the mask control which bitplane is considered by the operation
|
||||||
glStencilFunc(m_stencil_func, m_stencil_ref, m_stencil_mask);
|
glStencilFunc(m_stencil_func, m_stencil_ref, m_stencil_mask);
|
||||||
glStencilOp(m_stencil_sfail_op, m_stencil_spass_dfail_op, m_stencil_spass_dpass_op);
|
glStencilOp(m_stencil_sfail_op, m_stencil_spass_dfail_op, m_stencil_spass_dpass_op);
|
||||||
// FIXME only needed once since m_stencil_mask is constant
|
|
||||||
// Control which stencil bitplane are written
|
|
||||||
glStencilMask(m_stencil_mask);
|
|
||||||
} else
|
} else
|
||||||
glDisable(GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void debug() { debug_depth(); debug_stencil(); }
|
|
||||||
|
|
||||||
void debug_depth()
|
|
||||||
{
|
|
||||||
if (!m_depth_enable) return;
|
|
||||||
fprintf(stderr, "Depth %s. Mask %x\n", NameOfParam(m_depth_func), m_depth_mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
void debug_stencil()
|
|
||||||
{
|
|
||||||
if (!m_stencil_enable) return;
|
|
||||||
fprintf(stderr, "Stencil %s. Both pass op %s\n", NameOfParam(m_stencil_func), NameOfParam(m_stencil_spass_dpass_op));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsMaskEnable() { return m_depth_mask != GL_FALSE; }
|
bool IsMaskEnable() { return m_depth_mask != GL_FALSE; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -540,26 +478,17 @@ class GSDeviceOGL : public GSDevice
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
GSVertexBufferStateOGL* vb;
|
GSVertexBufferStateOGL* vb;
|
||||||
GLuint vs; // program
|
GSUniformBufferOGL* cb;
|
||||||
GSUniformBufferOGL* cb; // uniform current buffer
|
|
||||||
GLuint gs; // program
|
|
||||||
// FIXME texture binding. Maybe not equivalent for the state but the best I could find.
|
|
||||||
GSTextureOGL* ps_srv[3];
|
|
||||||
// ID3D11ShaderResourceView* ps_srv[3];
|
|
||||||
GLuint ps; // program
|
|
||||||
GLuint ps_ss[3]; // sampler
|
GLuint ps_ss[3]; // sampler
|
||||||
GSVector2i viewport;
|
GSVector2i viewport;
|
||||||
GSVector4i scissor;
|
GSVector4i scissor;
|
||||||
GSDepthStencilOGL* dss;
|
GSDepthStencilOGL* dss;
|
||||||
GSBlendStateOGL* bs;
|
GSBlendStateOGL* bs;
|
||||||
float bf;
|
float bf; // blend factor
|
||||||
// FIXME texture attachment in the FBO
|
|
||||||
// ID3D11RenderTargetView* rtv;
|
|
||||||
// ID3D11DepthStencilView* dsv;
|
|
||||||
GSTextureOGL* rtv;
|
|
||||||
GSTextureOGL* dsv;
|
|
||||||
GLuint fbo;
|
GLuint fbo;
|
||||||
GLenum draw;
|
GLenum draw;
|
||||||
|
GSTexture* rt; // render target
|
||||||
|
GSTexture* ds; // Depth-Stencil
|
||||||
} m_state;
|
} m_state;
|
||||||
|
|
||||||
GSShaderOGL* m_shader;
|
GSShaderOGL* m_shader;
|
||||||
|
@ -580,7 +509,6 @@ class GSDeviceOGL : public GSDevice
|
||||||
VSConstantBuffer m_vs_cb_cache;
|
VSConstantBuffer m_vs_cb_cache;
|
||||||
PSConstantBuffer m_ps_cb_cache;
|
PSConstantBuffer m_ps_cb_cache;
|
||||||
|
|
||||||
protected:
|
|
||||||
GSTexture* CreateSurface(int type, int w, int h, bool msaa, int format);
|
GSTexture* CreateSurface(int type, int w, int h, bool msaa, int format);
|
||||||
GSTexture* FetchSurface(int type, int w, int h, bool msaa, int format);
|
GSTexture* FetchSurface(int type, int w, int h, bool msaa, int format);
|
||||||
|
|
||||||
|
@ -589,6 +517,11 @@ class GSDeviceOGL : public GSDevice
|
||||||
void DoFXAA(GSTexture* st, GSTexture* dt);
|
void DoFXAA(GSTexture* st, GSTexture* dt);
|
||||||
void DoShadeBoost(GSTexture* st, GSTexture* dt);
|
void DoShadeBoost(GSTexture* st, GSTexture* dt);
|
||||||
|
|
||||||
|
void OMAttachRt(GSTexture* rt);
|
||||||
|
void OMAttachDs(GSTexture* ds);
|
||||||
|
void OMSetFBO(GLuint fbo);
|
||||||
|
void OMSetWriteBuffer(GLenum buffer = GL_COLOR_ATTACHMENT0);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GSDeviceOGL();
|
GSDeviceOGL();
|
||||||
virtual ~GSDeviceOGL();
|
virtual ~GSDeviceOGL();
|
||||||
|
@ -629,8 +562,6 @@ class GSDeviceOGL : public GSDevice
|
||||||
|
|
||||||
void SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vertices, bool datm);
|
void SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vertices, bool datm);
|
||||||
|
|
||||||
GSTexture* Resolve(GSTexture* t);
|
|
||||||
|
|
||||||
void EndScene();
|
void EndScene();
|
||||||
|
|
||||||
void IASetPrimitiveTopology(GLenum topology);
|
void IASetPrimitiveTopology(GLenum topology);
|
||||||
|
@ -642,11 +573,9 @@ class GSDeviceOGL : public GSDevice
|
||||||
|
|
||||||
void SetUniformBuffer(GSUniformBufferOGL* cb);
|
void SetUniformBuffer(GSUniformBufferOGL* cb);
|
||||||
|
|
||||||
void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1);
|
void PSSetShaderResource(const int i, GSTexture* sr);
|
||||||
void PSSetShaderResource(int i, GSTexture* sr);
|
void PSSetSamplerState(const int i, GLuint ss);
|
||||||
void PSSetSamplerState(GLuint ss0, GLuint ss1, GLuint ss2 = 0);
|
|
||||||
|
|
||||||
void OMSetFBO(GLuint fbo, GLenum buffer = GL_COLOR_ATTACHMENT0);
|
|
||||||
void OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref);
|
void OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref);
|
||||||
void OMSetBlendState(GSBlendStateOGL* bs, float bf);
|
void OMSetBlendState(GSBlendStateOGL* bs, float bf);
|
||||||
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL);
|
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL);
|
||||||
|
@ -665,6 +594,8 @@ class GSDeviceOGL : public GSDevice
|
||||||
void SetupIA(const void* vertex, int vertex_count, const uint32* index, int index_count, int prim);
|
void SetupIA(const void* vertex, int vertex_count, const uint32* index, int index_count, int prim);
|
||||||
void SetupVS(VSSelector sel, const VSConstantBuffer* cb);
|
void SetupVS(VSSelector sel, const VSConstantBuffer* cb);
|
||||||
void SetupGS(GSSelector sel);
|
void SetupGS(GSSelector sel);
|
||||||
void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel);
|
void SetupPS(PSSelector sel, const PSConstantBuffer* cb);
|
||||||
|
void SetupSampler(PSSelector sel, PSSamplerSelector ssel);
|
||||||
void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix);
|
void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -486,6 +486,11 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
||||||
ps_ssel.tau = (context->CLAMP.WMS + 3) >> 1;
|
ps_ssel.tau = (context->CLAMP.WMS + 3) >> 1;
|
||||||
ps_ssel.tav = (context->CLAMP.WMT + 3) >> 1;
|
ps_ssel.tav = (context->CLAMP.WMT + 3) >> 1;
|
||||||
ps_ssel.ltf = bilinear && simple_sample;
|
ps_ssel.ltf = bilinear && simple_sample;
|
||||||
|
|
||||||
|
dev->SetupSampler(ps_sel, ps_ssel);
|
||||||
|
dev->PSSetShaderResource(0, tex->m_texture);
|
||||||
|
if (tex->m_palette)
|
||||||
|
dev->PSSetShaderResource(1, tex->m_palette);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -497,8 +502,6 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
||||||
GSVector4i scissor = GSVector4i(GSVector4(rtscale).xyxy() * context->scissor.in).rintersect(GSVector4i(rtsize).zwxy());
|
GSVector4i scissor = GSVector4i(GSVector4(rtscale).xyxy() * context->scissor.in).rintersect(GSVector4i(rtsize).zwxy());
|
||||||
|
|
||||||
dev->OMSetRenderTargets(rt, ds, &scissor);
|
dev->OMSetRenderTargets(rt, ds, &scissor);
|
||||||
dev->PSSetShaderResource(0, tex ? tex->m_texture : NULL);
|
|
||||||
dev->PSSetShaderResource(1, tex ? tex->m_palette : NULL);
|
|
||||||
|
|
||||||
uint8 afix = context->ALPHA.FIX;
|
uint8 afix = context->ALPHA.FIX;
|
||||||
|
|
||||||
|
@ -507,7 +510,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
||||||
dev->SetupOM(om_dssel, om_bsel, afix);
|
dev->SetupOM(om_dssel, om_bsel, afix);
|
||||||
dev->SetupVS(vs_sel, &vs_cb);
|
dev->SetupVS(vs_sel, &vs_cb);
|
||||||
dev->SetupGS(gs_sel);
|
dev->SetupGS(gs_sel);
|
||||||
dev->SetupPS(ps_sel, &ps_cb, ps_ssel);
|
dev->SetupPS(ps_sel, &ps_cb);
|
||||||
|
|
||||||
// draw
|
// draw
|
||||||
|
|
||||||
|
@ -524,7 +527,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
||||||
ps_selneg.colclip = 2;
|
ps_selneg.colclip = 2;
|
||||||
|
|
||||||
dev->SetupOM(om_dssel, om_bselneg, afix);
|
dev->SetupOM(om_dssel, om_bselneg, afix);
|
||||||
dev->SetupPS(ps_selneg, &ps_cb, ps_ssel);
|
dev->SetupPS(ps_selneg, &ps_cb);
|
||||||
|
|
||||||
dev->DrawIndexedPrimitive();
|
dev->DrawIndexedPrimitive();
|
||||||
dev->SetupOM(om_dssel, om_bsel, afix);
|
dev->SetupOM(om_dssel, om_bsel, afix);
|
||||||
|
@ -539,7 +542,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
||||||
|
|
||||||
ps_sel.atst = iatst[ps_sel.atst];
|
ps_sel.atst = iatst[ps_sel.atst];
|
||||||
|
|
||||||
dev->SetupPS(ps_sel, &ps_cb, ps_ssel);
|
dev->SetupPS(ps_sel, &ps_cb);
|
||||||
|
|
||||||
bool z = om_dssel.zwe;
|
bool z = om_dssel.zwe;
|
||||||
bool r = om_bsel.wr;
|
bool r = om_bsel.wr;
|
||||||
|
@ -577,7 +580,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
||||||
ps_selneg.colclip = 2;
|
ps_selneg.colclip = 2;
|
||||||
|
|
||||||
dev->SetupOM(om_dssel, om_bselneg, afix);
|
dev->SetupOM(om_dssel, om_bselneg, afix);
|
||||||
dev->SetupPS(ps_selneg, &ps_cb, ps_ssel);
|
dev->SetupPS(ps_selneg, &ps_cb);
|
||||||
|
|
||||||
dev->DrawIndexedPrimitive();
|
dev->DrawIndexedPrimitive();
|
||||||
}
|
}
|
||||||
|
|
|
@ -318,6 +318,8 @@ std::string GSShaderOGL::GenGlslHeader(const std::string& entry, GLenum type, co
|
||||||
|
|
||||||
GLuint GSShaderOGL::Compile(const std::string& glsl_file, const std::string& entry, GLenum type, const char* glsl_h_code, const std::string& macro_sel)
|
GLuint GSShaderOGL::Compile(const std::string& glsl_file, const std::string& entry, GLenum type, const char* glsl_h_code, const std::string& macro_sel)
|
||||||
{
|
{
|
||||||
|
ASSERT(glsl_h_code != NULL);
|
||||||
|
|
||||||
GLuint program = 0;
|
GLuint program = 0;
|
||||||
|
|
||||||
#ifndef ENABLE_GLES
|
#ifndef ENABLE_GLES
|
||||||
|
@ -331,26 +333,22 @@ GLuint GSShaderOGL::Compile(const std::string& glsl_file, const std::string& ent
|
||||||
const char* sources[2];
|
const char* sources[2];
|
||||||
|
|
||||||
std::string header = GenGlslHeader(entry, type, macro_sel);
|
std::string header = GenGlslHeader(entry, type, macro_sel);
|
||||||
|
int shader_nb = 1;
|
||||||
|
#if 0
|
||||||
sources[0] = header.c_str();
|
sources[0] = header.c_str();
|
||||||
|
|
||||||
if (glsl_h_code)
|
|
||||||
sources[1] = glsl_h_code;
|
sources[1] = glsl_h_code;
|
||||||
else
|
shader_nb++;
|
||||||
sources[1] = '\0';
|
#else
|
||||||
|
sources[0] = header.append(glsl_h_code).c_str();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (m_sso) {
|
if (m_sso) {
|
||||||
#ifndef ENABLE_GLES
|
#ifndef ENABLE_GLES
|
||||||
#if 0
|
program = gl_CreateShaderProgramv(type, shader_nb, sources);
|
||||||
const GLchar* ShaderSource[1];
|
|
||||||
ShaderSource[0] = header.append(glsl_h_code).c_str();
|
|
||||||
program = gl_CreateShaderProgramv(type, 1, &ShaderSource[0]);
|
|
||||||
#else
|
|
||||||
program = gl_CreateShaderProgramv(type, 2, sources);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
program = gl_CreateShader(type);
|
program = gl_CreateShader(type);
|
||||||
gl_ShaderSource(program, 2, sources, NULL);
|
gl_ShaderSource(program, shader_nb, sources, NULL);
|
||||||
gl_CompileShader(program);
|
gl_CompileShader(program);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ void GSTextureCacheOGL::Read(Target* t, const GSVector4i& r)
|
||||||
{
|
{
|
||||||
if(t->m_type != RenderTarget)
|
if(t->m_type != RenderTarget)
|
||||||
{
|
{
|
||||||
assert(0);
|
ASSERT(0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -96,6 +96,7 @@ void GSTextureCacheOGL::Read(Target* t, const GSVector4i& r)
|
||||||
offscreen->Unmap();
|
offscreen->Unmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME invalidate data
|
||||||
m_renderer->m_dev->Recycle(offscreen);
|
m_renderer->m_dev->Recycle(offscreen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,7 @@ void GSDeviceOGL::SetupGS(GSSelector sel)
|
||||||
m_shader->GS(gs);
|
m_shader->GS(gs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel)
|
void GSDeviceOGL::SetupPS(PSSelector sel, const PSConstantBuffer* cb)
|
||||||
{
|
{
|
||||||
// *************************************************************
|
// *************************************************************
|
||||||
// Static
|
// Static
|
||||||
|
@ -174,25 +174,18 @@ void GSDeviceOGL::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerS
|
||||||
m_ps_cb->upload(cb);
|
m_ps_cb->upload(cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint ss0, ss1;
|
m_shader->PS(ps);
|
||||||
ss0 = ss1 = 0;
|
}
|
||||||
if(sel.tfx != 4)
|
|
||||||
|
void GSDeviceOGL::SetupSampler(PSSelector sel, PSSamplerSelector ssel)
|
||||||
{
|
{
|
||||||
if(!(sel.fmt < 3 && sel.wms < 3 && sel.wmt < 3))
|
if(!(sel.fmt < 3 && sel.wms < 3 && sel.wmt < 3))
|
||||||
{
|
{
|
||||||
ssel.ltf = 0;
|
ssel.ltf = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ss0 = m_ps_ss[ssel];
|
PSSetSamplerState(0, m_ps_ss[ssel]);
|
||||||
|
PSSetSamplerState(1, m_palette_ss);
|
||||||
if(sel.fmt >= 3)
|
|
||||||
{
|
|
||||||
ss1 = m_palette_ss;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PSSetSamplerState(ss0, ss1, 0);
|
|
||||||
m_shader->PS(ps);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix)
|
void GSDeviceOGL::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix)
|
||||||
|
|
|
@ -24,15 +24,12 @@
|
||||||
#include "GSTextureOGL.h"
|
#include "GSTextureOGL.h"
|
||||||
static GLuint g_state_texture_unit = -1;
|
static GLuint g_state_texture_unit = -1;
|
||||||
static GLuint g_state_texture_id[7] = {0, 0, 0, 0, 0, 0, 0};
|
static GLuint g_state_texture_id[7] = {0, 0, 0, 0, 0, 0, 0};
|
||||||
static GLuint g_color0 = 0;
|
|
||||||
static GLuint g_color1 = 0;
|
|
||||||
static GLuint g_depth = 0;
|
|
||||||
|
|
||||||
// FIXME: check if it possible to always use those setup by default
|
// FIXME: check if it possible to always use those setup by default
|
||||||
// glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
// glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
// glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
// glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format, GLuint fbo_read)
|
GSTextureOGL::GSTextureOGL(int type, int w, int h, int format, GLuint fbo_read)
|
||||||
: m_pbo_id(0),
|
: m_pbo_id(0),
|
||||||
m_pbo_size(0)
|
m_pbo_size(0)
|
||||||
{
|
{
|
||||||
|
@ -62,15 +59,14 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format, GLuint
|
||||||
m_size.y = max(1,h);
|
m_size.y = max(1,h);
|
||||||
m_format = format;
|
m_format = format;
|
||||||
m_type = type;
|
m_type = type;
|
||||||
m_msaa = msaa;
|
|
||||||
m_fbo_read = fbo_read;
|
m_fbo_read = fbo_read;
|
||||||
|
m_texture_id = 0;
|
||||||
|
|
||||||
// Generate the buffer
|
// Generate the buffer
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
case GSTexture::Offscreen:
|
case GSTexture::Offscreen:
|
||||||
//FIXME I not sure we need a pixel buffer object. It seems more a texture
|
//FIXME I not sure we need a pixel buffer object. It seems more a texture
|
||||||
// gl_GenBuffers(1, &m_texture_id);
|
// gl_GenBuffers(1, &m_texture_id);
|
||||||
// m_texture_target = GL_PIXEL_UNPACK_BUFFER;
|
|
||||||
// ASSERT(0);
|
// ASSERT(0);
|
||||||
// Note there is also a buffer texture!!!
|
// Note there is also a buffer texture!!!
|
||||||
// http://www.opengl.org/wiki/Buffer_Texture
|
// http://www.opengl.org/wiki/Buffer_Texture
|
||||||
|
@ -81,11 +77,8 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format, GLuint
|
||||||
case GSTexture::RenderTarget:
|
case GSTexture::RenderTarget:
|
||||||
case GSTexture::DepthStencil:
|
case GSTexture::DepthStencil:
|
||||||
glGenTextures(1, &m_texture_id);
|
glGenTextures(1, &m_texture_id);
|
||||||
m_texture_target = GL_TEXTURE_2D;
|
|
||||||
break;
|
break;
|
||||||
case GSTexture::Backbuffer:
|
case GSTexture::Backbuffer:
|
||||||
m_texture_target = 0;
|
|
||||||
m_texture_id = 0;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -93,16 +86,6 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format, GLuint
|
||||||
// Extra buffer to handle various pixel transfer
|
// Extra buffer to handle various pixel transfer
|
||||||
gl_GenBuffers(1, &m_pbo_id);
|
gl_GenBuffers(1, &m_pbo_id);
|
||||||
|
|
||||||
#if 0
|
|
||||||
uint32 msaa_level;
|
|
||||||
if (m_msaa) {
|
|
||||||
// FIXME which level of MSAA
|
|
||||||
msaa_level = 1;
|
|
||||||
} else {
|
|
||||||
msaa_level = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Allocate the buffer
|
// Allocate the buffer
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
case GSTexture::Offscreen:
|
case GSTexture::Offscreen:
|
||||||
|
@ -117,19 +100,12 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format, GLuint
|
||||||
gl_BindBuffer(GL_PIXEL_PACK_BUFFER, m_pbo_id);
|
gl_BindBuffer(GL_PIXEL_PACK_BUFFER, m_pbo_id);
|
||||||
gl_BufferData(GL_PIXEL_PACK_BUFFER, m_pbo_size, NULL, GL_STREAM_DRAW);
|
gl_BufferData(GL_PIXEL_PACK_BUFFER, m_pbo_size, NULL, GL_STREAM_DRAW);
|
||||||
gl_BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
gl_BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||||
ASSERT(!m_msaa);
|
|
||||||
|
|
||||||
case GSTexture::DepthStencil:
|
case GSTexture::DepthStencil:
|
||||||
case GSTexture::RenderTarget:
|
case GSTexture::RenderTarget:
|
||||||
case GSTexture::Texture:
|
case GSTexture::Texture:
|
||||||
EnableUnit(3);
|
EnableUnit(3);
|
||||||
if (m_msaa) {
|
gl_TexStorage2D(GL_TEXTURE_2D, 1, m_format, m_size.x, m_size.y);
|
||||||
ASSERT(m_texture_target == GL_TEXTURE_2D_MULTISAMPLE);
|
|
||||||
// Require a recent GL4.3 extension
|
|
||||||
//gl_TexStorage2DMultisample(m_texture_target, msaa_level, m_format, m_size.x, m_size.y, false);
|
|
||||||
} else {
|
|
||||||
gl_TexStorage2D(m_texture_target, 1, m_format, m_size.x, m_size.y);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
@ -146,45 +122,9 @@ GSTextureOGL::~GSTextureOGL()
|
||||||
glDeleteTextures(1, &m_texture_id);
|
glDeleteTextures(1, &m_texture_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSTextureOGL::Attach(GLenum attachment)
|
|
||||||
{
|
|
||||||
switch(attachment) {
|
|
||||||
case GL_COLOR_ATTACHMENT0:
|
|
||||||
if (g_color0 != m_texture_id) {
|
|
||||||
g_color0 = m_texture_id;
|
|
||||||
gl_FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, m_texture_target, m_texture_id, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GL_COLOR_ATTACHMENT1:
|
|
||||||
if (g_color1 != m_texture_id) {
|
|
||||||
g_color1 = m_texture_id;
|
|
||||||
gl_FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, m_texture_target, m_texture_id, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GL_DEPTH_STENCIL_ATTACHMENT:
|
|
||||||
if (g_depth != m_texture_id) {
|
|
||||||
gl_FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, m_texture_target, m_texture_id, 0);
|
|
||||||
g_depth = m_texture_id;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
gl_FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, m_texture_target, m_texture_id, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME DEBUG
|
|
||||||
//fprintf(stderr, "FB status %x\n", gl_CheckFramebufferStatus(GL_FRAMEBUFFER));
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSTextureOGL::AttachRead(GLenum attachment)
|
|
||||||
{
|
|
||||||
gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, attachment, m_texture_target, m_texture_id, 0);
|
|
||||||
glReadBuffer(attachment);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
|
bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
|
||||||
{
|
{
|
||||||
if (m_type == GSTexture::DepthStencil || m_type == GSTexture::Offscreen) ASSERT(0);
|
ASSERT(m_type != GSTexture::DepthStencil && m_type != GSTexture::Offscreen);
|
||||||
|
|
||||||
// FIXME warning order of the y axis
|
// FIXME warning order of the y axis
|
||||||
// FIXME I'm not confident with GL_UNSIGNED_BYTE type
|
// FIXME I'm not confident with GL_UNSIGNED_BYTE type
|
||||||
|
@ -234,7 +174,7 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), format, type, data);
|
glTexSubImage2D(GL_TEXTURE_2D, 0, r.x, r.y, r.width(), r.height(), format, type, data);
|
||||||
|
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // Restore default behavior
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // Restore default behavior
|
||||||
|
|
||||||
|
@ -253,25 +193,26 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSTextureOGL::EnableUnit(uint32 unit)
|
void GSTextureOGL::EnableUnit(const uint32 unit)
|
||||||
{
|
{
|
||||||
/* Not a real texture */
|
/* Not a real texture */
|
||||||
if (IsBackbuffer()) {
|
ASSERT(!IsBackbuffer());
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_state_texture_unit != unit) {
|
if (g_state_texture_unit != unit) {
|
||||||
gl_ActiveTexture(GL_TEXTURE0 + unit);
|
gl_ActiveTexture(GL_TEXTURE0 + unit);
|
||||||
g_state_texture_unit = unit;
|
g_state_texture_unit = unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_state_texture_id[unit] != m_texture_id) {
|
if (g_state_texture_id[unit] != m_texture_id) {
|
||||||
g_state_texture_id[unit] = m_texture_id;
|
g_state_texture_id[unit] = m_texture_id;
|
||||||
glBindTexture(m_texture_target, m_texture_id);
|
glBindTexture(GL_TEXTURE_2D, m_texture_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
|
bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
|
||||||
{
|
{
|
||||||
|
if (m_type != GSTexture::Offscreen) return false;
|
||||||
|
|
||||||
// The function allow to modify the texture from the CPU
|
// The function allow to modify the texture from the CPU
|
||||||
// Set m.bits <- pointer to the data
|
// Set m.bits <- pointer to the data
|
||||||
// Set m.pitch <- size of a row
|
// Set m.pitch <- size of a row
|
||||||
|
@ -279,11 +220,11 @@ bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
|
||||||
//
|
//
|
||||||
// gl_MapBuffer — map a buffer object's data store
|
// gl_MapBuffer — 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) {
|
|
||||||
// Bind the texture to the read framebuffer to avoid any disturbance
|
// Bind the texture to the read framebuffer to avoid any disturbance
|
||||||
EnableUnit(5);
|
EnableUnit(5);
|
||||||
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
|
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
|
||||||
gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture_target, m_texture_id, 0);
|
gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture_id, 0);
|
||||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
|
|
||||||
// FIXME It might be possible to only read a subrange of the texture based on r object
|
// FIXME It might be possible to only read a subrange of the texture based on r object
|
||||||
|
@ -317,9 +258,7 @@ bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
|
||||||
gl_BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
gl_BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
#if 0
|
#if 0
|
||||||
if(m_texture && m_desc.Usage == D3D11_USAGE_STAGING)
|
if(m_texture && m_desc.Usage == D3D11_USAGE_STAGING)
|
||||||
{
|
{
|
||||||
|
@ -465,7 +404,7 @@ bool GSTextureOGL::Save(const string& fn, bool dds)
|
||||||
} else if(IsDss()) {
|
} else if(IsDss()) {
|
||||||
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
|
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
|
||||||
|
|
||||||
gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_texture_target, m_texture_id, 0);
|
gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_texture_id, 0);
|
||||||
glReadPixels(0, 0, m_size.x, m_size.y, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, image);
|
glReadPixels(0, 0, m_size.x, m_size.y, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, image);
|
||||||
|
|
||||||
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||||
|
@ -473,7 +412,7 @@ bool GSTextureOGL::Save(const string& fn, bool dds)
|
||||||
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
|
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
|
||||||
|
|
||||||
EnableUnit(6);
|
EnableUnit(6);
|
||||||
gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture_target, m_texture_id, 0);
|
gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture_id, 0);
|
||||||
|
|
||||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
if (m_format == GL_RGBA8)
|
if (m_format == GL_RGBA8)
|
||||||
|
|
|
@ -26,14 +26,13 @@
|
||||||
class GSTextureOGL : public GSTexture
|
class GSTextureOGL : public GSTexture
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
GLenum m_texture_target; // texture target: 2D, rectangle etc...
|
|
||||||
GLuint m_texture_id; // the texture id
|
GLuint m_texture_id; // the texture id
|
||||||
uint32 m_pbo_id;
|
uint32 m_pbo_id;
|
||||||
int m_pbo_size;
|
int m_pbo_size;
|
||||||
GLuint m_fbo_read;
|
GLuint m_fbo_read;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GSTextureOGL(int type, int w, int h, bool msaa, int format, GLuint fbo_read);
|
explicit GSTextureOGL(int type, int w, int h, int format, GLuint fbo_read);
|
||||||
virtual ~GSTextureOGL();
|
virtual ~GSTextureOGL();
|
||||||
|
|
||||||
bool Update(const GSVector4i& r, const void* data, int pitch);
|
bool Update(const GSVector4i& r, const void* data, int pitch);
|
||||||
|
@ -42,13 +41,10 @@ class GSTextureOGL : public GSTexture
|
||||||
bool Save(const string& fn, bool dds = false);
|
bool Save(const string& fn, bool dds = false);
|
||||||
void Save(const string& fn, const void* image, uint32 pitch);
|
void Save(const string& fn, const void* image, uint32 pitch);
|
||||||
|
|
||||||
void EnableUnit(uint32 unit);
|
void EnableUnit(const uint32 unit);
|
||||||
void Attach(GLenum attachment);
|
|
||||||
void AttachRead(GLenum attachment);
|
|
||||||
|
|
||||||
bool IsBackbuffer() { return (m_type == GSTexture::Backbuffer); }
|
bool IsBackbuffer() { return (m_type == GSTexture::Backbuffer); }
|
||||||
bool IsDss() { return (m_type == GSTexture::DepthStencil); }
|
bool IsDss() { return (m_type == GSTexture::DepthStencil); }
|
||||||
|
|
||||||
GLuint GetID() { return m_texture_id; }
|
GLuint GetID() { return m_texture_id; }
|
||||||
GLenum GetTarget() { return m_texture_target; }
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,12 +25,10 @@ class GSUniformBufferOGL {
|
||||||
GLuint buffer; // data object
|
GLuint buffer; // data object
|
||||||
GLuint index; // GLSL slot
|
GLuint index; // GLSL slot
|
||||||
uint32 size; // size of the data
|
uint32 size; // size of the data
|
||||||
const GLenum target;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GSUniformBufferOGL(GLuint index, uint32 size) : index(index)
|
GSUniformBufferOGL(GLuint index, uint32 size) : index(index)
|
||||||
, size(size)
|
, size(size)
|
||||||
,target(GL_UNIFORM_BUFFER)
|
|
||||||
{
|
{
|
||||||
gl_GenBuffers(1, &buffer);
|
gl_GenBuffers(1, &buffer);
|
||||||
bind();
|
bind();
|
||||||
|
@ -40,17 +38,17 @@ public:
|
||||||
|
|
||||||
void bind()
|
void bind()
|
||||||
{
|
{
|
||||||
gl_BindBuffer(target, buffer);
|
gl_BindBuffer(GL_UNIFORM_BUFFER, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void allocate()
|
void allocate()
|
||||||
{
|
{
|
||||||
gl_BufferData(target, size, NULL, GL_STREAM_DRAW);
|
gl_BufferData(GL_UNIFORM_BUFFER, size, NULL, GL_STREAM_DRAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
void attach()
|
void attach()
|
||||||
{
|
{
|
||||||
gl_BindBufferBase(target, index, buffer);
|
gl_BindBufferBase(GL_UNIFORM_BUFFER, index, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void upload(const void* src)
|
void upload(const void* src)
|
||||||
|
@ -58,7 +56,7 @@ public:
|
||||||
// glMapBufferRange allow to set various parameter but the call is
|
// glMapBufferRange allow to set various parameter but the call is
|
||||||
// synchronous whereas glBufferSubData could be asynchronous.
|
// synchronous whereas glBufferSubData could be asynchronous.
|
||||||
// TODO: investigate the extension ARB_invalidate_subdata
|
// TODO: investigate the extension ARB_invalidate_subdata
|
||||||
gl_BufferSubData(target, 0, size, src);
|
gl_BufferSubData(GL_UNIFORM_BUFFER, 0, size, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
~GSUniformBufferOGL() {
|
~GSUniformBufferOGL() {
|
||||||
|
|
Loading…
Reference in New Issue