Allow D3D9 context creation to bail if shader compilation fails (D3D9 runtime not installed).
Fixes an issue where after switching to D3D9 on a PC without the D3D9 runtime, it's impossible to start PPSSPP anymore.
This commit is contained in:
parent
a6cf2e6ca0
commit
017d3da067
16 changed files with 45 additions and 18 deletions
|
@ -1,6 +1,7 @@
|
|||
#include "pch.h"
|
||||
#include "PPSSPP_UWPMain.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <mutex>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
@ -323,6 +324,7 @@ void PPSSPP_UWPMain::LoadStorageFile(StorageFile ^file) {
|
|||
UWPGraphicsContext::UWPGraphicsContext(std::shared_ptr<DX::DeviceResources> resources) {
|
||||
draw_ = Draw::T3DCreateD3D11Context(
|
||||
resources->GetD3DDevice(), resources->GetD3DDeviceContext(), resources->GetD3DDevice(), resources->GetD3DDeviceContext(), resources->GetDeviceFeatureLevel(), 0);
|
||||
assert(draw_->CreatePresets());
|
||||
}
|
||||
|
||||
void UWPGraphicsContext::Shutdown() {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Common/CommonWindows.h"
|
||||
#include <d3d11.h>
|
||||
#include <cassert>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "util/text/utf8.h"
|
||||
|
@ -139,6 +140,7 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
|||
#endif
|
||||
|
||||
draw_ = Draw::T3DCreateD3D11Context(device_, context_, device1_, context1_, featureLevel_, hWnd_);
|
||||
assert(draw_->CreatePresets()); // If we can run D3D11, there's a compiler installed. I think.
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
|
|
@ -165,6 +165,13 @@ bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
|||
//deviceEx->SetMaximumFrameLatency(1);
|
||||
}
|
||||
draw_ = Draw::T3DCreateDX9Context(d3d_, d3dEx_, adapterId_, device_, deviceEx_);
|
||||
if (!draw_->CreatePresets()) {
|
||||
// Shader compiler not installed? Return an error so we can fall back to GL.
|
||||
device_->Release();
|
||||
d3d_->Release();
|
||||
*error_message = "DirectX9 runtime not correctly installed. Please install.";
|
||||
return false;
|
||||
}
|
||||
if (draw_)
|
||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, 0, 0, nullptr);
|
||||
return true;
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
// TODO: What a mess this is :(
|
||||
|
||||
#include <cassert>
|
||||
#include "Common/Log.h"
|
||||
#include "Common/CommonWindows.h"
|
||||
#include "gfx/gl_common.h"
|
||||
|
@ -358,6 +357,7 @@ bool WindowsGLContext::Init(HINSTANCE hInst, HWND window, std::string *error_mes
|
|||
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
assert(draw_->CreatePresets()); // if we get this far, there will always be a GLSL compiler capable of compiling these.
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
return true; // Success
|
||||
}
|
||||
|
|
|
@ -203,7 +203,7 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m
|
|||
}
|
||||
|
||||
draw_ = Draw::T3DCreateVulkanContext(g_Vulkan);
|
||||
|
||||
assert(draw_->CreatePresets()); // Doesn't fail, we include the compiler.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -133,6 +133,7 @@ bool AndroidEGLGraphicsContext::Init(ANativeWindow *wnd, int backbufferWidth, in
|
|||
gl->MakeCurrent();
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
assert(draw_->CreatePresets()); // There will always be a GLSL compiler capable of compiling these.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -157,6 +158,7 @@ public:
|
|||
AndroidJavaEGLGraphicsContext() {
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
assert(draw_->CreatePresets());
|
||||
}
|
||||
~AndroidJavaEGLGraphicsContext() {
|
||||
delete draw_;
|
||||
|
@ -310,6 +312,7 @@ bool AndroidVulkanContext::Init(ANativeWindow *wnd, int desiredBackbufferSizeX,
|
|||
}
|
||||
g_Vulkan->InitObjects(true);
|
||||
draw_ = Draw::T3DCreateVulkanContext(g_Vulkan);
|
||||
assert(draw_->CreatePresets()); // Doesn't fail, we ship the compiler.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ SDLJoystick *joystick = NULL;
|
|||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
#include "base/display.h"
|
||||
#include "base/logging.h"
|
||||
|
@ -51,6 +52,7 @@ public:
|
|||
GLDummyGraphicsContext() {
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
assert(draw_->CreatePresets());
|
||||
}
|
||||
~GLDummyGraphicsContext() { delete draw_; }
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ QTM_USE_NAMESPACE
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "base/display.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/timeutil.h"
|
||||
|
@ -42,6 +44,7 @@ class QtDummyGraphicsContext : public DummyGraphicsContext {
|
|||
public:
|
||||
QtDummyGraphicsContext() {
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
assert(draw_->CreatePresets());
|
||||
}
|
||||
~QtDummyGraphicsContext() {
|
||||
delete draw_;
|
||||
|
|
|
@ -299,12 +299,14 @@ static ShaderModule *CreateShader(DrawContext *draw, ShaderStage stage, const st
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void DrawContext::CreatePresets() {
|
||||
bool DrawContext::CreatePresets() {
|
||||
vsPresets_[VS_TEXTURE_COLOR_2D] = CreateShader(this, ShaderStage::VERTEX, vsTexCol);
|
||||
vsPresets_[VS_COLOR_2D] = CreateShader(this, ShaderStage::VERTEX, vsCol);
|
||||
|
||||
fsPresets_[FS_TEXTURE_COLOR_2D] = CreateShader(this, ShaderStage::FRAGMENT, fsTexCol);
|
||||
fsPresets_[FS_COLOR_2D] = CreateShader(this, ShaderStage::FRAGMENT, fsCol);
|
||||
|
||||
return vsPresets_[VS_TEXTURE_COLOR_2D] && vsPresets_[VS_COLOR_2D] && fsPresets_[FS_TEXTURE_COLOR_2D] && fsPresets_[FS_COLOR_2D];
|
||||
}
|
||||
|
||||
DrawContext::~DrawContext() {
|
||||
|
|
|
@ -583,6 +583,7 @@ struct RenderPassInfo {
|
|||
class DrawContext {
|
||||
public:
|
||||
virtual ~DrawContext();
|
||||
bool CreatePresets();
|
||||
|
||||
virtual const DeviceCaps &GetDeviceCaps() const = 0;
|
||||
virtual uint32_t GetDataFormatSupport(DataFormat fmt) const = 0;
|
||||
|
@ -691,8 +692,6 @@ public:
|
|||
virtual void FlushState() {}
|
||||
|
||||
protected:
|
||||
void CreatePresets();
|
||||
|
||||
ShaderModule *vsPresets_[VS_MAX_PRESET];
|
||||
ShaderModule *fsPresets_[FS_MAX_PRESET];
|
||||
|
||||
|
|
|
@ -242,7 +242,6 @@ D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *de
|
|||
}
|
||||
dxgiDevice->Release();
|
||||
}
|
||||
CreatePresets();
|
||||
|
||||
// Temp texture for read-back of small images. Custom textures are created on demand for larger ones.
|
||||
// TODO: Should really benchmark if this extra complexity has any benefit.
|
||||
|
|
|
@ -585,7 +585,6 @@ private:
|
|||
|
||||
D3D9Context::D3D9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx)
|
||||
: d3d_(d3d), d3dEx_(d3dEx), adapterId_(adapterId), device_(device), deviceEx_(deviceEx), caps_{} {
|
||||
CreatePresets();
|
||||
if (FAILED(d3d->GetAdapterIdentifier(adapterId, 0, &identifier_))) {
|
||||
ELOG("Failed to get adapter identifier: %d", adapterId);
|
||||
}
|
||||
|
@ -633,6 +632,10 @@ Pipeline *D3D9Context::CreateGraphicsPipeline(const PipelineDesc &desc) {
|
|||
}
|
||||
D3D9Pipeline *pipeline = new D3D9Pipeline(device_);
|
||||
for (auto iter : desc.shaders) {
|
||||
if (!iter) {
|
||||
ELOG("NULL shader passed to CreateGraphicsPipeline");
|
||||
return false;
|
||||
}
|
||||
if (iter->GetStage() == ShaderStage::FRAGMENT) {
|
||||
pipeline->pshader = static_cast<D3D9ShaderModule *>(iter);
|
||||
}
|
||||
|
@ -947,20 +950,24 @@ void D3D9Context::SetBlendFactor(float color[4]) {
|
|||
}
|
||||
|
||||
bool D3D9ShaderModule::Compile(LPDIRECT3DDEVICE9 device, const uint8_t *data, size_t size) {
|
||||
LPD3DXMACRO defines = NULL;
|
||||
LPD3DXINCLUDE includes = NULL;
|
||||
LPD3DXMACRO defines = nullptr;
|
||||
LPD3DXINCLUDE includes = nullptr;
|
||||
DWORD flags = 0;
|
||||
LPD3DXBUFFER codeBuffer;
|
||||
LPD3DXBUFFER errorBuffer;
|
||||
LPD3DXBUFFER codeBuffer = nullptr;
|
||||
LPD3DXBUFFER errorBuffer = nullptr;
|
||||
const char *source = (const char *)data;
|
||||
const char *profile = stage_ == ShaderStage::FRAGMENT ? "ps_2_0" : "vs_2_0";
|
||||
HRESULT hr = dyn_D3DXCompileShader(source, (UINT)strlen(source), defines, includes, "main", profile, flags, &codeBuffer, &errorBuffer, nullptr);
|
||||
if (FAILED(hr)) {
|
||||
const char *error = (const char *)errorBuffer->GetBufferPointer();
|
||||
const char *error = errorBuffer ? (const char *)errorBuffer->GetBufferPointer() : "(no errorbuffer returned)";
|
||||
if (hr == ERROR_MOD_NOT_FOUND) {
|
||||
// No D3D9-compatible shader compiler installed.
|
||||
error = "D3D9 shader compiler not installed";
|
||||
}
|
||||
OutputDebugStringA(source);
|
||||
OutputDebugStringA(error);
|
||||
errorBuffer->Release();
|
||||
|
||||
if (errorBuffer)
|
||||
errorBuffer->Release();
|
||||
if (codeBuffer)
|
||||
codeBuffer->Release();
|
||||
return false;
|
||||
|
|
|
@ -591,8 +591,6 @@ private:
|
|||
};
|
||||
|
||||
OpenGLContext::OpenGLContext() {
|
||||
CreatePresets();
|
||||
|
||||
// TODO: Detect more caps
|
||||
if (gl_extensions.IsGLES) {
|
||||
if (gl_extensions.OES_packed_depth_stencil || gl_extensions.OES_depth24) {
|
||||
|
|
|
@ -719,7 +719,6 @@ VKContext::VKContext(VulkanContext *vulkan)
|
|||
viewport_.minDepth = 0.0f;
|
||||
viewport_.maxDepth = 0.0f;
|
||||
memset(boundTextures_, 0, sizeof(boundTextures_));
|
||||
CreatePresets();
|
||||
|
||||
VkDescriptorPoolSize dpTypes[2];
|
||||
dpTypes[0].descriptorCount = 200;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <SDL.h>
|
||||
#include <cassert>
|
||||
#include "gfx/gl_lost_manager.h"
|
||||
|
||||
#include "headless/SDLHeadlessHost.h"
|
||||
|
@ -54,6 +55,7 @@ public:
|
|||
GLDummyGraphicsContext() {
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
assert(draw_->CreatePresets());
|
||||
}
|
||||
~GLDummyGraphicsContext() { delete draw_; }
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#import "ViewController.h"
|
||||
#import "AudioEngine.h"
|
||||
#import <GLKit/GLKit.h>
|
||||
#include <cassert>
|
||||
|
||||
#include "base/display.h"
|
||||
#include "base/timeutil.h"
|
||||
|
@ -38,6 +39,7 @@ public:
|
|||
IOSDummyGraphicsContext() {
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
assert(draw_->CreatePresets());
|
||||
}
|
||||
~IOSDummyGraphicsContext() {
|
||||
delete draw_;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue