From 19a3e166ec049c9f93f24f870f094b8323664e37 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 22 Apr 2017 18:17:03 -0700 Subject: [PATCH 1/9] Headless: Fix DirectX11 support on Windows. --- headless/Headless.cpp | 8 +++++++- headless/Headless.vcxproj | 9 +++++---- headless/Headless.vcxproj.filters | 3 +++ headless/WindowsHeadlessHost.cpp | 4 +++- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 3bc2ac03dc38..af5342ee58f4 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -94,7 +94,7 @@ int printUsage(const char *progname, const char *reason) #if defined(HEADLESSHOST_CLASS) { fprintf(stderr, " --graphics=BACKEND use the full gpu backend (slower)\n"); - fprintf(stderr, " options: gles, software, directx9\n"); + fprintf(stderr, " options: gles, software, directx9, etc.\n"); fprintf(stderr, " --screenshot=FILE compare against a screenshot\n"); } #endif @@ -157,6 +157,8 @@ bool RunAutoTest(HeadlessHost *headlessHost, CoreParameter &coreParameter, bool static double deadline; deadline = time_now() + timeout; + PSP_BeginHostFrame(); + coreState = CORE_RUNNING; while (coreState == CORE_RUNNING) { @@ -180,6 +182,8 @@ bool RunAutoTest(HeadlessHost *headlessHost, CoreParameter &coreParameter, bool } } + PSP_EndHostFrame(); + PSP_Shutdown(); headlessHost->FlushDebugOutput(); @@ -250,6 +254,8 @@ int main(int argc, const char* argv[]) gpuCore = GPUCORE_SOFTWARE; else if (!strcasecmp(gpuName, "directx9")) gpuCore = GPUCORE_DIRECTX9; + else if (!strcasecmp(gpuName, "directx11")) + gpuCore = GPUCORE_DIRECTX11; else if (!strcasecmp(gpuName, "vulkan")) gpuCore = GPUCORE_VULKAN; else if (!strcasecmp(gpuName, "null")) diff --git a/headless/Headless.vcxproj b/headless/Headless.vcxproj index 29f56c584bdd..17d3f2fee8dd 100644 --- a/headless/Headless.vcxproj +++ b/headless/Headless.vcxproj @@ -92,7 +92,7 @@ NotUsing Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_32=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS - ../Common;..;../Core;../ext/glew;../ext/native + ../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native Default StreamingSIMDExtensions2 Fast @@ -124,7 +124,7 @@ NotUsing Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_64=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../Common;..;../Core;../ext/glew;../ext/native + ../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native NotSet Fast false @@ -159,7 +159,7 @@ true true USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_32=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS - ../Common;..;../Core;../ext/glew;../ext/native + ../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native false StreamingSIMDExtensions2 Fast @@ -194,7 +194,7 @@ true true USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_64=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../Common;..;../Core;../ext/glew;../ext/native + ../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native false NotSet Fast @@ -225,6 +225,7 @@ + diff --git a/headless/Headless.vcxproj.filters b/headless/Headless.vcxproj.filters index 97d9382999ed..3f7bc674deea 100644 --- a/headless/Headless.vcxproj.filters +++ b/headless/Headless.vcxproj.filters @@ -19,6 +19,9 @@ Windows + + Windows + diff --git a/headless/WindowsHeadlessHost.cpp b/headless/WindowsHeadlessHost.cpp index 62edd1e27f6f..4ad37bd21920 100644 --- a/headless/WindowsHeadlessHost.cpp +++ b/headless/WindowsHeadlessHost.cpp @@ -29,6 +29,7 @@ #include "GPU/GPUState.h" #include "Windows/GPU/WindowsGLContext.h" #include "Windows/GPU/D3D9Context.h" +#include "Windows/GPU/D3D11Context.h" #include "Windows/GPU/WindowsVulkanContext.h" #include "base/logging.h" @@ -164,7 +165,8 @@ bool WindowsHeadlessHost::InitGraphics(std::string *error_message, GraphicsConte break; case GPUCORE_DIRECTX11: - return false; + graphicsContext = new D3D11Context(); + break; case GPUCORE_VULKAN: graphicsContext = new WindowsVulkanContext(); From b2711c2ebf68cabaaa118725b95035674907f65c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 22 Apr 2017 18:17:48 -0700 Subject: [PATCH 2/9] Headless: Enable mipmaps. --- headless/Headless.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/headless/Headless.cpp b/headless/Headless.cpp index af5342ee58f4..748c67cf817f 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -362,6 +362,7 @@ int main(int argc, const char* argv[]) g_Config.bVertexDecoderJit = true; g_Config.bBlockTransferGPU = true; g_Config.iSplineBezierQuality = 2; + g_Config.bMipMap = true; #ifdef _WIN32 InitSysDirectories(); From 6aad8ff2a2fb02a2c0ef8e6f7fa69d14a68636fb Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 22 Apr 2017 18:19:43 -0700 Subject: [PATCH 3/9] GPU: Correct const mip 0 detection. The other clause was mip 1. --- GPU/Common/TextureCacheCommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 1d0ff19f1e32..590367483342 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -130,7 +130,7 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl sClamp = gstate.isTexCoordClampedS(); tClamp = gstate.isTexCoordClampedT(); - bool noMip = (gstate.texlevel & 0xFFFFFF) == 0x000001 || (gstate.texlevel & 0xFFFFFF) == 0x100001; // Fix texlevel at 0 + bool noMip = (gstate.texlevel & 0xFFFFFF) == 0x000001; // Fix texlevel at 0 if (IsFakeMipmapChange()) noMip = gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST; From 8e9945df9797fc1b9468a8873c16a6df08553d8d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 22 Apr 2017 18:22:22 -0700 Subject: [PATCH 4/9] D3D11: Approximate AUTO/CONST mip bias. These generally work, as long as the mip levels are halving. --- GPU/Common/TextureCacheCommon.h | 6 ++++-- GPU/D3D11/TextureCacheD3D11.cpp | 26 +++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index bcca4c19f59d..18ce41711d98 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -69,8 +69,10 @@ struct SamplerCacheKey { bool magFilt : 1; bool sClamp : 1; bool tClamp : 1; - int lodBias : 4; - int maxLevel : 4; + bool lodAuto : 1; + bool : 1; + int8_t lodBias : 8; + int8_t maxLevel : 4; }; }; diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 5ab1d898fa5c..2c112229ea4c 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -88,11 +88,25 @@ ID3D11SamplerState *SamplerCacheD3D11::GetOrCreateSampler(ID3D11Device *device, #if PPSSPP_PLATFORM(UWP) && PPSSPP_ARCH(ARM) // For some reason, can't set MaxLOD on mobile. samp.MaxLOD = FLT_MAX; -#else - samp.MaxLOD = key.maxLevel; -#endif samp.MinLOD = -FLT_MAX; samp.MipLODBias = 0.0f; +#else + if (!key.mipEnable) { + samp.MaxLOD = 0.0f; + samp.MinLOD = 0.0f; + samp.MipLODBias = 0.0f; + } else if (key.lodAuto) { + // Auto selected mip + bias. + samp.MaxLOD = key.maxLevel; + samp.MinLOD = 0.0f; + samp.MipLODBias = (float)key.lodBias / 16.0f; + } else { + // Constant mip at bias. + samp.MaxLOD = (float)key.lodBias / 16.0f; + samp.MinLOD = (float)key.lodBias / 16.0f; + samp.MipLODBias = 0.0f; + } +#endif samp.ComparisonFunc = D3D11_COMPARISON_NEVER; for (int i = 0; i < 4; i++) { samp.BorderColor[i] = 1.0f; @@ -169,7 +183,13 @@ void TextureCacheD3D11::UpdateSamplingParams(TexCacheEntry &entry, SamplerCacheK key.magFilt = magFilt & 1; key.sClamp = sClamp; key.tClamp = tClamp; + key.lodBias = (s8)((gstate.texlevel >> 16) & 0xFF); + if (key.lodBias > entry.maxLevel * 16) { + key.lodBias = entry.maxLevel * 16; + } key.maxLevel = entry.maxLevel; + key.lodAuto = gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_AUTO; + // TODO: GE_TEXLEVEL_MODE_SLOPE if (entry.framebuffer) { WARN_LOG_REPORT_ONCE(wrongFramebufAttach, G3D, "Framebuffer still attached in UpdateSamplingParams()?"); From 90ad6c0a239646e32a408fb838e1b137c80b7b0b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 22 Apr 2017 18:22:59 -0700 Subject: [PATCH 5/9] D3D9: Disable mips when mip filtering disabled. Only GE_{LINEAR,NEAREST}_MIPMAP_* enable mipmaps. --- GPU/Directx9/TextureCacheDX9.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 683279fae49d..980e08c1eb47 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -133,10 +133,10 @@ static const u8 MinFilt[8] = { }; static const u8 MipFilt[8] = { - D3DTEXF_POINT, - D3DTEXF_LINEAR, - D3DTEXF_POINT, - D3DTEXF_LINEAR, + D3DTEXF_NONE, + D3DTEXF_NONE, + D3DTEXF_NONE, + D3DTEXF_NONE, D3DTEXF_POINT, // GL_NEAREST_MIPMAP_NEAREST, D3DTEXF_POINT, // GL_LINEAR_MIPMAP_NEAREST, D3DTEXF_LINEAR, // GL_NEAREST_MIPMAP_LINEAR, From ae4c28aa4da2012d2eb8ae9a2dadbf215194777d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 22 Apr 2017 18:36:25 -0700 Subject: [PATCH 6/9] D3D9: Support AUTO mip bias and approximate CONST. --- GPU/Directx9/FramebufferDX9.cpp | 2 ++ GPU/Directx9/TextureCacheDX9.cpp | 21 +++++++++++++++++---- GPU/GPUState.h | 1 + ext/native/gfx/d3d9_state.cpp | 3 ++- ext/native/gfx/d3d9_state.h | 1 + 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferDX9.cpp index 46c719555b7b..3471108f30e0 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferDX9.cpp @@ -313,6 +313,8 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { dxstate.texMagFilter.set(D3DTEXF_POINT); dxstate.texMinFilter.set(D3DTEXF_POINT); } + dxstate.texMipLodBias.set(0.0f); + dxstate.texMaxMipLevel.set(0); device_->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); HRESULT hr = device_->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coord, 5 * sizeof(float)); if (FAILED(hr)) { diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 980e08c1eb47..148bbff86ca1 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -160,17 +160,26 @@ void TextureCacheDX9::UpdateSamplingParams(TexCacheEntry &entry, bool force) { GETexLevelMode mode = gstate.getTexLevelMode(); switch (mode) { case GE_TEXLEVEL_MODE_AUTO: - // TODO + dxstate.texMaxMipLevel.set(0); + dxstate.texMipLodBias.set(lodBias); break; case GE_TEXLEVEL_MODE_CONST: - dxstate.texMipLodBias.set(lodBias); - // TODO + // TODO: This is just an approximation - texMaxMipLevel sets the lowest numbered mip to use. + // Unfortunately, this doesn't support a const 1.5 or etc. + dxstate.texMaxMipLevel.set((int)lodBias); + dxstate.texMipLodBias.set(-1000.0f); break; case GE_TEXLEVEL_MODE_SLOPE: - // TODO + WARN_LOG_REPORT_ONCE(texSlope, G3D, "Unsupported texture lod slope: %f + %f", gstate.getTextureLodSlope(), lodBias); + // TODO: This behavior isn't correct. + dxstate.texMaxMipLevel.set(0); + dxstate.texMipLodBias.set(lodBias); break; } entry.lodBias = lodBias; + } else { + dxstate.texMaxMipLevel.set(0); + dxstate.texMipLodBias.set(0.0f); } D3DTEXTUREFILTERTYPE minf = (D3DTEXTUREFILTERTYPE)MinFilt[minFilt]; @@ -199,6 +208,8 @@ void TextureCacheDX9::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHe dxstate.texMinFilter.set(MinFilt[minFilt]); dxstate.texMipFilter.set(MipFilt[minFilt]); dxstate.texMagFilter.set(MagFilt[magFilt]); + dxstate.texMipLodBias.set(0.0f); + dxstate.texMaxMipLevel.set(0.0f); // Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case. // This happens whether we have OES_texture_npot or not. @@ -437,6 +448,8 @@ void TextureCacheDX9::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFrame device_->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); device_->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); device_->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); + device_->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, 0); + device_->SetSamplerState(0, D3DSAMP_MAXMIPLEVEL, 0); shaderApply.Shade(); diff --git a/GPU/GPUState.h b/GPU/GPUState.h index a64265674b7e..b49010460e7f 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -304,6 +304,7 @@ struct GPUgstate { bool isTextureSwizzled() const { return texmode & 1; } bool isClutSharedForMipmaps() const { return (texmode & 0x100) == 0; } int getTextureMaxLevel() const { return (texmode >> 16) & 0x7; } + float getTextureLodSlope() const { return getFloat24(texlodslope); } // Lighting bool isLightingEnabled() const { return lightingEnable & 1; } diff --git a/ext/native/gfx/d3d9_state.cpp b/ext/native/gfx/d3d9_state.cpp index 9bbb60097d72..4fadf21b4453 100644 --- a/ext/native/gfx/d3d9_state.cpp +++ b/ext/native/gfx/d3d9_state.cpp @@ -59,6 +59,7 @@ void DirectXState::Restore() { texMagFilter.restore(); count++; texMipFilter.restore(); count++; texMipLodBias.restore(); count++; + texMaxMipLevel.restore(); count++; texAddressU.restore(); count++; texAddressV.restore(); count++; } @@ -76,4 +77,4 @@ void DirectXState::SetVSyncInterval(int interval) { } // namespace DX9 -#endif // _MSC_VER \ No newline at end of file +#endif // _MSC_VER diff --git a/ext/native/gfx/d3d9_state.h b/ext/native/gfx/d3d9_state.h index e0735832d817..a9a8eed86d5f 100644 --- a/ext/native/gfx/d3d9_state.h +++ b/ext/native/gfx/d3d9_state.h @@ -480,6 +480,7 @@ class DirectXState { DxSampler0State1 texMagFilter; DxSampler0State1 texMipFilter; DxSampler0State1Float texMipLodBias; + DxSampler0State1 texMaxMipLevel; DxSampler0State1 texAddressU; DxSampler0State1 texAddressV; From 57a839db170507a46f6493081b20c767df04bf2d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 22 Apr 2017 18:38:24 -0700 Subject: [PATCH 7/9] Vulkan: NULL initialize some handles. Was getting crashes until I realized buffered rendering was on. --- GPU/Vulkan/FramebufferVulkan.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/Vulkan/FramebufferVulkan.h b/GPU/Vulkan/FramebufferVulkan.h index 3f44706d14ea..a32a4f1e2ff1 100644 --- a/GPU/Vulkan/FramebufferVulkan.h +++ b/GPU/Vulkan/FramebufferVulkan.h @@ -152,8 +152,8 @@ class FramebufferManagerVulkan : public FramebufferManagerCommon { // The command buffer of the current framebuffer pass being rendered to. // One framebuffer can be used as a texturing source at multiple times in a frame, // but then the contents have to be copied out into a new texture every time. - VkCommandBuffer curCmd_; - VkCommandBuffer cmdInit_; + VkCommandBuffer curCmd_ = VK_NULL_HANDLE; + VkCommandBuffer cmdInit_ = VK_NULL_HANDLE; // Used by DrawPixels VulkanTexture *drawPixelsTex_; From f3db8bccad014de15a418bcd8e30938aa72091c9 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 22 Apr 2017 18:40:18 -0700 Subject: [PATCH 8/9] GLES: Support AUTO and CONST mip bias. --- GPU/GLES/TextureCacheGLES.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index ac914fb63785..47f853d35a9a 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -136,21 +136,33 @@ void TextureCacheGLES::UpdateSamplingParams(TexCacheEntry &entry, bool force) { GETexLevelMode mode = gstate.getTexLevelMode(); switch (mode) { case GE_TEXLEVEL_MODE_AUTO: - // TODO - break; - case GE_TEXLEVEL_MODE_CONST: - // Sigh, LOD_BIAS is not even in ES 3.0.. #ifndef USING_GLES2 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, lodBias); #endif + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (float)entry.maxLevel); + break; + case GE_TEXLEVEL_MODE_CONST: + // Sigh, LOD_BIAS is not even in ES 3.0.. but we could do it in the shader via texture()... + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, lodBias); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, lodBias); break; case GE_TEXLEVEL_MODE_SLOPE: - // TODO + WARN_LOG_REPORT_ONCE(texSlope, G3D, "Unsupported texture lod slope: %f + %f", gstate.getTextureLodSlope(), lodBias); + // TODO: This behavior isn't correct. +#ifndef USING_GLES2 + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, lodBias); +#endif + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (float)entry.maxLevel); break; } } entry.lodBias = lodBias; } + } else { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0.0f); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0.0f); } if (force || entry.minFilt != minFilt) { @@ -699,7 +711,6 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry, bool replaceImag LoadTextureLevel(*entry, replaced, i, replaceImages, scaleFactor, dstFmt); } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, maxLevel); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (float)maxLevel); } } else { // Avoid PowerVR driver bug From 33ade5f916ae5eca1d630c336add6d2eec63ab7d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 23 Apr 2017 10:51:25 -0700 Subject: [PATCH 9/9] GLES: Avoid MIN/MAX LOD without LOD control flag. --- GPU/GLES/TextureCacheGLES.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 47f853d35a9a..0072a36b6efc 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -137,13 +137,13 @@ void TextureCacheGLES::UpdateSamplingParams(TexCacheEntry &entry, bool force) { switch (mode) { case GE_TEXLEVEL_MODE_AUTO: #ifndef USING_GLES2 + // Sigh, LOD_BIAS is not even in ES 3.0.. but we could do it in the shader via texture()... glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, lodBias); #endif glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (float)entry.maxLevel); break; case GE_TEXLEVEL_MODE_CONST: - // Sigh, LOD_BIAS is not even in ES 3.0.. but we could do it in the shader via texture()... glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, lodBias); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, lodBias); break; @@ -160,7 +160,7 @@ void TextureCacheGLES::UpdateSamplingParams(TexCacheEntry &entry, bool force) { } entry.lodBias = lodBias; } - } else { + } else if (gstate_c.Supports(GPU_SUPPORTS_TEXTURE_LOD_CONTROL)) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0.0f); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0.0f); }