Merge pull request #6765 from hrydgard/thin3d

Switch UI drawing from GL to Thin3D. This activates the D3D9 path as well.
This commit is contained in:
Henrik Rydgård 2014-08-23 10:52:21 +02:00
commit 5d836bfa5a
50 changed files with 614 additions and 629 deletions

View file

@ -762,7 +762,6 @@ set(NativeAppSource
UI/TouchControlLayoutScreen.cpp
UI/TouchControlVisibilityScreen.cpp
UI/GamepadEmu.cpp
UI/UIShader.cpp
UI/OnScreenDisplay.cpp
UI/ControlMappingScreen.cpp
UI/Store.cpp
@ -897,6 +896,9 @@ add_library(native STATIC
native/net/url.h
native/profiler/profiler.cpp
native/profiler/profiler.h
native/thin3d/thin3d.cpp
native/thin3d/thin3d.h
native/thin3d/thin3d_gl.cpp
native/thread/prioritizedworkqueue.cpp
native/thread/prioritizedworkqueue.h
native/thread/threadutil.cpp

View file

@ -747,7 +747,7 @@ bool KeyFromPspButton(int btn, std::vector<KeyDef> *keys) {
bool AxisToPspButton(int deviceId, int axisId, int direction, std::vector<int> *pspKeys) {
int key = TranslateKeyCodeFromAxis(axisId, direction);
return KeyToPspButton(deviceId, key, pspKeys);
return KeyToPspButton(deviceId, key, pspKeys);
}
bool AxisFromPspButton(int btn, int *deviceId, int *axisId, int *direction) {

View file

@ -386,6 +386,7 @@ static int DefaultAndroidHwScale() {
static ConfigSetting graphicsSettings[] = {
ConfigSetting("ShowFPSCounter", &g_Config.iShowFPSCounter, 0),
ReportedConfigSetting("GPUBackend", &g_Config.iGPUBackend, 0),
ReportedConfigSetting("RenderingMode", &g_Config.iRenderingMode, &DefaultRenderingMode),
ConfigSetting("SoftwareRendering", &g_Config.bSoftwareRendering, false),
ReportedConfigSetting("HardwareTransform", &g_Config.bHardwareTransform, true),
@ -1060,5 +1061,3 @@ void Config::GetReportingInfo(UrlEncoder &data) {
}
}
}

View file

@ -39,6 +39,12 @@ enum {
ROTATION_LOCKED_VERTICAL180 = 4,
};
// Software is not among these because it will have one of these perform the blit to display.
enum {
GPU_BACKEND_OPENGL = 0,
GPU_BACKEND_DIRECT3D9 = 1,
};
namespace http {
class Download;
class Downloader;
@ -101,8 +107,8 @@ public:
std::vector<std::string> vPinnedPaths;
std::string sLanguageIni;
// GFX
int iGPUBackend;
bool bSoftwareRendering;
bool bHardwareTransform; // only used in the GLES backend
bool bSoftwareSkinning; // may speed up some games

View file

@ -33,6 +33,7 @@
#ifdef _WIN32
#ifndef _XBOX
#include "Windows/OpenGLBase.h"
#include "Windows/D3D9Base.h"
#endif
#include "Windows/InputDevice.h"
#endif
@ -151,6 +152,21 @@ void UpdateRunLoop() {
}
}
#if defined(USING_WIN_UI)
void GPU_SwapBuffers() {
switch (g_Config.iGPUBackend) {
case GPU_BACKEND_OPENGL:
GL_SwapBuffers();
break;
case GPU_BACKEND_DIRECT3D9:
D3D9_SwapBuffers();
break;
}
}
#endif
void Core_RunLoop() {
while ((GetUIState() != UISTATE_INGAME || !PSP_IsInited()) && GetUIState() != UISTATE_EXIT) {
time_update();
@ -165,7 +181,7 @@ void Core_RunLoop() {
if (sleepTime > 0)
Sleep(sleepTime);
if (!windowHidden) {
GL_SwapBuffers();
GPU_SwapBuffers();
}
#else
UpdateRunLoop();
@ -177,7 +193,7 @@ void Core_RunLoop() {
UpdateRunLoop();
#if defined(USING_WIN_UI)
if (!windowHidden && !Core_IsStepping()) {
GL_SwapBuffers();
GPU_SwapBuffers();
}
#endif
}

View file

@ -185,6 +185,7 @@ void SaveFileInfo::DoState(PointerWrap &p)
p.Do(hasTexture);
if (hasTexture) {
if (p.mode == p.MODE_READ) {
delete texture;
texture = new PPGeImage("");
}
texture->DoState(p);

View file

@ -1670,15 +1670,15 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr)
if (optionAddr) {
lmoption = (SceKernelLMOption *)Memory::GetPointer(optionAddr);
if (lmoption->position < PSP_SMEM_Low || lmoption->position > PSP_SMEM_HighAligned) {
ERROR_LOG_REPORT(LOADER, "sceKernelLoadModule(%s): invalid position", name, lmoption->position);
ERROR_LOG_REPORT(LOADER, "sceKernelLoadModule(%s): invalid position (%i)", name, (int)lmoption->position);
return SCE_KERNEL_ERROR_ILLEGAL_MEMBLOCKTYPE;
}
if (lmoption->position == PSP_SMEM_LowAligned || lmoption->position == PSP_SMEM_HighAligned) {
ERROR_LOG_REPORT(LOADER, "sceKernelLoadModule(%s): invalid position (aligned)", name, lmoption->position);
ERROR_LOG_REPORT(LOADER, "sceKernelLoadModule(%s): invalid position (aligned)", name);
return SCE_KERNEL_ERROR_ILLEGAL_ALIGNMENT_SIZE;
}
if (lmoption->position == PSP_SMEM_Addr) {
ERROR_LOG_REPORT(LOADER, "sceKernelLoadModule(%s): invalid position (fixed)", name, lmoption->position);
ERROR_LOG_REPORT(LOADER, "sceKernelLoadModule(%s): invalid position (fixed)", name);
return SCE_KERNEL_ERROR_MEMBLOCK_ALLOC_FAILED;
}
WARN_LOG_REPORT(LOADER, "sceKernelLoadModule: unsupported options size=%08x, flags=%08x, pos=%d, access=%d, data=%d, text=%d", lmoption->size, lmoption->flags, lmoption->position, lmoption->access, lmoption->mpiddata, lmoption->mpidtext);

View file

@ -316,7 +316,7 @@ MIPSOpcode JitBlockCache::GetEmuHackOpForBlock(int blockNum) const {
}
int JitBlockCache::GetBlockNumberFromStartAddress(u32 addr, bool realBlocksOnly) {
if (!blocks_)
if (!blocks_ || !Memory::IsValidAddress(addr))
return -1;
MIPSOpcode inst = MIPSOpcode(Memory::Read_U32(addr));

View file

@ -241,19 +241,6 @@ void FramebufferManagerDX9::DrawPixels(const u8 *framebuf, GEBufferFormat pixelF
DrawActiveTexture(x, y, w, h, false, 480.0f / 512.0f);
}
// Depth in ogl is between -1;1 we need between 0;1
static void ConvertMatrices(Matrix4x4 & in) {
/*
in.zz *= 0.5f;
in.wz += 1.f;
*/
Matrix4x4 s;
Matrix4x4 t;
s.setScaling(Vec3(1, 1, 0.5f));
t.setTranslation(Vec3(0, 0, 0.5f));
in = in * s;
in = in * t;
}
void FramebufferManagerDX9::DrawActiveTexture(float x, float y, float w, float h, bool flip, float uscale, float vscale) {
float u2 = uscale;
@ -269,9 +256,9 @@ void FramebufferManagerDX9::DrawActiveTexture(float x, float y, float w, float h
};
Matrix4x4 ortho;
ConvertMatrices(ortho);
ortho.setOrtho(0, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, 0, -1, 1);
ConvertProjMatrixToD3D(ortho);
//pD3Ddevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
pD3Ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
@ -635,6 +622,7 @@ void FramebufferManagerDX9::CopyDisplayToOutput() {
dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
DEBUG_LOG(SCEGE, "Displaying FBO %08x", vfb->fb_address);
DisableState();
fbo_bind_color_as_texture(vfb->fbo, 0);
// These are in the output display coordinates

View file

@ -268,26 +268,17 @@ void LinkedShaderDX9::SetColorUniform3ExtraFloat(D3DXHANDLE uniform, u32 color,
void LinkedShaderDX9::SetMatrix4x3(D3DXHANDLE uniform, const float *m4x3) {
float m4x4[16];
ConvertMatrix4x3To4x4(m4x4, m4x3);
if (m_vs->constant->SetMatrix(pD3Ddevice, uniform, (D3DXMATRIX*)m4x4) == D3D_OK);
else
m_fs->constant->SetMatrix(pD3Ddevice, uniform, (D3DXMATRIX*)m4x4);
m_vs->constant->SetMatrix(pD3Ddevice, uniform, (D3DXMATRIX*)m4x4);
}
void LinkedShaderDX9::SetMatrix(D3DXHANDLE uniform, const float* pMatrix) {
D3DXMATRIX * pDxMat = (D3DXMATRIX*)pMatrix;
if (m_vs->constant->SetMatrix(pD3Ddevice, uniform, pDxMat) == D3D_OK);
else
m_fs->constant->SetMatrix(pD3Ddevice, uniform, pDxMat);
m_vs->constant->SetMatrix(pD3Ddevice, uniform, pDxMat);
}
// Depth in ogl is between -1;1 we need between 0;1
static void ConvertMatrices(Matrix4x4 & in) {
/*
in.zz *= 0.5f;
in.wz += 1.f;
*/
// Pretty sure this is wrong, our Z buffer is screwed up anyhow..
void ConvertProjMatrixToD3D(Matrix4x4 & in) {
Matrix4x4 s;
Matrix4x4 t;
s.setScaling(Vec3(1, 1, 0.5f));
@ -297,7 +288,6 @@ static void ConvertMatrices(Matrix4x4 & in) {
}
void LinkedShaderDX9::use() {
updateUniforms();
pD3Ddevice->SetPixelShader(m_fs->shader);
@ -325,7 +315,7 @@ void LinkedShaderDX9::updateUniforms() {
flippedMatrix[12] = -flippedMatrix[12];
}
// Convert matrices !
ConvertMatrices(flippedMatrix);
ConvertProjMatrixToD3D(flippedMatrix);
SetMatrix(u_proj, flippedMatrix.getReadPtr());
}
@ -335,7 +325,7 @@ void LinkedShaderDX9::updateUniforms() {
proj_through.setOrtho(0.0f, gstate_c.curRTWidth, gstate_c.curRTHeight, 0, 0, 1);
// Convert matrices !
ConvertMatrices(proj_through);
ConvertProjMatrixToD3D(proj_through);
SetMatrix(u_proj_through, proj_through.getReadPtr());
}

View file

@ -22,11 +22,14 @@
#include <map>
#include "GPU/Directx9/VertexShaderGeneratorDX9.h"
#include "GPU/Directx9/PixelShaderGeneratorDX9.h"
#include "thin3d/d3dx9_loader.h"
#include "math/lin/matrix4x4.h"
namespace DX9 {
class PSShader;
class VSShader;
void ConvertProjMatrixToD3D(Matrix4x4 & in);
class LinkedShaderDX9
{

View file

@ -77,6 +77,11 @@ static const D3DCMPFUNC ztests[] = {
D3DCMP_LESS, D3DCMP_LESSEQUAL, D3DCMP_GREATER, D3DCMP_GREATEREQUAL,
};
static const D3DCMPFUNC ztests_backwards[] = {
D3DCMP_NEVER, D3DCMP_ALWAYS, D3DCMP_EQUAL, D3DCMP_NOTEQUAL,
D3DCMP_GREATER, D3DCMP_GREATEREQUAL, D3DCMP_LESS, D3DCMP_LESSEQUAL,
};
static const D3DSTENCILOP stencilOps[] = {
D3DSTENCILOP_KEEP,
D3DSTENCILOP_ZERO,
@ -192,8 +197,8 @@ void TransformDrawEngineDX9::ApplyDrawState(int prim) {
}
// At this point, through all paths above, glBlendFuncA and glBlendFuncB will be set right somehow.
dxstate.blendFunc.set(glBlendFuncA, glBlendFuncB);
dxstate.blendEquation.set(eqLookup[blendFuncEq]);
dxstate.blendFunc.set(glBlendFuncA, glBlendFuncB, D3DBLEND_ONE, D3DBLEND_ZERO);
dxstate.blendEquation.set(eqLookup[blendFuncEq], D3DBLENDOP_ADD);
}
// Set Dither
@ -229,7 +234,6 @@ void TransformDrawEngineDX9::ApplyDrawState(int prim) {
}
} else {
// Set cull
bool wantCull = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled();
dxstate.cullMode.set(wantCull, gstate.getCullMode());

View file

@ -25,6 +25,7 @@
#include "GPU/GPUState.h"
#include "GPU/Directx9/TextureCacheDX9.h"
#include "GPU/Directx9/FramebufferDX9.h"
#include "GPU/Directx9/helper/dx_state.h"
#include "GPU/Common/TextureDecoder.h"
#include "Core/Config.h"
#include "Core/Host.h"
@ -32,6 +33,7 @@
#include "ext/xxhash.h"
#include "math/math_util.h"
extern int g_iNumVideos;
namespace DX9 {
@ -75,12 +77,14 @@ void TextureCacheDX9::Clear(bool delete_them) {
lastBoundTexture = INVALID_TEX;
if (delete_them) {
for (TexCache::iterator iter = cache.begin(); iter != cache.end(); ++iter) {
DEBUG_LOG(G3D, "Deleting texture %i", iter->second.texture);
iter->second.texture->Release();
DEBUG_LOG(G3D, "Deleting texture %p", iter->second.texture);
if (iter->second.texture)
iter->second.texture->Release();
}
for (TexCache::iterator iter = secondCache.begin(); iter != secondCache.end(); ++iter) {
DEBUG_LOG(G3D, "Deleting texture %i", iter->second.texture);
iter->second.texture->Release();
DEBUG_LOG(G3D, "Deleting texture %p", iter->second.texture);
if (iter->second.texture)
iter->second.texture->Release();
}
}
if (cache.size() + secondCache.size()) {
@ -103,7 +107,8 @@ void TextureCacheDX9::Decimate() {
int killAge = lowMemoryMode_ ? TEXTURE_KILL_AGE_LOWMEM : TEXTURE_KILL_AGE;
for (TexCache::iterator iter = cache.begin(); iter != cache.end(); ) {
if (iter->second.lastFrame + killAge < gpuStats.numFlips) {
iter->second.texture->Release();
if (iter->second.texture)
iter->second.texture->Release();
cache.erase(iter++);
} else {
++iter;
@ -114,7 +119,8 @@ void TextureCacheDX9::Decimate() {
for (TexCache::iterator iter = secondCache.begin(); iter != secondCache.end(); ) {
// In low memory mode, we kill them all.
if (lowMemoryMode_ || iter->second.lastFrame + TEXTURE_KILL_AGE < gpuStats.numFlips) {
iter->second.texture->Release();
if (iter->second.texture)
iter->second.texture->Release();
secondCache.erase(iter++);
} else {
++iter;
@ -451,7 +457,7 @@ D3DFORMAT getClutDestFormat(GEPaletteFormat format) {
static const u8 texByteAlignMap[] = {2, 2, 2, 4};
static const u32 MinFilt[8] = {
static const u8 MinFilt[8] = {
D3DTEXF_POINT,
D3DTEXF_LINEAR,
D3DTEXF_POINT,
@ -462,7 +468,7 @@ static const u32 MinFilt[8] = {
D3DTEXF_LINEAR, // GL_LINEAR_MIPMAP_LINEAR,
};
static const u32 MipFilt[8] = {
static const u8 MipFilt[8] = {
D3DTEXF_POINT,
D3DTEXF_LINEAR,
D3DTEXF_POINT,
@ -473,13 +479,11 @@ static const u32 MipFilt[8] = {
D3DTEXF_LINEAR, // GL_LINEAR_MIPMAP_LINEAR,
};
static const u32 MagFilt[2] = {
static const u8 MagFilt[2] = {
D3DTEXF_POINT,
D3DTEXF_LINEAR
};
// This should not have to be done per texture! OpenGL is silly yo
// TODO: Dirty-check this against the current texture.
void TextureCacheDX9::UpdateSamplingParams(TexCacheEntry &entry, bool force) {
int minFilt = gstate.texfilter & 0x7;
int magFilt = (gstate.texfilter>>8) & 1;
@ -517,23 +521,11 @@ void TextureCacheDX9::UpdateSamplingParams(TexCacheEntry &entry, bool force) {
minFilt &= 1;
}
if (force || entry.minFilt != minFilt) {
pD3Ddevice->SetSamplerState(0, D3DSAMP_MINFILTER, MinFilt[minFilt]);
pD3Ddevice->SetSamplerState(0, D3DSAMP_MIPFILTER, MipFilt[minFilt]);
entry.minFilt = minFilt;
}
if (force || entry.magFilt != magFilt) {
pD3Ddevice->SetSamplerState(0, D3DSAMP_MAGFILTER, MagFilt[magFilt]);
entry.magFilt = magFilt;
}
if (force || entry.sClamp != sClamp) {
pD3Ddevice->SetSamplerState(0, D3DSAMP_ADDRESSU, sClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP);
entry.sClamp = sClamp;
}
if (force || entry.tClamp != tClamp) {
pD3Ddevice->SetSamplerState(0, D3DSAMP_ADDRESSV, tClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP);
entry.tClamp = tClamp;
}
dxstate.texMinFilter.set(MinFilt[minFilt]);
dxstate.texMipFilter.set(MipFilt[minFilt]);
dxstate.texMagFilter.set(MagFilt[magFilt]);
dxstate.texAddressU.set(sClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP);
dxstate.texAddressV.set(tClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP);
#ifdef _XBOX
pD3Ddevice->SetRenderState(D3DRS_HALFPIXELOFFSET, TRUE );
@ -569,9 +561,8 @@ static void ClutConvertColors(void *dstBuf, const void *srcBuf, u32 dstFmt, int
const u16_le *src = (const u16_le *)srcBuf;
u16_le *dst = (u16_le *)dstBuf;
for (int i = 0; i < numPixels; i++) {
// Already good format
u16 rgb = src[i];
dst[i] = (rgb & 0xF) | (rgb & 0xF0)<<8 | ( rgb & 0xF00) | ((rgb & 0xF000)>>8);
dst[i] = ((rgb & 0xF) << 8) | (rgb & 0xF0F0) | ((rgb & 0xF00) >> 8);
}
}
break;
@ -581,7 +572,7 @@ static void ClutConvertColors(void *dstBuf, const void *srcBuf, u32 dstFmt, int
u16 *dst = (u16 *)dstBuf;
for (int i = 0; i < numPixels; i++) {
u16 rgb = src[i];
dst[i] = ((rgb & 0x1f) << 11) | ( rgb & 0x7e0) | ((rgb & 0xF800) >>11 );
dst[i] = ((rgb & 0x1f) << 11) | (rgb & 0x7e0) | ((rgb & 0xF800) >> 11);
}
}
break;
@ -721,12 +712,12 @@ void TextureCacheDX9::UpdateCurrentClut() {
clutAlphaLinear_ = true;
clutAlphaLinearColor_ = clut[15] & 0xFFF0;
for (int i = 0; i < 16; ++i) {
if ((clut[i] & 0xf) != i) {
if ((clut[i] >> 12) != i) {
clutAlphaLinear_ = false;
break;
}
// Alpha 0 doesn't matter.
if (i != 0 && (clut[i] & 0xFFF0) != clutAlphaLinearColor_) {
if (i != 0 && (clut[i] >> 12) != clutAlphaLinearColor_) {
clutAlphaLinear_ = false;
break;
}
@ -745,48 +736,6 @@ inline u32 TextureCacheDX9::GetCurrentClutHash() {
return clutHash_;
}
// #define DEBUG_TEXTURES
#ifdef DEBUG_TEXTURES
bool SetDebugTexture() {
static const int highlightFrames = 30;
static int numTextures = 0;
static int lastFrames = 0;
static int mostTextures = 1;
if (lastFrames != gpuStats.numFlips) {
mostTextures = std::max(mostTextures, numTextures);
numTextures = 0;
lastFrames = gpuStats.numFlips;
}
static GLuint solidTexture = 0;
bool changed = false;
if (((gpuStats.numFlips / highlightFrames) % mostTextures) == numTextures) {
if (gpuStats.numFlips % highlightFrames == 0) {
NOTICE_LOG(G3D, "Highlighting texture # %d / %d", numTextures, mostTextures);
}
static const u32 solidTextureData[] = {0x99AA99FF};
if (solidTexture == 0) {
glGenTextures(1, &solidTexture);
glBindTexture(GL_TEXTURE_2D, solidTexture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, solidTextureData);
} else {
glBindTexture(GL_TEXTURE_2D, solidTexture);
}
changed = true;
}
++numTextures;
return changed;
}
#endif
void TextureCacheDX9::SetTextureFramebuffer(TexCacheEntry *entry)
{
entry->framebuffer->usageFlags |= FB_USAGE_TEXTURE;
@ -1347,21 +1296,12 @@ void TextureCacheDX9::CheckAlpha(TexCacheEntry &entry, u32 *pixelData, u32 dstFm
{
const u32 *p = pixelData;
for (int i = 0; i < (w * h + 1) / 2; ++i) {
#ifndef BIG_ENDIAN
u32 a = p[i] & 0x000F000F;
hitZeroAlpha |= a ^ 0x000F000F;
if (a != 0x000F000F && a != 0x0000000F && a != 0x000F0000 && a != 0) {
hitSomeAlpha = 1;
break;
}
#else
u32 a = p[i] & 0xF000F000;
hitZeroAlpha |= a ^ 0xF000F000;
if (a != 0xF000F000 && a != 0x0000F000 && a != 0xF0000000 && a != 0) {
hitSomeAlpha = 1;
break;
}
#endif
}
}
break;
@ -1369,13 +1309,8 @@ void TextureCacheDX9::CheckAlpha(TexCacheEntry &entry, u32 *pixelData, u32 dstFm
{
const u32 *p = pixelData;
for (int i = 0; i < (w * h + 1) / 2; ++i) {
#ifndef BIG_ENDIAN
u32 a = p[i] & 0x00010001;
hitZeroAlpha |= a ^ 0x00010001;
#else
u32 a = p[i] & 0x10001000;
hitZeroAlpha |= a ^ 0x10001000;
#endif
u32 a = p[i] & 0x80008000;
hitZeroAlpha |= a ^ 0x80008000;
}
}
break;
@ -1409,12 +1344,13 @@ void TextureCacheDX9::CheckAlpha(TexCacheEntry &entry, u32 *pixelData, u32 dstFm
static inline void copyTexture(int xoffset, int yoffset, int w, int h, int pitch, int srcfmt, int fmt, void * pSrc, void * pDst) {
// Swap color
int y;
switch(fmt) {
case D3DFMT_R5G6B5:
case D3DFMT_A4R4G4B4:
case D3DFMT_A1R5G5B5:
// Really needed ?
for(int y = 0; y < h; y++) {
for(y = 0; y < h; y++) {
const u16 *src = (const u16 *)((u8*)pSrc + (w*2) * y);
u16 *dst = (u16*)((u8*)pDst + pitch * y);
memcpy(dst, src, w * sizeof(u16));
@ -1423,23 +1359,13 @@ static inline void copyTexture(int xoffset, int yoffset, int w, int h, int pitch
// 32 bit texture
case D3DFMT_A8R8G8B8:
for(int y = 0; y < h; y++) {
for(y = 0; y < h; y++) {
const u32 *src = (const u32 *)((u8*)pSrc + (w*4) * y);
u32 *dst = (u32*)((u8*)pDst + pitch * y);
/*
// todo use memcpy
for(int x = 0; x < w; x++) {
unsigned int rgb = src[x];
dst[x] = rgb;
}
*/
memcpy(dst, src, w * sizeof(u32));
}
break;
}
}
void TextureCacheDX9::LoadTextureLevel(TexCacheEntry &entry, int level, bool replaceImages) {
@ -1494,48 +1420,24 @@ void TextureCacheDX9::LoadTextureLevel(TexCacheEntry &entry, int level, bool rep
} else {
// Create texture
#ifdef _XBOX
pD3Ddevice->CreateTexture(w, h, 1, 0, (D3DFORMAT)D3DFMT(dstFmt), NULL, &entry.texture, NULL);
HRESULT hr = pD3Ddevice->CreateTexture(w, h, 1, 0, (D3DFORMAT)D3DFMT(dstFmt), NULL, &entry.texture, NULL);
#else
pD3Ddevice->CreateTexture(w, h, 1, 0, (D3DFORMAT)D3DFMT(dstFmt), D3DPOOL_MANAGED, &entry.texture, NULL);
HRESULT hr = pD3Ddevice->CreateTexture(w, h, 1, 0, (D3DFORMAT)D3DFMT(dstFmt), D3DPOOL_MANAGED, &entry.texture, NULL);
#endif
D3DLOCKED_RECT rect;
entry.texture->LockRect(level, &rect, NULL, 0);
if (FAILED(hr)) {
INFO_LOG(G3D, "Failed to create D3D texture");
} else {
D3DLOCKED_RECT rect;
entry.texture->LockRect(level, &rect, NULL, 0);
copyTexture(0, 0, w, h, rect.Pitch, entry.format, dstFmt, pixelData, rect.pBits);
copyTexture(0, 0, w, h, rect.Pitch, entry.format, dstFmt, pixelData, rect.pBits);
entry.texture->UnlockRect(level);
entry.texture->UnlockRect(level);
}
}
//#ifdef _DEBUG
#if 0
// Hack save to disk ...
char fname[256];
int fmt = 0;
static int ipic = 0;
switch(dstFmt) {
case D3DFMT_A4R4G4B4:
fmt = 0x4444;
break;
case D3DFMT_A1R5G5B5:
fmt = 0x5551;
break;
case D3DFMT_R5G6B5:
fmt = 0x5650;
break;
case D3DFMT_A8R8G8B8:
fmt = 0x8888;
break;
default:
fmt = 0xDEAD;
break;
}
sprintf(fname, "game:\\pic\\pic.%02x.%04x.%08x.%08x.png", ipic++, fmt, entry.format, clutformat);
D3DXSaveTextureToFile(fname, D3DXIFF_PNG, entry.texture, NULL);
#endif
}
}
// Only used by Qt UI?
bool TextureCacheDX9::DecodeTexture(u8* output, GPUgstate state)
{
OutputDebugStringA("TextureCache::DecodeTexture : FixMe\r\n");

View file

@ -106,13 +106,6 @@ private:
int maxLevel;
float lodBias;
// Cache the current filter settings so we can avoid setting it again.
// (OpenGL madness where filter settings are attached to each texture).
u8 magFilt;
u8 minFilt;
bool sClamp;
bool tClamp;
bool Matches(u16 dim2, u8 format2, int maxLevel2);
};

View file

@ -154,8 +154,8 @@ static const DeclTypeInfo VComp[] = {
{D3DDECLTYPE_UBYTE4N ,"D3DDECLTYPE_UBYTE4N "}, // DEC_U8_2,
{D3DDECLTYPE_UBYTE4N ,"D3DDECLTYPE_UBYTE4N "}, // DEC_U8_3,
{D3DDECLTYPE_UBYTE4N ,"D3DDECLTYPE_UBYTE4N "}, // DEC_U8_4,
{D3DDECLTYPE_USHORT4N ,"D3DDECLTYPE_USHORT4N "}, // DEC_U16_1,
{D3DDECLTYPE_USHORT4N ,"D3DDECLTYPE_USHORT4N "}, // DEC_U16_2,
{D3DDECLTYPE_USHORT2N, "D3DDECLTYPE_USHORT2N " }, // DEC_U16_1,
{D3DDECLTYPE_USHORT2N, "D3DDECLTYPE_USHORT2N " }, // DEC_U16_2,
{D3DDECLTYPE_USHORT4N ,"D3DDECLTYPE_USHORT4N "}, // DEC_U16_3,
{D3DDECLTYPE_USHORT4N ,"D3DDECLTYPE_USHORT4N "}, // DEC_U16_4,
#ifdef _XBOX
@ -164,7 +164,7 @@ static const DeclTypeInfo VComp[] = {
#else
// Not supported in regular DX9 so faking, will cause graphics bugs until worked around
{D3DDECLTYPE_UBYTE4 ,"D3DDECLTYPE_BYTE4 "}, // DEC_U8A_2,
{D3DDECLTYPE_USHORT4N ,"D3DDECLTYPE_USHORT4 "}, // DEC_U16A_2,
{D3DDECLTYPE_USHORT2N, "D3DDECLTYPE_USHORT4 " }, // DEC_U16A_2,
#endif
};
@ -219,6 +219,7 @@ static void LogDecFmtForDraw(const DecVtxFormat &decFmt) {
//pD3Ddevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
}
static void SetupDecFmtForDraw(LinkedShaderDX9 *program, const DecVtxFormat &decFmt, u32 pspFmt) {
auto vertexDeclCached = vertexDeclMap.find(pspFmt);
@ -271,13 +272,15 @@ static void SetupDecFmtForDraw(LinkedShaderDX9 *program, const DecVtxFormat &dec
memcpy(VertexElement, &end, sizeof(D3DVERTEXELEMENT9));
// Create declaration
pD3Ddevice->CreateVertexDeclaration( VertexElements, &pHardwareVertexDecl );
HRESULT hr = pD3Ddevice->CreateVertexDeclaration( VertexElements, &pHardwareVertexDecl );
if (FAILED(hr)) {
// Log
LogDecFmtForDraw(decFmt);
// DebugBreak();
}
// Add it to map
vertexDeclMap[pspFmt] = pHardwareVertexDecl;
// Log
//LogDecFmtForDraw(decFmt);
} else {
// Set it from map
pHardwareVertexDecl = vertexDeclCached->second;
@ -1135,23 +1138,25 @@ rotateVBO:
DEBUG_LOG(G3D, "Flush prim %i! %i verts in one go", prim, vertexCount);
SetupDecFmtForDraw(program, dec_->GetDecVtxFmt(), dec_->VertexType());
pD3Ddevice->SetVertexDeclaration(pHardwareVertexDecl);
if (vb_ == NULL) {
if (useElements) {
pD3Ddevice->DrawIndexedPrimitiveUP(glprim[prim], 0, vertexCount, D3DPrimCount(glprim[prim], vertexCount), decIndex, D3DFMT_INDEX16, decoded, dec_->GetDecVtxFmt().stride);
if (pHardwareVertexDecl) {
pD3Ddevice->SetVertexDeclaration(pHardwareVertexDecl);
if (vb_ == NULL) {
if (useElements) {
pD3Ddevice->DrawIndexedPrimitiveUP(glprim[prim], 0, vertexCount, D3DPrimCount(glprim[prim], vertexCount), decIndex, D3DFMT_INDEX16, decoded, dec_->GetDecVtxFmt().stride);
} else {
pD3Ddevice->DrawPrimitiveUP(glprim[prim], D3DPrimCount(glprim[prim], vertexCount), decoded, dec_->GetDecVtxFmt().stride);
}
} else {
pD3Ddevice->DrawPrimitiveUP(glprim[prim], D3DPrimCount(glprim[prim], vertexCount), decoded, dec_->GetDecVtxFmt().stride);
}
} else {
pD3Ddevice->SetStreamSource(0, vb_, 0, dec_->GetDecVtxFmt().stride);
pD3Ddevice->SetStreamSource(0, vb_, 0, dec_->GetDecVtxFmt().stride);
if (useElements) {
pD3Ddevice->SetIndices(ib_);
if (useElements) {
pD3Ddevice->SetIndices(ib_);
pD3Ddevice->DrawIndexedPrimitive(glprim[prim], 0, 0, 0, 0, D3DPrimCount(glprim[prim], vertexCount));
} else {
pD3Ddevice->DrawPrimitive(glprim[prim], 0, D3DPrimCount(glprim[prim], vertexCount));
pD3Ddevice->DrawIndexedPrimitive(glprim[prim], 0, 0, 0, 0, D3DPrimCount(glprim[prim], vertexCount));
} else {
pD3Ddevice->DrawPrimitive(glprim[prim], 0, D3DPrimCount(glprim[prim], vertexCount));
}
}
}
} else {

View file

@ -273,21 +273,20 @@ void VertexDecoderDX9::Step_Color4444() const
{
u8 *c = decoded_ + decFmt.c0off;
u16 cdata = (u16)(*(u16_le*)(ptr_ + coloff));
c[0] = Convert4To8((cdata >> (12)) & 0xF);
c[1] = Convert4To8((cdata >> (0)) & 0xF);
c[2] = Convert4To8((cdata >> (4)) & 0xF);
c[3] = Convert4To8((cdata >> (8)) & 0xF);
c[0] = Convert4To8((cdata >> (0)) & 0xF);
c[1] = Convert4To8((cdata >> (4)) & 0xF);
c[2] = Convert4To8((cdata >> (8)) & 0xF);
c[3] = Convert4To8((cdata >> (12)) & 0xF);
}
void VertexDecoderDX9::Step_Color8888() const
{
// Directx want ARGB
u8 *c = (u8*)(decoded_ + decFmt.c0off);
const u8 *cdata = (const u8*)(ptr_ + coloff);
c[0] = cdata[3];
c[1] = cdata[0];
c[2] = cdata[1];
c[3] = cdata[2];
c[0] = cdata[2];
c[1] = cdata[1];
c[2] = cdata[0];
c[3] = cdata[3];
}
void VertexDecoderDX9::Step_Color565Morph() const
@ -864,7 +863,7 @@ void VertexDecoderDX9::SetVertexType(u32 fmt) {
// The normal formats match the gl formats perfectly, let's use 'em.
switch (nrm) {
//case GE_VTYPE_NRM_8BIT >> GE_VTYPE_NRM_SHIFT: decFmt.nrmfmt = DEC_S8_3; break;
case GE_VTYPE_NRM_8BIT >> GE_VTYPE_NRM_SHIFT: decFmt.nrmfmt = DEC_FLOAT_3; break;
case GE_VTYPE_NRM_8BIT >> GE_VTYPE_NRM_SHIFT: decFmt.nrmfmt = DEC_FLOAT_3; break;
case GE_VTYPE_NRM_16BIT >> GE_VTYPE_NRM_SHIFT: decFmt.nrmfmt = DEC_S16_3; break;
case GE_VTYPE_NRM_FLOAT >> GE_VTYPE_NRM_SHIFT: decFmt.nrmfmt = DEC_FLOAT_3; break;
}

View file

@ -19,6 +19,7 @@ void DirectxState::Initialize() {
void DirectxState::Restore() {
int count = 0;
blend.restore(); count++;
blendEquation.restore(); count++;
blendFunc.restore(); count++;
@ -37,7 +38,8 @@ void DirectxState::Restore() {
depthWrite.restore(); count++;
colorMask.restore(); count++;
viewport.restore(); count++;
// viewport.restore(); count++;
stencilTest.restore(); count++;
stencilOp.restore(); count++;
@ -45,7 +47,14 @@ void DirectxState::Restore() {
dither.restore(); count++;
assert(count == state_count && "DirectxState::Restore is missing some states");
texMinFilter.restore(); count++;
texMagFilter.restore(); count++;
texMipFilter.restore(); count++;
texAddressU.restore(); count++;
texAddressV.restore(); count++;
//assert(count == state_count && "DirectxState::Restore is missing some states");
}
void CheckGLExtensions() {

View file

@ -6,10 +6,7 @@
namespace DX9 {
// OpenGL state cache. Should convert all code to use this instead of directly calling glEnable etc,
// as GL state changes can be expensive on some hardware.
class DirectxState
{
class DirectxState {
private:
template<D3DRENDERSTATETYPE cap, bool init>
class BoolState {
@ -58,6 +55,24 @@ private:
}
};
template<D3DSAMPLERSTATETYPE state1, DWORD p1def>
class DxSampler0State1 {
D3DSAMPLERSTATETYPE _state1;
DWORD p1;
public:
DxSampler0State1() : _state1(state1), p1(p1def) {
DirectxState::state_count++;
}
inline void set(DWORD newp1) {
p1 = newp1;
pD3Ddevice->SetSamplerState(0, _state1, p1);
}
void restore() {
pD3Ddevice->SetSamplerState(0, _state1, p1);
}
};
template<D3DRENDERSTATETYPE state1, DWORD p1def, D3DRENDERSTATETYPE state2, DWORD p2def>
class DxState2 {
D3DRENDERSTATETYPE _state1;
@ -104,12 +119,46 @@ private:
pD3Ddevice->SetRenderState(_state3, p3);
}
void restore() {
// pD3Ddevice->SetRenderState(_state1, p1);
// pD3Ddevice->SetRenderState(_state2, p2);
// pD3Ddevice->SetRenderState(_state3, p2);
pD3Ddevice->SetRenderState(_state1, p1);
pD3Ddevice->SetRenderState(_state2, p2);
pD3Ddevice->SetRenderState(_state3, p3);
}
};
template<D3DRENDERSTATETYPE state1, DWORD p1def, D3DRENDERSTATETYPE state2, DWORD p2def, D3DRENDERSTATETYPE state3, DWORD p3def, D3DRENDERSTATETYPE state4, DWORD p4def>
class DxState4 {
D3DRENDERSTATETYPE _state1;
D3DRENDERSTATETYPE _state2;
D3DRENDERSTATETYPE _state3;
D3DRENDERSTATETYPE _state4;
DWORD p1;
DWORD p2;
DWORD p3;
DWORD p4;
public:
DxState4() : _state1(state1), _state2(state2), _state3(state3), _state4(state4),
p1(p1def), p2(p2def), p3(p3def), p4(p4def) {
// DirectxState::state_count++;
}
inline void set(DWORD newp1, DWORD newp2, DWORD newp3, DWORD newp4) {
p1 = newp1;
p2 = newp2;
p3 = newp3;
p4 = newp4;
pD3Ddevice->SetRenderState(_state1, p1);
pD3Ddevice->SetRenderState(_state2, p2);
pD3Ddevice->SetRenderState(_state3, p3);
pD3Ddevice->SetRenderState(_state4, p4);
}
void restore() {
pD3Ddevice->SetRenderState(_state1, p1);
pD3Ddevice->SetRenderState(_state2, p2);
pD3Ddevice->SetRenderState(_state3, p3);
pD3Ddevice->SetRenderState(_state3, p4);
}
};
class SavedBlendFactor {
DWORD c;
@ -191,15 +240,6 @@ private:
viewport.Y=y;
viewport.Width=w;
viewport.Height=h;
/*
if (f > n) {
viewport.MinZ=n;
viewport.MaxZ=f;
} else {
viewport.MinZ=f;
viewport.MaxZ=n;
}
*/
viewport.MinZ=n;
viewport.MaxZ=f;
@ -232,12 +272,10 @@ private:
cull = D3DCULL_NONE;
} else {
// add front face ...
cull = cullmode==0?D3DCULL_CW:D3DCULL_CCW;
cull = cullmode==0 ? D3DCULL_CW:D3DCULL_CCW;
}
pD3Ddevice->SetRenderState(D3DRS_CULLMODE, cull);
}
inline void restore() {
pD3Ddevice->SetRenderState(D3DRS_CULLMODE, cull);
}
@ -253,8 +291,8 @@ public:
// When adding a state here, don't forget to add it to DirectxState::Restore() too
BoolState<D3DRS_ALPHABLENDENABLE, false> blend;
DxState2<D3DRS_SRCBLEND, D3DBLEND_SRCALPHA, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA> blendFunc;
DxState1<D3DRS_BLENDOP, D3DBLENDOP_ADD> blendEquation;
DxState4<D3DRS_SRCBLEND, D3DBLEND_SRCALPHA, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA, D3DRS_SRCBLENDALPHA, D3DBLEND_ONE, D3DRS_DESTBLENDALPHA, D3DBLEND_ZERO> blendFunc;
DxState2<D3DRS_BLENDOP, D3DBLENDOP_ADD, D3DRS_BLENDOPALPHA, D3DBLENDOP_ADD> blendEquation;
SavedBlendFactor blendColor;
BoolState<D3DRS_SCISSORTESTENABLE, false> scissorTest;
@ -278,6 +316,12 @@ public:
DxState3<D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP> stencilOp;
DxState3<D3DRS_STENCILFUNC, D3DCMP_ALWAYS, D3DRS_STENCILREF, 0, D3DRS_STENCILMASK, 0xFFFFFFFF> stencilFunc;
DxSampler0State1<D3DSAMP_MINFILTER, D3DTEXF_POINT> texMinFilter;
DxSampler0State1<D3DSAMP_MAGFILTER, D3DTEXF_POINT> texMagFilter;
DxSampler0State1<D3DSAMP_MIPFILTER, D3DTEXF_NONE> texMipFilter;
DxSampler0State1<D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP> texAddressU;
DxSampler0State1<D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP> texAddressV;
// Only works on Win32, all other platforms are "force-vsync"
void SetVSyncInterval(int interval); // one of the above VSYNC, or a higher number for multi-frame waits (could be useful for 30hz games)
};

View file

@ -2,12 +2,11 @@
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "base/logging.h"
#include "fbo.h"
namespace DX9 {
static LPDIRECT3DSURFACE9 currentRtt;
static LPDIRECT3DSURFACE9 workingRtt;
static LPDIRECT3DSURFACE9 deviceRTsurf;
static LPDIRECT3DSURFACE9 deviceDSsurf;
@ -18,10 +17,6 @@ struct FBO {
LPDIRECT3DSURFACE9 surf;
LPDIRECT3DSURFACE9 depthstencil;
LPDIRECT3DTEXTURE9 tex;
uint32_t color_texture;
uint32_t z_stencil_buffer; // Either this is set, or the two below.
uint32_t z_buffer;
uint32_t stencil_buffer;
int width;
int height;
@ -31,8 +26,11 @@ struct FBO {
void fbo_init() {
pD3Ddevice->GetRenderTarget(0, &deviceRTsurf);
pD3Ddevice->GetDepthStencilSurface(&deviceDSsurf);
}
//pD3Ddevice->CreateRenderTarget(1280/FB_DIV, 720/FB_DIV, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &workingRtt, NULL);
void fbo_shutdown() {
deviceRTsurf->Release();
deviceDSsurf->Release();
}
FBO * current_fbo = NULL;
@ -46,85 +44,49 @@ FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, F
fbo->height = height;
fbo->colorDepth = colorDepth;
// only support 32bit surfaces
//pD3Ddevice->CreateRenderTarget(fbo->width/4, fbo->height/4, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->surf, NULL);
/*
// Create depth + stencil target | forced to 24-bit Z, 8-bit stencil
pD3Ddevice->CreateDepthStencilSurface(fbo->width, fbo->height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->depthstencil, NULL);
*/
// Only needed on xbox
#ifdef _XBOX
pD3Ddevice->CreateTexture(fbo->width/FB_DIV, fbo->height/FB_DIV, 1, 0, D3DFMT_A8R8G8B8, 0, &fbo->tex, NULL);
if (workingRtt == NULL) {
pD3Ddevice->CreateRenderTarget(fbo->width/FB_DIV, fbo->height/FB_DIV, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &workingRtt, NULL);
HRESULT rtResult = pD3Ddevice->CreateTexture(fbo->width, fbo->height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &fbo->tex, NULL);
if (FAILED(rtResult)) {
ELOG("Failed to create render target");
delete fbo;
return NULL;
}
fbo->tex->GetSurfaceLevel(0, &fbo->surf);
HRESULT dsResult = pD3Ddevice->CreateDepthStencilSurface(fbo->width, fbo->height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->depthstencil, NULL);
if (FAILED(dsResult)) {
ELOG("Failed to create depth buffer");
fbo->surf->Release();
fbo->tex->Release();
delete fbo;
return NULL;
}
#else
pD3Ddevice->CreateRenderTarget(fbo->width/4, fbo->height/4, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->surf, NULL);
pD3Ddevice->CreateDepthStencilSurface(fbo->width, fbo->height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->depthstencil, NULL);
#endif
fbo->stencil_buffer = 8;
fbo->z_buffer = 24;
fbo->id = id++;
return fbo;
}
void fbo_destroy(FBO *fbo) {
fbo->tex->Release();
fbo->surf->Release();
fbo->depthstencil->Release();
delete fbo;
}
void * fbo_get_rtt(FBO *fbo) {
return fbo->tex;
}
void fbo_unbind() {
if (current_fbo != NULL) {
#ifdef _XBOX
D3DVECTOR4 White = {0.0f, 0.0f, 0.0f, 0.0f};
pD3Ddevice->Resolve( D3DRESOLVE_RENDERTARGET0|D3DRESOLVE_ALLFRAGMENTS|D3DRESOLVE_CLEARRENDERTARGET|D3DRESOLVE_CLEARDEPTHSTENCIL, NULL,
current_fbo->tex, NULL, 0, 0, &White, 0.0f, 0, NULL );
#else
// TODO?
#endif
/*
pD3Ddevice->Resolve( D3DRESOLVE_RENDERTARGET0|D3DRESOLVE_ALLFRAGMENTS, NULL,
current_fbo->tex, NULL, 0, 0, 0, 0.0f, 0, NULL );
*/
//pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER, 0xFFFFFFFF, 0, 0);
}
//pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER, 0xFFFFFFFF, 0, 0);
current_fbo = NULL;
pD3Ddevice->SetRenderTarget(0, deviceRTsurf);
//pD3Ddevice->SetDepthStencilSurface(deviceDSsurf);
currentRtt = deviceRTsurf;
pD3Ddevice->SetDepthStencilSurface(deviceDSsurf);
}
void fbo_resolve(FBO *fbo) {
if (fbo && fbo->tex) {
#ifdef _XBOX
pD3Ddevice->Resolve( D3DRESOLVE_RENDERTARGET0|D3DRESOLVE_ALLFRAGMENTS, NULL, fbo->tex, NULL, 0, 0, NULL, 0.0f, 0, NULL );
#else
// TODO?
#endif
}
#if 0
// Hack save to disk ...
char fname[256];
static int f = 0;
sprintf(fname, "game:\\rtt.%08x.%d.png", fbo->id, f++);
D3DXSaveTextureToFile(fname, D3DXIFF_PNG, fbo->tex, NULL);
//strcat(fname, "\n");
OutputDebugString(fname);
#endif
}
void fbo_bind_as_render_target(FBO *fbo) {
current_fbo = fbo;
pD3Ddevice->SetRenderTarget(0, workingRtt);
currentRtt = workingRtt;
//pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER, 0xFFFFFFFF, 0, 0);
//pD3Ddevice->SetDepthStencilSurface(fbo->depthstencil);
pD3Ddevice->SetRenderTarget(0, fbo->surf);
pD3Ddevice->SetDepthStencilSurface(fbo->depthstencil);
}
void fbo_bind_for_read(FBO *fbo) {
@ -132,37 +94,7 @@ void fbo_bind_for_read(FBO *fbo) {
}
void fbo_bind_color_as_texture(FBO *fbo, int color) {
#if 0
// Hack save to disk ...
char fname[256];
static int f = 0;
sprintf(fname, "game:\\rtt.%08x.%d.png", fbo->id, f++);
D3DXSaveTextureToFile(fname, D3DXIFF_PNG, fbo->tex, NULL);
//strcat(fname, "\n");
OutputDebugString(fname);
#endif
//pD3Ddevice->SetRenderTarget(0, workingRtt);
//pD3Ddevice->Resolve( D3DRESOLVE_RENDERTARGET0|D3DRESOLVE_ALLFRAGMENTS, NULL, fbo->tex, NULL, 0, 0, NULL, 0.0f, 0, NULL );
//pD3Ddevice->SetRenderTarget(0, currentRtt);
//OutputDebugStringA("fbo_bind_color_as_texture: Fix me\r\n");
pD3Ddevice->SetTexture(0, fbo->tex);
//pD3Ddevice->SetTexture(0, NULL);
}
void fbo_destroy(FBO *fbo) {
/*
fbo->depthstencil->Release();
*/
//fbo->surf->Release();
#ifdef _XBOX
fbo->tex->Release();
#else
fbo->depthstencil->Release();
fbo->surf->Release();
#endif
delete fbo;
}
void fbo_get_dimensions(FBO *fbo, int *w, int *h) {
@ -170,11 +102,4 @@ void fbo_get_dimensions(FBO *fbo, int *w, int *h) {
*h = fbo->height;
}
void SwapBuffer() {
pD3Ddevice->Present(0, 0, 0, 0);
// :s
//pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0 ,0), 0, 0);
}
};
}

View file

@ -1,5 +1,6 @@
#include "global.h"
#include "fbo.h"
#include "thin3d/d3dx9_loader.h"
namespace DX9 {
@ -91,6 +92,19 @@ bool CompilePixelShader(const char * code, LPDIRECT3DPIXELSHADER9 * pShader, LPD
&pShaderCode,
&pErrorMsg,
pShaderTable );
#else
// Compile pixel shader.
hr = dyn_D3DXCompileShader(code,
(UINT)strlen(code),
NULL,
NULL,
"main",
"ps_3_0",
0,
&pShaderCode,
&pErrorMsg,
pShaderTable);
#endif
if( FAILED(hr) )
{
@ -128,6 +142,17 @@ bool CompileVertexShader(const char * code, LPDIRECT3DVERTEXSHADER9 * pShader, L
&pShaderCode,
&pErrorMsg,
pShaderTable );
#else
hr = dyn_D3DXCompileShader(code,
(UINT)strlen(code),
NULL,
NULL,
"main",
"vs_3_0",
0,
&pShaderCode,
&pErrorMsg,
pShaderTable);
#endif
if( FAILED(hr) )
{
@ -163,6 +188,19 @@ void CompileShaders() {
&pShaderCode,
&pErrorMsg,
NULL );
#else
// Compile vertex shader.
hr = dyn_D3DXCompileShader(vscode,
(UINT)strlen(vscode),
NULL,
NULL,
"main",
"vs_2_0",
0,
&pShaderCode,
&pErrorMsg,
NULL);
#endif
if( FAILED(hr) )
@ -189,6 +227,19 @@ void CompileShaders() {
&pShaderCode,
&pErrorMsg,
NULL );
#else
// Compile pixel shader.
hr = dyn_D3DXCompileShader(pscode,
(UINT)strlen(pscode),
NULL,
NULL,
"main",
"ps_2_0",
0,
&pShaderCode,
&pErrorMsg,
NULL);
#endif
if( FAILED(hr) )

View file

@ -9,10 +9,11 @@
#define D3DFMT(x) x
#endif
namespace DX9 {
#include <d3d9.h>
#include <d3dx9.h>
struct ID3DXConstantTable;
namespace DX9 {
extern LPDIRECT3DDEVICE9 pD3Ddevice;
@ -22,8 +23,9 @@ extern LPDIRECT3DPIXELSHADER9 pFramebufferPixelShader; // Pixel Shader
extern IDirect3DVertexDeclaration9* pFramebufferVertexDecl;
extern IDirect3DVertexDeclaration9* pSoftVertexDecl;
bool CompilePixelShader(const char * code, LPDIRECT3DPIXELSHADER9 * pShader, LPD3DXCONSTANTTABLE * pShaderTable);
bool CompileVertexShader(const char * code, LPDIRECT3DVERTEXSHADER9 * pShader, LPD3DXCONSTANTTABLE * pShaderTable);
void CompileShaders();
bool CompilePixelShader(const char * code, LPDIRECT3DPIXELSHADER9 * pShader, ID3DXConstantTable **pShaderTable);
bool CompileVertexShader(const char * code, LPDIRECT3DVERTEXSHADER9 * pShader, ID3DXConstantTable **pShaderTable);
void DirectxInit(HWND window);
#define D3DBLEND_UNK D3DSTENCILOP_FORCE_DWORD

View file

@ -94,6 +94,8 @@ SOURCES += $$P/native/audio/*.cpp \
$$P/native/math/fast/*.c \
$$P/native/net/*.cpp \
$$P/native/profiler/profiler.cpp \
$$P/native/thin3d/thin3d.cpp \
$$P/native/thin3d/thin3d_gl.cpp \
$$P/native/thread/*.cpp \
$$P/native/ui/*.cpp \
$$P/native/util/bits/*.cpp \

View file

@ -191,7 +191,7 @@ int MixBackgroundAudio(short *buffer, int size) {
// last changed... (to prevent crazy amount of reads when skipping through a list)
if (!at3Reader && bgGamePath.size() && (time_now_d() - gameLastChanged > 0.5)) {
// Grab some audio from the current game and play it.
GameInfo *gameInfo = g_gameInfoCache.GetInfo(bgGamePath, GAMEINFO_WANTSND);
GameInfo *gameInfo = g_gameInfoCache.GetInfo(NULL, bgGamePath, GAMEINFO_WANTSND);
if (!gameInfo)
return 0;

View file

@ -30,7 +30,6 @@
#include "Core/Config.h"
#include "UI/ui_atlas.h"
#include "UI/ControlMappingScreen.h"
#include "UI/UIShader.h"
#include "UI/GameSettingsScreen.h"
class ControlMapper : public UI::LinearLayout {

View file

@ -28,7 +28,6 @@
#include "UI/OnScreenDisplay.h"
#include "UI/ui_atlas.h"
#include "UI/GamepadEmu.h"
#include "UI/UIShader.h"
#include "UI/MainScreen.h"
#include "UI/EmuScreen.h"

View file

@ -231,16 +231,20 @@ void SystemInfoScreen::CreateViews() {
deviceSpecs->Add(new InfoItem("Threads", cores));
#endif
deviceSpecs->Add(new ItemHeader("GPU Information"));
deviceSpecs->Add(new InfoItem("Vendor", (char *)glGetString(GL_VENDOR)));
deviceSpecs->Add(new InfoItem("Model", (char *)glGetString(GL_RENDERER)));
Thin3DContext *thin3d = screenManager()->getThin3DContext();
deviceSpecs->Add(new InfoItem("3D API", thin3d->GetInfoString(T3DInfo::APINAME)));
deviceSpecs->Add(new InfoItem("Vendor", thin3d->GetInfoString(T3DInfo::VENDOR)));
deviceSpecs->Add(new InfoItem("Model", thin3d->GetInfoString(T3DInfo::RENDERER)));
#ifdef _WIN32
deviceSpecs->Add(new InfoItem("Driver Version", System_GetProperty(SYSPROP_GPUDRIVER_VERSION)));
#endif
deviceSpecs->Add(new ItemHeader("OpenGL Version Information"));
std::string openGL = (char *)glGetString(GL_VERSION);
openGL.resize(30);
deviceSpecs->Add(new InfoItem("OpenGL", openGL));
deviceSpecs->Add(new InfoItem("GLSL", (char *)glGetString(GL_SHADING_LANGUAGE_VERSION)));
deviceSpecs->Add(new ItemHeader("Version Information"));
std::string apiVersion = thin3d->GetInfoString(T3DInfo::APIVERSION);
apiVersion.resize(30);
deviceSpecs->Add(new InfoItem("API Version", apiVersion));
deviceSpecs->Add(new InfoItem("Shading Language", thin3d->GetInfoString(T3DInfo::SHADELANGVERSION)));
#ifdef ANDROID
char temp[256];

View file

@ -50,7 +50,6 @@
#include "UI/ui_atlas.h"
#include "UI/OnScreenDisplay.h"
#include "UI/GamepadEmu.h"
#include "UI/UIShader.h"
#include "UI/MainScreen.h"
#include "UI/EmuScreen.h"
#include "UI/DevScreens.h"
@ -87,6 +86,9 @@ void EmuScreen::bootGame(const std::string &filename) {
CoreParameter coreParam;
coreParam.cpuCore = g_Config.bJit ? CPU_JIT : CPU_INTERPRETER;
coreParam.gpuCore = g_Config.bSoftwareRendering ? GPU_SOFTWARE : GPU_GLES;
if (g_Config.iGPUBackend == GPU_BACKEND_DIRECT3D9) {
coreParam.gpuCore = GPU_DIRECTX9;
}
coreParam.enableSound = g_Config.bEnableSound;
coreParam.fileToStart = filename;
coreParam.mountIso = "";
@ -136,11 +138,13 @@ void EmuScreen::bootComplete() {
#endif
memset(virtKeys, 0, sizeof(virtKeys));
const char *renderer = (const char*)glGetString(GL_RENDERER);
if (strstr(renderer, "Chainfire3D") != 0) {
osm.Show(s->T("Chainfire3DWarning", "WARNING: Chainfire3D detected, may cause problems"), 10.0f, 0xFF30a0FF, -1, true);
} else if (strstr(renderer, "GLTools") != 0) {
osm.Show(s->T("GLToolsWarning", "WARNING: GLTools detected, may cause problems"), 10.0f, 0xFF30a0FF, -1, true);
if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) {
const char *renderer = (const char*)glGetString(GL_RENDERER);
if (strstr(renderer, "Chainfire3D") != 0) {
osm.Show(s->T("Chainfire3DWarning", "WARNING: Chainfire3D detected, may cause problems"), 10.0f, 0xFF30a0FF, -1, true);
} else if (strstr(renderer, "GLTools") != 0) {
osm.Show(s->T("GLToolsWarning", "WARNING: GLTools detected, may cause problems"), 10.0f, 0xFF30a0FF, -1, true);
}
}
System_SendMessage("event", "startgame");
@ -702,17 +706,24 @@ void EmuScreen::render() {
return;
bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
if (useBufferedRendering)
if (useBufferedRendering && g_Config.iGPUBackend == GPU_BACKEND_OPENGL)
fbo_unbind();
UIShader_Prepare();
screenManager()->getUIContext()->RebindTexture();
Thin3DContext *thin3d = screenManager()->getThin3DContext();
uiTexture->Bind(0);
glstate.viewport.set(0, 0, pixel_xres, pixel_yres);
T3DViewport viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = pixel_xres;
viewport.Height = pixel_yres;
viewport.MaxDepth = 1.0;
viewport.MinDepth = 0.0;
thin3d->SetViewports(1, &viewport);
glstate.viewport.restore();
ui_draw2d.Begin(UIShader_Get(), DBMODE_NORMAL);
thin3d->SetBlendState(thin3d->GetBlendStatePreset(BS_STANDARD_ALPHA));
ui_draw2d.Begin(thin3d->GetShaderSetPreset(SS_TEXTURE_COLOR_2D), DBMODE_NORMAL);
if (root_) {
UI::LayoutViewHierarchy(*screenManager()->getUIContext(), root_);
@ -757,7 +768,6 @@ void EmuScreen::render() {
ui_draw2d.SetFontScale(1.0f, 1.0f);
}
glsl_bind(UIShader_Get());
ui_draw2d.End();
ui_draw2d.Flush();

View file

@ -24,6 +24,7 @@
#include "base/stringutil.h"
#include "file/file_util.h"
#include "file/zip_read.h"
#include "thin3d/thin3d.h"
#include "thread/prioritizedworkqueue.h"
#include "Common/FileUtil.h"
#include "Common/StringUtils.h"
@ -561,10 +562,8 @@ void GameInfoCache::FlushBGs() {
}
}
// This may run off-main-thread and we thus can't use the global
// pspFileSystem (well, we could with synchronization but there might not
// even be a game running).
GameInfo *GameInfoCache::GetInfo(const std::string &gamePath, int wantFlags) {
// Runs on the main thread.
GameInfo *GameInfoCache::GetInfo(Thin3DContext *thin3d, const std::string &gamePath, int wantFlags) {
GameInfo *info = 0;
auto iter = info_.find(gamePath);
@ -574,16 +573,16 @@ GameInfo *GameInfoCache::GetInfo(const std::string &gamePath, int wantFlags) {
// Need to start over. We'll just add a new work item.
goto again;
}
if (info->iconDataLoaded) {
SetupTexture(info, info->iconTextureData, info->iconTexture, info->timeIconWasLoaded);
if (thin3d && info->iconDataLoaded) {
SetupTexture(info, info->iconTextureData, thin3d, info->iconTexture, info->timeIconWasLoaded);
info->iconDataLoaded = false;
}
if (info->pic0DataLoaded) {
SetupTexture(info, info->pic0TextureData, info->pic0Texture, info->timePic0WasLoaded);
if (thin3d && info->pic0DataLoaded) {
SetupTexture(info, info->pic0TextureData, thin3d, info->pic0Texture, info->timePic0WasLoaded);
info->pic0DataLoaded = false;
}
if (info->pic1DataLoaded) {
SetupTexture(info, info->pic1TextureData, info->pic1Texture, info->timePic1WasLoaded);
if (thin3d && info->pic1DataLoaded) {
SetupTexture(info, info->pic1TextureData, thin3d, info->pic1Texture, info->timePic1WasLoaded);
info->pic1DataLoaded = false;
}
iter->second->lastAccessedTime = time_now_d();
@ -607,14 +606,14 @@ again:
return info;
}
void GameInfoCache::SetupTexture(GameInfo *info, std::string &textureData, Texture *&tex, double &loadTime) {
void GameInfoCache::SetupTexture(GameInfo *info, std::string &textureData, Thin3DContext *thin3d, Thin3DTexture *&tex, double &loadTime) {
if (textureData.size()) {
if (!tex) {
tex = new Texture();
if (tex->LoadPNG((const u8 *)textureData.data(), textureData.size(), false)) {
tex = thin3d->CreateTextureFromFileData(textureData.data(), textureData.size(), T3DFileType::PNG);
if (tex) {
loadTime = time_now_d();
} else {
delete tex;
tex->Release();
tex = 0;
}
}

View file

@ -23,10 +23,12 @@
#include "base/mutex.h"
#include "file/file_util.h"
#include "thread/prioritizedworkqueue.h"
#include "gfx/texture.h"
#include "Core/ELF/ParamSFO.h"
#include "Core/Loaders.h"
class Thin3DContext;
class Thin3DTexture;
// A GameInfo holds information about a game, and also lets you do things that the VSH
// does on the PSP, namely checking for and deleting savedata, and similar things.
// Only cares about games that are installed on the current device.
@ -128,11 +130,11 @@ public:
// Pre read the data, create a texture the next time (GL thread..)
std::string iconTextureData;
Texture *iconTexture;
Thin3DTexture *iconTexture;
std::string pic0TextureData;
Texture *pic0Texture;
Thin3DTexture *pic0Texture;
std::string pic1TextureData;
Texture *pic1Texture;
Thin3DTexture *pic1Texture;
std::string sndFileData;
@ -170,7 +172,7 @@ public:
// but filled in later asynchronously in the background. So keep calling this,
// redrawing the UI often. Only set flags to GAMEINFO_WANTBG or WANTSND if you really want them
// because they're big. bgTextures and sound may be discarded over time as well.
GameInfo *GetInfo(const std::string &gamePath, int wantFlags);
GameInfo *GetInfo(Thin3DContext *thin3d, const std::string &gamePath, int wantFlags);
void Decimate(); // Deletes old info.
void FlushBGs(); // Gets rid of all BG textures. Also gets rid of bg sounds.
@ -179,7 +181,7 @@ public:
void Load();
private:
void SetupTexture(GameInfo *info, std::string &textureData, Texture *&tex, double &loadTime);
void SetupTexture(GameInfo *info, std::string &textureData, Thin3DContext *thin3d, Thin3DTexture *&tex, double &loadTime);
// Maps ISO path to info.
std::map<std::string, GameInfo *> info_;

View file

@ -45,7 +45,7 @@ GameScreen::~GameScreen() {
}
void GameScreen::CreateViews() {
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
I18NCategory *d = GetI18NCategory("Dialog");
I18NCategory *ga = GetI18NCategory("Game");
@ -64,7 +64,7 @@ void GameScreen::CreateViews() {
leftColumn->Add(new Choice(d->T("Back"), "", false, new AnchorLayoutParams(150, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle(this, &GameScreen::OnSwitchBack);
if (info) {
texvGameIcon_ = leftColumn->Add(new TextureView(0, IS_DEFAULT, new AnchorLayoutParams(144 * 2, 80 * 2, 10, 10, NONE, NONE)));
texvGameIcon_ = leftColumn->Add(new Thin3DTextureView(0, IS_DEFAULT, new AnchorLayoutParams(144 * 2, 80 * 2, 10, 10, NONE, NONE)));
tvTitle_ = leftColumn->Add(new TextView(info->title, ALIGN_LEFT, false, new AnchorLayoutParams(10, 200, NONE, NONE)));
// This one doesn't need to be updated.
leftColumn->Add(new TextView(gamePath_, ALIGN_LEFT, true, new AnchorLayoutParams(10, 250, NONE, NONE)));
@ -105,7 +105,10 @@ void GameScreen::update(InputState &input) {
UIScreen::update(input);
I18NCategory *ga = GetI18NCategory("Game");
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
Thin3DContext *thin3d = screenManager()->getThin3DContext();
GameInfo *info = g_gameInfoCache.GetInfo(thin3d, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
if (tvTitle_)
tvTitle_->SetText(info->title + " (" + info->id + ")");
@ -166,7 +169,7 @@ UI::EventReturn GameScreen::OnPlay(UI::EventParams &e) {
}
UI::EventReturn GameScreen::OnGameSettings(UI::EventParams &e) {
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
if (info && info->paramSFOLoaded) {
std::string discID = info->paramSFO.GetValueString("DISC_ID");
screenManager()->push(new GameSettingsScreen(gamePath_, discID));
@ -177,7 +180,7 @@ UI::EventReturn GameScreen::OnGameSettings(UI::EventParams &e) {
UI::EventReturn GameScreen::OnDeleteSaveData(UI::EventParams &e) {
I18NCategory *d = GetI18NCategory("Dialog");
I18NCategory *ga = GetI18NCategory("Game");
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
if (info) {
// Check that there's any savedata to delete
std::vector<std::string> saveDirs = info->GetSaveDataDirectories();
@ -193,7 +196,7 @@ UI::EventReturn GameScreen::OnDeleteSaveData(UI::EventParams &e) {
}
void GameScreen::CallbackDeleteSaveData(bool yes) {
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, 0);
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, 0);
if (yes) {
info->DeleteAllSaveData();
info->saveDataSize = 0;
@ -204,7 +207,7 @@ void GameScreen::CallbackDeleteSaveData(bool yes) {
UI::EventReturn GameScreen::OnDeleteGame(UI::EventParams &e) {
I18NCategory *d = GetI18NCategory("Dialog");
I18NCategory *ga = GetI18NCategory("Game");
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
if (info) {
screenManager()->push(
new PromptScreen(d->T("DeleteConfirmGame", "Do you really want to delete this game\nfrom your device? You can't undo this."), ga->T("ConfirmDelete"), d->T("Cancel"),
@ -215,7 +218,7 @@ UI::EventReturn GameScreen::OnDeleteGame(UI::EventParams &e) {
}
void GameScreen::CallbackDeleteGame(bool yes) {
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, 0);
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, 0);
if (yes) {
info->DeleteGame();
g_gameInfoCache.Clear();
@ -224,7 +227,7 @@ void GameScreen::CallbackDeleteGame(bool yes) {
}
UI::EventReturn GameScreen::OnCreateShortcut(UI::EventParams &e) {
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, 0);
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, 0);
if (info) {
host->CreateDesktopShortcut(gamePath_, info->title);
}

View file

@ -52,7 +52,7 @@ private:
UI::EventReturn OnShowInFolder(UI::EventParams &e);
// As we load metadata in the background, we need to be able to update these after the fact.
UI::TextureView *texvGameIcon_;
UI::Thin3DTextureView *texvGameIcon_;
UI::TextView *tvTitle_;
UI::TextView *tvGameSize_;
UI::TextView *tvSaveDataSize_;

View file

@ -63,7 +63,7 @@ bool GameSettingsScreen::UseVerticalLayout() const {
}
void GameSettingsScreen::CreateViews() {
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
cap60FPS_ = g_Config.iForceMaxEmulatedFPS == 60;

View file

@ -174,8 +174,8 @@ private:
};
void GameButton::Draw(UIContext &dc) {
GameInfo *ginfo = g_gameInfoCache.GetInfo(gamePath_, 0);
Texture *texture = 0;
GameInfo *ginfo = g_gameInfoCache.GetInfo(dc.GetThin3DContext(), gamePath_, 0);
Thin3DTexture *texture = 0;
u32 color = 0, shadowColor = 0;
if (ginfo->iconTexture) {
@ -249,7 +249,7 @@ void GameButton::Draw(UIContext &dc) {
if (texture) {
dc.Draw()->Flush();
texture->Bind(0);
dc.GetThin3DContext()->SetTexture(0, texture);
if (holdFrameCount_ > 60) {
// Blink before launching by holding
if (((holdFrameCount_ >> 3) & 1) == 0)
@ -959,7 +959,7 @@ bool MainScreen::DrawBackgroundFor(UIContext &dc, const std::string &gamePath, f
GameInfo *ginfo = 0;
if (!gamePath.empty()) {
ginfo = g_gameInfoCache.GetInfo(gamePath, GAMEINFO_WANTBG);
ginfo = g_gameInfoCache.GetInfo(dc.GetThin3DContext(), gamePath, GAMEINFO_WANTBG);
// Loading texture data may bind a texture.
dc.RebindTexture();
@ -972,9 +972,9 @@ bool MainScreen::DrawBackgroundFor(UIContext &dc, const std::string &gamePath, f
}
if (ginfo->pic1Texture) {
ginfo->pic1Texture->Bind(0);
dc.GetThin3DContext()->SetTexture(0, ginfo->pic1Texture);
} else if (ginfo->pic0Texture) {
ginfo->pic0Texture->Bind(0);
dc.GetThin3DContext()->SetTexture(0, ginfo->pic0Texture);
}
uint32_t color = whiteAlpha(ease(progress)) & 0xFFc0c0c0;

View file

@ -18,7 +18,6 @@
#include "base/colorutil.h"
#include "base/timeutil.h"
#include "gfx_es2/draw_buffer.h"
#include "gfx_es2/gl_state.h"
#include "file/vfs.h"
#include "math/curves.h"
#include "i18n/i18n.h"
@ -85,11 +84,8 @@ void DrawBackground(UIContext &dc, float alpha = 1.0f) {
last_xres = xres;
last_yres = yres;
}
glstate.depthWrite.set(GL_TRUE);
glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glClearColor(0.1f, 0.2f, 0.43f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
dc.GetThin3DContext()->Clear(T3DClear::COLOR | T3DClear::DEPTH | T3DClear::STENCIL, 0xff224477, 0.0, 0);
int img = I_BG;
#ifdef GOLD
img = I_BG_GOLD;
@ -106,18 +102,18 @@ void DrawBackground(UIContext &dc, float alpha = 1.0f) {
}
void DrawGameBackground(UIContext &dc, const std::string &gamePath) {
GameInfo *ginfo = g_gameInfoCache.GetInfo(gamePath, GAMEINFO_WANTBG);
GameInfo *ginfo = g_gameInfoCache.GetInfo(dc.GetThin3DContext(), gamePath, GAMEINFO_WANTBG);
dc.Flush();
if (ginfo) {
bool hasPic = false;
double loadTime;
if (ginfo->pic1Texture) {
ginfo->pic1Texture->Bind(0);
dc.GetThin3DContext()->SetTexture(0, ginfo->pic1Texture);
loadTime = ginfo->timePic1WasLoaded;
hasPic = true;
} else if (ginfo->pic0Texture) {
ginfo->pic0Texture->Bind(0);
dc.GetThin3DContext()->SetTexture(0, ginfo->pic0Texture);
loadTime = ginfo->timePic0WasLoaded;
hasPic = true;
}
@ -396,7 +392,6 @@ bool LogoScreen::key(const KeyInput &key) {
void LogoScreen::render() {
UIScreen::render();
UIContext &dc = *screenManager()->getUIContext();
const Bounds &bounds = dc.GetBounds();
@ -435,6 +430,8 @@ void LogoScreen::render() {
ui_draw2d.DrawTextShadow(UBUNTU24, boot_filename.c_str(), bounds.centerX(), bounds.centerY() + 180, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER);
}
dc.DrawText(screenManager()->getThin3DContext()->GetInfoString(T3DInfo::APINAME), bounds.centerX(), bounds.y2() - 100, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER);
dc.End();
dc.Flush();
}

View file

@ -38,6 +38,7 @@
#include "ext/jpge/jpge.h"
#include "Windows/DSoundStream.h"
#include "Windows/WndMainWindow.h"
#include "Windows/D3D9Base.h"
#endif
#include "base/display.h"
@ -48,7 +49,7 @@
#include "file/zip_read.h"
#include "thread/thread.h"
#include "net/http_client.h"
#include "gfx_es2/gl_state.h"
#include "gfx_es2/gl_state.h" // only for screenshot!
#include "gfx_es2/draw_text.h"
#include "gfx_es2/draw_buffer.h"
#include "gfx/gl_lost_manager.h"
@ -58,6 +59,7 @@
#include "math/fast/fast_math.h"
#include "math/math_util.h"
#include "math/lin/matrix4x4.h"
#include "thin3d/thin3d.h"
#include "ui/ui.h"
#include "ui/screen.h"
#include "ui/ui_context.h"
@ -80,9 +82,10 @@
#include "ui_atlas.h"
#include "EmuScreen.h"
#include "GameInfoCache.h"
#include "UIShader.h"
#include "HostTypes.h"
#ifdef _WIN32
#include "GPU/Directx9/helper/dx_state.h"
#endif
#include "UI/OnScreenDisplay.h"
#include "UI/MiscScreens.h"
#include "UI/TiltEventProcessor.h"
@ -112,7 +115,7 @@ static UI::Theme ui_theme;
#include "android/android-ndk-profiler/prof.h"
#endif
Texture *uiTexture;
Thin3DTexture *uiTexture;
ScreenManager *screenManager;
std::string config_filename;
@ -132,6 +135,7 @@ struct PendingMessage {
static recursive_mutex pendingMutex;
static std::vector<PendingMessage> pendingMessages;
static Thin3DContext *thin3d;
static UIContext *uiContext;
std::thread *graphicsLoadThread;
@ -463,12 +467,23 @@ void NativeInit(int argc, const char *argv[],
void NativeInitGraphics() {
FPU_SetFastMode();
CheckGLExtensions();
#ifndef _WIN32
// Force backend to GL
g_Config.iGPUBackend = GPU_BACKEND_OPENGL;
#endif
if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) {
thin3d = T3DCreateGLContext();
CheckGLExtensions();
} else {
#ifdef _WIN32
thin3d = D3D9_CreateThin3DContext();
#endif
}
ui_draw2d.SetAtlas(&ui_atlas);
ui_draw2d_front.SetAtlas(&ui_atlas);
UIShader_Init();
// memset(&ui_theme, 0, sizeof(ui_theme));
// New style theme
#ifdef _WIN32
@ -487,18 +502,6 @@ void NativeInitGraphics() {
ui_theme.sliderKnob = I_CIRCLE;
ui_theme.dropShadow4Grid = I_DROP_SHADOW;
/*
ui_theme.buttonStyle.background = UI::Drawable(UI::DRAW_4GRID, I_BUTTON);
ui_theme.buttonStyle.fgColor = 0xFFFFFFFF;
ui_theme.buttonStyle.image = I_BUTTON;
ui_theme.buttonFocusedStyle.background = UI::Drawable(UI::DRAW_4GRID, I_BUTTON, 0xFFe0e0e0);
ui_theme.buttonFocusedStyle.fgColor = 0xFFFFFFFF;
ui_theme.buttonDownStyle.background = UI::Drawable(UI::DRAW_4GRID, I_BUTTON_SELECTED, 0xFFFFFFFF);
ui_theme.buttonDownStyle.fgColor = 0xFFFFFFFF;
ui_theme.buttonDisabledStyle.background = UI::Drawable(UI::DRAW_4GRID, I_BUTTON, 0xFF404040);
ui_theme.buttonDisabledStyle.fgColor = 0xFF707070;
*/
ui_theme.itemStyle.background = UI::Drawable(0x55000000);
ui_theme.itemStyle.fgColor = 0xFFFFFFFF;
ui_theme.itemFocusedStyle.background = UI::Drawable(0xFFedc24c);
@ -526,27 +529,29 @@ void NativeInitGraphics() {
ui_theme.popupTitle.fgColor = 0xFF59BEE3;
#endif
ui_draw2d.Init();
ui_draw2d_front.Init();
ui_draw2d.Init(thin3d);
ui_draw2d_front.Init(thin3d);
uiTexture = new Texture();
#ifdef USING_QT_UI
if (!uiTexture->Load("ui_atlas_lowmem.zim")) {
uiTexture = thin3d->CreateTextureFromFile("ui_atlas_lowmem.zim");
if (!uiTexture) {
#else
if (!uiTexture->Load("ui_atlas.zim")) {
uiTexture = thin3d->CreateTextureFromFile("ui_atlas.zim", T3DFileType::ZIM);
if (!uiTexture) {
#endif
PanicAlert("Failed to load ui_atlas.zim.\n\nPlace it in the directory \"assets\" under your PPSSPP directory.");
ELOG("Failed to load ui_atlas.zim");
}
uiTexture->Bind(0);
uiContext = new UIContext();
uiContext->theme = &ui_theme;
uiContext->Init(UIShader_Get(), UIShader_GetPlain(), uiTexture, &ui_draw2d, &ui_draw2d_front);
uiContext->Init(thin3d, thin3d->GetShaderSetPreset(SS_TEXTURE_COLOR_2D), thin3d->GetShaderSetPreset(SS_COLOR_2D), uiTexture, &ui_draw2d, &ui_draw2d_front);
if (uiContext->Text())
uiContext->Text()->SetFont("Tahoma", 20, 0);
screenManager->setUIContext(uiContext);
screenManager->setThin3DContext(thin3d);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
@ -567,8 +572,7 @@ void NativeShutdownGraphics() {
g_gameInfoCache.Clear();
delete uiTexture;
uiTexture = NULL;
uiTexture->Release();
delete uiContext;
uiContext = NULL;
@ -576,11 +580,17 @@ void NativeShutdownGraphics() {
ui_draw2d.Shutdown();
ui_draw2d_front.Shutdown();
UIShader_Shutdown();
thin3d->Release();
}
void TakeScreenshot() {
if (g_Config.iGPUBackend != GPU_BACKEND_OPENGL) {
// Not yet supported
return;
}
g_TakeScreenshot = false;
#if defined(_WIN32) || (defined(USING_QT_UI) && !defined(MOBILE_DEVICE))
mkDir(g_Config.memCardDirectory + "/PSP/SCREENSHOT");
@ -671,25 +681,43 @@ void DrawDownloadsOverlay(UIContext &dc) {
void NativeRender() {
g_GameManager.Update();
glstate.depthWrite.set(GL_TRUE);
glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
T3DViewport viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = pixel_xres;
viewport.Height = pixel_yres;
viewport.MaxDepth = 1.0;
viewport.MinDepth = 0.0;
thin3d->SetViewports(1, &viewport);
// Clearing the screen at the start of the frame is an optimization for tiled mobile GPUs, as it then doesn't need to keep it around between frames.
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) {
glstate.depthWrite.set(GL_TRUE);
glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glstate.Restore();
} else {
#ifdef _WIN32
DX9::dxstate.depthWrite.set(true);
DX9::dxstate.colorMask.set(true, true, true, true);
DX9::dxstate.Restore();
#endif
}
glstate.viewport.set(0, 0, pixel_xres, pixel_yres);
glstate.Restore();
thin3d->Clear(T3DClear::COLOR | T3DClear::DEPTH | T3DClear::STENCIL, 0xFF000000, 0.0f, 0);
thin3d->SetTargetSize(pixel_xres, pixel_yres);
float xres = dp_xres;
float yres = dp_yres;
// Apply the UIContext bounds as a 2D transformation matrix.
Matrix4x4 ortho;
ortho.setOrtho(0.0f, xres, yres, 0.0f, -1.0f, 1.0f);
if (g_Config.iGPUBackend == GPU_BACKEND_DIRECT3D9) {
ortho.setOrthoD3D(0.0f, xres, yres, 0.0f, -1.0f, 1.0f);
} else {
ortho.setOrtho(0.0f, xres, yres, 0.0f, -1.0f, 1.0f);
}
glsl_bind(UIShader_Get());
glUniformMatrix4fv(UIShader_Get()->u_worldviewproj, 1, GL_FALSE, ortho.getReadPtr());
ui_draw2d.SetDrawMatrix(ortho);
ui_draw2d_front.SetDrawMatrix(ortho);
screenManager->render();
if (screenManager->getUIContext()->Text()) {
@ -885,7 +913,6 @@ void NativeResized() {
#if defined(__APPLE__) && !defined(USING_QT_UI)
static int dp_xres_old=dp_xres;
if (dp_xres != dp_xres_old) {
UIShader_Init();
uiTexture->Load("ui_atlas.zim");
dp_xres_old = dp_xres;
}

View file

@ -38,7 +38,6 @@
<ClCompile Include="TouchControlLayoutScreen.cpp" />
<ClCompile Include="TouchControlVisibilityScreen.cpp" />
<ClCompile Include="InstallZipScreen.cpp" />
<ClCompile Include="UIShader.cpp" />
<ClCompile Include="ui_atlas.cpp" />
</ItemGroup>
<ItemGroup>
@ -60,7 +59,6 @@
<ClInclude Include="TouchControlLayoutScreen.h" />
<ClInclude Include="TouchControlVisibilityScreen.h" />
<ClInclude Include="InstallZipScreen.h" />
<ClInclude Include="UIShader.h" />
<ClInclude Include="ui_atlas.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
@ -192,4 +190,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View file

@ -5,7 +5,6 @@
<ClCompile Include="GamepadEmu.cpp" />
<ClCompile Include="NativeApp.cpp" />
<ClCompile Include="ui_atlas.cpp" />
<ClCompile Include="UIShader.cpp" />
<ClCompile Include="OnScreenDisplay.cpp" />
<ClCompile Include="EmuScreen.cpp">
<Filter>Screens</Filter>
@ -53,7 +52,6 @@
<ClInclude Include="GameInfoCache.h" />
<ClInclude Include="GamepadEmu.h" />
<ClInclude Include="ui_atlas.h" />
<ClInclude Include="UIShader.h" />
<ClInclude Include="OnScreenDisplay.h" />
<ClInclude Include="EmuScreen.h">
<Filter>Screens</Filter>

View file

@ -1,113 +0,0 @@
// Copyright (c) 2012- PPSSPP Project.
// 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, version 2.0 or later versions.
// 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 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "gfx_es2/glsl_program.h"
#include "gfx_es2/gl_state.h"
#include "UIShader.h"
static GLSLProgram *glslModulate;
static GLSLProgram *glslPlain;
static const char modulate_fs[] =
"#ifdef GL_ES\n"
"precision lowp float;\n"
"#endif\n"
"uniform sampler2D sampler0;\n"
"varying vec2 v_texcoord0;\n"
"varying vec4 v_color;\n"
"void main() {\n"
" gl_FragColor = texture2D(sampler0, v_texcoord0) * v_color;\n"
"}\n";
static const char modulate_vs[] =
"attribute vec4 a_position;\n"
"attribute vec4 a_color;\n"
"attribute vec2 a_texcoord0;\n"
"uniform mat4 u_worldviewproj;\n"
"varying vec2 v_texcoord0;\n"
"varying vec4 v_color;\n"
"void main() {\n"
" v_texcoord0 = a_texcoord0;\n"
" v_color = a_color;\n"
" gl_Position = u_worldviewproj * a_position;\n"
"}\n";
static const char plain_fs[] =
"#ifdef GL_ES\n"
"precision lowp float;\n"
"#endif\n"
"varying vec4 v_color;\n"
"void main() {\n"
" gl_FragColor = v_color;\n"
"}\n";
static const char plain_vs[] =
"attribute vec4 a_position;\n"
"attribute vec4 a_color;\n"
"uniform mat4 u_worldviewproj;\n"
"varying vec4 v_color;\n"
"void main() {\n"
" v_color = a_color;\n"
" gl_Position = u_worldviewproj * a_position;\n"
"}\n";
void UIShader_Init() {
// Compile UI shaders
glslModulate = glsl_create_source(modulate_vs, modulate_fs);
glslPlain = glsl_create_source(plain_vs, plain_fs);
}
GLSLProgram *UIShader_Get()
{
return glslModulate;
}
GLSLProgram *UIShader_GetPlain()
{
return glslPlain;
}
void UIShader_Shutdown()
{
glsl_destroy(glslModulate);
glsl_destroy(glslPlain);
}
void UIShader_Prepare()
{
// Draw 2D overlay stuff
glstate.cullFace.disable();
glstate.depthTest.disable();
glstate.scissorTest.disable();
glstate.stencilTest.disable();
glstate.stencilMask.set(0xFF);
#if !defined(USING_GLES2)
glstate.colorLogicOp.disable();
#endif
glstate.dither.enable();
glstate.blend.enable();
glstate.blendFuncSeparate.set(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glstate.blendEquationSeparate.set(GL_FUNC_ADD, GL_FUNC_ADD);
glstate.depthWrite.set(GL_TRUE);
glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glstate.Restore();
uiTexture->Bind(0);
}

View file

@ -1,31 +0,0 @@
// Copyright (c) 2012- PPSSPP Project.
// 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, version 2.0 or later versions.
// 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 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#pragma once
#include "gfx_es2/glsl_program.h"
#include "gfx/texture.h"
void UIShader_Init();
GLSLProgram *UIShader_Get();
GLSLProgram *UIShader_GetPlain(); // Just color
void UIShader_Shutdown();
void UIShader_Prepare();
// TODO: Remove
extern Texture *uiTexture;

123
Windows/D3D9Base.cpp Normal file
View file

@ -0,0 +1,123 @@
#include "Common/CommonWindows.h"
#include <d3d9.h>
#include "GPU/Directx9/helper/global.h"
#include "GPU/Directx9/helper/fbo.h"
#include "base/logging.h"
#include "util/text/utf8.h"
#include "i18n/i18n.h"
#include "Core/Config.h"
#include "Windows/D3D9Base.h"
#include "thin3d/thin3d.h"
#include "thin3d/d3dx9_loader.h"
static LPDIRECT3D9 d3d;
static int adapterId;
static LPDIRECT3DDEVICE9 device;
static HDC hDC; // Private GDI Device Context
static HGLRC hRC; // Permanent Rendering Context
static HWND hWnd; // Holds Our Window Handle
static int xres, yres;
// TODO: Make config?
static bool enableGLDebug = true;
void D3D9_SwapBuffers() {
device->EndScene();
device->Present(NULL, NULL, NULL, NULL);
device->BeginScene();
}
Thin3DContext *D3D9_CreateThin3DContext() {
return T3DCreateDX9Context(d3d, adapterId, device);
}
bool D3D9_Init(HWND hWnd, bool windowed, std::string *error_message) {
d3d = Direct3DCreate9(D3D_SDK_VERSION);
if (!d3d) {
ELOG("Failed to create D3D context");
return false;
}
RECT rc;
GetClientRect(hWnd, &rc);
int xres = rc.right - rc.left;
int yres = rc.bottom - rc.top;
D3DCAPS9 d3dCaps;
D3DDISPLAYMODE d3ddm;
if (FAILED(d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) {
d3d->Release();
return false;
}
adapterId = D3DADAPTER_DEFAULT;
if (FAILED(d3d->GetDeviceCaps(adapterId, D3DDEVTYPE_HAL, &d3dCaps))) {
d3d->Release();
return false;
}
HRESULT hr;
if (FAILED(hr = d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
d3ddm.Format,
D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE,
D3DFMT_D24S8))) {
if (hr == D3DERR_NOTAVAILABLE) {
d3d->Release();
return false;
}
}
DWORD dwBehaviorFlags = D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE;
if (d3dCaps.VertexProcessingCaps != 0)
dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
D3DPRESENT_PARAMETERS pp;
memset(&pp, 0, sizeof(pp));
pp.BackBufferWidth = xres;
pp.BackBufferHeight = yres;
pp.BackBufferFormat = d3ddm.Format;
pp.MultiSampleType = D3DMULTISAMPLE_NONE;
pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
pp.Windowed = windowed;
pp.hDeviceWindow = hWnd;
pp.EnableAutoDepthStencil = true;
pp.AutoDepthStencilFormat = D3DFMT_D24S8;
pp.PresentationInterval = (g_Config.bVSync) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
hr = d3d->CreateDevice(adapterId, D3DDEVTYPE_HAL, hWnd, dwBehaviorFlags, &pp, &device);
if (FAILED(hr)) {
ELOG("Failed to create D3D device");
d3d->Release();
return false;
}
device->BeginScene();
DX9::pD3Ddevice = device;
LoadD3DX9Dynamic();
DX9::CompileShaders();
DX9::fbo_init();
return true;
}
void D3D9_Resize(HWND window) {
}
void D3D9_Shutdown() {
device->EndScene();
device->Release();
d3d->Release();
hWnd = NULL;
}

13
Windows/D3D9Base.h Normal file
View file

@ -0,0 +1,13 @@
// Modelled on OpenD3DBase. Might make a cleaner interface later.
#pragma once
#include "Common/CommonWindows.h"
class Thin3DContext;
bool D3D9_Init(HWND window, bool windowed, std::string *error_message);
void D3D9_Shutdown();
void D3D9_Resize(HWND window);
void D3D9_SwapBuffers();
Thin3DContext *D3D9_CreateThin3DContext();

View file

@ -106,7 +106,7 @@ unsigned int WINAPI TheThread(void *)
std::string error_string;
if (!host->InitGL(&error_string)) {
Reporting::ReportMessage("OpenGL init error: %s", error_string.c_str());
Reporting::ReportMessage("Graphics init error: %s", error_string.c_str());
std::string full_error = StringFromFormat( "Failed initializing OpenGL. Try upgrading your graphics drivers.\n\nError message:\n\n%s", error_string.c_str());
MessageBox(0, ConvertUTF8ToWString(full_error).c_str(), L"OpenGL Error", MB_OK | MB_ICONERROR);
ERROR_LOG(BOOT, full_error.c_str());

View file

@ -1,10 +1,6 @@
// NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003.
#include "util/text/utf8.h"
#include "Common/CommonWindows.h"
#include "native/gfx_es2/gl_state.h"
#include "native/gfx/gl_common.h"
#include "util/text/utf8.h"
#include "GL/gl.h"
#include "GL/wglew.h"
#include "util/text/utf8.h"
@ -71,6 +67,7 @@ void DebugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity,
FILE *outFile = (FILE*)userParam;
char finalMessage[256];
FormatDebugOutputARB(finalMessage, 256, source, type, id, severity, message);
OutputDebugStringA(finalMessage);
ERROR_LOG(G3D, "GL: %s", finalMessage);
}

View file

@ -1,5 +1,3 @@
// NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003.
#pragma once
#include "Common/CommonWindows.h"

View file

@ -277,6 +277,7 @@
</ForcedIncludeFiles>
</ClCompile>
<ClCompile Include="ControlMapping.cpp" />
<ClCompile Include="D3D9Base.cpp" />
<ClCompile Include="Debugger\BreakpointWindow.cpp" />
<ClCompile Include="Debugger\CtrlDisAsmView.cpp" />
<ClCompile Include="Debugger\CtrlMemView.cpp" />
@ -330,6 +331,7 @@
<ClInclude Include="..\android\jni\TestRunner.h" />
<ClInclude Include="..\ios\ViewController.h" />
<ClInclude Include="ControlMapping.h" />
<ClInclude Include="D3D9Base.h" />
<ClInclude Include="Debugger\BreakpointWindow.h" />
<ClInclude Include="Debugger\CtrlDisAsmView.h" />
<ClInclude Include="Debugger\CtrlMemView.h" />

View file

@ -67,6 +67,9 @@
<ClCompile Include="DSoundStream.cpp">
<Filter>Windows\System</Filter>
</ClCompile>
<ClCompile Include="D3D9Base.cpp">
<Filter>Windows\System</Filter>
</ClCompile>
<ClCompile Include="OpenGLBase.cpp">
<Filter>Windows\System</Filter>
</ClCompile>
@ -187,6 +190,9 @@
<ClInclude Include="DSoundStream.h">
<Filter>Windows\System</Filter>
</ClInclude>
<ClInclude Include="D3D9Base.h">
<Filter>Windows\System</Filter>
</ClInclude>
<ClInclude Include="OpenGLBase.h">
<Filter>Windows\System</Filter>
</ClInclude>
@ -326,4 +332,4 @@
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
</Project>

View file

@ -42,6 +42,7 @@
#include "WindowsHost.h"
#include "WndMainWindow.h"
#include "OpenGLBase.h"
#include "D3D9Base.h"
#include "Windows/Debugger/DebuggerShared.h"
#include "Windows/Debugger/Debugger_Disasm.h"
@ -88,14 +89,26 @@ WindowsHost::WindowsHost(HWND mainWindow, HWND displayWindow)
SetConsolePosition();
}
bool WindowsHost::InitGL(std::string *error_message)
{
return GL_Init(displayWindow_, error_message);
bool WindowsHost::InitGL(std::string *error_message) {
switch (g_Config.iGPUBackend) {
case GPU_BACKEND_OPENGL:
return GL_Init(displayWindow_, error_message);
case GPU_BACKEND_DIRECT3D9:
return D3D9_Init(displayWindow_, true, error_message);
default:
return false;
}
}
void WindowsHost::ShutdownGL()
{
GL_Shutdown();
void WindowsHost::ShutdownGL() {
switch (g_Config.iGPUBackend) {
case GPU_BACKEND_OPENGL:
GL_Shutdown();
break;
case GPU_BACKEND_DIRECT3D9:
D3D9_Shutdown();
break;
}
PostMessage(mainWindow_, WM_CLOSE, 0, 0);
}

View file

@ -286,7 +286,6 @@ LOCAL_SRC_FILES := \
$(SRC)/UI/MainScreen.cpp \
$(SRC)/UI/MiscScreens.cpp \
$(SRC)/UI/Store.cpp \
$(SRC)/UI/UIShader.cpp \
$(SRC)/UI/GamepadEmu.cpp \
$(SRC)/UI/GameInfoCache.cpp \
$(SRC)/UI/GameScreen.cpp \

View file

@ -66,7 +66,8 @@ public:
};
struct InputState;
// Temporary hack around annoying linking error.
// Temporary hacks around annoying linking errors.
void D3D9_SwapBuffers() { }
void GL_SwapBuffers() { }
void NativeUpdate(InputState &input_state) { }
void NativeRender() { }

2
native

@ -1 +1 @@
Subproject commit 2ba8e36b2bde65021c9a5c0f937a0e3892c2ad62
Subproject commit 467599cf5655625aa7fe8c9c409624a131cdd6bd