From 46e1fbb78856c8304fbf3d4d820134462959507e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 19 Nov 2017 18:22:46 +0100 Subject: [PATCH] Initial texture work. Bugfix indexed drawing --- GPU/Common/TextureCacheCommon.cpp | 2 +- GPU/GLES/DrawEngineGLES.cpp | 17 ++-- GPU/GLES/FramebufferManagerGLES.cpp | 109 +++++++++---------------- GPU/GLES/GPU_GLES.cpp | 3 - GPU/GLES/TextureCacheGLES.cpp | 111 +++++++------------------- GPU/GLES/TextureCacheGLES.h | 7 +- ext/native/thin3d/GLRenderManager.cpp | 4 +- ext/native/thin3d/GLRenderManager.h | 12 +-- ext/native/thin3d/thin3d_gl.cpp | 3 +- 9 files changed, 91 insertions(+), 177 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index bcfa89ed31..75f9a5d14c 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -383,7 +383,7 @@ void TextureCacheCommon::SetTexture(bool force) { // Exponential backoff up to 512 frames. Textures are often reused. if (entry->numFrames > 32) { // Also, try to add some "randomness" to avoid rehashing several textures the same frame. - entry->framesUntilNextFullHash = std::min(512, entry->numFrames) + (((intptr_t)entry->textureName >> 8) & 15); + entry->framesUntilNextFullHash = std::min(512, entry->numFrames) + (((intptr_t)(entry->textureName) >> 12) & 15); } else { entry->framesUntilNextFullHash = entry->numFrames; } diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index d05489dd92..b7303b05dc 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -181,8 +181,8 @@ void DrawEngineGLES::InitDeviceObjects() { } for (int i = 0; i < GLRenderManager::MAX_INFLIGHT_FRAMES; i++) { - frameData_[i].pushVertex = new GLPushBuffer(render_, 1024 * 1024); - frameData_[i].pushIndex = new GLPushBuffer(render_, 512 * 1024); + frameData_[i].pushVertex = new GLPushBuffer(render_, GL_ARRAY_BUFFER, 1024 * 1024); + frameData_[i].pushIndex = new GLPushBuffer(render_, GL_ELEMENT_ARRAY_BUFFER, 512 * 1024); } int vertexSize = sizeof(TransformedVertex); @@ -695,14 +695,7 @@ rotateVBO: } ApplyDrawStateLate(); - - if (gstate_c.Supports(GPU_SUPPORTS_VAO) && vbo == 0) { - vbo = BindBuffer(decoded, dec_->GetDecVtxFmt().stride * indexGen.MaxIndex()); - if (useElements) { - ebo = BindElementBuffer(decIndex, sizeof(short) * indexGen.VertexCount()); - } - } - + LinkedShader *program = shaderManager_->ApplyFragmentShader(vsid, vshader, lastVType_, prim); GLRInputLayout *inputLayout = SetupDecFmtForDraw(program, dec_->GetDecVtxFmt()); render_->BindVertexBuffer(vertexBuffer); @@ -777,10 +770,10 @@ rotateVBO: if (drawIndexed) { vertexBufferOffset = (uint32_t)frameData.pushVertex->Push(drawBuffer, maxIndex * sizeof(TransformedVertex), &vertexBuffer); indexBufferOffset = (uint32_t)frameData.pushIndex->Push(decIndex, sizeof(uint16_t) * indexGen.VertexCount(), &indexBuffer); - render_->BindIndexBuffer(indexBuffer); render_->BindVertexBuffer(vertexBuffer); render_->BindInputLayout(softwareInputLayout_, (void *)(intptr_t)vertexBufferOffset); - render_->DrawIndexed(glprim[prim], numTrans, GL_UNSIGNED_SHORT, inds); + render_->BindIndexBuffer(indexBuffer); + render_->DrawIndexed(glprim[prim], numTrans, GL_UNSIGNED_SHORT, (void *)(intptr_t)indexBufferOffset); } else { vertexBufferOffset = (uint32_t)frameData.pushVertex->Push(drawBuffer, numTrans * sizeof(TransformedVertex), &vertexBuffer); render_->BindVertexBuffer(vertexBuffer); diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index fccf90b1f3..854a91e46c 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -347,65 +347,48 @@ void FramebufferManagerGLES::MakePixelTexture(const u8 *srcPixels, GEBufferForma // TODO: We can just change the texture format and flip some bits around instead of this. // Could share code with the texture cache perhaps. - bool useConvBuf = false; - if (srcPixelFormat != GE_FORMAT_8888 || srcStride != texWidth) { - useConvBuf = true; - u32 neededSize = texWidth * height * 4; - if (!convBuf_ || convBufSize_ < neededSize) { - delete [] convBuf_; - convBuf_ = new u8[neededSize]; - convBufSize_ = neededSize; - } - for (int y = 0; y < height; y++) { - switch (srcPixelFormat) { - case GE_FORMAT_565: - { - const u16 *src = (const u16 *)srcPixels + srcStride * y; - u8 *dst = convBuf_ + 4 * texWidth * y; - ConvertRGBA565ToRGBA8888((u32 *)dst, src, width); - } - break; - - case GE_FORMAT_5551: - { - const u16 *src = (const u16 *)srcPixels + srcStride * y; - u8 *dst = convBuf_ + 4 * texWidth * y; - ConvertRGBA5551ToRGBA8888((u32 *)dst, src, width); - } - break; - - case GE_FORMAT_4444: - { - const u16 *src = (const u16 *)srcPixels + srcStride * y; - u8 *dst = convBuf_ + 4 * texWidth * y; - ConvertRGBA4444ToRGBA8888((u32 *)dst, src, width); - } - break; - - case GE_FORMAT_8888: - { - const u8 *src = srcPixels + srcStride * 4 * y; - u8 *dst = convBuf_ + 4 * texWidth * y; - memcpy(dst, src, 4 * width); - } - break; - - case GE_FORMAT_INVALID: - _dbg_assert_msg_(G3D, false, "Invalid pixelFormat passed to DrawPixels()."); - break; + u32 neededSize = texWidth * height * 4; + u8 *convBuf = new u8[neededSize]; + for (int y = 0; y < height; y++) { + switch (srcPixelFormat) { + case GE_FORMAT_565: + { + const u16 *src = (const u16 *)srcPixels + srcStride * y; + u8 *dst = convBuf + 4 * texWidth * y; + ConvertRGBA565ToRGBA8888((u32 *)dst, src, width); } + break; + + case GE_FORMAT_5551: + { + const u16 *src = (const u16 *)srcPixels + srcStride * y; + u8 *dst = convBuf + 4 * texWidth * y; + ConvertRGBA5551ToRGBA8888((u32 *)dst, src, width); + } + break; + + case GE_FORMAT_4444: + { + const u16 *src = (const u16 *)srcPixels + srcStride * y; + u8 *dst = convBuf + 4 * texWidth * y; + ConvertRGBA4444ToRGBA8888((u32 *)dst, src, width); + } + break; + + case GE_FORMAT_8888: + { + const u8 *src = srcPixels + srcStride * 4 * y; + u8 *dst = convBuf + 4 * texWidth * y; + memcpy(dst, src, 4 * width); + } + break; + + case GE_FORMAT_INVALID: + _dbg_assert_msg_(G3D, false, "Invalid pixelFormat passed to DrawPixels()."); + break; } } - - // Try to skip uploading the unnecessary parts. - if (gstate_c.Supports(GPU_SUPPORTS_UNPACK_SUBIMAGE) && width != texWidth) { - glPixelStorei(GL_UNPACK_ROW_LENGTH, texWidth); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, useConvBuf ? convBuf_ : srcPixels); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, height, GL_RGBA, GL_UNSIGNED_BYTE, useConvBuf ? convBuf_ : srcPixels); - } - CHECK_GL_ERROR_IF_DEBUG(); + render_->TextureImage(drawPixelsTex_, 0, texWidth, height, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, convBuf); } void FramebufferManagerGLES::SetViewport2D(int x, int y, int w, int h) { @@ -979,20 +962,6 @@ void FramebufferManagerGLES::PackFramebufferSync_(VirtualFramebuffer *vfb, int x ConvertFromRGBA8888(dst, packed, vfb->fb_stride, packStride, packWidth, h, vfb->format); } } - - // TODO: Move this into Thin3d. - if (gl_extensions.GLES3 && glInvalidateFramebuffer != nullptr) { -#ifdef USING_GLES2 - // GLES3 doesn't support using GL_READ_FRAMEBUFFER here. - draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); - const GLenum target = GL_FRAMEBUFFER; -#else - const GLenum target = GL_READ_FRAMEBUFFER; -#endif - 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) { diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 594c980f05..8139f142ac 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -300,9 +300,6 @@ void GPU_GLES::CheckGPUFeatures() { if (gl_extensions.OES_texture_npot) features |= GPU_SUPPORTS_OES_TEXTURE_NPOT; - if (gl_extensions.EXT_unpack_subimage) - features |= GPU_SUPPORTS_UNPACK_SUBIMAGE; - if (gl_extensions.EXT_blend_minmax) features |= GPU_SUPPORTS_BLEND_MINMAX; diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index b841a32f23..43cbc96914 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -45,10 +45,6 @@ #include #endif -#ifndef GL_UNPACK_ROW_LENGTH -#define GL_UNPACK_ROW_LENGTH 0x0CF2 -#endif - TextureCacheGLES::TextureCacheGLES(Draw::DrawContext *draw) : TextureCacheCommon(draw) { timesInvalidatedAllThisFrame_ = 0; @@ -487,7 +483,7 @@ void TextureCacheGLES::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFram const u32 bytesPerColor = clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16); const u32 clutTotalColors = clutMaxBytes_ / bytesPerColor; - TexCacheEntry::TexStatus alphaStatus = CheckAlpha(clutBuf_, getClutDestFormat(clutFormat), clutTotalColors, clutTotalColors, 1); + TexCacheEntry::TexStatus alphaStatus = CheckAlpha((const uint8_t *)clutBuf_, getClutDestFormat(clutFormat), clutTotalColors, clutTotalColors, 1); gstate_c.SetTextureFullAlpha(alphaStatus == TexCacheEntry::STATUS_ALPHA_FULL); } else { entry->status &= ~TexCacheEntry::STATUS_DEPALETTIZE; @@ -674,35 +670,38 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry, bool replaceImag LoadTextureLevel(*entry, replaced, 0, replaceImages, scaleFactor, dstFmt); // Mipmapping only enable when texture scaling disable + int texMaxLevel = 0; if (maxLevel > 0 && scaleFactor == 1) { if (gstate_c.Supports(GPU_SUPPORTS_TEXTURE_LOD_CONTROL)) { if (badMipSizes) { // WARN_LOG(G3D, "Bad mipmap for texture sized %dx%dx%d - autogenerating", w, h, (int)format); if (canAutoGen) { - glGenerateMipmap(GL_TEXTURE_2D); + render_->GenerateMipmap(); } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + texMaxLevel = 0; maxLevel = 0; } } else { for (int i = 1; i <= maxLevel; i++) { LoadTextureLevel(*entry, replaced, i, replaceImages, scaleFactor, dstFmt); } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, maxLevel); + texMaxLevel = maxLevel; } } else { // Avoid PowerVR driver bug if (canAutoGen && w > 1 && h > 1 && !(h > w && (gl_extensions.bugs & BUG_PVR_GENMIPMAP_HEIGHT_GREATER))) { // Really! only seems to fail if height > width // NOTICE_LOG(G3D, "Generating mipmap for texture sized %dx%d%d", w, h, (int)format); - glGenerateMipmap(GL_TEXTURE_2D); + render_->GenerateMipmap(); } else { maxLevel = 0; } } } else if (gstate_c.Supports(GPU_SUPPORTS_TEXTURE_LOD_CONTROL)) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + texMaxLevel = 0; } + // TODO: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, texMaxLevel); + if (maxLevel == 0) { entry->status |= TexCacheEntry::STATUS_BAD_MIPS; } else { @@ -712,22 +711,8 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry, bool replaceImag entry->SetAlphaStatus(TexCacheEntry::TexStatus(replaced.AlphaStatus())); } - if (gstate_c.Supports(GPU_SUPPORTS_ANISOTROPY)) { - int aniso = 1 << g_Config.iAnisotropyLevel; - float anisotropyLevel = aniso; //(float) aniso > maxAnisotropyLevel ? maxAnisotropyLevel : (float) aniso; - if (anisotropyLevel > 1.0f) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropyLevel); - } - } - // This will rebind it, but that's okay. UpdateSamplingParams(*entry, true); - - //glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - //glPixelStorei(GL_PACK_ROW_LENGTH, 0); - glPixelStorei(GL_PACK_ALIGNMENT, 1); - CHECK_GL_ERROR_IF_DEBUG(); } GLenum TextureCacheGLES::GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const { @@ -752,7 +737,7 @@ GLenum TextureCacheGLES::GetDestFormat(GETextureFormat format, GEPaletteFormat c } } -void *TextureCacheGLES::DecodeTextureLevelOld(GETextureFormat format, GEPaletteFormat clutformat, int level, GLenum dstFmt, int scaleFactor, int *bufwout) { +u8 *TextureCacheGLES::DecodeTextureLevelOld(GETextureFormat format, GEPaletteFormat clutformat, int level, GLenum dstFmt, int scaleFactor, int *bufwout) { void *finalBuf = nullptr; u32 texaddr = gstate.getTextureAddress(level); int bufw = GetTextureBufw(level, texaddr, format); @@ -770,26 +755,26 @@ void *TextureCacheGLES::DecodeTextureLevelOld(GETextureFormat format, GEPaletteF decPitch = bufw * pixelSize; } - tmpTexBufRearrange_.resize(std::max(w, bufw) * h); - DecodeTextureLevel((u8 *)tmpTexBufRearrange_.data(), decPitch, format, clutformat, texaddr, level, bufw, true, false, false); - return tmpTexBufRearrange_.data(); + uint8_t *texBuf = new uint8_t[std::max(w, bufw) * h * pixelSize]; + DecodeTextureLevel(texBuf, decPitch, format, clutformat, texaddr, level, bufw, true, false, false); + return texBuf; } -TexCacheEntry::TexStatus TextureCacheGLES::CheckAlpha(const u32 *pixelData, GLenum dstFmt, int stride, int w, int h) { +TexCacheEntry::TexStatus TextureCacheGLES::CheckAlpha(const uint8_t *pixelData, GLenum dstFmt, int stride, int w, int h) { CheckAlphaResult res; switch (dstFmt) { case GL_UNSIGNED_SHORT_4_4_4_4: - res = CheckAlphaABGR4444Basic(pixelData, stride, w, h); + res = CheckAlphaABGR4444Basic((const uint32_t *)pixelData, stride, w, h); break; case GL_UNSIGNED_SHORT_5_5_5_1: - res = CheckAlphaABGR1555Basic(pixelData, stride, w, h); + res = CheckAlphaABGR1555Basic((const uint32_t *)pixelData, stride, w, h); break; case GL_UNSIGNED_SHORT_5_6_5: // Never has any alpha. res = CHECKALPHA_FULL; break; default: - res = CheckAlphaRGBA8888Basic(pixelData, stride, w, h); + res = CheckAlphaRGBA8888Basic((const uint32_t *)pixelData, stride, w, h); break; } @@ -800,7 +785,7 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r int w = gstate.getTextureWidth(level); int h = gstate.getTextureHeight(level); bool useUnpack = false; - u32 *pixelData; + uint8_t *pixelData; CHECK_GL_ERROR_IF_DEBUG(); @@ -812,10 +797,10 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r if (replaced.GetSize(level, w, h)) { PROFILE_THIS_SCOPE("replacetex"); - tmpTexBufRearrange_.resize(w * h); int bpp = replaced.Format(level) == ReplacedTextureFormat::F_8888 ? 4 : 2; - replaced.Load(level, tmpTexBufRearrange_.data(), bpp * w); - pixelData = tmpTexBufRearrange_.data(); + uint8_t *rearrange = new uint8_t[w * h * bpp]; + replaced.Load(level, rearrange, bpp * w); + pixelData = rearrange; dstFmt = ToGLESFormat(replaced.Format(level)); @@ -825,20 +810,14 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r GEPaletteFormat clutformat = gstate.getClutPaletteFormat(); int bufw; - void *finalBuf = DecodeTextureLevelOld(GETextureFormat(entry.format), clutformat, level, dstFmt, scaleFactor, &bufw); - if (finalBuf == NULL) { + uint8_t *finalBuf = DecodeTextureLevelOld(GETextureFormat(entry.format), clutformat, level, dstFmt, scaleFactor, &bufw); + if (!finalBuf) { return; } - // Can restore these and remove the fixup at the end of DecodeTextureLevel on desktop GL and GLES 3. - if (scaleFactor == 1 && gstate_c.Supports(GPU_SUPPORTS_UNPACK_SUBIMAGE) && w != bufw) { - glPixelStorei(GL_UNPACK_ROW_LENGTH, bufw); - useUnpack = true; - } - // Textures are always aligned to 16 bytes bufw, so this could safely be 4 always. texByteAlign = dstFmt == GL_UNSIGNED_BYTE ? 4 : 2; - pixelData = (u32 *)finalBuf; + pixelData = finalBuf; // We check before scaling since scaling shouldn't invent alpha from a full alpha texture. if ((entry.status & TexCacheEntry::STATUS_CHANGE_FREQUENT) == 0) { @@ -848,8 +827,9 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r entry.SetAlphaStatus(TexCacheEntry::STATUS_ALPHA_UNKNOWN); } - if (scaleFactor > 1) - scaler.Scale(pixelData, dstFmt, w, h, scaleFactor); + // TODO: Scale's buffer management doesn't work. + //if (scaleFactor > 1) + // scaler.Scale((uint32_t *)pixelData, dstFmt, w, h, scaleFactor); if (replacer_.Enabled()) { ReplacedTextureDecodeInfo replacedInfo; @@ -866,8 +846,6 @@ 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; @@ -876,7 +854,8 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r if (replaceImages) { PROFILE_THIS_SCOPE("repltex"); - glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, w, h, components2, dstFmt, pixelData); + Crash(); + // glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, w, h, components2, dstFmt, pixelData); } else { PROFILE_THIS_SCOPE("loadtex"); // Avoid misleading errors in texture upload, these are common. @@ -885,37 +864,9 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r WARN_LOG(G3D, "Got an error BEFORE texture upload: %08x (%s)", err, GLEnumToString(err).c_str()); } if (IsFakeMipmapChange()) - glTexImage2D(GL_TEXTURE_2D, 0, components, w, h, 0, components2, dstFmt, pixelData); + render_->TextureImage(entry.textureName, 0, w, h, components, components2, dstFmt, pixelData); 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"); - lowMemoryMode_ = true; - decimationCounter_ = 0; - Decimate(); - // Try again, now that we've cleared out textures in lowMemoryMode_. - glTexImage2D(GL_TEXTURE_2D, level, components, w, h, 0, components2, dstFmt, pixelData); - - I18NCategory *err = GetI18NCategory("Error"); - if (scaleFactor > 1) { - host->NotifyUserMessage(err->T("Warning: Video memory FULL, reducing upscaling and switching to slow caching mode"), 2.0f); - } else { - host->NotifyUserMessage(err->T("Warning: Video memory FULL, switching to slow caching mode"), 2.0f); - } - } else if (err != GL_NO_ERROR) { - // 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=%s components2=%s dstFmt=%s w=%d h=%d level=%d)", - err, GLEnumToString(err).c_str(), GLEnumToString(components).c_str(), GLEnumToString(components2).c_str(), GLEnumToString(dstFmt).c_str(), - w, h, level); - } - } - } - - if (useUnpack) { - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + render_->TextureImage(entry.textureName, level, w, h, components, components2, dstFmt, pixelData); } } diff --git a/GPU/GLES/TextureCacheGLES.h b/GPU/GLES/TextureCacheGLES.h index 559ccf7720..dcefcfb700 100644 --- a/GPU/GLES/TextureCacheGLES.h +++ b/GPU/GLES/TextureCacheGLES.h @@ -80,8 +80,11 @@ private: void UpdateSamplingParams(TexCacheEntry &entry, bool force); void LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &replaced, int level, bool replaceImages, int scaleFactor, GLenum dstFmt); GLenum GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const; - void *DecodeTextureLevelOld(GETextureFormat format, GEPaletteFormat clutformat, int level, GLenum dstFmt, int scaleFactor, int *bufw = 0); - TexCacheEntry::TexStatus CheckAlpha(const u32 *pixelData, GLenum dstFmt, int stride, int w, int h); + + // Caller owns the returned buffer. Delete[]. + u8 *DecodeTextureLevelOld(GETextureFormat format, GEPaletteFormat clutformat, int level, GLenum dstFmt, int scaleFactor, int *bufw = 0); + + TexCacheEntry::TexStatus CheckAlpha(const uint8_t *pixelData, GLenum dstFmt, int stride, int w, int h); void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) override; void ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) override; diff --git a/ext/native/thin3d/GLRenderManager.cpp b/ext/native/thin3d/GLRenderManager.cpp index 301418449d..167359eaeb 100644 --- a/ext/native/thin3d/GLRenderManager.cpp +++ b/ext/native/thin3d/GLRenderManager.cpp @@ -352,7 +352,7 @@ void GLRenderManager::Wipe() { steps_.clear(); } -GLPushBuffer::GLPushBuffer(GLRenderManager *render, size_t size) : render_(render), buf_(0), offset_(0), size_(size), writePtr_(nullptr) { +GLPushBuffer::GLPushBuffer(GLRenderManager *render, GLuint target, size_t size) : render_(render), target_(target), size_(size) { bool res = AddBuffer(); assert(res); } @@ -383,7 +383,7 @@ void GLPushBuffer::Unmap() { bool GLPushBuffer::AddBuffer() { BufInfo info; info.deviceMemory = new uint8_t[size_]; - info.buffer = render_->CreateBuffer(GL_ARRAY_BUFFER, size_, GL_DYNAMIC_DRAW); + info.buffer = render_->CreateBuffer(target_, size_, GL_DYNAMIC_DRAW); buf_ = buffers_.size(); buffers_.resize(buf_ + 1); buffers_[buf_] = info; diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index 4c08c36e05..616f932986 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -289,6 +289,7 @@ public: initSteps_.push_back(step); } + // Takes ownership over the data pointer and delete[]-s it. void TextureImage(GLRTexture *texture, int level, int width, int height, GLenum internalFormat, GLenum format, GLenum type, uint8_t *data, bool linearFilter = false) { GLRInitStep step{ GLRInitStepType::TEXTURE_IMAGE }; step.texture_image.texture = texture; @@ -603,7 +604,7 @@ public: }; public: - GLPushBuffer(GLRenderManager *render, size_t size); + GLPushBuffer(GLRenderManager *render, GLuint target, size_t size); ~GLPushBuffer(); void Destroy(); @@ -691,8 +692,9 @@ private: GLRenderManager *render_; std::vector buffers_; - size_t buf_; - size_t offset_; - size_t size_; - uint8_t *writePtr_; + size_t buf_ = 0; + size_t offset_ = 0; + size_t size_ = 0; + uint8_t *writePtr_ = nullptr; + GLuint target_; }; diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index 33a890d90d..751e839e22 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -539,7 +539,7 @@ OpenGLContext::OpenGLContext() { break; } for (int i = 0; i < GLRenderManager::MAX_INFLIGHT_FRAMES; i++) { - frameData_[i].push = new GLPushBuffer(&renderManager_, 64 * 1024); + frameData_[i].push = new GLPushBuffer(&renderManager_, GL_ARRAY_BUFFER, 64 * 1024); } } @@ -1164,7 +1164,6 @@ void OpenGLContext::DrawUP(const void *vdata, int vertexCount) { renderManager_.BindInputLayout(curPipeline_->inputLayout->inputLayout_, (void *)offset); renderManager_.Draw(curPipeline_->prim, 0, vertexCount); - renderManager_.BindVertexBuffer(nullptr); #else ApplySamplers(); renderManager_.BindInputLayout(curPipeline_->inputLayout->inputLayout_, (void *)vdata);