mirror of https://github.com/PCSX2/pcsx2.git
gsdx-ogl: preliminary work of an opengl backend. So far only skeleton and various note.
Current goal is to implement the SW render with pure opengl instead of SDL. I plan to use OpenGL4.2 capability (the latest actually) => need libglew1.7 and a Dx11 capable GPU/drivers. git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl@4970 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
b2ba781df8
commit
da66ca7fd9
|
@ -58,6 +58,7 @@ set(GSdxSources
|
||||||
GSCodeBuffer.cpp
|
GSCodeBuffer.cpp
|
||||||
GSCrc.cpp
|
GSCrc.cpp
|
||||||
GSDevice.cpp
|
GSDevice.cpp
|
||||||
|
GSDeviceOGL.cpp
|
||||||
GSDeviceSDL.cpp
|
GSDeviceSDL.cpp
|
||||||
GSDeviceSW.cpp
|
GSDeviceSW.cpp
|
||||||
GSDeviceNull.cpp
|
GSDeviceNull.cpp
|
||||||
|
@ -76,6 +77,7 @@ set(GSdxSources
|
||||||
GSRasterizer.cpp
|
GSRasterizer.cpp
|
||||||
GSRenderer.cpp
|
GSRenderer.cpp
|
||||||
GSRendererNull.cpp
|
GSRendererNull.cpp
|
||||||
|
GSRendererOGL.cpp
|
||||||
GSRendererSW.cpp
|
GSRendererSW.cpp
|
||||||
GSSetting.cpp
|
GSSetting.cpp
|
||||||
GSSetupPrimCodeGenerator.cpp
|
GSSetupPrimCodeGenerator.cpp
|
||||||
|
@ -88,6 +90,8 @@ set(GSdxSources
|
||||||
GSTexture.cpp
|
GSTexture.cpp
|
||||||
GSTextureCache.cpp
|
GSTextureCache.cpp
|
||||||
GSTextureCacheSW.cpp
|
GSTextureCacheSW.cpp
|
||||||
|
GSTextureCacheOGL.cpp
|
||||||
|
GSTextureOGL.cpp
|
||||||
GSTextureNull.cpp
|
GSTextureNull.cpp
|
||||||
GSTextureSW.cpp
|
GSTextureSW.cpp
|
||||||
GSThread.cpp
|
GSThread.cpp
|
||||||
|
@ -123,6 +127,7 @@ set(GSdxHeaders
|
||||||
GSCodeBuffer.h
|
GSCodeBuffer.h
|
||||||
GSCrc.h
|
GSCrc.h
|
||||||
GSDevice.h
|
GSDevice.h
|
||||||
|
GSDeviceOGL.h
|
||||||
GSDeviceNull.h
|
GSDeviceNull.h
|
||||||
GSDirtyRect.h
|
GSDirtyRect.h
|
||||||
GSDrawScanline.h
|
GSDrawScanline.h
|
||||||
|
@ -137,6 +142,8 @@ set(GSdxHeaders
|
||||||
GSRenderer.h
|
GSRenderer.h
|
||||||
GSRendererNull.h
|
GSRendererNull.h
|
||||||
GSRendererSW.h
|
GSRendererSW.h
|
||||||
|
GSRendererHW.h
|
||||||
|
GSRendererOGL.h
|
||||||
GSScanlineEnvironment.h
|
GSScanlineEnvironment.h
|
||||||
GSSetting.h
|
GSSetting.h
|
||||||
GSSetupPrimCodeGenerator.h
|
GSSetupPrimCodeGenerator.h
|
||||||
|
@ -145,6 +152,7 @@ set(GSdxHeaders
|
||||||
GSTexture.h
|
GSTexture.h
|
||||||
GSTextureCache.h
|
GSTextureCache.h
|
||||||
GSTextureCacheSW.h
|
GSTextureCacheSW.h
|
||||||
|
GSTextureCacheOGL.h
|
||||||
GSTextureNull.h
|
GSTextureNull.h
|
||||||
GSThread.h
|
GSThread.h
|
||||||
GSUtil.h
|
GSUtil.h
|
||||||
|
|
|
@ -39,6 +39,9 @@ static HRESULT s_hr = E_FAIL;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#include "GSDeviceOGL.h"
|
||||||
|
#include "GSRendererOGL.h"
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <gdk/gdkx.h>
|
#include <gdk/gdkx.h>
|
||||||
|
|
||||||
|
@ -215,6 +218,7 @@ static int _GSopen(void** dsp, char* title, int renderer, int threads = -1)
|
||||||
#endif
|
#endif
|
||||||
case 2: dev = new GSDeviceSDL(); break;
|
case 2: dev = new GSDeviceSDL(); break;
|
||||||
case 3: dev = new GSDeviceNull(); break;
|
case 3: dev = new GSDeviceNull(); break;
|
||||||
|
case 4: dev = new GSDeviceOGL(); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dev == NULL)
|
if(dev == NULL)
|
||||||
|
@ -227,11 +231,13 @@ static int _GSopen(void** dsp, char* title, int renderer, int threads = -1)
|
||||||
switch(renderer % 3)
|
switch(renderer % 3)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
#ifdef _WINDOWS
|
|
||||||
case 0:
|
case 0:
|
||||||
|
#ifdef _WINDOWS
|
||||||
s_gs = (renderer / 3) == 0 ? (GSRenderer*)new GSRendererDX9() : (GSRenderer*)new GSRendererDX11();
|
s_gs = (renderer / 3) == 0 ? (GSRenderer*)new GSRendererDX9() : (GSRenderer*)new GSRendererDX11();
|
||||||
break;
|
#else
|
||||||
|
s_gs = (GSRenderer*)new GSRendererOGL();
|
||||||
#endif
|
#endif
|
||||||
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
s_gs = new GSRendererSW(threads);
|
s_gs = new GSRendererSW(threads);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -0,0 +1,643 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011-2011 Gregory hainaut
|
||||||
|
* Copyright (C) 2007-2009 Gabest
|
||||||
|
*
|
||||||
|
* This Program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This Program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
* http://www.gnu.org/copyleft/gpl.html
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "GSDeviceOGL.h"
|
||||||
|
|
||||||
|
// Various Note: separate build of shader
|
||||||
|
// ************************** BUILD METHOD 1
|
||||||
|
// 1/ create a stand alone prog
|
||||||
|
// uint CreateShaderProgramv( enum type, sizei count, const char **strings );
|
||||||
|
// 2/ Create various prog pipeline (maybe 1 foreach combination or only 1)
|
||||||
|
// glGenProgramPipelines
|
||||||
|
// 3/ Attach a program to a pipeline
|
||||||
|
// void UseProgramStages( uint pipeline, bitfield stages, uint program );
|
||||||
|
// ...
|
||||||
|
// ...
|
||||||
|
// 5/ Before the use of the program, we can validate it. (mandatory or not ?)
|
||||||
|
// glValidateProgramPipeline
|
||||||
|
//
|
||||||
|
// ************************** BUILD METHOD 2
|
||||||
|
// Humm, there is another solutions. You can setup function pointer in GLSL and configure them with OPENGL. shader_subroutine. glUseProgram must be replace with glUseProgramInstance in this case (and instance must be managed)
|
||||||
|
//GL EXT: Overview
|
||||||
|
//GL EXT:
|
||||||
|
//GL EXT: This extension adds support to shaders for "indirect subroutine calls",
|
||||||
|
//GL EXT: where a single shader can include many subroutines and dynamically select
|
||||||
|
//GL EXT: through the API which subroutine is called from each call site.
|
||||||
|
//GL EXT: Switching subroutines dynamically in this fashion can avoid the cost of
|
||||||
|
//GL EXT: recompiling and managing multiple shaders, while still retaining most of
|
||||||
|
//GL EXT: the performance of specialized shaders.
|
||||||
|
//
|
||||||
|
// ************************** Uniform buffer
|
||||||
|
// // Note don't know how to chose block_binding_point (probably managed like texture unit
|
||||||
|
// maybe any number will be fine)
|
||||||
|
// index=glGetUniformBlockIndex(program, "BlockName");
|
||||||
|
// glBindBufferBase(GL_UNIFORM_BUFFER, block_binding_point, some_buffer_object);
|
||||||
|
// glUniformBlockBinding(program, block_index, block_binding_point);
|
||||||
|
|
||||||
|
|
||||||
|
GSDeviceOGL::GSDeviceOGL()
|
||||||
|
{
|
||||||
|
/* TODO */
|
||||||
|
m_msaa = theApp.GetConfig("msaa", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
GSDeviceOGL::~GSDeviceOGL() { /* TODO */ }
|
||||||
|
|
||||||
|
GSTexture* GSDeviceOGL::CreateSurface(int type, int w, int h, bool msaa, int format)
|
||||||
|
{
|
||||||
|
// A wrapper to call GSTextureOGL, with the different kind of parameter
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
#if 0
|
||||||
|
if(m_msaa < 2) {
|
||||||
|
msaa = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
msaa = false;
|
||||||
|
|
||||||
|
return GSDevice::FetchSurface(type, w, h, msaa, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GSDeviceOGL::Create(GSWnd* wnd)
|
||||||
|
{
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GSDeviceOGL::Reset(int w, int h)
|
||||||
|
{
|
||||||
|
// Hum map, m_backbuffer to a GSTexture
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap buffer (back buffer, front buffer)
|
||||||
|
// Warning it is not OGL dependent but application dependant (glx and so not portable)
|
||||||
|
void GSDeviceOGL::Flip() { /* TODO */ }
|
||||||
|
|
||||||
|
// glDrawArrays
|
||||||
|
void GSDeviceOGL::DrawPrimitive() { /* TODO */ }
|
||||||
|
|
||||||
|
// Just a wrapper around glClear* functions
|
||||||
|
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c) { /* TODO */ }
|
||||||
|
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, uint32 c) { /* TODO */ }
|
||||||
|
void GSDeviceOGL::ClearDepth(GSTexture* t, float c) { /* TODO */ }
|
||||||
|
void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c) { /* TODO */ }
|
||||||
|
|
||||||
|
// the 4 next functions are only used to set some default value for the format.
|
||||||
|
// Need to find the default format...
|
||||||
|
// depth_stencil => GL_DEPTH32F_STENCIL8
|
||||||
|
// others => (need 4* 8bits unsigned normalized integer) (GL_RGBA8 )
|
||||||
|
GSTexture* GSDeviceOGL::CreateRenderTarget(int w, int h, bool msaa, int format) { /* TODO */ }
|
||||||
|
GSTexture* GSDeviceOGL::CreateDepthStencil(int w, int h, bool msaa, int format) { /* TODO */ }
|
||||||
|
GSTexture* GSDeviceOGL::CreateTexture(int w, int h, int format) { /* TODO */ }
|
||||||
|
GSTexture* GSDeviceOGL::CreateOffscreen(int w, int h, int format) { /* TODO */ }
|
||||||
|
|
||||||
|
// blit a texture into an offscreen buffer
|
||||||
|
GSTexture* GSDeviceOGL::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format)
|
||||||
|
{
|
||||||
|
// 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 != DXGI_FORMAT_R8G8B8A8_UNORM && format != DXGI_FORMAT_R16_UINT)
|
||||||
|
{
|
||||||
|
ASSERT(0);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GSTexture* rt = CreateRenderTarget(w, h, false, format))
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
if(src2 != src) Recycle(src2);
|
||||||
|
}
|
||||||
|
|
||||||
|
dst = CreateOffscreen(w, h, format);
|
||||||
|
|
||||||
|
if(dst)
|
||||||
|
{
|
||||||
|
m_ctx->CopyResource(*(GSTexture11*)dst, *(GSTexture11*)rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
Recycle(rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy a sub part of a texture into another
|
||||||
|
// Several question to answer did texture have same size?
|
||||||
|
// From a sub-part to the same sub-part
|
||||||
|
// From a sub-part to a full texture
|
||||||
|
void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
if(!st || !dt)
|
||||||
|
{
|
||||||
|
ASSERT(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Raster flow to resize a texture
|
||||||
|
// Note just call the StretchRect hardware accelerated
|
||||||
|
void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader, bool linear)
|
||||||
|
{
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, GLuint ps, GSUniformBufferOGL* ps_cb, bool linear)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 0
|
||||||
|
if(!st || !dt)
|
||||||
|
{
|
||||||
|
ASSERT(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BeginScene();
|
||||||
|
|
||||||
|
GSVector2i ds = dt->GetSize();
|
||||||
|
|
||||||
|
// om
|
||||||
|
|
||||||
|
OMSetDepthStencilState(m_convert.dss, 0);
|
||||||
|
OMSetBlendState(bs, 0);
|
||||||
|
OMSetRenderTargets(dt, NULL);
|
||||||
|
|
||||||
|
// ia
|
||||||
|
|
||||||
|
float left = dr.x * 2 / ds.x - 1.0f;
|
||||||
|
float top = 1.0f - dr.y * 2 / ds.y;
|
||||||
|
float right = dr.z * 2 / ds.x - 1.0f;
|
||||||
|
float bottom = 1.0f - dr.w * 2 / ds.y;
|
||||||
|
|
||||||
|
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)},
|
||||||
|
{GSVector4(left, bottom, 0.5f, 1.0f), GSVector2(sr.x, sr.w)},
|
||||||
|
{GSVector4(right, bottom, 0.5f, 1.0f), GSVector2(sr.z, sr.w)},
|
||||||
|
};
|
||||||
|
|
||||||
|
IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices));
|
||||||
|
IASetInputLayout(m_convert.il);
|
||||||
|
IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||||
|
|
||||||
|
// vs
|
||||||
|
|
||||||
|
VSSetShader(m_convert.vs, NULL);
|
||||||
|
|
||||||
|
// gs
|
||||||
|
|
||||||
|
GSSetShader(NULL);
|
||||||
|
|
||||||
|
// ps
|
||||||
|
|
||||||
|
PSSetShaderResources(st, NULL);
|
||||||
|
PSSetSamplerState(linear ? m_convert.ln : m_convert.pt, NULL);
|
||||||
|
PSSetShader(ps, ps_cb);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
DrawPrimitive();
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
EndScene();
|
||||||
|
|
||||||
|
PSSetShaderResources(NULL, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSDeviceOGL::DoMerge(GSTexture* st[2], GSVector4* sr, GSTexture* dt, GSVector4* dr, bool slbg, bool mmod, const GSVector4& c)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
ClearRenderTarget(dt, c);
|
||||||
|
|
||||||
|
if(st[1] && !slbg)
|
||||||
|
{
|
||||||
|
StretchRect(st[1], sr[1], dt, dr[1], m_merge.ps[0], NULL, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(st[0])
|
||||||
|
{
|
||||||
|
m_ctx->UpdateSubresource(m_merge.cb, 0, NULL, &c, 0, 0);
|
||||||
|
|
||||||
|
StretchRect(st[0], sr[0], dt, dr[0], m_merge.ps[mmod ? 1 : 0], m_merge.cb, m_merge.bs, true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSDeviceOGL::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
GSVector4 s = GSVector4(dt->GetSize());
|
||||||
|
|
||||||
|
GSVector4 sr(0, 0, 1, 1);
|
||||||
|
GSVector4 dr(0.0f, yoffset, s.x, s.y + yoffset);
|
||||||
|
|
||||||
|
InterlaceConstantBuffer cb;
|
||||||
|
|
||||||
|
cb.ZrH = GSVector2(0, 1.0f / s.y);
|
||||||
|
cb.hH = s.y / 2;
|
||||||
|
|
||||||
|
m_ctx->UpdateSubresource(m_interlace.cb, 0, NULL, &cb, 0, 0);
|
||||||
|
|
||||||
|
StretchRect(st, sr, dt, dr, m_interlace.ps[shader], m_interlace.cb, linear);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
ASSERT(t != NULL && t->IsMSAA());
|
||||||
|
|
||||||
|
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::IASetVertexBuffer(const void* vertices, size_t stride, size_t count)
|
||||||
|
{
|
||||||
|
ASSERT(m_vertices.count == 0);
|
||||||
|
|
||||||
|
if(count * stride > m_vertices.limit * m_vertices.stride)
|
||||||
|
{
|
||||||
|
// Current GPU buffer is too small need to realocate a new one
|
||||||
|
#if 0
|
||||||
|
m_vb_old = m_vb;
|
||||||
|
m_vb = NULL;
|
||||||
|
|
||||||
|
m_vertices.start = 0;
|
||||||
|
m_vertices.count = 0;
|
||||||
|
m_vertices.limit = std::max<int>(count * 3 / 2, 11000);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_vb == NULL)
|
||||||
|
{
|
||||||
|
// Allocate a GPU buffer: GL_DYNAMIC_DRAW vs GL_STREAM_DRAW !!!
|
||||||
|
// glBufferData(GL_ARRAY_BUFFER, m_vertices.limit, NULL, GL_DYNAMIC_DRAW)
|
||||||
|
#if 0
|
||||||
|
D3D11_BUFFER_DESC bd;
|
||||||
|
|
||||||
|
memset(&bd, 0, sizeof(bd));
|
||||||
|
|
||||||
|
bd.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
bd.ByteWidth = m_vertices.limit * stride;
|
||||||
|
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||||
|
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
|
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = m_dev->CreateBuffer(&bd, NULL, &m_vb);
|
||||||
|
|
||||||
|
if(FAILED(hr)) return;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// append data or go back to the beginning
|
||||||
|
// Hum why we don't always go back to the beginning !!!
|
||||||
|
#if 0
|
||||||
|
D3D11_MAP type = D3D11_MAP_WRITE_NO_OVERWRITE;
|
||||||
|
|
||||||
|
if(m_vertices.start + count > m_vertices.limit || stride != m_vertices.stride)
|
||||||
|
{
|
||||||
|
m_vertices.start = 0;
|
||||||
|
|
||||||
|
type = D3D11_MAP_WRITE_DISCARD;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Allocate the buffer
|
||||||
|
// glBufferSubData
|
||||||
|
#if 0
|
||||||
|
D3D11_MAPPED_SUBRESOURCE m;
|
||||||
|
|
||||||
|
if(SUCCEEDED(m_ctx->Map(m_vb, 0, type, 0, &m)))
|
||||||
|
{
|
||||||
|
GSVector4i::storent((uint8*)m.pData + m_vertices.start * stride, vertices, count * stride);
|
||||||
|
|
||||||
|
m_ctx->Unmap(m_vb, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_vertices.count = count;
|
||||||
|
m_vertices.stride = stride;
|
||||||
|
|
||||||
|
// Useless ?
|
||||||
|
// binding of the buffer must be done anyway before glBufferSubData or glBufferData calls.
|
||||||
|
#if 0
|
||||||
|
IASetVertexBuffer(m_vb, stride);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Useless ?
|
||||||
|
#if 0
|
||||||
|
void GSDeviceOGL::IASetVertexBuffer(GLuint vb, size_t stride)
|
||||||
|
{
|
||||||
|
if(m_state.vb != vb || m_state.vb_stride != stride)
|
||||||
|
{
|
||||||
|
m_state.vb = vb;
|
||||||
|
m_state.vb_stride = stride;
|
||||||
|
|
||||||
|
uint32 stride2 = stride;
|
||||||
|
uint32 offset = 0;
|
||||||
|
|
||||||
|
m_ctx->IASetVertexBuffers(0, 1, &vb, &stride2, &offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Useless ?
|
||||||
|
#if 0
|
||||||
|
void GSDeviceOGL::IASetInputLayout(ID3D11InputLayout* layout)
|
||||||
|
{
|
||||||
|
if(m_state.layout != layout)
|
||||||
|
{
|
||||||
|
m_state.layout = layout;
|
||||||
|
|
||||||
|
m_ctx->IASetInputLayout(layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Useless ?
|
||||||
|
#if 0
|
||||||
|
void GSDeviceOGL::IASetPrimitiveTopology(GLenum topology)
|
||||||
|
{
|
||||||
|
if(m_state.topology != topology)
|
||||||
|
{
|
||||||
|
m_state.topology = topology;
|
||||||
|
|
||||||
|
m_ctx->IASetPrimitiveTopology(topology);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void GSDeviceOGL::VSSetShader(GLuint vs, GSUniformBufferOGL* vs_cb)
|
||||||
|
{
|
||||||
|
// glUseProgramStage
|
||||||
|
#if 0
|
||||||
|
if(m_state.vs != vs)
|
||||||
|
{
|
||||||
|
m_state.vs = vs;
|
||||||
|
|
||||||
|
m_ctx->VSSetShader(vs, NULL, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// glBindBufferBase
|
||||||
|
#if 0
|
||||||
|
if(m_state.vs_cb != vs_cb)
|
||||||
|
{
|
||||||
|
m_state.vs_cb = vs_cb;
|
||||||
|
|
||||||
|
m_ctx->VSSetConstantBuffers(0, 1, &vs_cb);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSDeviceOGL::GSSetShader(GLuint gs)
|
||||||
|
{
|
||||||
|
// glUseProgramStage
|
||||||
|
#if 0
|
||||||
|
if(m_state.gs != gs)
|
||||||
|
{
|
||||||
|
m_state.gs = gs;
|
||||||
|
|
||||||
|
m_ctx->GSSetShader(gs, NULL, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSDeviceOGL::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
|
||||||
|
{
|
||||||
|
PSSetShaderResource(0, sr0);
|
||||||
|
PSSetShaderResource(1, sr1);
|
||||||
|
PSSetShaderResource(2, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSDeviceOGL::PSSetShaderResource(int i, GSTexture* sr)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
ID3D11ShaderResourceView* srv = NULL;
|
||||||
|
|
||||||
|
if(sr) srv = *(GSTexture11*)sr;
|
||||||
|
|
||||||
|
if(m_state.ps_srv[i] != srv)
|
||||||
|
{
|
||||||
|
m_state.ps_srv[i] = srv;
|
||||||
|
|
||||||
|
m_srv_changed = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSDeviceOGL::PSSetSamplerState(GLuint ss0, GLuint ss1, GLuint ss2)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
if(m_state.ps_ss[0] != ss0 || m_state.ps_ss[1] != ss1 || m_state.ps_ss[2] != ss2)
|
||||||
|
{
|
||||||
|
m_state.ps_ss[0] = ss0;
|
||||||
|
m_state.ps_ss[1] = ss1;
|
||||||
|
m_state.ps_ss[2] = ss2;
|
||||||
|
|
||||||
|
m_ss_changed = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSDeviceOGL::PSSetShader(GLuint ps, GSUniformBufferOGL* ps_cb)
|
||||||
|
{
|
||||||
|
|
||||||
|
// glUseProgramStage
|
||||||
|
#if 0
|
||||||
|
if(m_state.ps != ps)
|
||||||
|
{
|
||||||
|
m_state.ps = ps;
|
||||||
|
|
||||||
|
m_ctx->PSSetShader(ps, NULL, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Sampler and texture must be set at the same time
|
||||||
|
// 1/ select the texture unit
|
||||||
|
// glActiveTexture(GL_TEXTURE0 + 1);
|
||||||
|
// 2/ bind the texture
|
||||||
|
// glBindTexture(GL_TEXTURE_2D , brickTexture);
|
||||||
|
// 3/ sets the texture sampler in GLSL (could be useless with layout stuff)
|
||||||
|
// glUniform1i(brickSamplerId , 1);
|
||||||
|
// 4/ set the sampler state
|
||||||
|
// glBindSampler(1 , sampler);
|
||||||
|
#if 0
|
||||||
|
if (m_srv_changed)
|
||||||
|
{
|
||||||
|
m_ctx->PSSetShaderResources(0, 3, m_state.ps_srv);
|
||||||
|
|
||||||
|
m_srv_changed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_ss_changed)
|
||||||
|
{
|
||||||
|
m_ctx->PSSetSamplers(0, 3, m_state.ps_ss);
|
||||||
|
|
||||||
|
m_ss_changed = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// glBindBufferBase
|
||||||
|
#if 0
|
||||||
|
if(m_state.ps_cb != ps_cb)
|
||||||
|
{
|
||||||
|
m_state.ps_cb = ps_cb;
|
||||||
|
|
||||||
|
m_ctx->PSSetConstantBuffers(0, 1, &ps_cb);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSDeviceOGL::OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref)
|
||||||
|
{
|
||||||
|
// Setup the stencil object. sref can be set by glStencilFunc (note remove it from the structure)
|
||||||
|
#if 0
|
||||||
|
if(m_state.dss != dss || m_state.sref != sref)
|
||||||
|
{
|
||||||
|
m_state.dss = dss;
|
||||||
|
m_state.sref = sref;
|
||||||
|
|
||||||
|
m_ctx->OMSetDepthStencilState(dss, sref);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSDeviceOGL::OMSetBlendState(GSBlendStateOGL* bs, float bf)
|
||||||
|
{
|
||||||
|
// DX:Blend factor D3D11_BLEND_BLEND_FACTOR | D3D11_BLEND_INV_BLEND_FACTOR
|
||||||
|
// OPENGL: GL_CONSTANT_COLOR | GL_ONE_MINUS_CONSTANT_COLOR
|
||||||
|
// Note factor must be set before by glBlendColor
|
||||||
|
#if 0
|
||||||
|
if(m_state.bs != bs || m_state.bf != bf)
|
||||||
|
{
|
||||||
|
m_state.bs = bs;
|
||||||
|
m_state.bf = bf;
|
||||||
|
|
||||||
|
float BlendFactor[] = {bf, bf, bf, 0};
|
||||||
|
|
||||||
|
m_ctx->OMSetBlendState(bs, BlendFactor, 0xffffffff);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor)
|
||||||
|
{
|
||||||
|
// set the attachment inside the FBO
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
ID3D11RenderTargetView* rtv = NULL;
|
||||||
|
ID3D11DepthStencilView* dsv = NULL;
|
||||||
|
|
||||||
|
if(rt) rtv = *(GSTexture11*)rt;
|
||||||
|
if(ds) dsv = *(GSTexture11*)ds;
|
||||||
|
|
||||||
|
if(m_state.rtv != rtv || m_state.dsv != dsv)
|
||||||
|
{
|
||||||
|
m_state.rtv = rtv;
|
||||||
|
m_state.dsv = dsv;
|
||||||
|
|
||||||
|
m_ctx->OMSetRenderTargets(1, &rtv, dsv);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Viewport -> glViewport
|
||||||
|
#if 0
|
||||||
|
if(m_state.viewport != rt->GetSize())
|
||||||
|
{
|
||||||
|
m_state.viewport = rt->GetSize();
|
||||||
|
|
||||||
|
D3D11_VIEWPORT vp;
|
||||||
|
|
||||||
|
memset(&vp, 0, sizeof(vp));
|
||||||
|
|
||||||
|
vp.TopLeftX = 0;
|
||||||
|
vp.TopLeftY = 0;
|
||||||
|
vp.Width = (float)rt->GetWidth();
|
||||||
|
vp.Height = (float)rt->GetHeight();
|
||||||
|
vp.MinDepth = 0.0f;
|
||||||
|
vp.MaxDepth = 1.0f;
|
||||||
|
|
||||||
|
m_ctx->RSSetViewports(1, &vp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Scissor -> glScissor (note must be enabled)
|
||||||
|
#if 0
|
||||||
|
GSVector4i r = scissor ? *scissor : GSVector4i(rt->GetSize()).zwxy();
|
||||||
|
|
||||||
|
if(!m_state.scissor.eq(r))
|
||||||
|
{
|
||||||
|
m_state.scissor = r;
|
||||||
|
|
||||||
|
m_ctx->RSSetScissorRects(1, r);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,242 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011-2011 Gregory hainaut
|
||||||
|
* Copyright (C) 2007-2009 Gabest
|
||||||
|
*
|
||||||
|
* This Program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This Program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
* http://www.gnu.org/copyleft/gpl.html
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GSDevice.h"
|
||||||
|
#include "GSTextureOGL.h"
|
||||||
|
#include "GSdx.h"
|
||||||
|
|
||||||
|
struct GSBlendStateOGL {
|
||||||
|
// Note: You can also select the index of the draw buffer for which to set the blend setting
|
||||||
|
// We will keep basic the first try
|
||||||
|
bool m_enable;
|
||||||
|
GLenum m_equation_RGB;
|
||||||
|
GLenum m_equation_ALPHA;
|
||||||
|
GLenum m_func_RGB;
|
||||||
|
GLenum m_func_ALPHA;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GSDepthStencilOGL {
|
||||||
|
bool m_depth_enable;
|
||||||
|
GLenum m_depth_func;
|
||||||
|
// Note front face and back can be split might. But it seems they have same parameter configuration
|
||||||
|
bool m_stencil_enable;
|
||||||
|
GLuint m_stencil_mask;
|
||||||
|
GLuint m_stencil_func;
|
||||||
|
GLuint m_stencil_ref;
|
||||||
|
GLuint m_stencil_sfail_op;
|
||||||
|
GLuint m_stencil_spass_dfail_op;
|
||||||
|
GLuint m_stencil_spass_dpass_op;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GSUniformBufferOGL {
|
||||||
|
GLuint buffer;
|
||||||
|
GLuint index;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GSDeviceOGL : public GSDevice
|
||||||
|
{
|
||||||
|
uint32 m_msaa;
|
||||||
|
|
||||||
|
// Vertex buffer: glGenBuffers, glBindBuffer GL_ARRAY_BUFFER
|
||||||
|
GLuint m_vb; // buffer object
|
||||||
|
|
||||||
|
struct {
|
||||||
|
GLuint ps[2]; // program object
|
||||||
|
GSUniformBufferOGL* cb; // uniform buffer object
|
||||||
|
GSBlendStateOGL* bs;
|
||||||
|
} m_merge;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
GLuint ps[4]; // program object
|
||||||
|
GSUniformBufferOGL* cb; // uniform buffer object
|
||||||
|
} m_interlace;
|
||||||
|
|
||||||
|
//struct
|
||||||
|
//{
|
||||||
|
// CComPtr<ID3D11InputLayout> il;
|
||||||
|
// CComPtr<ID3D11VertexShader> vs; // program object
|
||||||
|
// CComPtr<ID3D11PixelShader> ps[8]; // program object
|
||||||
|
// CComPtr<ID3D11SamplerState> ln;
|
||||||
|
// CComPtr<ID3D11SamplerState> pt;
|
||||||
|
// CComPtr<ID3D11DepthStencilState> dss;
|
||||||
|
// CComPtr<ID3D11BlendState> bs; // no equivalent
|
||||||
|
//} m_convert;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
// Hum I think this one is useless. As far as I understand
|
||||||
|
// it only get the index name of GLSL-equivalent input attribut
|
||||||
|
// ??? CComPtr<ID3D11InputLayout> il;
|
||||||
|
GLuint vs; // program object
|
||||||
|
GLuint ps[8]; // program object
|
||||||
|
GLuint ln; // sampler object
|
||||||
|
GLuint pt; // sampler object
|
||||||
|
GSDepthStencilOGL* dss;
|
||||||
|
GSBlendStateOGL* bs;
|
||||||
|
} m_convert;
|
||||||
|
|
||||||
|
// struct
|
||||||
|
// {
|
||||||
|
// CComPtr<ID3D11DepthStencilState> dss;
|
||||||
|
// CComPtr<ID3D11BlendState> bs;
|
||||||
|
// } m_date;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
GSDepthStencilOGL* dss;
|
||||||
|
GSBlendStateOGL* bs;
|
||||||
|
} m_date;
|
||||||
|
|
||||||
|
// struct
|
||||||
|
// {
|
||||||
|
// ID3D11Buffer* vb;
|
||||||
|
// size_t vb_stride;
|
||||||
|
// ID3D11InputLayout* layout;
|
||||||
|
// D3D11_PRIMITIVE_TOPOLOGY topology;
|
||||||
|
// ID3D11VertexShader* vs;
|
||||||
|
// ID3D11Buffer* vs_cb;
|
||||||
|
// ID3D11GeometryShader* gs;
|
||||||
|
// ID3D11ShaderResourceView* ps_srv[3];
|
||||||
|
// ID3D11PixelShader* ps;
|
||||||
|
// ID3D11Buffer* ps_cb;
|
||||||
|
// ID3D11SamplerState* ps_ss[3];
|
||||||
|
// GSVector2i viewport;
|
||||||
|
// GSVector4i scissor;
|
||||||
|
// ID3D11DepthStencilState* dss;
|
||||||
|
// uint8 sref;
|
||||||
|
// ID3D11BlendState* bs;
|
||||||
|
// float bf;
|
||||||
|
// ID3D11RenderTargetView* rtv;
|
||||||
|
// ID3D11DepthStencilView* dsv;
|
||||||
|
// } m_state;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
GLuint vb;
|
||||||
|
// Hum I think those things can be dropped on OGL. It probably need an others architecture (see glVertexAttribPointer)
|
||||||
|
// size_t vb_stride;
|
||||||
|
// ID3D11InputLayout* layout;
|
||||||
|
GLenum topology; // (ie GL_TRIANGLES...)
|
||||||
|
GLuint vs; // program
|
||||||
|
GSUniformBufferOGL* vs_cb; // uniform 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
|
||||||
|
GSUniformBufferOGL* ps_cb; // uniform buffer
|
||||||
|
GLuint ps_ss[3]; // sampler
|
||||||
|
GSVector2i viewport;
|
||||||
|
GSVector4i scissor;
|
||||||
|
GSDepthStencilOGL* dss;
|
||||||
|
uint8 sref;
|
||||||
|
GSBlendStateOGL* bs;
|
||||||
|
float bf;
|
||||||
|
// FIXME texture attachment in the FBO
|
||||||
|
// ID3D11RenderTargetView* rtv;
|
||||||
|
// ID3D11DepthStencilView* dsv;
|
||||||
|
} m_state;
|
||||||
|
|
||||||
|
bool m_srv_changed;
|
||||||
|
bool m_ss_changed;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
CComPtr<ID3D11Device> m_dev;
|
||||||
|
CComPtr<ID3D11DeviceContext> m_ctx;
|
||||||
|
CComPtr<IDXGISwapChain> m_swapchain;
|
||||||
|
|
||||||
|
CComPtr<ID3D11RasterizerState> m_rs;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
CComPtr<ID3D11PixelShader> ps;
|
||||||
|
CComPtr<ID3D11Buffer> cb;
|
||||||
|
} m_fxaa;
|
||||||
|
|
||||||
|
|
||||||
|
// Shaders...
|
||||||
|
|
||||||
|
hash_map<uint32, GSVertexShader11 > m_vs;
|
||||||
|
CComPtr<ID3D11Buffer> m_vs_cb;
|
||||||
|
hash_map<uint32, CComPtr<ID3D11GeometryShader> > m_gs;
|
||||||
|
hash_map<uint32, CComPtr<ID3D11PixelShader> > m_ps;
|
||||||
|
CComPtr<ID3D11Buffer> m_ps_cb;
|
||||||
|
hash_map<uint32, CComPtr<ID3D11SamplerState> > m_ps_ss;
|
||||||
|
CComPtr<ID3D11SamplerState> m_palette_ss;
|
||||||
|
CComPtr<ID3D11SamplerState> m_rt_ss;
|
||||||
|
hash_map<uint32, CComPtr<ID3D11DepthStencilState> > m_om_dss;
|
||||||
|
hash_map<uint32, CComPtr<ID3D11BlendState> > m_om_bs;
|
||||||
|
|
||||||
|
VSConstantBuffer m_vs_cb_cache;
|
||||||
|
PSConstantBuffer m_ps_cb_cache;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GSTexture* CreateSurface(int type, int w, int h, bool msaa, int format);
|
||||||
|
GSTexture* FetchSurface(int type, int w, int h, bool msaa, int format);
|
||||||
|
void DoMerge(GSTexture* st[2], GSVector4* sr, GSTexture* dt, GSVector4* dr, bool slbg, bool mmod, const GSVector4& c);
|
||||||
|
void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset = 0);
|
||||||
|
|
||||||
|
public:
|
||||||
|
GSDeviceOGL();
|
||||||
|
virtual ~GSDeviceOGL();
|
||||||
|
|
||||||
|
bool Create(GSWnd* wnd);
|
||||||
|
bool Reset(int w, int h);
|
||||||
|
void Flip();
|
||||||
|
|
||||||
|
void DrawPrimitive();
|
||||||
|
|
||||||
|
void ClearRenderTarget(GSTexture* t, const GSVector4& c);
|
||||||
|
void ClearRenderTarget(GSTexture* t, uint32 c);
|
||||||
|
void ClearDepth(GSTexture* t, float c);
|
||||||
|
void ClearStencil(GSTexture* t, uint8 c);
|
||||||
|
|
||||||
|
GSTexture* CreateRenderTarget(int w, int h, bool msaa, int format = 0);
|
||||||
|
GSTexture* CreateDepthStencil(int w, int h, bool msaa, int format = 0);
|
||||||
|
GSTexture* CreateTexture(int w, int h, int format = 0);
|
||||||
|
GSTexture* CreateOffscreen(int w, int h, int format = 0);
|
||||||
|
|
||||||
|
GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0);
|
||||||
|
|
||||||
|
void CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r);
|
||||||
|
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true);
|
||||||
|
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, GLuint ps, GSUniformBufferOGL* ps_cb, bool linear);
|
||||||
|
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, GLuint ps, GSUniformBufferOGL ps_cb, GSBlendStateOGL* bs, bool linear);
|
||||||
|
|
||||||
|
GSTexture* Resolve(GSTexture* t);
|
||||||
|
|
||||||
|
void IASetVertexBuffer(const void* vertices, size_t stride, size_t count);
|
||||||
|
|
||||||
|
void VSSetShader(GLuint vs, GSUniformBufferOGL* vs_cb);
|
||||||
|
void GSSetShader(GLuint gs);
|
||||||
|
|
||||||
|
void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1);
|
||||||
|
void PSSetShaderResource(int i, GSTexture* sr);
|
||||||
|
void PSSetSamplerState(GLuint ss0, GLuint ss1, GLuint ss2);
|
||||||
|
void PSSetShader(GLuint ps, GSUniformBufferOGL* ps_cb);
|
||||||
|
|
||||||
|
void OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref);
|
||||||
|
void OMSetBlendState(GSBlendStateOGL* bs, float bf);
|
||||||
|
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL);
|
||||||
|
|
||||||
|
|
||||||
|
};
|
|
@ -42,6 +42,7 @@ static void SysMessage(const char *fmt, ...)
|
||||||
|
|
||||||
bool RunLinuxDialog()
|
bool RunLinuxDialog()
|
||||||
{
|
{
|
||||||
|
// FIXME need to add msaa option configuration
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
GtkWidget *main_frame, *main_box;
|
GtkWidget *main_frame, *main_box;
|
||||||
GtkWidget *render_label, *render_combo_box;
|
GtkWidget *render_label, *render_combo_box;
|
||||||
|
@ -76,10 +77,25 @@ bool RunLinuxDialog()
|
||||||
|
|
||||||
if(!s.note.empty()) label += format(" (%s)", s.note.c_str());
|
if(!s.note.empty()) label += format(" (%s)", s.note.c_str());
|
||||||
|
|
||||||
|
// (dev only) for any NULL stuff
|
||||||
|
if (i >= 7 && i <= 9) label += " (debug only)";
|
||||||
|
// (experimental) for opengl stuff
|
||||||
|
if (i == 10 || i == 11) label += " (experimental)";
|
||||||
|
|
||||||
gtk_combo_box_append_text(GTK_COMBO_BOX(render_combo_box), label.c_str());
|
gtk_combo_box_append_text(GTK_COMBO_BOX(render_combo_box), label.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_combo_box_set_active(GTK_COMBO_BOX(render_combo_box), 0);
|
int renderer_box_position = 0;
|
||||||
|
switch (theApp.GetConfig("renderer", 0)) {
|
||||||
|
// Note the value are based on m_gs_renderers vector on GSdx.cpp
|
||||||
|
case 7 : renderer_box_position = 0; break;
|
||||||
|
case 8 : renderer_box_position = 1; break;
|
||||||
|
case 10: renderer_box_position = 2; break;
|
||||||
|
case 11: renderer_box_position = 3; break;
|
||||||
|
case 12: renderer_box_position = 4; break;
|
||||||
|
case 13: renderer_box_position = 5; break;
|
||||||
|
}
|
||||||
|
gtk_combo_box_set_active(GTK_COMBO_BOX(render_combo_box), renderer_box_position );
|
||||||
gtk_container_add(GTK_CONTAINER(main_box), render_label);
|
gtk_container_add(GTK_CONTAINER(main_box), render_label);
|
||||||
gtk_container_add(GTK_CONTAINER(main_box), render_combo_box);
|
gtk_container_add(GTK_CONTAINER(main_box), render_combo_box);
|
||||||
|
|
||||||
|
@ -142,12 +158,22 @@ bool RunLinuxDialog()
|
||||||
if (return_value == GTK_RESPONSE_ACCEPT)
|
if (return_value == GTK_RESPONSE_ACCEPT)
|
||||||
{
|
{
|
||||||
// Get all the settings from the dialog box.
|
// Get all the settings from the dialog box.
|
||||||
|
if (gtk_combo_box_get_active(GTK_COMBO_BOX(render_combo_box)) != -1) {
|
||||||
|
// FIXME test current opengl version supported through glxinfo (OpenGL version string:)
|
||||||
|
// Warn the user if 4.2 is not supported and switch back to basic SDL renderer
|
||||||
|
switch (gtk_combo_box_get_active(GTK_COMBO_BOX(render_combo_box))) {
|
||||||
|
// Note the value are based on m_gs_renderers vector on GSdx.cpp
|
||||||
|
case 0: theApp.SetConfig("renderer", 7); break;
|
||||||
|
case 1: theApp.SetConfig("renderer", 8); break;
|
||||||
|
case 2: theApp.SetConfig("renderer", 10); break;
|
||||||
|
case 3: theApp.SetConfig("renderer", 11); break;
|
||||||
|
case 4: theApp.SetConfig("renderer", 12); break;
|
||||||
|
case 5: theApp.SetConfig("renderer", 13); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// I'll put the right variable names in later.
|
// I'll put the right variable names in later.
|
||||||
if (gtk_combo_box_get_active(GTK_COMBO_BOX(render_combo_box)) != -1)
|
|
||||||
renderer = gtk_combo_box_get_active(GTK_COMBO_BOX(render_combo_box));
|
|
||||||
|
|
||||||
// Crash, for some interlace options
|
// Crash, for some interlace options
|
||||||
if (gtk_combo_box_get_active(GTK_COMBO_BOX(interlace_combo_box)) != -1)
|
if (gtk_combo_box_get_active(GTK_COMBO_BOX(interlace_combo_box)) != -1)
|
||||||
theApp.SetConfig( "interlace", (int)gtk_combo_box_get_active(GTK_COMBO_BOX(interlace_combo_box)) );
|
theApp.SetConfig( "interlace", (int)gtk_combo_box_get_active(GTK_COMBO_BOX(interlace_combo_box)) );
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011-2011 Gregory hainaut
|
||||||
|
* Copyright (C) 2007-2009 Gabest
|
||||||
|
*
|
||||||
|
* This Program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This Program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
* http://www.gnu.org/copyleft/gpl.html
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "GSRendererOGL.h"
|
||||||
|
#include "GSRenderer.h"
|
||||||
|
|
||||||
|
|
||||||
|
GSRendererOGL::GSRendererOGL()
|
||||||
|
// FIXME
|
||||||
|
//: GSRendererHW<GSVertexHWOGL>(new GSTextureCacheOGL(this))
|
||||||
|
: GSRendererHW<GSVertexHW11>(new GSTextureCacheOGL(this))
|
||||||
|
{
|
||||||
|
// TODO must be implementer with macro InitVertexKick(GSRendererOGL)
|
||||||
|
// template<uint32 prim, uint32 tme, uint32 fst> void VertexKick(bool skip);
|
||||||
|
InitVertexKick(GSRendererOGL);
|
||||||
|
}
|
||||||
|
|
||||||
|
GSRendererOGL::~GSRendererOGL() { /* TODO */ }
|
||||||
|
|
||||||
|
bool GSRendererOGL::CreateDevice(GSDevice* dev) { /* TODO */ }
|
||||||
|
|
||||||
|
template<uint32 prim, uint32 tme, uint32 fst>
|
||||||
|
void GSRendererOGL::VertexKick(bool skip) { /* TODO */ }
|
||||||
|
|
||||||
|
void GSRendererOGL::Draw(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) { /* TODO */ }
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011-2011 Gregory hainaut
|
||||||
|
* Copyright (C) 2007-2009 Gabest
|
||||||
|
*
|
||||||
|
* This Program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This Program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
* http://www.gnu.org/copyleft/gpl.html
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GSRendererHW.h"
|
||||||
|
|
||||||
|
#include "GSRenderer.h"
|
||||||
|
#include "GSTextureCacheOGL.h"
|
||||||
|
#include "GSVertexHW.h"
|
||||||
|
|
||||||
|
// FIXME does it need a GSVertexHWOGL ??? Data order can be easily programmed on opengl (the only potential
|
||||||
|
// issue is the unsupported praga push/pop
|
||||||
|
// Note it impact GSVertexTrace.cpp => void GSVertexTrace::Update(const GSVertexHWOGL* v, int count, GS_PRIM_CLASS primclass)
|
||||||
|
class GSRendererOGL : public GSRendererHW<GSVertexHW11>
|
||||||
|
//class GSRendererOGL : public GSRendererHW<GSVertexHWOGL>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GSTextureCache* m_tc;
|
||||||
|
|
||||||
|
void Draw(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex);
|
||||||
|
|
||||||
|
public:
|
||||||
|
GSRendererOGL();
|
||||||
|
virtual ~GSRendererOGL();
|
||||||
|
|
||||||
|
template<uint32 prim, uint32 tme, uint32 fst> void VertexKick(bool skip);
|
||||||
|
|
||||||
|
bool CreateDevice(GSDevice* dev);
|
||||||
|
};
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
struct GSSetting
|
struct GSSetting
|
||||||
{
|
{
|
||||||
uint32 id;
|
uint32 id;
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011-2011 Gregory hainaut
|
||||||
|
* Copyright (C) 2007-2009 Gabest
|
||||||
|
* http://www.gabest.org
|
||||||
|
*
|
||||||
|
* This Program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This Program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
* http://www.gnu.org/copyleft/gpl.html
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "GSTextureCacheOGL.h"
|
||||||
|
|
||||||
|
GSTextureCacheOGL::GSTextureCacheOGL(GSRenderer* r)
|
||||||
|
: GSTextureCache(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
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GIFRegTEX0& TEX0 = t->m_TEX0;
|
||||||
|
|
||||||
|
if(TEX0.PSM != PSM_PSMCT32
|
||||||
|
&& TEX0.PSM != PSM_PSMCT24
|
||||||
|
&& TEX0.PSM != PSM_PSMCT16
|
||||||
|
&& TEX0.PSM != PSM_PSMCT16S)
|
||||||
|
{
|
||||||
|
//ASSERT(0);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!t->m_dirty.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf("GSRenderTarget::Read %d,%d - %d,%d (%08x)\n", r.left, r.top, r.right, r.bottom, TEX0.TBP0);
|
||||||
|
|
||||||
|
int w = r.width();
|
||||||
|
int h = r.height();
|
||||||
|
|
||||||
|
GSVector4 src = GSVector4(r) * GSVector4(t->m_texture->GetScale()).xyxy() / GSVector4(t->m_texture->GetSize()).xyxy();
|
||||||
|
|
||||||
|
DXGI_FORMAT format = TEX0.PSM == PSM_PSMCT16 || TEX0.PSM == PSM_PSMCT16S ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
|
||||||
|
if(GSTexture* offscreen = m_renderer->m_dev->CopyOffscreen(t->m_texture, src, w, h, format))
|
||||||
|
{
|
||||||
|
GSTexture::GSMap m;
|
||||||
|
|
||||||
|
if(offscreen->Map(m))
|
||||||
|
{
|
||||||
|
// TODO: block level write
|
||||||
|
|
||||||
|
GSOffset* o = m_renderer->m_mem.GetOffset(TEX0.TBP0, TEX0.TBW, TEX0.PSM);
|
||||||
|
|
||||||
|
switch(TEX0.PSM)
|
||||||
|
{
|
||||||
|
case PSM_PSMCT32:
|
||||||
|
m_renderer->m_mem.WritePixel32(m.bits, m.pitch, o, r);
|
||||||
|
break;
|
||||||
|
case PSM_PSMCT24:
|
||||||
|
m_renderer->m_mem.WritePixel24(m.bits, m.pitch, o, r);
|
||||||
|
break;
|
||||||
|
case PSM_PSMCT16:
|
||||||
|
case PSM_PSMCT16S:
|
||||||
|
m_renderer->m_mem.WritePixel16(m.bits, m.pitch, o, r);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
offscreen->Unmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_renderer->m_dev->Recycle(offscreen);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011-2011 Gregory hainaut
|
||||||
|
* Copyright (C) 2007-2009 Gabest
|
||||||
|
* http://www.gabest.org
|
||||||
|
*
|
||||||
|
* This Program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This Program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
* http://www.gnu.org/copyleft/gpl.html
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GSTextureCache.h"
|
||||||
|
#include "GSDeviceOGL.h"
|
||||||
|
|
||||||
|
class GSTextureCacheOGL : public GSTextureCache
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
int Get8bitFormat() {/* TODO return DXGI_FORMAT_A8_UNORM;*/}
|
||||||
|
|
||||||
|
void Read(Target* t, const GSVector4i& r);
|
||||||
|
|
||||||
|
public:
|
||||||
|
GSTextureCacheOGL(GSRenderer* r);
|
||||||
|
};
|
|
@ -0,0 +1,257 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011-2011 Gregory hainaut
|
||||||
|
* Copyright (C) 2007-2009 Gabest
|
||||||
|
*
|
||||||
|
* This Program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This Program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
* http://www.gnu.org/copyleft/gpl.html
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GSTextureOGL.h"
|
||||||
|
|
||||||
|
GSTextureOGL::GSTextureOGL(/* ID3D11Texture2D* texture */ )
|
||||||
|
{
|
||||||
|
// *************************************************************
|
||||||
|
// Opengl world
|
||||||
|
|
||||||
|
// http://www.opengl.org/wiki/Renderbuffer_Object
|
||||||
|
// render: constructor -> glGenRenderbuffers, glDeleteRenderbuffers
|
||||||
|
// info -> glGetRenderbufferParameteriv, glIsRenderbuffer
|
||||||
|
// binding -> glBindRenderbuffer (only 1 target), glFramebufferRenderbuffer (attach actually)
|
||||||
|
// setup param -> glRenderbufferStorageMultisample (after this call the buffer is unitialized)
|
||||||
|
//
|
||||||
|
// the only way to use a renderbuffer object is to attach it to a Framebuffer Object. After you bind that
|
||||||
|
// FBO to the context, and set up the draw or read buffers appropriately, you can use pixel transfer operations
|
||||||
|
// to read and write to it. Of course, you can also render to it. The standard glClear function will also clear the appropriate buffer.
|
||||||
|
//
|
||||||
|
// Render work in parallal with framebuffer object (FBO) http://www.opengl.org/wiki/Framebuffer_Objects
|
||||||
|
// render are attached to FBO through : glFramebufferRenderbuffer. You can query the number of colorattachement with GL_MAX_COLOR_ATTACHMENTS
|
||||||
|
// FBO : constructor -> glGenFramebuffers, glDeleteFramebuffers
|
||||||
|
// binding -> glBindFramebuffer (target can be read/write/both)
|
||||||
|
// blit -> glBlitFramebuffer (read FB to draw FB)
|
||||||
|
// info -> glIsFramebuffer, glGetFramebufferAttachmentParameter, glCheckFramebufferStatus
|
||||||
|
//
|
||||||
|
// There are two types of framebuffer-attachable images; texture images and renderbuffer images.
|
||||||
|
// If an image of a texture object is attached to a framebuffer, OpenGL performs "render to texture".
|
||||||
|
// And if an image of a renderbuffer object is attached to a framebuffer, then OpenGL performs "offscreen rendering".
|
||||||
|
// Blitting:
|
||||||
|
// glDrawBuffers
|
||||||
|
// glReadBuffer
|
||||||
|
// glBlitFramebuffer
|
||||||
|
|
||||||
|
// *************************************************************
|
||||||
|
// Doc
|
||||||
|
// It might need a texture structure to replace ID3D11Texture2D.
|
||||||
|
//
|
||||||
|
// == The function need to set (from parameter)
|
||||||
|
// : m_size.x
|
||||||
|
// : m_size.y
|
||||||
|
// : m_type
|
||||||
|
// : m_format
|
||||||
|
// : m_msaa
|
||||||
|
// == Might be useful to save
|
||||||
|
// : m_texture_target (like GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE etc...)
|
||||||
|
// : m_texture_id (return by glGen*)
|
||||||
|
//
|
||||||
|
// == Then generate the texture or buffer.
|
||||||
|
// D3D11_BIND_RENDER_TARGET: Bind a texture as a render target for the output-merger stage.
|
||||||
|
// => glGenRenderbuffers with GL_COLOR_ATTACHMENTi (Hum glGenTextures might work too)
|
||||||
|
// D3D11_BIND_DEPTH_STENCIL: Bind a texture as a depth-stencil target for the output-merger stage.
|
||||||
|
// => glGenRenderbuffers with GL_DEPTH_STENCIL_ATTACHMENT
|
||||||
|
// D3D11_BIND_SHADER_RESOURCE: Bind a buffer or texture to a shader stage
|
||||||
|
// => glGenTextures
|
||||||
|
// D3D11_USAGE_STAGING: A resource that supports data transfer (copy) from the GPU to the CPU.
|
||||||
|
// glGenTextures
|
||||||
|
// glReadPixels seems to use a framebuffer. In this case you can setup the source
|
||||||
|
// with glReadBuffer(GL_COLOR_ATTACHMENTi)
|
||||||
|
// glGetTexImage: read pixels of a bound texture
|
||||||
|
// => To allow map/unmap. I think we can use a pixel buffer (target GL_PIXEL_UNPACK_BUFFER)
|
||||||
|
// http://www.opengl.org/wiki/Pixel_Buffer_Objects
|
||||||
|
// == Enable texture Unit
|
||||||
|
// EnableUnit();
|
||||||
|
// == Allocate space
|
||||||
|
// glRenderbufferStorageMultisample or glTexStorage2D
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
m_texture->GetDevice(&m_dev);
|
||||||
|
m_texture->GetDesc(&m_desc);
|
||||||
|
|
||||||
|
m_dev->GetImmediateContext(&m_ctx);
|
||||||
|
|
||||||
|
m_size.x = (int)m_desc.Width;
|
||||||
|
m_size.y = (int)m_desc.Height;
|
||||||
|
|
||||||
|
if(m_desc.BindFlags & D3D11_BIND_RENDER_TARGET) m_type = RenderTarget;
|
||||||
|
else if(m_desc.BindFlags & D3D11_BIND_DEPTH_STENCIL) m_type = DepthStencil;
|
||||||
|
else if(m_desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) m_type = Texture;
|
||||||
|
else if(m_desc.Usage == D3D11_USAGE_STAGING) m_type = Offscreen;
|
||||||
|
|
||||||
|
m_format = (int)m_desc.Format;
|
||||||
|
|
||||||
|
m_msaa = m_desc.SampleDesc.Count > 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
GSTextureOGL::~GSTextureOGL()
|
||||||
|
{
|
||||||
|
// glDeleteTextures or glDeleteRenderbuffers
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSTextureOGL::EnableUnit()
|
||||||
|
{
|
||||||
|
// == For texture, the Unit must be selected
|
||||||
|
// glActiveTexture
|
||||||
|
// !!!!!!!!!! VERY BIG ISSUE, how to ensure that the different texture use different texture unit.
|
||||||
|
// I think we need to create a pool on GSdevice.
|
||||||
|
// 1/ this->m_device_ogl
|
||||||
|
// 2/ int GSDeviceOGL::get_free_texture_unit() called from GSTextureOGL constructor
|
||||||
|
// 3/ void GSDeviceOGL::release_texture_unit(int) called from GSDeviceOGL destructor
|
||||||
|
// Another (better) idea, will be to create a global static pool
|
||||||
|
//
|
||||||
|
// == Bind the texture or buffer
|
||||||
|
// glBindRenderbuffer or glBindTexture
|
||||||
|
//
|
||||||
|
// !!!!!!!!!! Maybe attach to the FBO but where to manage the FBO!!!
|
||||||
|
// Create a separare public method for attachment ???
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
|
||||||
|
{
|
||||||
|
// To update only a part of the texture you can use:
|
||||||
|
// glTexSubImage2D — specify a two-dimensional texture subimage
|
||||||
|
#if 0
|
||||||
|
if(m_dev && m_texture)
|
||||||
|
{
|
||||||
|
D3D11_BOX box = {r.left, r.top, 0, r.right, r.bottom, 1};
|
||||||
|
|
||||||
|
m_ctx->UpdateSubresource(m_texture, 0, &box, data, pitch, 0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
|
||||||
|
{
|
||||||
|
// The function allow to modify the texture from the CPU
|
||||||
|
// Set m.bits <- pointer to the data
|
||||||
|
// Set m.pitch <- size of a row
|
||||||
|
// I think in opengl we need to copy back the data to the RAM: glReadPixels — read a block of pixels from the frame buffer
|
||||||
|
//
|
||||||
|
// glMapBuffer — map a buffer object's data store
|
||||||
|
#if 0
|
||||||
|
if(r != NULL)
|
||||||
|
{
|
||||||
|
// ASSERT(0); // not implemented
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_texture && m_desc.Usage == D3D11_USAGE_STAGING)
|
||||||
|
{
|
||||||
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
|
|
||||||
|
if(SUCCEEDED(m_ctx->Map(m_texture, 0, D3D11_MAP_READ_WRITE, 0, &map)))
|
||||||
|
{
|
||||||
|
m.bits = (uint8*)map.pData;
|
||||||
|
m.pitch = (int)map.RowPitch;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSTextureOGL::Unmap()
|
||||||
|
{
|
||||||
|
// copy the texture to the GPU
|
||||||
|
// GLboolean glUnmapBuffer(GLenum target);
|
||||||
|
#if 0
|
||||||
|
if(m_texture)
|
||||||
|
{
|
||||||
|
m_ctx->Unmap(m_texture, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// If I'm correct, this function only dump some buffer. Debug only, still very useful!
|
||||||
|
// Note: check zzogl implementation
|
||||||
|
bool GSTextureOGL::Save(const string& fn, bool dds)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
CComPtr<ID3D11Resource> res;
|
||||||
|
|
||||||
|
if(m_desc.BindFlags & D3D11_BIND_DEPTH_STENCIL)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
|
|
||||||
|
memset(&desc, 0, sizeof(desc));
|
||||||
|
|
||||||
|
m_texture->GetDesc(&desc);
|
||||||
|
|
||||||
|
desc.Usage = D3D11_USAGE_STAGING;
|
||||||
|
desc.BindFlags = 0;
|
||||||
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||||
|
|
||||||
|
CComPtr<ID3D11Texture2D> src, dst;
|
||||||
|
|
||||||
|
hr = m_dev->CreateTexture2D(&desc, NULL, &src);
|
||||||
|
|
||||||
|
m_ctx->CopyResource(src, m_texture);
|
||||||
|
|
||||||
|
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
|
|
||||||
|
hr = m_dev->CreateTexture2D(&desc, NULL, &dst);
|
||||||
|
|
||||||
|
D3D11_MAPPED_SUBRESOURCE sm, dm;
|
||||||
|
|
||||||
|
hr = m_ctx->Map(src, 0, D3D11_MAP_READ, 0, &sm);
|
||||||
|
hr = m_ctx->Map(dst, 0, D3D11_MAP_WRITE, 0, &dm);
|
||||||
|
|
||||||
|
uint8* s = (uint8*)sm.pData;
|
||||||
|
uint8* d = (uint8*)dm.pData;
|
||||||
|
|
||||||
|
for(uint32 y = 0; y < desc.Height; y++, s += sm.RowPitch, d += dm.RowPitch)
|
||||||
|
{
|
||||||
|
for(uint32 x = 0; x < desc.Width; x++)
|
||||||
|
{
|
||||||
|
((uint32*)d)[x] = (uint32)(ldexpf(((float*)s)[x*2], 32));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ctx->Unmap(src, 0);
|
||||||
|
m_ctx->Unmap(dst, 0);
|
||||||
|
|
||||||
|
res = dst;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res = m_texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCEEDED(D3DX11SaveTextureToFile(m_ctx, res, dds ? D3DX11_IFF_DDS : D3DX11_IFF_BMP, fn.c_str()));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011-2011 Gregory hainaut
|
||||||
|
* Copyright (C) 2007-2009 Gabest
|
||||||
|
*
|
||||||
|
* This Program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This Program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
* http://www.gnu.org/copyleft/gpl.html
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GSTexture.h"
|
||||||
|
|
||||||
|
class GSTextureOGL : public GSTexture
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
GLenum m_texture_target; // texture target: 2D, rectangle etc...
|
||||||
|
GLuint m_texture_id; // the texture id
|
||||||
|
int m_texture_unit; // the texture unit offset
|
||||||
|
|
||||||
|
void EnableUnit();
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit GSTextureOGL();
|
||||||
|
virtual ~GSTextureOGL();
|
||||||
|
|
||||||
|
bool Update(const GSVector4i& r, const void* data, int pitch);
|
||||||
|
bool Map(GSMap& m, const GSVector4i* r = NULL);
|
||||||
|
void Unmap();
|
||||||
|
bool Save(const string& fn, bool dds = false);
|
||||||
|
};
|
|
@ -33,7 +33,7 @@ public:
|
||||||
{
|
{
|
||||||
m_base = _aligned_malloc(sizeof(Vertex) * countof(m_v), 32);
|
m_base = _aligned_malloc(sizeof(Vertex) * countof(m_v), 32);
|
||||||
|
|
||||||
for(int i = 0; i < countof(m_v); i++)
|
for(uint i = 0; i < countof(m_v); i++)
|
||||||
{
|
{
|
||||||
m_v[i] = &((Vertex*)m_base)[i];
|
m_v[i] = &((Vertex*)m_base)[i];
|
||||||
}
|
}
|
||||||
|
|
|
@ -376,6 +376,22 @@ bool GSWnd::Create(const string& title, int w, int h)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_managed = true;
|
m_managed = true;
|
||||||
|
|
||||||
|
// If the user request OpenGL acceleration, we take recent OGL version (4.2)
|
||||||
|
// We keep the default 2.1 version in SW mode (only DX11 capable card, are compatible with OGL4)
|
||||||
|
if ( theApp.GetConfig("renderer", 0) / 3 == 4 ) {
|
||||||
|
// Setup visual attribute
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 32 );
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 );
|
||||||
|
// Ask for an advance opengl version
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 4 );
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 2 );
|
||||||
|
}
|
||||||
|
|
||||||
m_window = SDL_CreateWindow(title.c_str(), 100, 100, w, h, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
|
m_window = SDL_CreateWindow(title.c_str(), 100, 100, w, h, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
|
||||||
|
|
||||||
// Get the X window from the newly created window
|
// Get the X window from the newly created window
|
||||||
|
|
|
@ -116,6 +116,8 @@ GSdxApp::GSdxApp()
|
||||||
m_gs_renderers.push_back(GSSetting(8, "SDL 1.3", "Null"));
|
m_gs_renderers.push_back(GSSetting(8, "SDL 1.3", "Null"));
|
||||||
m_gs_renderers.push_back(GSSetting(10, "Null", "Software"));
|
m_gs_renderers.push_back(GSSetting(10, "Null", "Software"));
|
||||||
m_gs_renderers.push_back(GSSetting(11, "Null", "Null"));
|
m_gs_renderers.push_back(GSSetting(11, "Null", "Null"));
|
||||||
|
m_gs_renderers.push_back(GSSetting(12, "OpenGL", "Hardware"));
|
||||||
|
m_gs_renderers.push_back(GSSetting(13, "OpenGL", "Software"));
|
||||||
|
|
||||||
m_gs_interlace.push_back(GSSetting(0, "None", ""));
|
m_gs_interlace.push_back(GSSetting(0, "None", ""));
|
||||||
m_gs_interlace.push_back(GSSetting(1, "Weave tff", "saw-tooth"));
|
m_gs_interlace.push_back(GSSetting(1, "Weave tff", "saw-tooth"));
|
||||||
|
|
|
@ -111,6 +111,10 @@ using namespace stdext;
|
||||||
//#include <ext/hash_map>
|
//#include <ext/hash_map>
|
||||||
//#include <ext/hash_set>
|
//#include <ext/hash_set>
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <GL/glext.h>
|
||||||
|
|
||||||
//using namespace __gnu_cxx;
|
//using namespace __gnu_cxx;
|
||||||
|
|
||||||
#define DIRECTORY_SEPARATOR '/'
|
#define DIRECTORY_SEPARATOR '/'
|
||||||
|
@ -333,4 +337,4 @@ extern void vmfree(void* ptr, size_t size);
|
||||||
//#define NO_CRC_HACKS // Disable all game specific hacks
|
//#define NO_CRC_HACKS // Disable all game specific hacks
|
||||||
#ifdef HW_NO_TEXTURE_CACHE
|
#ifdef HW_NO_TEXTURE_CACHE
|
||||||
#define NO_CRC_HACKS
|
#define NO_CRC_HACKS
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue