From ccdb4d186d9d82dc7979c4aadb6e91edb4560f4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 20 Jan 2018 00:05:59 +0100 Subject: [PATCH] gl-render-manager: Fix HW tesselation. Remove 1D texture support, likely no benefit. --- GPU/Common/DrawEngineCommon.h | 1 + GPU/GLES/DrawEngineGLES.cpp | 132 +++++++------------------ GPU/GLES/DrawEngineGLES.h | 10 +- GPU/GLES/GPU_GLES.cpp | 3 +- GPU/GLES/ShaderManagerGLES.cpp | 12 +-- GPU/GLES/TextureCacheGLES.cpp | 6 -- GPU/GLES/VertexShaderGeneratorGLES.cpp | 19 ++-- UI/GameSettingsScreen.cpp | 15 +-- ext/native/gfx_es2/gpu_features.cpp | 2 + ext/native/gfx_es2/gpu_features.h | 2 + ext/native/thin3d/GLQueueRunner.cpp | 18 ++-- ext/native/thin3d/GLQueueRunner.h | 1 - 12 files changed, 80 insertions(+), 141 deletions(-) diff --git a/GPU/Common/DrawEngineCommon.h b/GPU/Common/DrawEngineCommon.h index 961e5dad5e..24599a094b 100644 --- a/GPU/Common/DrawEngineCommon.h +++ b/GPU/Common/DrawEngineCommon.h @@ -170,6 +170,7 @@ protected: colStride = 4; } virtual void SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) = 0; + virtual void EndFrame() {} }; TessellationDataTransfer *tessDataTransfer; }; diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 68257d3dce..77717aea19 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -133,7 +133,7 @@ DrawEngineGLES::DrawEngineGLES(Draw::DrawContext *draw) : vai_(256), draw_(draw) InitDeviceObjects(); - tessDataTransfer = new TessellationDataTransferGLES(gl_extensions.VersionGEThan(3, 0, 0)); + tessDataTransfer = new TessellationDataTransferGLES(render_); } DrawEngineGLES::~DrawEngineGLES() { @@ -211,6 +211,7 @@ void DrawEngineGLES::EndFrame() { FrameData &frameData = frameData_[render_->GetCurFrame()]; frameData.pushIndex->End(); frameData.pushVertex->End(); + tessDataTransfer->EndFrame(); } struct GlTypeInfo { @@ -761,7 +762,6 @@ rotateVBO: #ifndef MOBILE_DEVICE host->GPUNotifyDraw(); #endif - CHECK_GL_ERROR_IF_DEBUG(); } bool DrawEngineGLES::IsCodePtrVertexDecoder(const u8 *ptr) const { @@ -769,103 +769,45 @@ bool DrawEngineGLES::IsCodePtrVertexDecoder(const u8 *ptr) const { } void DrawEngineGLES::TessellationDataTransferGLES::SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) { - // TODO: Implement with the render manager - /* -#ifndef USING_GLES2 - if (isAllowTexture1D_) { - // Position - glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_1D, data_tex[0]); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (prevSize < size) { - glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, size, 0, GL_RGBA, GL_FLOAT, (GLfloat*)pos); - prevSize = size; - } else { - glTexSubImage1D(GL_TEXTURE_1D, 0, 0, size, GL_RGBA, GL_FLOAT, (GLfloat*)pos); - } + // Removed the 1D texture support, it's unlikely to be relevant for performance. + if (data_tex[0]) + renderManager_->DeleteTexture(data_tex[0]); + uint8_t *pos_data = new uint8_t[size * sizeof(float) * 4]; + memcpy(pos_data, pos, size * sizeof(float) * 4); + data_tex[0] = renderManager_->CreateTexture(GL_TEXTURE_2D); + renderManager_->TextureImage(data_tex[0], 0, size, 1, GL_RGBA32F, GL_RGBA, GL_FLOAT, pos_data, false); + renderManager_->FinalizeTexture(data_tex[0], 0, false); + renderManager_->BindTexture(4, data_tex[0]); - // Texcoords - if (hasTexCoords) { - glActiveTexture(GL_TEXTURE5); - glBindTexture(GL_TEXTURE_1D, data_tex[1]); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (prevSizeTex < size) { - glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, size, 0, GL_RGBA, GL_FLOAT, (GLfloat*)tex); - prevSizeTex = size; - } else { - glTexSubImage1D(GL_TEXTURE_1D, 0, 0, size, GL_RGBA, GL_FLOAT, (GLfloat*)tex); - } - } + // Texcoords + if (hasTexCoords) { + if (data_tex[1]) + renderManager_->DeleteTexture(data_tex[1]); + uint8_t *tex_data = new uint8_t[size * sizeof(float) * 4]; + memcpy(tex_data, pos, size * sizeof(float) * 4); + data_tex[1] = renderManager_->CreateTexture(GL_TEXTURE_2D); + renderManager_->TextureImage(data_tex[1], 0, size, 1, GL_RGBA32F, GL_RGBA, GL_FLOAT, tex_data, false); + renderManager_->FinalizeTexture(data_tex[1], 0, false); + renderManager_->BindTexture(5, data_tex[1]); + } - // Color - glActiveTexture(GL_TEXTURE6); - glBindTexture(GL_TEXTURE_1D, data_tex[2]); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - int sizeColor = hasColor ? size : 1; - if (prevSizeCol < sizeColor) { - glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, sizeColor, 0, GL_RGBA, GL_FLOAT, (GLfloat*)col); - prevSizeCol = sizeColor; - } else { - glTexSubImage1D(GL_TEXTURE_1D, 0, 0, sizeColor, GL_RGBA, GL_FLOAT, (GLfloat*)col); - } - } else -#endif - { - // Position - glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_2D, data_tex[0]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (prevSize < size) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, size, 1, 0, GL_RGBA, GL_FLOAT, (GLfloat*)pos); - prevSize = size; - } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, 1, GL_RGBA, GL_FLOAT, (GLfloat*)pos); - } + if (data_tex[2]) + renderManager_->DeleteTexture(data_tex[2]); + data_tex[2] = renderManager_->CreateTexture(GL_TEXTURE_2D); + int sizeColor = hasColor ? size : 1; + uint8_t *col_data = new uint8_t[sizeColor * sizeof(float) * 4]; + memcpy(col_data, col, sizeColor * sizeof(float) * 4); - // Texcoords - if (hasTexCoords) { - glActiveTexture(GL_TEXTURE5); - glBindTexture(GL_TEXTURE_2D, data_tex[1]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (prevSizeTex < size) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, size, 1, 0, GL_RGBA, GL_FLOAT, (GLfloat*)tex); - prevSizeTex = size; - } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, 1, GL_RGBA, GL_FLOAT, (GLfloat*)tex); - } - } + renderManager_->TextureImage(data_tex[2], 0, sizeColor, 1, GL_RGBA32F, GL_RGBA, GL_FLOAT, col_data, false); + renderManager_->FinalizeTexture(data_tex[2], 0, false); + renderManager_->BindTexture(6, data_tex[2]); +} - // Color - glActiveTexture(GL_TEXTURE6); - glBindTexture(GL_TEXTURE_2D, data_tex[2]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - int sizeColor = hasColor ? size : 1; - if (prevSizeCol < sizeColor) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, sizeColor, 1, 0, GL_RGBA, GL_FLOAT, (GLfloat*)col); - prevSizeCol = sizeColor; - } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, sizeColor, 1, GL_RGBA, GL_FLOAT, (GLfloat*)col); +void DrawEngineGLES::TessellationDataTransferGLES::EndFrame() { + for (int i = 0; i < 3; i++) { + if (data_tex[i]) { + renderManager_->DeleteTexture(data_tex[i]); + data_tex[i] = nullptr; } } - glActiveTexture(GL_TEXTURE0); - CHECK_GL_ERROR_IF_DEBUG(); - */ } diff --git a/GPU/GLES/DrawEngineGLES.h b/GPU/GLES/DrawEngineGLES.h index ea75d346e6..7fa9f1e816 100644 --- a/GPU/GLES/DrawEngineGLES.h +++ b/GPU/GLES/DrawEngineGLES.h @@ -202,10 +202,14 @@ private: class TessellationDataTransferGLES : public TessellationDataTransfer { private: GLRTexture *data_tex[3]{}; - bool isAllowTexture1D_; + GLRenderManager *renderManager_; public: - TessellationDataTransferGLES(bool isAllowTexture1D) : TessellationDataTransfer(), isAllowTexture1D_(isAllowTexture1D) { } - ~TessellationDataTransferGLES() { } + TessellationDataTransferGLES(GLRenderManager *renderManager) + : renderManager_(renderManager) { } + ~TessellationDataTransferGLES() { + EndFrame(); + } void SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) override; + void EndFrame() override; // Queues textures for deletion. }; }; diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 7887292baa..5417a24a87 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -316,8 +316,7 @@ void GPU_GLES::CheckGPUFeatures() { if (instanceRendering) features |= GPU_SUPPORTS_INSTANCE_RENDERING; - int maxVertexTextureImageUnits; - glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextureImageUnits); + int maxVertexTextureImageUnits = gl_extensions.maxVertexTextureUnits; if (maxVertexTextureImageUnits >= 3) // At least 3 for hardware tessellation features |= GPU_SUPPORTS_VERTEX_TEXTURE_FETCH; diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 4c10e61527..a33ce2b80c 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -168,12 +168,12 @@ LinkedShader::LinkedShader(GLRenderManager *render, VShaderID VSID, Shader *vs, availableUniforms = vs->GetUniformMask() | fs->GetUniformMask(); std::vector initialize; - initialize.push_back({ &u_tex, 0, 0 }); - initialize.push_back({ &u_fbotex, 0, 1 }); - initialize.push_back({ &u_testtex, 0, 2 }); - initialize.push_back({ &u_tess_pos_tex, 4 }); // Texture unit 4 - initialize.push_back({ &u_tess_tex_tex, 5 }); // Texture unit 5 - initialize.push_back({ &u_tess_col_tex, 6 }); // Texture unit 6 + initialize.push_back({ &u_tex, 0, 0 }); + initialize.push_back({ &u_fbotex, 0, 1 }); + initialize.push_back({ &u_testtex, 0, 2 }); + initialize.push_back({ &u_tess_pos_tex, 0, 4 }); // Texture unit 4 + initialize.push_back({ &u_tess_tex_tex, 0, 5 }); // Texture unit 5 + initialize.push_back({ &u_tess_col_tex, 0, 6 }); // Texture unit 6 program = render->CreateProgram(shaders, semantics, queries, initialize, gstate_c.featureFlags & GPU_SUPPORTS_DUALSOURCE_BLEND); diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 39b3c7ede1..61e585a8aa 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -115,7 +115,6 @@ 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; @@ -157,7 +156,6 @@ void TextureCacheGLES::UpdateSamplingParams(TexCacheEntry &entry, bool force) { float aniso = 0.0f; render_->SetTextureSampler(sClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, tClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, MagFiltGL[magFilt], MinFiltGL[minFilt], aniso); - CHECK_GL_ERROR_IF_DEBUG(); } void TextureCacheGLES::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight) { @@ -735,8 +733,6 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r bool useUnpack = false; uint8_t *pixelData; - CHECK_GL_ERROR_IF_DEBUG(); - // TODO: only do this once u32 texByteAlign = 1; @@ -794,8 +790,6 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r } } - CHECK_GL_ERROR_IF_DEBUG(); - GLuint components = dstFmt == GL_UNSIGNED_SHORT_5_6_5 ? GL_RGB : GL_RGBA; GLuint components2 = components; diff --git a/GPU/GLES/VertexShaderGeneratorGLES.cpp b/GPU/GLES/VertexShaderGeneratorGLES.cpp index 1517d58643..f9de2d312b 100644 --- a/GPU/GLES/VertexShaderGeneratorGLES.cpp +++ b/GPU/GLES/VertexShaderGeneratorGLES.cpp @@ -107,7 +107,6 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, const char *attribute = "attribute"; const char * const * boneWeightDecl = boneWeightAttrDecl; const char *texelFetch = NULL; - bool isAllowTexture1D = false; bool highpFog = false; bool highpTexcoord = false; @@ -135,13 +134,11 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, glslES30 = true; WRITE(p, "#version 330\n"); texelFetch = "texelFetch"; - isAllowTexture1D = true; } else if (gl_extensions.VersionGEThan(3, 0, 0)) { WRITE(p, "#version 130\n"); if (gl_extensions.EXT_gpu_shader4) { WRITE(p, "#extension GL_EXT_gpu_shader4 : enable\n"); texelFetch = "texelFetch"; - isAllowTexture1D = true; } } else { WRITE(p, "#version 110\n"); @@ -374,10 +371,9 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, if (doBezier || doSpline) { *uniformMask |= DIRTY_BEZIERSPLINE; - const char *sampler = !isAllowTexture1D ? "sampler2D" : "sampler1D"; - WRITE(p, "uniform %s u_tess_pos_tex;\n", sampler); - WRITE(p, "uniform %s u_tess_tex_tex;\n", sampler); - WRITE(p, "uniform %s u_tess_col_tex;\n", sampler); + WRITE(p, "uniform sampler2D u_tess_pos_tex;\n"); + WRITE(p, "uniform sampler2D u_tess_tex_tex;\n"); + WRITE(p, "uniform sampler2D u_tess_col_tex;\n"); WRITE(p, "uniform int u_spline_count_u;\n"); @@ -502,12 +498,11 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, WRITE(p, " for (int i = 0; i < 4; i++) {\n"); WRITE(p, " for (int j = 0; j < 4; j++) {\n"); WRITE(p, " int index = (i + v%s) * u_spline_count_u + (j + u%s);\n", doBezier ? " * 3" : "", doBezier ? " * 3" : ""); - const char *index = !isAllowTexture1D ? "ivec2(index, 0)" : "index"; - WRITE(p, " _pos[i * 4 + j] = %s(u_tess_pos_tex, %s, 0).xyz;\n", texelFetch, index); + WRITE(p, " _pos[i * 4 + j] = %s(u_tess_pos_tex, ivec2(index, 0), 0).xyz;\n", texelFetch); if (doTexture && hasTexcoord && hasTexcoordTess) - WRITE(p, " _tex[i * 4 + j] = %s(u_tess_tex_tex, %s, 0).xy;\n", texelFetch, index); + WRITE(p, " _tex[i * 4 + j] = %s(u_tess_tex_tex, ivec2(index, 0), 0).xy;\n", texelFetch); if (hasColor && hasColorTess) - WRITE(p, " _col[i * 4 + j] = %s(u_tess_col_tex, %s, 0).rgba;\n", texelFetch, index); + WRITE(p, " _col[i * 4 + j] = %s(u_tess_col_tex, ivec2(index, 0), 0).rgba;\n", texelFetch); WRITE(p, " }\n"); WRITE(p, " }\n"); WRITE(p, " vec2 tess_pos = position.xy;\n"); @@ -536,7 +531,7 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, if (hasColorTess) WRITE(p, " vec4 col = tess_sample(_col, weights);\n"); else - WRITE(p, " vec4 col = %s(u_tess_col_tex, %s, 0).rgba;\n", texelFetch, !isAllowTexture1D ? "ivec2(0, 0)" : "0"); + WRITE(p, " vec4 col = %s(u_tess_col_tex, ivec2(0, 0), 0).rgba;\n", texelFetch); } if (hasNormal) { // Curved surface is probably always need to compute normal(not sampling from control points) diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 34fec613b6..6b63263d7d 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -63,10 +63,6 @@ #include "Windows/W32Util/ShellUtil.h" #endif -#if !PPSSPP_PLATFORM(UWP) -#include "gfx/gl_common.h" -#endif - extern bool VulkanMayBeAvailable(); GameSettingsScreen::GameSettingsScreen(std::string gamePath, std::string gameID, bool editThenRestore) @@ -85,8 +81,7 @@ bool CheckSupportInstancedTessellationGLES() { return true; #else // TODO: Make work with non-GL backends - int maxVertexTextureImageUnits; - glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextureImageUnits); + int maxVertexTextureImageUnits = gl_extensions.maxVertexTextureUnits; bool vertexTexture = maxVertexTextureImageUnits >= 3; // At least 3 for hardware tessellation bool canUseInstanceID = gl_extensions.EXT_draw_instanced || gl_extensions.ARB_draw_instanced; @@ -100,7 +95,7 @@ bool CheckSupportInstancedTessellationGLES() { #endif } -bool IsBackendSupportHWTess() { +bool DoesBackendSupportHWTess() { switch (GetGPUBackend()) { case GPUBackend::OPENGL: return CheckSupportInstancedTessellationGLES(); @@ -353,7 +348,7 @@ void GameSettingsScreen::CreateViews() { settingInfo_->Show(gr->T("HardwareTessellation Tip", "Uses hardware to make curves, always uses a fixed quality"), e.v); return UI::EVENT_CONTINUE; }); - tessHWEnable_ = IsBackendSupportHWTess() && !g_Config.bSoftwareRendering && g_Config.bHardwareTransform; + tessHWEnable_ = DoesBackendSupportHWTess() && !g_Config.bSoftwareRendering && g_Config.bHardwareTransform; tessellationHW->SetEnabledPtr(&tessHWEnable_); // In case we're going to add few other antialiasing option like MSAA in the future. @@ -798,13 +793,13 @@ UI::EventReturn GameSettingsScreen::OnSoftwareRendering(UI::EventParams &e) { postProcEnable_ = !g_Config.bSoftwareRendering && (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE); resolutionEnable_ = !g_Config.bSoftwareRendering && (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE); bloomHackEnable_ = !g_Config.bSoftwareRendering && (g_Config.iInternalResolution != 1); - tessHWEnable_ = IsBackendSupportHWTess() && !g_Config.bSoftwareRendering && g_Config.bHardwareTransform; + tessHWEnable_ = DoesBackendSupportHWTess() && !g_Config.bSoftwareRendering && g_Config.bHardwareTransform; return UI::EVENT_DONE; } UI::EventReturn GameSettingsScreen::OnHardwareTransform(UI::EventParams &e) { vtxCacheEnable_ = !g_Config.bSoftwareRendering && g_Config.bHardwareTransform; - tessHWEnable_ = IsBackendSupportHWTess() && !g_Config.bSoftwareRendering && g_Config.bHardwareTransform; + tessHWEnable_ = DoesBackendSupportHWTess() && !g_Config.bSoftwareRendering && g_Config.bHardwareTransform; return UI::EVENT_DONE; } diff --git a/ext/native/gfx_es2/gpu_features.cpp b/ext/native/gfx_es2/gpu_features.cpp index c758645fc9..69ffa7c897 100644 --- a/ext/native/gfx_es2/gpu_features.cpp +++ b/ext/native/gfx_es2/gpu_features.cpp @@ -393,6 +393,8 @@ void CheckGLExtensions() { } #endif + glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &gl_extensions.maxVertexTextureUnits); + // This is probably a waste of time, implementations lie. if (gl_extensions.IsGLES || strstr(extString, "GL_ARB_ES2_compatibility") || gl_extensions.VersionGEThan(4, 1)) { const GLint precisions[6] = { diff --git a/ext/native/gfx_es2/gpu_features.h b/ext/native/gfx_es2/gpu_features.h index 2f405546b8..b12b406eee 100644 --- a/ext/native/gfx_es2/gpu_features.h +++ b/ext/native/gfx_es2/gpu_features.h @@ -96,6 +96,8 @@ struct GLExtensions { int range[2][6][2]; // [vs,fs][lowf,mediumf,highf,lowi,mediumi,highi][min,max] int precision[2][6]; // [vs,fs][lowf...] + int maxVertexTextureUnits; + // greater-or-equal than bool VersionGEThan(int major, int minor, int sub = 0); }; diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index d7a724ae25..c07085bf70 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -182,8 +182,6 @@ void GLQueueRunner::RunInitSteps(const std::vector &steps) { InitCreateFramebuffer(step); break; } - case GLRInitStepType::TEXTURE_SUBDATA: - break; case GLRInitStepType::TEXTURE_IMAGE: { GLRTexture *tex = step.texture_image.texture; @@ -193,13 +191,20 @@ void GLQueueRunner::RunInitSteps(const std::vector &steps) { glBindTexture(tex->target, tex->texture); boundTexture = tex->texture; } + if (!step.texture_image.data) + Crash(); + // For things to show in RenderDoc, need to split into glTexImage2D(..., nullptr) and glTexSubImage. glTexImage2D(tex->target, step.texture_image.level, step.texture_image.internalFormat, step.texture_image.width, step.texture_image.height, 0, step.texture_image.format, step.texture_image.type, step.texture_image.data); delete[] step.texture_image.data; CHECK_GL_ERROR_IF_DEBUG(); - glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(tex->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER, step.texture_image.linearFilter ? GL_LINEAR : GL_NEAREST); - glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, step.texture_image.linearFilter ? GL_LINEAR : GL_NEAREST); + tex->wrapS = GL_CLAMP_TO_EDGE; + tex->wrapT = GL_CLAMP_TO_EDGE; + tex->magFilter = step.texture_image.linearFilter ? GL_LINEAR : GL_NEAREST; + tex->minFilter = step.texture_image.linearFilter ? GL_LINEAR : GL_NEAREST; + glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, tex->wrapS); + glTexParameteri(tex->target, GL_TEXTURE_WRAP_T, tex->wrapT); + glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER, tex->magFilter); + glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, tex->minFilter); break; } case GLRInitStepType::TEXTURE_FINALIZE: @@ -210,6 +215,7 @@ void GLQueueRunner::RunInitSteps(const std::vector &steps) { boundTexture = tex->texture; } glTexParameteri(tex->target, GL_TEXTURE_MAX_LEVEL, step.texture_finalize.maxLevel); + tex->maxLod = step.texture_finalize.maxLevel; if (step.texture_finalize.genMips) { glGenerateMipmap(tex->target); } diff --git a/ext/native/thin3d/GLQueueRunner.h b/ext/native/thin3d/GLQueueRunner.h index 362d3e30f3..95d71292f8 100644 --- a/ext/native/thin3d/GLQueueRunner.h +++ b/ext/native/thin3d/GLQueueRunner.h @@ -185,7 +185,6 @@ enum class GLRInitStepType : uint8_t { CREATE_FRAMEBUFFER, TEXTURE_IMAGE, - TEXTURE_SUBDATA, TEXTURE_FINALIZE, BUFFER_SUBDATA, };