GSdx: started a hardware independent device, will be useful for GDI/SDL/etc output later.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4328 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gabest11 2011-02-20 18:59:02 +00:00
parent 870da347be
commit dcf81693f6
14 changed files with 512 additions and 79 deletions

View File

@ -26,8 +26,8 @@
const GSVector4i GPULocalMemory::m_xxxa(0x00008000);
const GSVector4i GPULocalMemory::m_xxbx(0x00007c00);
const GSVector4i GPULocalMemory::m_xgxx(0x000003e0);
const GSVector4i GPULocalMemory::m_rxxx(0x0000001f);
const GSVector4i GPULocalMemory::m_rxxx(0x0000001f);
#define VM_SIZE ((1 << (12 + 11)) * sizeof(uint16))
#define VM_ALLOC_SIZE (VM_SIZE * 2)
#define TEX_ALLOC_SIZE (256 * 256 * (1 + 1 + 4) * 32)
@ -573,10 +573,10 @@ void GPULocalMemory::Expand24(const uint16* RESTRICT src, uint32* RESTRICT dst,
}
}
void GPULocalMemory::SaveBMP(const string& path, const GSVector4i& r2, int tp, int cx, int cy)
{
#ifdef _WINDOWS
#include "GSTextureSW.h"
void GPULocalMemory::SaveBMP(const string& fn, const GSVector4i& r2, int tp, int cx, int cy)
{
GSVector4i r;
r.left = r2.left << m_scale.x;
@ -587,36 +587,23 @@ void GPULocalMemory::SaveBMP(const string& path, const GSVector4i& r2, int tp, i
r.left &= ~1;
r.right &= ~1;
if(FILE* fp = fopen(path.c_str(), "wb"))
GSTextureSW t(GSTexture::Offscreen, r.width(), r.height());
GSTexture::GSMap m;
if(t.Map(m, NULL))
{
BITMAPINFOHEADER bih;
memset(&bih, 0, sizeof(bih));
bih.biSize = sizeof(bih);
bih.biWidth = r.width();
bih.biHeight = r.height();
bih.biPlanes = 1;
bih.biBitCount = 32;
bih.biCompression = BI_RGB;
bih.biSizeImage = bih.biWidth * bih.biHeight * 4;
BITMAPFILEHEADER bfh;
memset(&bfh, 0, sizeof(bfh));
bfh.bfType = 'MB';
bfh.bfOffBits = sizeof(bfh) + sizeof(bih);
bfh.bfSize = bfh.bfOffBits + bih.biSizeImage;
bfh.bfReserved1 = bfh.bfReserved2 = 0;
fwrite(&bfh, 1, sizeof(bfh), fp);
fwrite(&bih, 1, sizeof(bih), fp);
int pitch = GetWidth();
uint16* buff = (uint16*)_aligned_malloc(pitch * sizeof(WORD), 16);
uint32* buff32 = (uint32*)_aligned_malloc(pitch * sizeof(uint32), 16);
uint16* src = GetPixelAddress(r.left, r.bottom - 1);
const uint16* clut = GetCLUT(tp, cx, cy);
const uint16* RESTRICT src = GetPixelAddress(r.left, r.top);
const uint16* RESTRICT clut = GetCLUT(tp, cx, cy);
for(int j = r.bottom - 1; j >= r.top; j--, src -= pitch)
uint8* RESTRICT dst = m.bits;
uint16* RESTRICT buff = (uint16*)_aligned_malloc(pitch * sizeof(uint16), 32);
uint32* RESTRICT buff32 = (uint32*)_aligned_malloc(pitch * sizeof(uint32), 32);
for(int j = r.top; j < r.bottom; j++, src += pitch, dst += m.pitch)
{
switch(tp)
{
@ -662,18 +649,14 @@ void GPULocalMemory::SaveBMP(const string& path, const GSVector4i& r2, int tp, i
buff32[i] = (buff32[i] & 0xff00ff00) | ((buff32[i] & 0x00ff0000) >> 16) | ((buff32[i] & 0x000000ff) << 16);
}
fwrite(buff32, 1, r.width() * 4, fp);
memcpy(dst, buff32, r.width() << 2);
}
_aligned_free(buff);
_aligned_free(buff32);
fclose(fp);
t.Unmap();
t.Save(fn);
}
#else
// TODO: linux
#endif
}

View File

@ -80,5 +80,5 @@ public:
void Expand16(const uint16* RESTRICT src, uint32* RESTRICT dst, int pixels);
void Expand24(const uint16* RESTRICT src, uint32* RESTRICT dst, int pixels);
void SaveBMP(const string& path, const GSVector4i& r, int tp, int cx, int cy);
void SaveBMP(const string& fn, const GSVector4i& r, int tp, int cx, int cy);
};

View File

@ -121,12 +121,13 @@ public: // TODO
VSConstantBuffer m_vs_cb_cache;
PSConstantBuffer m_ps_cb_cache;
bool CreateTextureFX();
public:
GSDevice11();
virtual ~GSDevice11();
bool Create(GSWnd* wnd);
bool CreateTextureFX();
bool Reset(int w, int h);
void Flip();

161
plugins/GSdx/GSDeviceSW.cpp Normal file
View File

@ -0,0 +1,161 @@
/*
* 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 "GSDeviceSW.h"
bool GSDeviceSW::Create(GSWnd* wnd)
{
if(!GSDevice::Create(wnd))
return false;
Reset(1, 1);
return true;
}
bool GSDeviceSW::Reset(int w, int h)
{
if(!GSDevice::Reset(w, h))
return false;
return true;
}
void GSDeviceSW::Flip()
{
}
GSTexture* GSDeviceSW::Create(int type, int w, int h, bool msaa, int format)
{
if(format != 0) return false; // there is only one format
return new GSTextureSW(type, w, h);
}
void GSDeviceSW::BeginScene()
{
// TODO
}
void GSDeviceSW::DrawPrimitive()
{
// TODO
}
void GSDeviceSW::EndScene()
{
// TODO
}
void GSDeviceSW::ClearRenderTarget(GSTexture* t, const GSVector4& c)
{
Clear(t, c.rgba32());
}
void GSDeviceSW::ClearRenderTarget(GSTexture* t, uint32 c)
{
Clear(t, c);
}
void GSDeviceSW::ClearDepth(GSTexture* t, float c)
{
Clear(t, *(uint32*)&c);
}
void GSDeviceSW::ClearStencil(GSTexture* t, uint8 c)
{
Clear(t, c);
}
GSTexture* GSDeviceSW::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format)
{
// TODO
return NULL;
}
void GSDeviceSW::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
{
// TODO
}
void GSDeviceSW::StretchRect(GSTexture* st, GSTexture* dt, const GSVector4& dr, int shader, bool linear)
{
// TODO
}
void GSDeviceSW::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader, bool linear)
{
// TODO
}
void GSDeviceSW::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
{
// TODO
}
void GSDeviceSW::PSSetShaderResource(int i, GSTexture* sr)
{
// TODO
}
void GSDeviceSW::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor)
{
// TODO
}
//
void GSDeviceSW::DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c)
{
// TODO
}
void GSDeviceSW::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset)
{
// TODO
}
void GSDeviceSW::Clear(GSTexture* t, uint32 c)
{
int h = t->GetHeight();
int w = t->GetWidth();
GSTexture::GSMap m;
if(t->Map(m, NULL))
{
GSVector4i v((int)c);
uint8* p = m.bits;
for(int j = 0; j < h; j++, p += m.pitch)
{
for(int i = 0; i < w; i += 4)
{
*(GSVector4i*)&p[i] = v;
}
}
t->Unmap();
}
}

64
plugins/GSdx/GSDeviceSW.h Normal file
View File

@ -0,0 +1,64 @@
/*
* 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 "GSDevice.h"
#include "GSTextureSW.h"
class GSDeviceSW : public GSDevice
{
GSTexture* Create(int type, int w, int h, bool msaa, int format);
void DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c);
void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset = 0);
void Clear(GSTexture* t, uint32 c);
public:
GSDeviceSW();
bool Create(GSWnd* wnd);
bool Reset(int w, int h);
void Flip();
// drawing may be routed through here, the software renderers use the rasterizer directly now
void BeginScene();
void DrawPrimitive();
void EndScene();
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* 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, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true);
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true);
void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1);
void PSSetShaderResource(int i, GSTexture* sr);
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL);
};

View File

@ -129,7 +129,7 @@ void GSDialog::ComboBoxInit(UINT id, const vector<GSSetting>& settings, uint32 s
SendMessage(hWnd, CB_RESETCONTENT, 0, 0);
for(int i = 0; i < settings.size(); i++)
for(size_t i = 0; i < settings.size(); i++)
{
const GSSetting& s = settings[i];

View File

@ -1851,10 +1851,10 @@ void GSLocalMemory::ReadTextureBlock4HHP(uint32 bp, uint8* dst, int dstpitch, co
//
#include "GSTextureSW.h"
void GSLocalMemory::SaveBMP(const string& fn, uint32 bp, uint32 bw, uint32 psm, int w, int h)
{
#ifdef _WINDOWS
int pitch = w * 4;
int size = pitch * h;
void* bits = _aligned_malloc(size, 32);
@ -1875,41 +1875,20 @@ void GSLocalMemory::SaveBMP(const string& fn, uint32 bp, uint32 bw, uint32 psm,
uint8* p = (uint8*)bits;
for(int j = h-1; j >= 0; j--, p += pitch)
for(int i = 0; i < w; i++)
((uint32*)p)[i] = (this->*rp)(i, j, TEX0.TBP0, TEX0.TBW);
if(FILE* fp = fopen(fn.c_str(), "wb"))
for(int j = 0; j < h; j++, p += pitch)
{
BITMAPINFOHEADER bih;
memset(&bih, 0, sizeof(bih));
bih.biSize = sizeof(bih);
bih.biWidth = w;
bih.biHeight = h;
bih.biPlanes = 1;
bih.biBitCount = 32;
bih.biCompression = BI_RGB;
bih.biSizeImage = size;
for(int i = 0; i < w; i++)
{
((uint32*)p)[i] = (this->*rp)(i, j, TEX0.TBP0, TEX0.TBW);
}
}
BITMAPFILEHEADER bfh;
memset(&bfh, 0, sizeof(bfh));
bfh.bfType = 'MB';
bfh.bfOffBits = sizeof(bfh) + sizeof(bih);
bfh.bfSize = bfh.bfOffBits + size;
bfh.bfReserved1 = bfh.bfReserved2 = 0;
GSTextureSW t(GSTexture::Offscreen, w, h);
fwrite(&bfh, 1, sizeof(bfh), fp);
fwrite(&bih, 1, sizeof(bih), fp);
fwrite(bits, 1, size, fp);
fclose(fp);
if(t.Update(GSVector4i(0, 0, w, h), bits, pitch))
{
t.Save(fn);
}
_aligned_free(bits);
#else
// TODO: linux
#endif
}

View File

@ -0,0 +1,162 @@
/*
* 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 "GSTextureSW.h"
GSTextureSW::GSTextureSW(int type, int width, int height)
: m_mapped(0)
{
m_size = GSVector2i(width, height);
m_type = type;
m_format = 0;
m_pitch = ((width << 2) + 31) & ~31;
m_data = _aligned_malloc(m_pitch * height, 32);
}
GSTextureSW::~GSTextureSW()
{
_aligned_free(m_data);
}
bool GSTextureSW::Update(const GSVector4i& r, const void* data, int pitch)
{
GSMap m;
if(m_data != NULL && Map(m, &r))
{
uint8* RESTRICT src = (uint8*)data;
uint8* RESTRICT dst = m.bits;
int rowbytes = r.width() << 2;
for(int h = r.height(); h > 0; h--, src += pitch, dst += m.pitch)
{
memcpy(dst, src, rowbytes);
}
Unmap();
return true;
}
return false;
}
bool GSTextureSW::Map(GSMap& m, const GSVector4i* r)
{
HRESULT hr;
if(m_data != NULL && r->left >= 0 && r->right <= m_size.x && r->top >= 0 && r->bottom <= m_size.y)
{
if(!_interlockedbittestandset(&m_mapped, 0))
{
m.bits = (uint8*)m_data + ((m_pitch * r->top + r->left) << 2);
m.pitch = m_pitch;
return true;
}
}
return false;
}
void GSTextureSW::Unmap()
{
m_mapped = 0;
}
#ifndef _WINDOWS
#pragma pack(push, 1)
struct BITMAPFILEHEADER
{
uint16 bfType;
uint32 bfSize;
uint16 bfReserved1;
uint16 bfReserved2;
uint32 bfOffBits;
};
struct BITMAPINFOHEADER
{
uint32 biSize;
int32 biWidth;
int32 biHeight;
uint16 biPlanes;
uint16 biBitCount;
uint32 biCompression;
uint32 biSizeImage;
int32 biXPelsPerMeter;
int32 biYPelsPerMeter;
uint32 biClrUsed;
uint32 biClrImportant;
};
#pragma pack(pop)
#endif
bool GSTextureSW::Save(const string& fn, bool dds)
{
if(dds) return false; // not implemented
if(FILE* fp = fopen(fn.c_str(), "wb"))
{
BITMAPINFOHEADER bih;
memset(&bih, 0, sizeof(bih));
bih.biSize = sizeof(bih);
bih.biWidth = m_size.x;
bih.biHeight = m_size.y;
bih.biPlanes = 1;
bih.biBitCount = 32;
bih.biCompression = BI_RGB;
bih.biSizeImage = m_size.x * m_size.y << 2;
BITMAPFILEHEADER bfh;
memset(&bfh, 0, sizeof(bfh));
bfh.bfType = 'MB';
bfh.bfOffBits = sizeof(bfh) + sizeof(bih);
bfh.bfSize = bfh.bfOffBits + bih.biSizeImage;
bfh.bfReserved1 = bfh.bfReserved2 = 0;
fwrite(&bfh, 1, sizeof(bfh), fp);
fwrite(&bih, 1, sizeof(bih), fp);
uint8* data = (uint8*)m_data + (m_size.y - 1) * m_pitch;
for(int h = m_size.y; h > 0; h--, data -= m_pitch)
{
fwrite(data, 1, m_size.x << 2, fp); // TODO: swap red-blue?
}
fclose(fp);
return true;
}
return false;
}

View File

@ -0,0 +1,42 @@
/*
* 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 "GSTexture.h"
class GSTextureSW : public GSTexture
{
// mem texture, always 32-bit rgba (might add 8-bit for palette if needed)
int m_pitch;
void* m_data;
long m_mapped;
public:
GSTextureSW(int type, int width, int height);
virtual ~GSTextureSW();
bool Update(const GSVector4i& r, const void* data, int pitch);
bool Map(GSMap& m, const GSVector4i* r);
void Unmap();
bool Save(const string& fn, bool dds = false);
};

View File

@ -283,7 +283,7 @@ static bool DXUTDelayLoadDXGI()
{
s_hModDXGI = LoadLibrary("dxgi.dll");
if(s_hModDXGI)
if(s_hModDXGI != NULL)
{
s_DynamicCreateDXGIFactory = (FNPTR_CREATEDXGIFACTORY)GetProcAddress(s_hModDXGI, "CreateDXGIFactory");
}
@ -321,9 +321,11 @@ static bool DXUTDelayLoadDXGI()
bool GSUtil::CheckDirect3D11Level(D3D_FEATURE_LEVEL& level)
{
HRESULT hr;
level = (D3D_FEATURE_LEVEL)0;
if(!_bittestandset(&s_D3D11Checked, 0)) // thread safety...
if(!_interlockedbittestandset(&s_D3D11Checked, 0)) // thread safety...
{
if(!DXUTDelayLoadDXGI())
{
@ -345,14 +347,14 @@ bool GSUtil::CheckDirect3D11Level(D3D_FEATURE_LEVEL& level)
CComPtr<ID3D11Device> dev;
CComPtr<ID3D11DeviceContext> ctx;
HRESULT hr = s_DynamicD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_SINGLETHREADED, levels, countof(levels), D3D11_SDK_VERSION, &dev, &level, &ctx);
hr = s_DynamicD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_SINGLETHREADED, levels, countof(levels), D3D11_SDK_VERSION, &dev, &level, &ctx);
s_D3D11Level = level;
}
level = s_D3D11Level;
return level >= D3D_FEATURE_LEVEL_11_0;
return SUCCEEDED(hr) && level >= D3D_FEATURE_LEVEL_9_1;
}
void GSUtil::UnloadDynamicLibraries()

View File

@ -719,6 +719,7 @@
<ClCompile Include="GSDevice9.cpp" />
<ClCompile Include="GSDeviceDX.cpp" />
<ClCompile Include="GSDeviceNull.cpp" />
<ClCompile Include="GSDeviceSW.cpp" />
<ClCompile Include="GSDialog.cpp" />
<ClCompile Include="GSDirtyRect.cpp" />
<ClCompile Include="GSDrawScanline.cpp">
@ -793,6 +794,7 @@
<ClCompile Include="GSTextureFX11.cpp" />
<ClCompile Include="GSTextureFX9.cpp" />
<ClCompile Include="GSTextureNull.cpp" />
<ClCompile Include="GSTextureSW.cpp" />
<ClCompile Include="GSThread.cpp" />
<ClCompile Include="GSUtil.cpp">
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='Release SSE4|Win32'">AssemblyAndSourceCode</AssemblerOutput>
@ -1771,6 +1773,7 @@
<ClInclude Include="GSDevice9.h" />
<ClInclude Include="GSDeviceDX.h" />
<ClInclude Include="GSDeviceNull.h" />
<ClInclude Include="GSDeviceSW.h" />
<ClInclude Include="GSDialog.h" />
<ClInclude Include="GSDirtyRect.h" />
<ClInclude Include="GSDrawingContext.h" />
@ -1804,6 +1807,7 @@
<ClInclude Include="GSTextureCache9.h" />
<ClInclude Include="GSTextureCacheSW.h" />
<ClInclude Include="GSTextureNull.h" />
<ClInclude Include="GSTextureSW.h" />
<ClInclude Include="GSThread.h" />
<ClInclude Include="GSUtil.h" />
<ClInclude Include="GSVector.h" />

View File

@ -279,6 +279,12 @@
<ClCompile Include="GSDeviceDX.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GSTextureSW.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GSDeviceSW.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="GS.h">
@ -590,6 +596,12 @@
<ClInclude Include="GPUVertex.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GSTextureSW.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GSDeviceSW.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="res\logo10.bmp">

View File

@ -1163,6 +1163,10 @@
RelativePath=".\GSDeviceNull.cpp"
>
</File>
<File
RelativePath=".\GSDeviceSW.cpp"
>
</File>
<File
RelativePath=".\GSDialog.cpp"
>
@ -1435,6 +1439,10 @@
RelativePath=".\GSTextureNull.cpp"
>
</File>
<File
RelativePath=".\GSTextureSW.cpp"
>
</File>
<File
RelativePath=".\GSThread.cpp"
>
@ -1693,6 +1701,10 @@
RelativePath=".\GSDeviceNull.h"
>
</File>
<File
RelativePath=".\GSDeviceSW.h"
>
</File>
<File
RelativePath=".\GSDialog.h"
>
@ -1829,6 +1841,10 @@
RelativePath=".\GSTextureNull.h"
>
</File>
<File
RelativePath=".\GSTextureSW.h"
>
</File>
<File
RelativePath=".\GSThread.h"
>

View File

@ -287,6 +287,13 @@ __forceinline unsigned char _interlockedbittestandreset(volatile long* a, const
return retval;
}
__forceinline unsigned char _interlockedbittestandset(volatile long* a, const long b)
{
unsigned char retval;
__asm__("lock; btsl %[b], %[a]; setc %b[retval]" : [retval] "=q" (retval), [a] "+m" (*a) : [b] "Ir" (b) : "memory");
return retval;
}
#ifdef __GNUC__
__forceinline unsigned long long __rdtsc()