mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-24 08:39:51 +00:00
Sprinkle calls to CHECK_GL_ERROR_IF_DEBUG all over the place, disabled by default.
This commit is contained in:
parent
b0eab68760
commit
5d4700ae7e
@ -72,6 +72,7 @@
|
||||
#include "Core/Config.h"
|
||||
#include "Core/CoreTiming.h"
|
||||
|
||||
#include "gfx/gl_debug_log.h"
|
||||
#include "profiler/profiler.h"
|
||||
|
||||
#include "GPU/Math3D.h"
|
||||
@ -256,6 +257,7 @@ static inline void VertexAttribSetup(int attrib, int fmt, int stride, u8 *ptr) {
|
||||
|
||||
// TODO: Use VBO and get rid of the vertexData pointers - with that, we will supply only offsets
|
||||
static void SetupDecFmtForDraw(LinkedShader *program, const DecVtxFormat &decFmt, u8 *vertexData) {
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
VertexAttribSetup(ATTR_W1, decFmt.w0fmt, decFmt.stride, vertexData + decFmt.w0off);
|
||||
VertexAttribSetup(ATTR_W2, decFmt.w1fmt, decFmt.stride, vertexData + decFmt.w1off);
|
||||
VertexAttribSetup(ATTR_TEXCOORD, decFmt.uvfmt, decFmt.stride, vertexData + decFmt.uvoff);
|
||||
@ -263,6 +265,7 @@ static void SetupDecFmtForDraw(LinkedShader *program, const DecVtxFormat &decFmt
|
||||
VertexAttribSetup(ATTR_COLOR1, decFmt.c1fmt, decFmt.stride, vertexData + decFmt.c1off);
|
||||
VertexAttribSetup(ATTR_NORMAL, decFmt.nrmfmt, decFmt.stride, vertexData + decFmt.nrmoff);
|
||||
VertexAttribSetup(ATTR_POSITION, decFmt.posfmt, decFmt.stride, vertexData + decFmt.posoff);
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
void DrawEngineGLES::SetupVertexDecoder(u32 vertType) {
|
||||
@ -643,14 +646,14 @@ void DrawEngineGLES::FreeVertexArray(VertexArrayInfo *vai) {
|
||||
|
||||
void DrawEngineGLES::DoFlush() {
|
||||
PROFILE_THIS_SCOPE("flush");
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
|
||||
gpuStats.numFlushes++;
|
||||
gpuStats.numTrackedVertexArrays = (int)vai_.size();
|
||||
|
||||
// This is not done on every drawcall, we should collect vertex data
|
||||
// until critical state changes. That's when we draw (flush).
|
||||
|
||||
GEPrimitiveType prim = prevPrim_;
|
||||
ApplyDrawState(prim);
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
|
||||
ShaderID vsid;
|
||||
Shader *vshader = shaderManager_->ApplyVertexShader(prim, lastVType_, &vsid);
|
||||
@ -1003,6 +1006,7 @@ rotateVBO:
|
||||
#ifndef MOBILE_DEVICE
|
||||
host->GPUNotifyDraw();
|
||||
#endif
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
void DrawEngineGLES::Resized() {
|
||||
@ -1212,4 +1216,5 @@ void DrawEngineGLES::TessellationDataTransferGLES::SendDataToShader(const float
|
||||
}
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "gfx/gl_debug_log.h"
|
||||
#include "Core/Config.h"
|
||||
#include "GPU/GLES/FragmentTestCacheGLES.h"
|
||||
#include "GPU/GPUState.h"
|
||||
@ -55,10 +56,12 @@ void FragmentTestCacheGLES::BindTestTexture(GLenum unit) {
|
||||
// Already bound, hurray.
|
||||
return;
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
glActiveTexture(unit);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
// Always return to the default.
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
lastTexture_ = tex;
|
||||
return;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "profiler/profiler.h"
|
||||
#include "gfx/gl_common.h"
|
||||
#include "gfx/gl_debug_log.h"
|
||||
#include "gfx_es2/glsl_program.h"
|
||||
#include "thin3d/thin3d.h"
|
||||
|
||||
@ -347,6 +348,7 @@ void FramebufferManagerGLES::MakePixelTexture(const u8 *srcPixels, GEBufferForma
|
||||
}
|
||||
}
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, useConvBuf ? convBuf_ : srcPixels);
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
void FramebufferManagerGLES::SetViewport2D(int x, int y, int w, int h) {
|
||||
@ -670,6 +672,7 @@ void FramebufferManagerGLES::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb)
|
||||
draw_->BindFramebufferAsRenderTarget(nvfb->fbo);
|
||||
ClearBuffer();
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) {
|
||||
@ -721,6 +724,7 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX,
|
||||
const bool yOverlap = src == dst && srcY2 > dstY1 && srcY1 < dstY2;
|
||||
if (sameSize && sameDepth && srcInsideBounds && dstInsideBounds && !(xOverlap && yOverlap)) {
|
||||
draw_->CopyFramebufferImage(src->fbo, 0, srcX1, srcY1, 0, dst->fbo, 0, dstX1, dstY1, 0, dstX2 - dstX1, dstY2 - dstY1, 1, Draw::FB_COLOR_BIT);
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -767,6 +771,7 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX,
|
||||
}
|
||||
|
||||
glstate.scissorTest.restore();
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
// TODO: SSE/NEON
|
||||
@ -887,6 +892,7 @@ static void LogReadPixelsError(GLenum error) {
|
||||
#endif
|
||||
|
||||
static void SafeGLReadPixels(GLint x, GLint y, GLsizei w, GLsizei h, GLenum fmt, GLenum type, void *pixels) {
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
if (!gl_extensions.IsGLES || (gl_extensions.GLES3 && gl_extensions.gpuVendor != GPU_VENDOR_NVIDIA)) {
|
||||
// Some drivers seem to require we specify this. See #8254.
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, w);
|
||||
@ -900,9 +906,11 @@ static void SafeGLReadPixels(GLint x, GLint y, GLsizei w, GLsizei h, GLenum fmt,
|
||||
if (!gl_extensions.IsGLES || gl_extensions.GLES3) {
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
void FramebufferManagerGLES::PackFramebufferAsync_(VirtualFramebuffer *vfb) {
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
const int MAX_PBO = 2;
|
||||
GLubyte *packed = 0;
|
||||
bool unbind = false;
|
||||
@ -1050,6 +1058,7 @@ void FramebufferManagerGLES::PackFramebufferAsync_(VirtualFramebuffer *vfb) {
|
||||
if (unbind) {
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
void FramebufferManagerGLES::PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h) {
|
||||
@ -1097,6 +1106,7 @@ void FramebufferManagerGLES::PackFramebufferSync_(VirtualFramebuffer *vfb, int x
|
||||
if (UseBGRA8888()) {
|
||||
glfmt = GL_BGRA_EXT;
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
|
||||
SafeGLReadPixels(0, y, h == 1 ? packWidth : vfb->fb_stride, h, glfmt, GL_UNSIGNED_BYTE, packed);
|
||||
|
||||
@ -1116,6 +1126,7 @@ void FramebufferManagerGLES::PackFramebufferSync_(VirtualFramebuffer *vfb, int x
|
||||
GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT };
|
||||
glInvalidateFramebuffer(target, 3, attachments);
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h) {
|
||||
@ -1157,9 +1168,11 @@ void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int
|
||||
depth[i] = (int)scaled;
|
||||
}
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
void FramebufferManagerGLES::EndFrame() {
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
if (resized_) {
|
||||
// TODO: Only do this if the new size actually changed the renderwidth/height.
|
||||
DestroyAllFBOs(false);
|
||||
@ -1230,6 +1243,7 @@ void FramebufferManagerGLES::EndFrame() {
|
||||
}
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
void FramebufferManagerGLES::DeviceLost() {
|
||||
@ -1258,6 +1272,7 @@ std::vector<FramebufferInfo> FramebufferManagerGLES::GetFramebufferList() {
|
||||
}
|
||||
|
||||
void FramebufferManagerGLES::DestroyAllFBOs(bool forceDelete) {
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
currentRenderVfb_ = 0;
|
||||
displayFramebuf_ = 0;
|
||||
@ -1284,6 +1299,7 @@ void FramebufferManagerGLES::DestroyAllFBOs(bool forceDelete) {
|
||||
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
DisableState();
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
void FramebufferManagerGLES::FlushBeforeCopy() {
|
||||
@ -1295,6 +1311,7 @@ void FramebufferManagerGLES::FlushBeforeCopy() {
|
||||
// do something more focused here.
|
||||
SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason);
|
||||
drawEngine_->Flush();
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
void FramebufferManagerGLES::Resized() {
|
||||
@ -1343,6 +1360,7 @@ bool FramebufferManagerGLES::GetFramebuffer(u32 fb_address, int fb_stride, GEBuf
|
||||
|
||||
// We may have blitted to a temp FBO.
|
||||
RebindFramebuffer();
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1354,6 +1372,7 @@ bool FramebufferManagerGLES::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
|
||||
buffer.Allocate(pw, ph, GPU_DBG_FORMAT_888_RGB, true);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
SafeGLReadPixels(0, 0, pw, ph, GL_RGB, GL_UNSIGNED_BYTE, buffer.GetData());
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1384,7 +1403,7 @@ bool FramebufferManagerGLES::GetDepthbuffer(u32 fb_address, int fb_stride, u32 z
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
||||
SafeGLReadPixels(0, 0, vfb->renderWidth, vfb->renderHeight, GL_DEPTH_COMPONENT, GL_FLOAT, buffer.GetData());
|
||||
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1409,7 +1428,7 @@ bool FramebufferManagerGLES::GetStencilbuffer(u32 fb_address, int fb_stride, GPU
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 2);
|
||||
SafeGLReadPixels(0, 0, vfb->renderWidth, vfb->renderHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, buffer.GetData());
|
||||
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/timeutil.h"
|
||||
#include "gfx/gl_debug_log.h"
|
||||
#include "i18n/i18n.h"
|
||||
#include "math/math_util.h"
|
||||
#include "math/lin/matrix4x4.h"
|
||||
@ -80,6 +81,7 @@ Shader::Shader(const char *code, uint32_t glShaderType, bool useHWTransform)
|
||||
} else {
|
||||
DEBUG_LOG(G3D, "Compiled shader:\n%s\n", (const char *)code);
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
Shader::~Shader() {
|
||||
@ -313,6 +315,7 @@ LinkedShader::LinkedShader(ShaderID VSID, Shader *vs, ShaderID FSID, Shader *fs,
|
||||
|
||||
// The rest, use the "dirty" mechanism.
|
||||
dirtyUniforms = DIRTY_ALL_UNIFORMS;
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
LinkedShader::~LinkedShader() {
|
||||
@ -435,6 +438,8 @@ void LinkedShader::stop() {
|
||||
}
|
||||
|
||||
void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid) {
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
|
||||
u64 dirty = dirtyUniforms & availableUniforms;
|
||||
dirtyUniforms = 0;
|
||||
if (!dirty)
|
||||
@ -743,6 +748,7 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid) {
|
||||
if (dirty & DIRTY_SPLINETYPEV)
|
||||
glUniform1i(u_spline_type_v, gstate_c.spline_type_v);
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
ShaderManagerGLES::ShaderManagerGLES()
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "StateMappingGLES.h"
|
||||
#include "profiler/profiler.h"
|
||||
#include "gfx/gl_debug_log.h"
|
||||
|
||||
#include "GPU/Math3D.h"
|
||||
#include "GPU/GPUState.h"
|
||||
@ -344,6 +345,7 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
|
||||
if (vpAndScissor.dirtyDepth) {
|
||||
gstate_c.Dirty(DIRTY_DEPTHRANGE);
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
void DrawEngineGLES::ApplyDrawStateLate() {
|
||||
@ -351,9 +353,11 @@ void DrawEngineGLES::ApplyDrawStateLate() {
|
||||
// TODO: Set the nearest/linear here (since we correctly know if alpha/color tests are needed)?
|
||||
if (!gstate.isModeClear()) {
|
||||
if (fboTexNeedBind_) {
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
// Note that this is positions, not UVs, that we need the copy from.
|
||||
framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY);
|
||||
framebufferManager_->RebindFramebuffer();
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
// If we are rendering at a higher resolution, linear is probably best for the dest color.
|
||||
@ -362,15 +366,19 @@ void DrawEngineGLES::ApplyDrawStateLate() {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
fboTexBound_ = true;
|
||||
fboTexNeedBind_ = false;
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
|
||||
// Apply the texture after the FBO tex, since it might unbind the texture.
|
||||
// TODO: Could use a separate texture unit to be safer?
|
||||
textureCache_->ApplyTexture();
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
|
||||
// Apply last, once we know the alpha params of the texture.
|
||||
if (gstate.isAlphaTestEnabled() || gstate.isColorTestEnabled()) {
|
||||
fragmentTestCache_->BindTestTexture(GL_TEXTURE2);
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "ext/xxhash.h"
|
||||
#include "gfx/gl_debug_log.h"
|
||||
#include "i18n/i18n.h"
|
||||
#include "math/math_util.h"
|
||||
#include "profiler/profiler.h"
|
||||
@ -121,6 +122,7 @@ static const GLuint MagFiltGL[2] = {
|
||||
|
||||
// This should not have to be done per texture! OpenGL is silly yo
|
||||
void TextureCacheGLES::UpdateSamplingParams(TexCacheEntry &entry, bool force) {
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
int minFilt;
|
||||
int magFilt;
|
||||
bool sClamp;
|
||||
@ -172,6 +174,7 @@ void TextureCacheGLES::UpdateSamplingParams(TexCacheEntry &entry, bool force) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, tClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT);
|
||||
entry.tClamp = tClamp;
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
void TextureCacheGLES::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight) {
|
||||
@ -325,11 +328,14 @@ bool SetDebugTexture() {
|
||||
#endif
|
||||
|
||||
void TextureCacheGLES::BindTexture(TexCacheEntry *entry) {
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
if (entry->textureName != lastBoundTexture) {
|
||||
glBindTexture(GL_TEXTURE_2D, entry->textureName);
|
||||
lastBoundTexture = entry->textureName;
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
UpdateSamplingParams(*entry, false);
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
void TextureCacheGLES::Unbind() {
|
||||
@ -514,6 +520,8 @@ void TextureCacheGLES::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFram
|
||||
framebufferManagerGL_->RebindFramebuffer();
|
||||
SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight);
|
||||
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
|
||||
lastBoundTexture = INVALID_TEX;
|
||||
}
|
||||
|
||||
@ -675,7 +683,7 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry, bool replaceImag
|
||||
LoadTextureLevel(*entry, replaced, level, replaceImages, scaleFactor, dstFmt);
|
||||
} else
|
||||
LoadTextureLevel(*entry, replaced, 0, replaceImages, scaleFactor, dstFmt);
|
||||
|
||||
|
||||
// Mipmapping only enable when texture scaling disable
|
||||
if (maxLevel > 0 && scaleFactor == 1) {
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_TEXTURE_LOD_CONTROL)) {
|
||||
@ -721,6 +729,7 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry, bool replaceImag
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
//glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
u32 TextureCacheGLES::AllocTextureName() {
|
||||
@ -806,6 +815,8 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r
|
||||
bool useBGRA;
|
||||
u32 *pixelData;
|
||||
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
|
||||
// TODO: only do this once
|
||||
u32 texByteAlign = 1;
|
||||
|
||||
@ -871,6 +882,8 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, texByteAlign);
|
||||
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
|
||||
GLuint components = dstFmt == GL_UNSIGNED_SHORT_5_6_5 ? GL_RGB : GL_RGBA;
|
||||
|
||||
GLuint components2 = components;
|
||||
@ -888,6 +901,7 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r
|
||||
else
|
||||
glTexImage2D(GL_TEXTURE_2D, level, components, w, h, 0, components2, dstFmt, pixelData);
|
||||
if (!lowMemoryMode_) {
|
||||
// TODO: We really, really should avoid calling glGetError.
|
||||
GLenum err = glGetError();
|
||||
if (err == GL_OUT_OF_MEMORY) {
|
||||
WARN_LOG_REPORT(G3D, "Texture cache ran out of GPU memory; switching to low memory mode");
|
||||
@ -911,7 +925,9 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r
|
||||
case GL_INVALID_VALUE: str = "invalid_value"; break;
|
||||
}
|
||||
// We checked the err anyway, might as well log if there is one.
|
||||
WARN_LOG(G3D, "Got an error in texture upload: %08x (%s) (components=%04x components2=%04x dstFmt=%04x w=%d h=%d level=%d)", err, str, components, components2, dstFmt, w, h, level);
|
||||
WARN_LOG(G3D, "Got an error in texture upload: %08x (%s) (components=%s components2=%s dstFmt=%s w=%d h=%d level=%d)",
|
||||
err, str, GLEnumToString(components).c_str(), GLEnumToString(components2).c_str(), GLEnumToString(dstFmt).c_str(),
|
||||
w, h, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ VkSampler SamplerCache::GetOrCreateSampler(const SamplerCacheKey &key) {
|
||||
VkSamplerCreateInfo samp = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
|
||||
samp.addressModeU = key.sClamp ? VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE : VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samp.addressModeV = key.tClamp ? VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE : VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samp.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samp.addressModeW = samp.addressModeU; // irrelevant, but Mali recommends that all clamp modes are the same if possible.
|
||||
samp.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
|
||||
samp.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||
samp.flags = 0;
|
||||
|
@ -1,54 +1,40 @@
|
||||
#include "gfx/gl_common.h"
|
||||
#include "base/logging.h"
|
||||
#include <cstdlib>
|
||||
|
||||
void glCheckzor(const char *file, int line) {
|
||||
GLenum err = glGetError();
|
||||
if (err != GL_NO_ERROR) {
|
||||
ELOG("GL error on line %i in %s: %i (%04x)", line, file, (int)err, (int)err);
|
||||
#include "base/logging.h"
|
||||
#include "gfx/gl_common.h"
|
||||
#include "gfx/gl_debug_log.h"
|
||||
|
||||
// This we can expand as needed.
|
||||
std::string GLEnumToString(uint16_t value) {
|
||||
char str[64];
|
||||
switch (value) {
|
||||
case GL_UNSIGNED_SHORT_4_4_4_4: return "GL_UNSIGNED_SHORT_4_4_4_4";
|
||||
case GL_UNSIGNED_SHORT_5_5_5_1: return "GL_UNSIGNED_SHORT_5_5_5_1";
|
||||
case GL_UNSIGNED_SHORT_5_6_5: return "GL_UNSIGNED_SHORT_5_6_5";
|
||||
case GL_RGBA: return "GL_RGBA";
|
||||
case GL_RGB: return "GL_RGB";
|
||||
#if !defined(USING_GLES2)
|
||||
case GL_BGRA: return "GL_BGRA";
|
||||
case GL_UNSIGNED_SHORT_4_4_4_4_REV: return "GL_UNSIGNED_SHORT_4_4_4_4_REV";
|
||||
case GL_UNSIGNED_SHORT_5_6_5_REV: return "GL_UNSIGNED_SHORT_5_6_5_REV";
|
||||
case GL_UNSIGNED_SHORT_1_5_5_5_REV: return "GL_UNSIGNED_SHORT_1_5_5_5_REV";
|
||||
case GL_UNSIGNED_INT_8_8_8_8_REV: return "GL_UNSIGNED_INT_8_8_8_8_REV";
|
||||
#endif
|
||||
case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
|
||||
case GL_PACK_ALIGNMENT: return "GL_PACK_ALIGNMENT";
|
||||
case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
|
||||
case GL_INVALID_VALUE: return "GL_INVALID_VALUE";
|
||||
case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
|
||||
default: {
|
||||
snprintf(str, sizeof(str), "(unk:%04x)", value);
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(USING_GLES2)
|
||||
#if 0
|
||||
void log_callback(GLenum source, GLenum type,
|
||||
GLuint id,
|
||||
GLenum severity,
|
||||
GLsizei length,
|
||||
const GLchar* message,
|
||||
GLvoid* userParam) {
|
||||
const char *src = "unknown";
|
||||
switch (source) {
|
||||
case GL_DEBUG_SOURCE_API_GL_ARB:
|
||||
src = "GL";
|
||||
break;
|
||||
case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
|
||||
src = "GLSL";
|
||||
break;
|
||||
case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
|
||||
src = "X";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (type) {
|
||||
case GL_DEBUG_TYPE_ERROR_ARB:
|
||||
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
|
||||
ELOG("%s: %s", src, message);
|
||||
break;
|
||||
default:
|
||||
ILOG("%s: %s", src, message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void gl_log_enable() {
|
||||
#if !defined(USING_GLES2)
|
||||
#if 0
|
||||
glEnable(DEBUG_OUTPUT_SYNCHRONOUS_ARB); // TODO: Look into disabling, for more perf
|
||||
glDebugMessageCallback(&log_callback, 0);
|
||||
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE);
|
||||
#endif
|
||||
#endif
|
||||
void CheckGLError(const char *file, int line) {
|
||||
GLenum err = glGetError();
|
||||
if (err != GL_NO_ERROR) {
|
||||
ELOG("GL error %s on %s:%d", GLEnumToString(err).c_str(), file, line);
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
// Utility to be able to liberally sprinkle GL error checks around your code
|
||||
// and easily disable them all in release builds - just undefine DEBUG_OPENGL.
|
||||
|
||||
|
||||
void gl_log_enable();
|
||||
|
||||
#if !defined(USING_GLES2)
|
||||
//#define DEBUG_OPENGL
|
||||
#endif
|
||||
// #define DEBUG_OPENGL
|
||||
|
||||
#if defined(DEBUG_OPENGL)
|
||||
|
||||
void glCheckzor(const char *file, int line);
|
||||
#define GL_CHECK() glCheckzor(__FILE__, __LINE__)
|
||||
void CheckGLError(const char *file, int line);
|
||||
#define CHECK_GL_ERROR_IF_DEBUG() CheckGLError(__FILE__, __LINE__)
|
||||
|
||||
#else
|
||||
|
||||
#define GL_CHECK()
|
||||
#define CHECK_GL_ERROR_IF_DEBUG()
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
std::string GLEnumToString(uint16_t value);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "math/lin/matrix4x4.h"
|
||||
#include "thin3d/thin3d.h"
|
||||
#include "gfx/gl_common.h"
|
||||
#include "gfx/gl_debug_log.h"
|
||||
#include "gfx/GLStateCache.h"
|
||||
#include "gfx_es2/gpu_features.h"
|
||||
#include "gfx/gl_lost_manager.h"
|
||||
@ -754,6 +755,7 @@ void OpenGLTexture::SetImageData(int x, int y, int z, int width, int height, int
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
switch (target_) {
|
||||
case GL_TEXTURE_2D:
|
||||
glTexImage2D(GL_TEXTURE_2D, level, internalFormat, width_, height_, 0, format, type, data);
|
||||
@ -762,11 +764,7 @@ void OpenGLTexture::SetImageData(int x, int y, int z, int width, int height, int
|
||||
ELOG("Thin3D GL: Targets other than GL_TEXTURE_2D not yet supported");
|
||||
break;
|
||||
}
|
||||
|
||||
GLenum err2 = glGetError();
|
||||
if (err2) {
|
||||
ELOG("Thin3D GL: Error loading texture: %08x", err2);
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
Texture *OpenGLContext::CreateTexture(const TextureDesc &desc) {
|
||||
@ -1336,6 +1334,7 @@ Framebuffer *OpenGLContext::CreateFramebuffer(const FramebufferDesc &desc) {
|
||||
}
|
||||
// If GLES2, we have basic FBO support and can just proceed.
|
||||
#endif
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
|
||||
OpenGLFramebuffer *fbo = new OpenGLFramebuffer();
|
||||
fbo->width = desc.width;
|
||||
@ -1444,6 +1443,7 @@ Framebuffer *OpenGLContext::CreateFramebuffer(const FramebufferDesc &desc) {
|
||||
// Unbind state we don't need
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
|
||||
currentDrawHandle_ = fbo->handle;
|
||||
currentReadHandle_ = fbo->handle;
|
||||
@ -1512,16 +1512,20 @@ void OpenGLContext::BindFramebufferAsRenderTarget(Framebuffer *fbo) {
|
||||
fbo_bind_fb_target(false, fb->handle);
|
||||
// Always restore viewport after render target binding
|
||||
glstate.viewport.restore();
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
void OpenGLContext::BindBackbufferAsRenderTarget() {
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
fbo_unbind();
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
// For GL_EXT_FRAMEBUFFER_BLIT and similar.
|
||||
void OpenGLContext::BindFramebufferForRead(Framebuffer *fbo) {
|
||||
OpenGLFramebuffer *fb = (OpenGLFramebuffer *)fbo;
|
||||
fbo_bind_fb_target(true, fb->handle);
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
void OpenGLContext::CopyFramebufferImage(Framebuffer *fbsrc, int srcLevel, int srcX, int srcY, int srcZ, Framebuffer *fbdst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits) {
|
||||
@ -1562,6 +1566,7 @@ void OpenGLContext::CopyFramebufferImage(Framebuffer *fbsrc, int srcLevel, int s
|
||||
width, height, depth);
|
||||
}
|
||||
#endif
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
||||
bool OpenGLContext::BlitFramebuffer(Framebuffer *fbsrc, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *fbdst, int dstX1, int dstY1, int dstX2, int dstY2, int channels, FBBlitFilter linearFilter) {
|
||||
@ -1578,10 +1583,12 @@ bool OpenGLContext::BlitFramebuffer(Framebuffer *fbsrc, int srcX1, int srcY1, in
|
||||
BindFramebufferForRead(src);
|
||||
if (gl_extensions.GLES3 || gl_extensions.ARB_framebuffer_object) {
|
||||
glBlitFramebuffer(srcX1, srcY1, srcX2, srcY2, dstX1, dstY1, dstX2, dstY2, bits, linearFilter == FB_BLIT_LINEAR ? GL_LINEAR : GL_NEAREST);
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
#if defined(USING_GLES2) && defined(__ANDROID__) // We only support this extension on Android, it's not even available on PC.
|
||||
return true;
|
||||
} else if (gl_extensions.NV_framebuffer_blit) {
|
||||
glBlitFramebufferNV(srcX1, srcY1, srcX2, srcY2, dstX1, dstY1, dstX2, dstY2, bits, linearFilter == FB_BLIT_LINEAR ? GL_LINEAR : GL_NEAREST);
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
#endif // defined(USING_GLES2) && defined(__ANDROID__)
|
||||
return true;
|
||||
} else {
|
||||
@ -1590,8 +1597,13 @@ bool OpenGLContext::BlitFramebuffer(Framebuffer *fbsrc, int srcX1, int srcY1, in
|
||||
}
|
||||
|
||||
uintptr_t OpenGLContext::GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) {
|
||||
// Unimplemented
|
||||
return 0;
|
||||
OpenGLFramebuffer *fb = (OpenGLFramebuffer *)fbo;
|
||||
switch (channelBits) {
|
||||
case FB_COLOR_BIT: return (uintptr_t)fb->color_texture;
|
||||
case FB_DEPTH_BIT: return (uintptr_t)(fb->z_buffer ? fb->z_buffer : fb->z_stencil_buffer);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int color) {
|
||||
@ -1612,6 +1624,7 @@ void OpenGLContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBCh
|
||||
}
|
||||
|
||||
OpenGLFramebuffer::~OpenGLFramebuffer() {
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, handle);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user