Merge branch 'master' into TemporaryHackishBranch

# Conflicts:
#	Windows/resource.h
This commit is contained in:
LunaMoo committed 2017-12-24 02:49:12 +01:00
commit 2d0de56573
19 files changed
+355 -203

No files matched your search

+2 -2
View File
@@ -84,7 +84,7 @@ if(NOT ANDROID)
endif()
endif()
if(NOT WIN32 AND VULKAN)
if(VULKAN AND NOT WIN32 AND NOT ANDROID)
IF (NOT Vulkan_FOUND)
find_library(Vulkan_LIBRARY NAMES vulkan HINTS "$ENV{VULKAN_SDK}/lib" "${CMAKE_SOURCE_DIR}/ext/vulkan" REQUIRED)
IF (Vulkan_LIBRARY)
@@ -1676,7 +1676,7 @@ set(GlslangLibs glslang OGLCompiler OSDependent SPIRV SPVRemapper spirv-cross-gl
target_link_libraries(${CoreLibName} Common native kirk cityhash sfmt19937 xbrz xxhash ${GlslangLibs}
${CoreExtraLibs} ${OPENGL_LIBRARIES} ${X11_LIBRARIES} ${CMAKE_DL_LIBS})
if(VULKAN)
if(VULKAN AND NOT ANDROID AND NOT WIN32)
target_link_libraries(${CoreLibName} ${Vulkan_LIBRARY})
endif()
+1 -1
View File
@@ -174,7 +174,7 @@ void AVIDump::AddFrame()
u32 h = buf.GetHeight();
CheckResolution(w, h);
u8 *flipbuffer = nullptr;
const u8 *buffer = ConvertBufferTo888RGB(buf, flipbuffer, w, h);
const u8 *buffer = ConvertBufferToScreenshot(buf, false, flipbuffer, w, h);
#ifdef USE_FFMPEG
+62 -22
View File
@@ -125,12 +125,14 @@ static bool WriteScreenshotToPNG(png_imagep image, const char *filename, int con
}
#endif
static bool ConvertPixelTo888RGB(GPUDebugBufferFormat fmt, u8 &r, u8 &g, u8 &b, const void *buffer, int offset, bool rev) {
static bool ConvertPixelTo8888RGBA(GPUDebugBufferFormat fmt, u8 &r, u8 &g, u8 &b, u8 &a, const void *buffer, int offset, bool rev) {
const u8 *buf8 = (const u8 *)buffer;
const u16 *buf16 = (const u16 *)buffer;
const u32 *buf32 = (const u32 *)buffer;
const float *fbuf = (const float *)buffer;
// NOTE: a and r might be the same channel. This is used for RGB.
u32 src;
double fsrc;
switch (fmt) {
@@ -139,6 +141,7 @@ static bool ConvertPixelTo888RGB(GPUDebugBufferFormat fmt, u8 &r, u8 &g, u8 &b,
if (rev) {
src = bswap16(src);
}
a = 255;
r = Convert5To8((src >> 0) & 0x1F);
g = Convert6To8((src >> 5) & 0x3F);
b = Convert5To8((src >> 11) & 0x1F);
@@ -148,6 +151,7 @@ static bool ConvertPixelTo888RGB(GPUDebugBufferFormat fmt, u8 &r, u8 &g, u8 &b,
if (rev) {
src = bswap16(src);
}
a = (src >> 15) ? 255 : 0;
r = Convert5To8((src >> 0) & 0x1F);
g = Convert5To8((src >> 5) & 0x1F);
b = Convert5To8((src >> 10) & 0x1F);
@@ -157,6 +161,7 @@ static bool ConvertPixelTo888RGB(GPUDebugBufferFormat fmt, u8 &r, u8 &g, u8 &b,
if (rev) {
src = bswap16(src);
}
a = Convert4To8((src >> 12) & 0xF);
r = Convert4To8((src >> 0) & 0xF);
g = Convert4To8((src >> 4) & 0xF);
b = Convert4To8((src >> 8) & 0xF);
@@ -166,54 +171,62 @@ static bool ConvertPixelTo888RGB(GPUDebugBufferFormat fmt, u8 &r, u8 &g, u8 &b,
if (rev) {
src = bswap32(src);
}
a = (src >> 24) & 0xFF;
r = (src >> 0) & 0xFF;
g = (src >> 8) & 0xFF;
b = (src >> 16) & 0xFF;
break;
case GPU_DBG_FORMAT_FLOAT:
fsrc = fbuf[offset];
r = fsrc >= 1.0 ? 255 : (fsrc < 0.0 ? 0 : (int)(fsrc * 255.0));
r = 255;
g = 0;
b = 0;
a = fsrc >= 1.0 ? 255 : (fsrc < 0.0 ? 0 : (int)(fsrc * 255.0));
break;
case GPU_DBG_FORMAT_16BIT:
src = buf16[offset];
r = src >> 8;
r = 255;
g = 0;
b = 0;
a = src >> 8;
break;
case GPU_DBG_FORMAT_8BIT:
src = buf8[offset];
r = src;
r = 255;
g = 0;
b = 0;
a = src;
break;
case GPU_DBG_FORMAT_24BIT_8X:
src = buf32[offset];
r = (src >> 16) & 0xFF;
r = 255;
g = 0;
b = 0;
a = (src >> 16) & 0xFF;
break;
case GPU_DBG_FORMAT_24X_8BIT:
src = buf32[offset];
r = (src >> 24) & 0xFF;
r = 255;
g = 0;
b = 0;
a = (src >> 24) & 0xFF;
break;
case GPU_DBG_FORMAT_24BIT_8X_DIV_256:
src = buf32[offset]& 0x00FFFFFF;
src = src - 0x800000 + 0x8000;
r = (src >> 8) & 0xFF;
r = 255;
g = 0;
b = 0;
a = (src >> 8) & 0xFF;
break;
case GPU_DBG_FORMAT_FLOAT_DIV_256:
fsrc = fbuf[offset];
src = (int)(fsrc * 16777215.0);
src = src - 0x800000 + 0x8000;
r = (src >> 8) & 0xFF;
r = 255;
g = 0;
b = 0;
a = (src >> 8) & 0xFF;
break;
default:
_assert_msg_(SYSTEM, false, "Unsupported framebuffer format for screenshot: %d", fmt);
@@ -223,24 +236,27 @@ static bool ConvertPixelTo888RGB(GPUDebugBufferFormat fmt, u8 &r, u8 &g, u8 &b,
return true;
}
const u8 *ConvertBufferTo888RGB(const GPUDebugBuffer &buf, u8 *&temp, u32 &w, u32 &h) {
const u8 *ConvertBufferToScreenshot(const GPUDebugBuffer &buf, bool alpha, u8 *&temp, u32 &w, u32 &h) {
int pixelSize = alpha ? 4 : 3;
GPUDebugBufferFormat nativeFmt = alpha ? GPU_DBG_FORMAT_8888 : GPU_DBG_FORMAT_888_RGB;
w = std::min(w, buf.GetStride());
h = std::min(h, buf.GetHeight());
// The temp buffer will be freed by the caller if set, and can be the return value.
if (buf.GetFlipped() || buf.GetFormat() != GPU_DBG_FORMAT_888_RGB) {
temp = new u8[3 * w * h];
if (buf.GetFlipped() || buf.GetFormat() != nativeFmt) {
temp = new u8[pixelSize * w * h];
} else {
temp = nullptr;
}
const u8 *buffer = buf.GetData();
if (buf.GetFlipped() && buf.GetFormat() == GPU_DBG_FORMAT_888_RGB) {
if (buf.GetFlipped() && buf.GetFormat() == nativeFmt) {
// Silly OpenGL reads upside down, we flip to another buffer for simplicity.
for (u32 y = 0; y < h; y++) {
memcpy(temp + y * w * 3, buffer + (buf.GetHeight() - y - 1) * buf.GetStride() * 3, w * 3);
memcpy(temp + y * w * pixelSize, buffer + (buf.GetHeight() - y - 1) * buf.GetStride() * pixelSize, w * pixelSize);
}
} else if (buf.GetFormat() < GPU_DBG_FORMAT_FLOAT) {
} else if (buf.GetFormat() < GPU_DBG_FORMAT_FLOAT && buf.GetFormat() != nativeFmt) {
// Let's boil it down to how we need to interpret the bits.
int baseFmt = buf.GetFormat() & ~(GPU_DBG_FORMAT_REVERSE_FLAG | GPU_DBG_FORMAT_BRSWAP_FLAG);
bool rev = (buf.GetFormat() & GPU_DBG_FORMAT_REVERSE_FLAG) != 0;
@@ -252,21 +268,22 @@ const u8 *ConvertBufferTo888RGB(const GPUDebugBuffer &buf, u8 *&temp, u32 &w, u3
for (u32 x = 0; x < w; x++) {
u8 *dst;
if (flip) {
dst = &temp[(h - y - 1) * w * 3 + x * 3];
dst = &temp[(h - y - 1) * w * pixelSize + x * pixelSize];
} else {
dst = &temp[y * w * 3 + x * 3];
dst = &temp[y * w * pixelSize + x * pixelSize];
}
u8 &r = brswap ? dst[2] : dst[0];
u8 &g = dst[1];
u8 &b = brswap ? dst[0] : dst[2];
u8 &a = alpha ? dst[3] : r;
if (!ConvertPixelTo888RGB(GPUDebugBufferFormat(baseFmt), r, g, b, buffer, y * buf.GetStride() + x, rev)) {
if (!ConvertPixelTo8888RGBA(GPUDebugBufferFormat(baseFmt), r, g, b, a, buffer, y * buf.GetStride() + x, rev)) {
return nullptr;
}
}
}
} else if (buf.GetFormat() != GPU_DBG_FORMAT_888_RGB) {
} else if (buf.GetFormat() != nativeFmt) {
bool flip = buf.GetFlipped();
// This is pretty inefficient.
@@ -274,12 +291,13 @@ const u8 *ConvertBufferTo888RGB(const GPUDebugBuffer &buf, u8 *&temp, u32 &w, u3
for (u32 x = 0; x < w; x++) {
u8 *dst;
if (flip) {
dst = &temp[(h - y - 1) * w * 3 + x * 3];
dst = &temp[(h - y - 1) * w * pixelSize + x * pixelSize];
} else {
dst = &temp[y * w * 3 + x * 3];
dst = &temp[y * w * pixelSize + x * pixelSize];
}
if (!ConvertPixelTo888RGB(buf.GetFormat(), dst[0], dst[1], dst[2], buffer, y * buf.GetStride() + x, false)) {
u8 &a = alpha ? dst[3] : dst[0];
if (!ConvertPixelTo8888RGBA(buf.GetFormat(), dst[0], dst[1], dst[2], a, buffer, y * buf.GetStride() + x, false)) {
return nullptr;
}
}
@@ -316,7 +334,7 @@ bool TakeGameScreenshot(const char *filename, ScreenshotFormat fmt, ScreenshotTy
u8 *flipbuffer = nullptr;
if (success) {
const u8 *buffer = ConvertBufferTo888RGB(buf, flipbuffer, w, h);
const u8 *buffer = ConvertBufferToScreenshot(buf, false, flipbuffer, w, h);
success = buffer != nullptr;
if (success) {
if (width)
@@ -364,3 +382,25 @@ bool Save888RGBScreenshot(const char *filename, ScreenshotFormat fmt, const u8 *
}
#endif
}
bool Save8888RGBAScreenshot(const char *filename, const u8 *buffer, int w, int h) {
#ifdef USING_QT_UI
QImage image(buffer, w, h, QImage::Format_RGBA8888);
return image.save(filename, "PNG");
#else
png_image png;
memset(&png, 0, sizeof(png));
png.version = PNG_IMAGE_VERSION;
png.format = PNG_FORMAT_RGBA;
png.width = w;
png.height = h;
bool success = WriteScreenshotToPNG(&png, filename, 0, buffer, w * 4, nullptr);
png_image_free(&png);
if (png.warning_or_error >= 2) {
ERROR_LOG(SYSTEM, "Saving screenshot to PNG produced errors.");
success = false;
}
return success;
#endif
}
+2 -1
View File
@@ -33,8 +33,9 @@ enum ScreenshotType {
SCREENSHOT_RENDER,
};
const u8 *ConvertBufferTo888RGB(const GPUDebugBuffer &buf, u8 *&temp, u32 &w, u32 &h);
const u8 *ConvertBufferToScreenshot(const GPUDebugBuffer &buf, bool alpha, u8 *&temp, u32 &w, u32 &h);
// Can only be used while in game.
bool TakeGameScreenshot(const char *filename, ScreenshotFormat fmt, ScreenshotType type, int *width = nullptr, int *height = nullptr, int maxRes = -1);
bool Save888RGBScreenshot(const char *filename, ScreenshotFormat fmt, const u8 *bufferRGB888, int w, int h);
bool Save8888RGBAScreenshot(const char *filename, const u8 *bufferRGBA8888, int w, int h);
+1 -1
View File
@@ -489,7 +489,7 @@ u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr,
}
bool DrawEngineCommon::ApplyShaderBlending() {
if (gstate_c.featureFlags & GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH) {
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH)) {
return true;
}
+15 -11
View File
@@ -1970,8 +1970,11 @@ bool FramebufferManagerCommon::GetDepthbuffer(u32 fb_address, int fb_stride, u32
} else {
buffer.Allocate(w, h, GPU_DBG_FORMAT_FLOAT, flipY);
}
draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_DEPTH_BIT, 0, 0, w, h, Draw::DataFormat::D32F, buffer.GetData(), w);
return true;
// No need to free on failure, that's the caller's job (it likely will reuse a buffer.)
bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_DEPTH_BIT, 0, 0, w, h, Draw::DataFormat::D32F, buffer.GetData(), w);
// That may have unbound the framebuffer, rebind to avoid crashes when debugging.
RebindFramebuffer();
return retval;
}
bool FramebufferManagerCommon::GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer) {
@@ -1996,21 +1999,22 @@ bool FramebufferManagerCommon::GetStencilbuffer(u32 fb_address, int fb_stride, G
}
bool flipY = (g_Config.iGPUBackend == GPU_BACKEND_OPENGL && !useBufferedRendering_) ? true : false;
// No need to free on failure, the caller/destructor will do that. Usually this is a reused buffer, anyway.
buffer.Allocate(w, h, GPU_DBG_FORMAT_8BIT, flipY);
if (draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_STENCIL_BIT, 0, 0, w,h, Draw::DataFormat::S8, buffer.GetData(), w)) {
return true;
} else {
buffer.Free();
return false;
}
bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_STENCIL_BIT, 0, 0, w,h, Draw::DataFormat::S8, buffer.GetData(), w);
// That may have unbound the framebuffer, rebind to avoid crashes when debugging.
RebindFramebuffer();
return retval;
}
bool FramebufferManagerCommon::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
int w, h;
draw_->GetFramebufferDimensions(nullptr, &w, &h);
buffer.Allocate(w, h, GE_FORMAT_8888, false, true);
draw_->CopyFramebufferToMemorySync(nullptr, Draw::FB_COLOR_BIT, 0, 0, w, h, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), w);
return true;
bool retval = draw_->CopyFramebufferToMemorySync(nullptr, Draw::FB_COLOR_BIT, 0, 0, w, h, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), w);
// That may have unbound the framebuffer, rebind to avoid crashes when debugging.
RebindFramebuffer();
return retval;
}
// This function takes an already correctly-sized framebuffer and packs it into RAM.
@@ -2113,7 +2117,7 @@ void FramebufferManagerCommon::RebindFramebuffer() {
if (currentRenderVfb_ && currentRenderVfb_->fbo) {
draw_->BindFramebufferAsRenderTarget(currentRenderVfb_->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
} else {
// Should this even happen?
// Should this even happen? It could while debugging, but maybe we can just skip binding at all.
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
}
gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE);
+3 -3
View File
@@ -303,7 +303,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
case GE_DSTBLEND_DOUBLESRCALPHA:
// We can't technically do this correctly (due to clamping) without reading the dst color.
// Using a copy isn't accurate either, though, when there's overlap.
if (gstate_c.featureFlags & GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH)
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH))
return !allowShaderBlend ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
return REPLACE_BLEND_PRE_SRC_2X_ALPHA;
@@ -445,14 +445,14 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
case GE_DSTBLEND_DOUBLESRCALPHA:
if (funcA == GE_SRCBLEND_SRCALPHA || funcA == GE_SRCBLEND_INVSRCALPHA) {
// Can't safely double alpha, will clamp. However, a copy may easily be worse due to overlap.
if (gstate_c.featureFlags & GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH)
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH))
return !allowShaderBlend ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
return REPLACE_BLEND_PRE_SRC_2X_ALPHA;
} else {
// This means dst alpha/color is used in the src factor.
// Unfortunately, copying here causes overlap problems in Silent Hill games (it seems?)
// We will just hope that doubling alpha for the dst factor will not clamp too badly.
if (gstate_c.featureFlags & GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH)
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH))
return !allowShaderBlend ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
return REPLACE_BLEND_2X_ALPHA;
}
+4 -4
View File
@@ -58,7 +58,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
if (gl_extensions.IsGLES) {
// ES doesn't support dual source alpha :(
if (gstate_c.featureFlags & GPU_SUPPORTS_GLSL_ES_300) {
if (gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300)) {
WRITE(p, "#version 300 es\n"); // GLSL ES 3.0
fragColor0 = "fragColor0";
texture = "texture";
@@ -91,8 +91,8 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
highpFog = (gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_BAD) ? true : false;
highpTexcoord = highpFog;
if (gstate_c.featureFlags & GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH) {
if ((gstate_c.featureFlags & GPU_SUPPORTS_GLSL_ES_300) != 0 && gl_extensions.EXT_shader_framebuffer_fetch) {
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH)) {
if (gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300) && gl_extensions.EXT_shader_framebuffer_fetch) {
WRITE(p, "#extension GL_EXT_shader_framebuffer_fetch : require\n");
lastFragData = "fragColor0";
} else if (gl_extensions.EXT_shader_framebuffer_fetch) {
@@ -535,7 +535,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
if (replaceBlend == REPLACE_BLEND_COPY_FBO) {
// If we have NV_shader_framebuffer_fetch / EXT_shader_framebuffer_fetch, we skip the blit.
// We can just read the prev value more directly.
if (gstate_c.featureFlags & GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH) {
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH)) {
WRITE(p, " lowp vec4 destColor = %s;\n", lastFragData);
} else if (!texelFetch) {
WRITE(p, " lowp vec4 destColor = %s(fbotex, gl_FragCoord.xy * u_fbotexSize.xy);\n", texture);
+2 -1
View File
@@ -175,7 +175,8 @@ GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
if (g_Config.bHardwareTessellation) {
// Disable hardware tessellation if device is unsupported.
if (!gstate_c.SupportsAll(GPU_SUPPORTS_INSTANCE_RENDERING | GPU_SUPPORTS_VERTEX_TEXTURE_FETCH | GPU_SUPPORTS_TEXTURE_FLOAT)) {
bool hasTexelFetch = gl_extensions.GLES3 || (!gl_extensions.IsGLES && gl_extensions.VersionGEThan(3, 3, 0)) || gl_extensions.EXT_gpu_shader4;
if (!gstate_c.SupportsAll(GPU_SUPPORTS_INSTANCE_RENDERING | GPU_SUPPORTS_VERTEX_TEXTURE_FETCH | GPU_SUPPORTS_TEXTURE_FLOAT) || !hasTexelFetch) {
// TODO: Check unsupported device name list.(Above gpu features are supported but it has issues with weak gpu, memory, shader compiler etc...)
g_Config.bHardwareTessellation = false;
ERROR_LOG(G3D, "Hardware Tessellation is unsupported, falling back to software tessellation");
+2 -2
View File
@@ -114,7 +114,7 @@ LinkedShader::LinkedShader(VShaderID VSID, Shader *vs, FShaderID FSID, Shader *f
glBindAttribLocation(program, ATTR_COLOR1, "color1");
#if !defined(USING_GLES2)
if (gstate_c.featureFlags & GPU_SUPPORTS_DUALSOURCE_BLEND) {
if (gstate_c.Supports(GPU_SUPPORTS_DUALSOURCE_BLEND)) {
// Dual source alpha
glBindFragDataLocationIndexed(program, 0, 0, "fragColor0");
glBindFragDataLocationIndexed(program, 0, 1, "fragColor1");
@@ -123,7 +123,7 @@ LinkedShader::LinkedShader(VShaderID VSID, Shader *vs, FShaderID FSID, Shader *f
}
#elif !defined(IOS)
if (gl_extensions.GLES3) {
if (gstate_c.featureFlags & GPU_SUPPORTS_DUALSOURCE_BLEND) {
if (gstate_c.Supports(GPU_SUPPORTS_DUALSOURCE_BLEND)) {
glBindFragDataLocationIndexedEXT(program, 0, 0, "fragColor0");
glBindFragDataLocationIndexedEXT(program, 0, 1, "fragColor1");
}
+4 -2
View File
@@ -36,15 +36,17 @@ SDLJoystick *joystick = NULL;
#include "Common/Vulkan/VulkanDebug.h"
#include "math.h"
#if !defined(__APPLE__)
#include "SDL_syswm.h"
#endif
#if defined(VK_USE_PLATFORM_XLIB_KHR)
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "SDL_syswm.h"
#elif defined(VK_USE_PLATFORM_XCB_KHR)
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xlib-xcb.h>
#include "SDL_syswm.h"
#endif
#if defined(USING_EGL)
+2 -1
View File
@@ -99,8 +99,9 @@ bool CheckSupportInstancedTessellationGLES() {
bool instanceRendering = gl_extensions.GLES3 || (canUseInstanceID && canDefInstanceID);
bool textureFloat = gl_extensions.ARB_texture_float || gl_extensions.OES_texture_float;
bool hasTexelFetch = gl_extensions.GLES3 || (!gl_extensions.IsGLES && gl_extensions.VersionGEThan(3, 3, 0)) || gl_extensions.EXT_gpu_shader4;
return instanceRendering && vertexTexture && textureFloat;
return instanceRendering && vertexTexture && textureFloat && hasTexelFetch;
#endif
}
+36 -9
View File
@@ -157,16 +157,27 @@ void CGEDebugger::SetupPreviews() {
PrimaryPreviewHover(x, y);
});
primaryWindow->SetRightClickMenu(subMenu, [&] (int cmd) {
HMENU subMenu = GetSubMenu(g_hPopupMenus, POPUP_SUBMENU_ID_GEDBG_PREVIEW);
switch (cmd) {
case 0:
// Setup.
CheckMenuItem(subMenu, ID_GEDBG_ENABLE_PREVIEW, MF_BYCOMMAND | ((previewsEnabled_ & 1) ? MF_CHECKED : MF_UNCHECKED));
break;
case ID_GEDBG_EXPORT_IMAGE:
PreviewExport(primaryBuffer_);
break;
case ID_GEDBG_ENABLE_PREVIEW:
previewsEnabled_ ^= 1;
primaryWindow->Redraw();
default:
break;
}
return true;
});
primaryWindow->SetRedrawCallback([&] {
HandleRedraw(1);
});
primaryWindow->Clear();
}
if (secondWindow == nullptr) {
@@ -178,16 +189,27 @@ void CGEDebugger::SetupPreviews() {
SecondPreviewHover(x, y);
});
secondWindow->SetRightClickMenu(subMenu, [&] (int cmd) {
HMENU subMenu = GetSubMenu(g_hPopupMenus, POPUP_SUBMENU_ID_GEDBG_PREVIEW);
switch (cmd) {
case 0:
// Setup.
CheckMenuItem(subMenu, ID_GEDBG_ENABLE_PREVIEW, MF_BYCOMMAND | ((previewsEnabled_ & 2) ? MF_CHECKED : MF_UNCHECKED));
break;
case ID_GEDBG_EXPORT_IMAGE:
PreviewExport(secondBuffer_);
break;
case ID_GEDBG_ENABLE_PREVIEW:
previewsEnabled_ ^= 2;
secondWindow->Redraw();
default:
break;
}
return true;
});
secondWindow->SetRedrawCallback([&] {
HandleRedraw(2);
});
secondWindow->Clear();
}
}
@@ -229,13 +251,18 @@ void CGEDebugger::PreviewExport(const GPUDebugBuffer *dbgBuffer) {
std::string fn;
if (W32Util::BrowseForFileName(false, GetDlgHandle(), L"Save Preview Image...", nullptr, filter, L"png", fn)) {
ScreenshotFormat fmt = fn.find(".jpg") != fn.npos ? ScreenshotFormat::JPG : ScreenshotFormat::PNG;
bool saveAlpha = fmt == ScreenshotFormat::PNG;
u8 *flipbuffer = nullptr;
u32 w = (u32)-1;
u32 h = (u32)-1;
const u8 *buffer = ConvertBufferTo888RGB(*dbgBuffer, flipbuffer, w, h);
const u8 *buffer = ConvertBufferToScreenshot(*dbgBuffer, saveAlpha, flipbuffer, w, h);
if (buffer != nullptr) {
Save888RGBScreenshot(fn.c_str(), fmt, buffer, w, h);
if (saveAlpha) {
Save8888RGBAScreenshot(fn.c_str(), buffer, w, h);
} else {
Save888RGBScreenshot(fn.c_str(), fmt, buffer, w, h);
}
}
delete [] flipbuffer;
}
@@ -253,19 +280,18 @@ void CGEDebugger::UpdatePreviews() {
state = gpuDebug->GetGState();
}
updating_ = true;
UpdateTextureLevel(textureLevel_);
UpdatePrimaryPreview(state);
UpdateSecondPreview(state);
u32 primOp = PrimPreviewOp();
if (primOp != 0) {
UpdatePrimPreview(primOp, 3);
}
DisplayList list;
if (gpuDebug != nullptr && gpuDebug->GetCurrentDisplayList(list)) {
const u32 op = Memory::Read_U32(list.pc);
const u32 cmd = op >> 24;
// TODO: Bezier/spline?
if (cmd == GE_CMD_PRIM && !showClut_) {
UpdatePrimPreview(op);
}
displayList->setDisplayList(list);
}
@@ -277,6 +303,7 @@ void CGEDebugger::UpdatePreviews() {
matrices->Update();
lists->Update();
watch->Update();
updating_ = false;
}
u32 CGEDebugger::TexturePreviewFlags(const GPUgstate &state) {
+5 -1
View File
@@ -70,8 +70,10 @@ private:
void UpdatePreviews();
void UpdatePrimaryPreview(const GPUgstate &state);
void UpdateSecondPreview(const GPUgstate &state);
void UpdatePrimPreview(u32 op);
u32 PrimPreviewOp();
void UpdatePrimPreview(u32 op, int which);
void CleanupPrimPreview();
void HandleRedraw(int which);
void UpdateSize(WORD width, WORD height);
void SavePosition();
void SetBreakNext(BreakNextType type);
@@ -106,6 +108,8 @@ private:
const GPUDebugBuffer *primaryBuffer_ = nullptr;
const GPUDebugBuffer *secondBuffer_ = nullptr;
bool updating_ = false;
int previewsEnabled_ = 3;
int minWidth_;
int minHeight_;
};
+21 -6
View File
@@ -68,8 +68,7 @@ static const char basic_vs[] =
"}\n";
SimpleGLWindow::SimpleGLWindow(HWND wnd)
: hWnd_(wnd), valid_(false), drawProgram_(nullptr), vao_(0), tex_(0), flags_(0), zoom_(false),
dragging_(false), offsetX_(0), offsetY_(0), reformatBuf_(nullptr), hoverCallback_(nullptr) {
: hWnd_(wnd) {
SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR) this);
}
@@ -365,10 +364,23 @@ void SimpleGLWindow::GetContentSize(float &x, float &y, float &fw, float &fh) {
void SimpleGLWindow::Redraw(bool andSwap) {
DrawChecker();
if (tw_ == 0 && th_ == 0) {
auto swapWithCallback = [andSwap, this]() {
if (andSwap) {
Swap();
swapped_ = false;
if (redrawCallback_ && !inRedrawCallback_) {
inRedrawCallback_ = true;
redrawCallback_();
inRedrawCallback_ = false;
}
// In case the callback swaps, don't do it twice.
if (!swapped_) {
Swap();
}
}
};
if (tw_ == 0 && th_ == 0) {
swapWithCallback();
return;
}
@@ -412,7 +424,7 @@ void SimpleGLWindow::Redraw(bool andSwap) {
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, vao_ ? 0 : indices);
if (andSwap) {
Swap();
swapWithCallback();
}
}
@@ -423,7 +435,9 @@ void SimpleGLWindow::Clear() {
}
void SimpleGLWindow::Begin() {
Redraw(false);
if (!inRedrawCallback_) {
Redraw(false);
}
if (vao_) {
glBindVertexArray(0);
@@ -549,6 +563,7 @@ bool SimpleGLWindow::RightClick(int mouseX, int mouseY) {
POINT pt{mouseX, mouseY};
ClientToScreen(hWnd_, &pt);
rightClickCallback_(0);
int result = TrackPopupMenuEx(rightClickMenu_, TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, hWnd_, 0);
if (result != 0) {
rightClickCallback_(result);
+23 -14
View File
@@ -81,6 +81,7 @@ struct SimpleGLWindow {
}
void Swap() {
swapped_ = true;
SwapBuffers(hDC_);
}
@@ -106,10 +107,15 @@ struct SimpleGLWindow {
void GetContentSize(float &x, float &y, float &fw, float &fh);
void SetRedrawCallback(std::function<void()> callback) {
redrawCallback_ = callback;
}
void SetHoverCallback(std::function<void(int, int)> hoverCallback) {
hoverCallback_ = hoverCallback;
}
// Called first with 0 that it's opening, then the selected item.
void SetRightClickMenu(HMENU menu, std::function<void(int)> callback) {
rightClickCallback_ = callback;
rightClickMenu_ = menu;
@@ -134,7 +140,7 @@ protected:
HWND hWnd_;
HDC hDC_;
HGLRC hGLRC_;
bool valid_;
bool valid_ = false;
// Width and height of the window.
int w_;
int h_;
@@ -143,25 +149,28 @@ protected:
int th_;
bool tflipped_;
GLSLProgram *drawProgram_;
GLuint vao_;
GLuint ibuf_;
GLuint vbuf_;
GLuint checker_;
GLuint tex_;
u32 flags_;
GLSLProgram *drawProgram_ = nullptr;
GLuint vao_ = 0;
GLuint ibuf_ = 0;
GLuint vbuf_ = 0;
GLuint checker_ = 0;
GLuint tex_ = 0;
u32 flags_ = 0;
// Disable shrink (toggled by double click.)
bool zoom_;
bool dragging_;
bool zoom_ = false;
bool dragging_ = false;
bool inRedrawCallback_ = false;
bool swapped_ = false;
int dragStartX_;
int dragStartY_;
u32 dragLastUpdate_;
// Offset to position the texture is drawn at.
int offsetX_;
int offsetY_;
u32 *reformatBuf_;
u32 reformatBufSize_;
int offsetX_ = 0;
int offsetY_ = 0;
u32 *reformatBuf_ = nullptr;
u32 reformatBufSize_ = 0;
std::function<void()> redrawCallback_;
std::function<void(int, int)> hoverCallback_;
std::function<void(int)> rightClickCallback_;
HMENU rightClickMenu_;
+167 -121
View File
@@ -151,7 +151,21 @@ static void ExpandRectangles(std::vector<GPUDebugVertex> &vertices, std::vector<
count *= 3;
}
void CGEDebugger::UpdatePrimPreview(u32 op) {
u32 CGEDebugger::PrimPreviewOp() {
DisplayList list;
if (gpuDebug != nullptr && gpuDebug->GetCurrentDisplayList(list)) {
const u32 op = Memory::Read_U32(list.pc);
const u32 cmd = op >> 24;
// TODO: Bezier/spline?
if (cmd == GE_CMD_PRIM && !showClut_) {
return op;
}
}
return 0;
}
void CGEDebugger::UpdatePrimPreview(u32 op, int which) {
const u32 prim_type = (op >> 16) & 0x7;
int count = op & 0xFFFF;
if (prim_type >= 7) {
@@ -162,7 +176,8 @@ void CGEDebugger::UpdatePrimPreview(u32 op) {
ERROR_LOG(G3D, "Invalid debugging environment, shutting down?");
return;
}
if (count == 0) {
which &= previewsEnabled_;
if (count == 0 || which == 0) {
return;
}
@@ -182,17 +197,6 @@ void CGEDebugger::UpdatePrimPreview(u32 op) {
float fw, fh;
float x, y;
primaryWindow->Begin();
primaryWindow->GetContentSize(x, y, fw, fh);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_ADD);
glBindTexture(GL_TEXTURE_2D, 0);
glViewport((GLint)x, (GLint)y, (GLsizei)fw, (GLsizei)fh);
glScissor((GLint)x, (GLint)y, (GLsizei)fw, (GLsizei)fh);
BindPreviewProgram(previewProgram);
// TODO: Probably there's a better way and place to do this.
u16 minIndex = 0;
u16 maxIndex = count - 1;
@@ -209,124 +213,155 @@ void CGEDebugger::UpdatePrimPreview(u32 op) {
}
}
const float invTexWidth = 1.0f / gstate_c.curTextureWidth;
const float invTexHeight = 1.0f / gstate_c.curTextureHeight;
auto wrapCoord = [](float &coord) {
if (coord < 0.0f) {
coord += ceilf(-coord);
}
if (coord > 1.0f) {
coord -= floorf(coord);
}
};
const float invTexWidth = 1.0f / gpuDebug->GetGState().getTextureWidth(0);
const float invTexHeight = 1.0f / gpuDebug->GetGState().getTextureHeight(0);
const float invRealTexWidth = 1.0f / gstate_c.curTextureWidth;
const float invRealTexHeight = 1.0f / gstate_c.curTextureHeight;
bool clampS = gpuDebug->GetGState().isTexCoordClampedS();
bool clampT = gpuDebug->GetGState().isTexCoordClampedT();
for (u16 i = minIndex; i <= maxIndex; ++i) {
vertices[i].u *= invTexWidth;
vertices[i].v *= invTexHeight;
if (vertices[i].u > 1.0f || vertices[i].u < 0.0f)
vertices[i].u -= floor(vertices[i].u);
if (vertices[i].v > 1.0f || vertices[i].v < 0.0f)
vertices[i].v -= floor(vertices[i].v);
if (!clampS)
wrapCoord(vertices[i].u);
if (!clampT)
wrapCoord(vertices[i].v);
}
if (previewVao == 0 && gl_extensions.ARB_vertex_array_object) {
glGenVertexArrays(1, &previewVao);
glBindVertexArray(previewVao);
glEnableVertexAttribArray(previewProgram->a_position);
if (which & 1) {
primaryWindow->Begin();
primaryWindow->GetContentSize(x, y, fw, fh);
glGenBuffers(1, &ibuf);
glGenBuffers(1, &vbuf);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf);
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_ADD);
glBindTexture(GL_TEXTURE_2D, 0);
// The surface is upside down, so vertical offsets are negated.
glViewport((GLint)x, (GLint)-(y + fh - primaryWindow->Height()), (GLsizei)fw, (GLsizei)fh);
glScissor((GLint)x, (GLint)-(y + fh - primaryWindow->Height()), (GLsizei)fw, (GLsizei)fh);
BindPreviewProgram(previewProgram);
glVertexAttribPointer(previewProgram->a_position, 3, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), (void *)(2 * sizeof(float)));
if (previewVao == 0 && gl_extensions.ARB_vertex_array_object) {
glGenVertexArrays(1, &previewVao);
glBindVertexArray(previewVao);
glEnableVertexAttribArray(previewProgram->a_position);
glGenBuffers(1, &ibuf);
glGenBuffers(1, &vbuf);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf);
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glVertexAttribPointer(previewProgram->a_position, 3, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), (void *)(2 * sizeof(float)));
}
if (vbuf != 0) {
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GPUDebugVertex), vertices.data(), GL_STREAM_DRAW);
}
if (ibuf != 0 && !indices.empty()) {
glBindVertexArray(previewVao);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(u16), indices.data(), GL_STREAM_DRAW);
}
float scale[] = {
480.0f / (float)PSP_CoreParameter().renderWidth,
272.0f / (float)PSP_CoreParameter().renderHeight,
};
Matrix4x4 ortho;
ortho.setOrtho(-(float)gstate_c.curRTOffsetX, (primaryWindow->TexWidth() - (int)gstate_c.curRTOffsetX) * scale[0], primaryWindow->TexHeight() * scale[1], 0, -1, 1);
glUniformMatrix4fv(previewProgram->u_viewproj, 1, GL_FALSE, ortho.getReadPtr());
if (previewVao != 0) {
glBindVertexArray(previewVao);
} else {
glEnableVertexAttribArray(previewProgram->a_position);
glVertexAttribPointer(previewProgram->a_position, 3, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), (float *)vertices.data() + 2);
}
if (indices.empty()) {
glDrawArrays(glprim[prim], 0, count);
} else {
glDrawElements(glprim[prim], count, GL_UNSIGNED_SHORT, previewVao != 0 ? 0 : indices.data());
}
if (previewVao == 0) {
glDisableVertexAttribArray(previewProgram->a_position);
}
primaryWindow->End();
}
if (vbuf != 0) {
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GPUDebugVertex), vertices.data(), GL_STREAM_DRAW);
if (which & 2) {
secondWindow->Begin();
secondWindow->GetContentSize(x, y, fw, fh);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_ADD);
glBindTexture(GL_TEXTURE_2D, 0);
// The surface is upside down, so vertical offsets are flipped.
glViewport((GLint)x, (GLint)-(y + fh - secondWindow->Height()), (GLsizei)fw, (GLsizei)fh);
glScissor((GLint)x, (GLint)-(y + fh - secondWindow->Height()), (GLsizei)fw, (GLsizei)fh);
BindPreviewProgram(texPreviewProgram);
if (texPreviewVao == 0 && gl_extensions.ARB_vertex_array_object) {
glGenVertexArrays(1, &texPreviewVao);
glBindVertexArray(texPreviewVao);
glEnableVertexAttribArray(texPreviewProgram->a_position);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf);
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glVertexAttribPointer(texPreviewProgram->a_position, 2, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), 0);
}
// TODO: For some reason we have to re-upload the data?
if (vbuf != 0) {
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GPUDebugVertex), vertices.data(), GL_STREAM_DRAW);
}
if (ibuf != 0 && !indices.empty()) {
glBindVertexArray(texPreviewVao);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(u16), indices.data(), GL_STREAM_DRAW);
}
Matrix4x4 ortho;
ortho.setOrtho(0.0f - (float)gstate_c.curTextureXOffset * invRealTexWidth, 1.0f - (float)gstate_c.curTextureXOffset * invRealTexWidth, 1.0f - (float)gstate_c.curTextureYOffset * invRealTexHeight, 0.0f - (float)gstate_c.curTextureYOffset * invRealTexHeight, -1.0f, 1.0f);
glUniformMatrix4fv(texPreviewProgram->u_viewproj, 1, GL_FALSE, ortho.getReadPtr());
if (texPreviewVao != 0) {
glBindVertexArray(texPreviewVao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf);
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glEnableVertexAttribArray(texPreviewProgram->a_position);
glVertexAttribPointer(texPreviewProgram->a_position, 2, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), 0);
} else {
glEnableVertexAttribArray(texPreviewProgram->a_position);
glVertexAttribPointer(texPreviewProgram->a_position, 2, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), (float *)vertices.data());
}
if (indices.empty()) {
glDrawArrays(glprim[prim], 0, count);
} else {
glDrawElements(glprim[prim], count, GL_UNSIGNED_SHORT, texPreviewVao != 0 ? 0 : indices.data());
}
if (texPreviewVao == 0) {
glDisableVertexAttribArray(previewProgram->a_position);
}
secondWindow->End();
}
if (ibuf != 0 && !indices.empty()) {
glBindVertexArray(previewVao);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(u16), indices.data(), GL_STREAM_DRAW);
}
float scale[] = {
480.0f / (float)PSP_CoreParameter().renderWidth,
272.0f / (float)PSP_CoreParameter().renderHeight,
};
Matrix4x4 ortho;
ortho.setOrtho(-(float)gstate_c.curRTOffsetX, (primaryWindow->TexWidth() - (int)gstate_c.curRTOffsetX) * scale[0], primaryWindow->TexHeight() * scale[1], 0, -1, 1);
glUniformMatrix4fv(previewProgram->u_viewproj, 1, GL_FALSE, ortho.getReadPtr());
if (previewVao != 0) {
glBindVertexArray(previewVao);
} else {
glEnableVertexAttribArray(previewProgram->a_position);
glVertexAttribPointer(previewProgram->a_position, 3, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), (float *)vertices.data() + 2);
}
if (indices.empty()) {
glDrawArrays(glprim[prim], 0, count);
} else {
glDrawElements(glprim[prim], count, GL_UNSIGNED_SHORT, previewVao != 0 ? 0 : indices.data());
}
if (previewVao == 0) {
glDisableVertexAttribArray(previewProgram->a_position);
}
primaryWindow->End();
secondWindow->Begin();
secondWindow->GetContentSize(x, y, fw, fh);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_ADD);
glBindTexture(GL_TEXTURE_2D, 0);
glViewport((GLint)x, (GLint)y, (GLsizei)fw, (GLsizei)fh);
glScissor((GLint)x, (GLint)y, (GLsizei)fw, (GLsizei)fh);
BindPreviewProgram(texPreviewProgram);
if (texPreviewVao == 0 && gl_extensions.ARB_vertex_array_object) {
glGenVertexArrays(1, &texPreviewVao);
glBindVertexArray(texPreviewVao);
glEnableVertexAttribArray(texPreviewProgram->a_position);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf);
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glVertexAttribPointer(texPreviewProgram->a_position, 2, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), 0);
}
// TODO: For some reason we have to re-upload the data?
if (vbuf != 0) {
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GPUDebugVertex), vertices.data(), GL_STREAM_DRAW);
}
if (ibuf != 0 && !indices.empty()) {
glBindVertexArray(texPreviewVao);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(u16), indices.data(), GL_STREAM_DRAW);
}
ortho.setOrtho(0.0f - (float)gstate_c.curTextureXOffset * invTexWidth, 1.0f - (float)gstate_c.curTextureXOffset * invTexWidth, 1.0f - (float)gstate_c.curTextureYOffset * invTexHeight, 0.0f - (float)gstate_c.curTextureYOffset * invTexHeight, -1.0f, 1.0f);
glUniformMatrix4fv(texPreviewProgram->u_viewproj, 1, GL_FALSE, ortho.getReadPtr());
if (texPreviewVao != 0) {
glBindVertexArray(texPreviewVao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf);
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glEnableVertexAttribArray(texPreviewProgram->a_position);
glVertexAttribPointer(texPreviewProgram->a_position, 2, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), 0);
} else {
glEnableVertexAttribArray(texPreviewProgram->a_position);
glVertexAttribPointer(texPreviewProgram->a_position, 2, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), (float *)vertices.data());
}
if (indices.empty()) {
glDrawArrays(glprim[prim], 0, count);
} else {
glDrawElements(glprim[prim], count, GL_UNSIGNED_SHORT, texPreviewVao != 0 ? 0 : indices.data());
}
if (texPreviewVao == 0) {
glDisableVertexAttribArray(previewProgram->a_position);
}
secondWindow->End();
}
void CGEDebugger::CleanupPrimPreview() {
@@ -337,3 +372,14 @@ void CGEDebugger::CleanupPrimPreview() {
glsl_destroy(texPreviewProgram);
}
}
void CGEDebugger::HandleRedraw(int which) {
if (updating_) {
return;
}
u32 op = PrimPreviewOp();
if (op) {
UpdatePrimPreview(op, which);
}
}
+1
View File
@@ -657,6 +657,7 @@ BEGIN
POPUP "gepreviewoptions"
BEGIN
MENUITEM "Export Image...", ID_GEDBG_EXPORT_IMAGE
MENUITEM "Show Prim Preview" ID_GEDBG_ENABLE_PREVIEW
END
END
+2 -1
View File
@@ -335,6 +335,7 @@
#define ID_HELP_GITHUB 40168
#define IDC_GEDBG_RECORD 40169
#define ID_GEDBG_EXPORT_IMAGE 40170
#define ID_GEDBG_ENABLE_PREVIEW 40171
#define ID_SIMPLEUI_TOGGLE 40200
#define ID_SIMPLEUI_HIDE 40201
@@ -349,7 +350,7 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 256
#define _APS_NEXT_COMMAND_VALUE 40171
#define _APS_NEXT_COMMAND_VALUE 40172
#define _APS_NEXT_CONTROL_VALUE 1200
#define _APS_NEXT_SYMED_VALUE 101
#endif