Skip to content

Commit

Permalink
Merge pull request #9633 from unknownbrackets/mipmaps
Browse files Browse the repository at this point in the history
Improve support for mipmaps and related headless fixes
  • Loading branch information
hrydgard authored Apr 23, 2017
2 parents 4f0e1a0 + 33ade5f commit 1a58629
Show file tree
Hide file tree
Showing 14 changed files with 93 additions and 29 deletions.
2 changes: 1 addition & 1 deletion GPU/Common/TextureCacheCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
6 changes: 4 additions & 2 deletions GPU/Common/TextureCacheCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
};

Expand Down
26 changes: 23 additions & 3 deletions GPU/D3D11/TextureCacheD3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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()?");
Expand Down
2 changes: 2 additions & 0 deletions GPU/Directx9/FramebufferDX9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
29 changes: 21 additions & 8 deletions GPU/Directx9/TextureCacheDX9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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];
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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();

Expand Down
23 changes: 17 additions & 6 deletions GPU/GLES/TextureCacheGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
// 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:
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 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);
}

if (force || entry.minFilt != minFilt) {
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions GPU/GPUState.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
4 changes: 2 additions & 2 deletions GPU/Vulkan/FramebufferVulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_;
Expand Down
3 changes: 2 additions & 1 deletion ext/native/gfx/d3d9_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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++;
}
Expand All @@ -76,4 +77,4 @@ void DirectXState::SetVSyncInterval(int interval) {

} // namespace DX9

#endif // _MSC_VER
#endif // _MSC_VER
1 change: 1 addition & 0 deletions ext/native/gfx/d3d9_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,7 @@ class DirectXState {
DxSampler0State1<D3DSAMP_MAGFILTER, D3DTEXF_POINT> texMagFilter;
DxSampler0State1<D3DSAMP_MIPFILTER, D3DTEXF_NONE> texMipFilter;
DxSampler0State1Float<D3DSAMP_MIPMAPLODBIAS, 0> texMipLodBias;
DxSampler0State1<D3DSAMP_MAXMIPLEVEL, 0> texMaxMipLevel;
DxSampler0State1<D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP> texAddressU;
DxSampler0State1<D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP> texAddressV;

Expand Down
9 changes: 8 additions & 1 deletion headless/Headless.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
{
Expand All @@ -180,6 +182,8 @@ bool RunAutoTest(HeadlessHost *headlessHost, CoreParameter &coreParameter, bool
}
}

PSP_EndHostFrame();

PSP_Shutdown();

headlessHost->FlushDebugOutput();
Expand Down Expand Up @@ -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"))
Expand Down Expand Up @@ -356,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();
Expand Down
9 changes: 5 additions & 4 deletions headless/Headless.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<PreprocessorDefinitions>_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</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../Common;..;../Core;../ext/glew;../ext/native</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native</AdditionalIncludeDirectories>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
Expand Down Expand Up @@ -124,7 +124,7 @@
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_64=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../Common;..;../Core;../ext/glew;../ext/native</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<OmitFramePointers>false</OmitFramePointers>
Expand Down Expand Up @@ -159,7 +159,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_32=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../Common;..;../Core;../ext/glew;../ext/native</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
Expand Down Expand Up @@ -194,7 +194,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_64=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../Common;..;../Core;../ext/glew;../ext/native</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
Expand Down Expand Up @@ -225,6 +225,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\ext\glew\glew.c" />
<ClCompile Include="..\Windows\GPU\D3D11Context.cpp" />
<ClCompile Include="..\Windows\GPU\D3D9Context.cpp" />
<ClCompile Include="..\Windows\GPU\WindowsGLContext.cpp" />
<ClCompile Include="..\Windows\GPU\WindowsVulkanContext.cpp" />
Expand Down
3 changes: 3 additions & 0 deletions headless/Headless.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
<ClCompile Include="..\Windows\W32Util\Misc.cpp">
<Filter>Windows</Filter>
</ClCompile>
<ClCompile Include="..\Windows\GPU\D3D11Context.cpp">
<Filter>Windows</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="headless.txt" />
Expand Down
4 changes: 3 additions & 1 deletion headless/WindowsHeadlessHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 1a58629

Please sign in to comment.