CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/libretro/LibretroGraphicsContext.cpp
Views: 1401
1
2
#include "libretro/LibretroGraphicsContext.h"
3
#include "libretro/LibretroGLContext.h"
4
#include "libretro/LibretroGLCoreContext.h"
5
#include "libretro/LibretroVulkanContext.h"
6
#ifdef _WIN32
7
#include "libretro/LibretroD3D11Context.h"
8
#endif
9
10
#include "Common/Log.h"
11
#include "Core/Config.h"
12
#include "Core/System.h"
13
#include "GPU/GPUInterface.h"
14
15
retro_video_refresh_t LibretroGraphicsContext::video_cb;
16
17
extern "C" {
18
retro_hw_get_proc_address_t libretro_get_proc_address;
19
};
20
21
void retro_set_video_refresh(retro_video_refresh_t cb) { LibretroGraphicsContext::video_cb = cb; }
22
static void context_reset() { ((LibretroHWRenderContext *)Libretro::ctx)->ContextReset(); }
23
static void context_destroy() { ((LibretroHWRenderContext *)Libretro::ctx)->ContextDestroy(); }
24
25
bool LibretroHWRenderContext::Init(bool cache_context) {
26
hw_render_.cache_context = cache_context;
27
if (!Libretro::environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER, &hw_render_))
28
return false;
29
libretro_get_proc_address = hw_render_.get_proc_address;
30
return true;
31
}
32
33
LibretroHWRenderContext::LibretroHWRenderContext(retro_hw_context_type context_type, unsigned version_major, unsigned version_minor) {
34
hw_render_.context_type = context_type;
35
hw_render_.version_major = version_major;
36
hw_render_.version_minor = version_minor;
37
hw_render_.context_reset = context_reset;
38
hw_render_.context_destroy = context_destroy;
39
hw_render_.depth = true;
40
}
41
42
void LibretroHWRenderContext::ContextReset() {
43
INFO_LOG(Log::G3D, "Context reset");
44
45
if (gpu && Libretro::useEmuThread) {
46
Libretro::EmuThreadPause();
47
}
48
49
if (gpu) {
50
gpu->DeviceLost();
51
}
52
53
if (!draw_) {
54
CreateDrawContext();
55
bool success = draw_->CreatePresets();
56
_assert_(success);
57
}
58
59
GotBackbuffer();
60
61
if (gpu) {
62
gpu->DeviceRestore(draw_);
63
}
64
65
if (gpu && Libretro::useEmuThread) {
66
Libretro::EmuThreadStart();
67
}
68
}
69
70
void LibretroHWRenderContext::ContextDestroy() {
71
INFO_LOG(Log::G3D, "Context destroy");
72
73
if (Libretro::useEmuThread) {
74
Libretro::EmuThreadStop();
75
}
76
77
if (gpu) {
78
gpu->DeviceLost();
79
}
80
81
if (!hw_render_.cache_context && Libretro::useEmuThread && draw_ && Libretro::emuThreadState != Libretro::EmuThreadState::PAUSED) {
82
DestroyDrawContext();
83
}
84
85
if (!hw_render_.cache_context && !Libretro::useEmuThread) {
86
Shutdown();
87
}
88
}
89
90
void LibretroGraphicsContext::GotBackbuffer() { draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); }
91
92
void LibretroGraphicsContext::LostBackbuffer() { draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, -1, -1); }
93
94
LibretroGraphicsContext *LibretroGraphicsContext::CreateGraphicsContext() {
95
LibretroGraphicsContext *ctx;
96
97
retro_hw_context_type preferred;
98
if (!Libretro::environ_cb(RETRO_ENVIRONMENT_GET_PREFERRED_HW_RENDER, &preferred))
99
preferred = RETRO_HW_CONTEXT_DUMMY;
100
101
if (Libretro::backend != RETRO_HW_CONTEXT_DUMMY)
102
preferred = Libretro::backend;
103
104
#ifndef USING_GLES2
105
if (preferred == RETRO_HW_CONTEXT_DUMMY || preferred == RETRO_HW_CONTEXT_OPENGL_CORE) {
106
ctx = new LibretroGLCoreContext();
107
108
if (ctx->Init()) {
109
return ctx;
110
}
111
delete ctx;
112
}
113
#endif
114
115
if (preferred == RETRO_HW_CONTEXT_DUMMY || preferred == RETRO_HW_CONTEXT_OPENGL || preferred == RETRO_HW_CONTEXT_OPENGLES3) {
116
ctx = new LibretroGLContext();
117
118
if (ctx->Init()) {
119
return ctx;
120
}
121
delete ctx;
122
}
123
124
#ifndef HAVE_LIBNX
125
if (preferred == RETRO_HW_CONTEXT_DUMMY || preferred == RETRO_HW_CONTEXT_VULKAN) {
126
ctx = new LibretroVulkanContext();
127
128
if (ctx->Init()) {
129
return ctx;
130
}
131
delete ctx;
132
}
133
#endif
134
135
#ifdef _WIN32
136
if (preferred == RETRO_HW_CONTEXT_DUMMY || preferred == RETRO_HW_CONTEXT_DIRECT3D) {
137
ctx = new LibretroD3D11Context();
138
139
if (ctx->Init()) {
140
return ctx;
141
}
142
delete ctx;
143
144
ctx = new LibretroD3D9Context();
145
if (ctx->Init()) {
146
return ctx;
147
}
148
delete ctx;
149
}
150
#endif
151
152
ctx = new LibretroSoftwareContext();
153
ctx->Init();
154
return ctx;
155
}
156
157
std::vector<u32> TranslateDebugBufferToCompare(const GPUDebugBuffer *buffer, u32 stride, u32 h) {
158
// If the output was small, act like everything outside was 0.
159
// This can happen depending on viewport parameters.
160
u32 safeW = std::min(stride, buffer->GetStride());
161
u32 safeH = std::min(h, buffer->GetHeight());
162
163
std::vector<u32> data;
164
data.resize(stride * h, 0);
165
166
const u32 *pixels32 = (const u32 *)buffer->GetData();
167
const u16 *pixels16 = (const u16 *)buffer->GetData();
168
int outStride = buffer->GetStride();
169
#if 0
170
if (!buffer->GetFlipped()) {
171
// Bitmaps are flipped, so we have to compare backwards in this case.
172
int toLastRow = outStride * (h > buffer->GetHeight() ? buffer->GetHeight() - 1 : h - 1);
173
pixels32 += toLastRow;
174
pixels16 += toLastRow;
175
outStride = -outStride;
176
}
177
#endif
178
// Skip the bottom of the image in the buffer was smaller. Remember, we're flipped.
179
u32 *dst = &data[0];
180
if (safeH < h) {
181
dst += (h - safeH) * stride;
182
}
183
184
for (u32 y = 0; y < safeH; ++y) {
185
switch (buffer->GetFormat()) {
186
case GPU_DBG_FORMAT_8888:
187
ConvertBGRA8888ToRGBA8888(&dst[y * stride], pixels32, safeW);
188
break;
189
case GPU_DBG_FORMAT_8888_BGRA:
190
memcpy(&dst[y * stride], pixels32, safeW * sizeof(u32));
191
break;
192
193
case GPU_DBG_FORMAT_565:
194
ConvertRGB565ToBGRA8888(&dst[y * stride], pixels16, safeW);
195
break;
196
case GPU_DBG_FORMAT_5551:
197
ConvertRGBA5551ToBGRA8888(&dst[y * stride], pixels16, safeW);
198
break;
199
case GPU_DBG_FORMAT_4444:
200
ConvertRGBA4444ToBGRA8888(&dst[y * stride], pixels16, safeW);
201
break;
202
203
default:
204
data.resize(0);
205
return data;
206
}
207
208
pixels32 += outStride;
209
pixels16 += outStride;
210
}
211
212
return data;
213
}
214
215