Skip to content

Commit a1981cc

Browse files
committed
Simplify code for MipMap creation
1 parent 216f736 commit a1981cc

File tree

2 files changed

+82
-57
lines changed

2 files changed

+82
-57
lines changed

Dllmain/BuildNo.rc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
#define BUILD_NUMBER 8163
1+
#define BUILD_NUMBER 8164

ddraw/IDirectDrawSurfaceX.cpp

Lines changed: 81 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -4555,17 +4555,28 @@ HRESULT m_IDirectDrawSurfaceX::CreateD9Surface()
45554555
HRESULT hr = DD_OK;
45564556

45574557
do {
4558-
// Create depth stencil
4558+
// Create depth stencil surface
45594559
if (IsDepthStencil() && surface.Pool != D3DPOOL_SYSTEMMEM)
45604560
{
45614561
surface.IsLockable = false;
45624562
surface.Type = D3DTYPE_DEPTHSTENCIL;
45634563
surface.Usage = D3DUSAGE_DEPTHSTENCIL;
45644564
surface.Pool = D3DPOOL_DEFAULT;
4565+
4566+
// Get multisample type and quality
45654567
ddrawParent->GetMultiSampleTypeQuality(surface.MultiSampleType, surface.MultiSampleQuality);
4568+
45664569
BOOL Discard = surface.MultiSampleType != D3DMULTISAMPLE_NONE;
4567-
if (FAILED((*d3d9Device)->CreateDepthStencilSurface(surface.Width, surface.Height, Format, surface.MultiSampleType, surface.MultiSampleQuality, Discard, &surface.Surface, nullptr)) &&
4568-
FAILED((*d3d9Device)->CreateDepthStencilSurface(surface.Width, surface.Height, GetFailoverFormat(Format), surface.MultiSampleType, surface.MultiSampleQuality, Discard, &surface.Surface, nullptr)))
4570+
4571+
HRESULT hr_ds = (*d3d9Device)->CreateDepthStencilSurface(surface.Width, surface.Height, Format, surface.MultiSampleType, surface.MultiSampleQuality, Discard, &surface.Surface, nullptr);
4572+
4573+
// Failover format if needed
4574+
if (FAILED(hr_ds))
4575+
{
4576+
hr_ds = (*d3d9Device)->CreateDepthStencilSurface(surface.Width, surface.Height, GetFailoverFormat(Format), surface.MultiSampleType, surface.MultiSampleQuality, Discard, &surface.Surface, nullptr);
4577+
}
4578+
4579+
if (FAILED(hr_ds))
45694580
{
45704581
LOG_LIMIT(100, __FUNCTION__ << " Error: failed to create depth stencil surface. Size: " << surface.Width << "x" << surface.Height << " Format: " << Format << " dwCaps: " << surfaceDesc2.ddsCaps);
45714582
hr = DDERR_GENERIC;
@@ -4582,8 +4593,16 @@ HRESULT m_IDirectDrawSurfaceX::CreateD9Surface()
45824593
{
45834594
surface.IsLockable = false;
45844595
surface.Type = D3DTYPE_TEXTURE;
4585-
if (FAILED((*d3d9Device)->CreateTexture(surface.Width, surface.Height, 1, surface.Usage, Format, surface.Pool, &surface.Texture, nullptr)) &&
4586-
FAILED((*d3d9Device)->CreateTexture(surface.Width, surface.Height, 1, surface.Usage, GetFailoverFormat(Format), surface.Pool, &surface.Texture, nullptr)))
4596+
4597+
HRESULT hr_tex = (*d3d9Device)->CreateTexture(surface.Width, surface.Height, 1, surface.Usage, Format, surface.Pool, &surface.Texture, nullptr);
4598+
4599+
// Failover format if needed
4600+
if (FAILED(hr_tex))
4601+
{
4602+
hr_tex = (*d3d9Device)->CreateTexture(surface.Width, surface.Height, 1, surface.Usage, GetFailoverFormat(Format), surface.Pool, &surface.Texture, nullptr);
4603+
}
4604+
4605+
if (FAILED(hr_tex))
45874606
{
45884607
LOG_LIMIT(100, __FUNCTION__ << " Error: failed to create render target texture. Size: " << surface.Width << "x" << surface.Height << " Format: " << Format << " dwCaps: " << surfaceDesc2.ddsCaps);
45894608
hr = DDERR_GENERIC;
@@ -4593,10 +4612,22 @@ HRESULT m_IDirectDrawSurfaceX::CreateD9Surface()
45934612
else
45944613
{
45954614
surface.Type = D3DTYPE_RENDERTARGET;
4615+
4616+
// Get multisample info
45964617
ddrawParent->GetMultiSampleTypeQuality(surface.MultiSampleType, surface.MultiSampleQuality);
4618+
4619+
// Determine if lockable
45974620
BOOL IsLockable = !surface.MultiSampleType && !Config.DdrawUseShadowSurface && !(surfaceDesc2.ddsCaps.dwCaps2 & DDSCAPS2_NOTUSERLOCKABLE);
4598-
if (FAILED((*d3d9Device)->CreateRenderTarget(surface.Width, surface.Height, Format, surface.MultiSampleType, surface.MultiSampleQuality, IsLockable, &surface.Surface, nullptr)) &&
4599-
FAILED((*d3d9Device)->CreateRenderTarget(surface.Width, surface.Height, GetFailoverFormat(Format), surface.MultiSampleType, surface.MultiSampleQuality, IsLockable, &surface.Surface, nullptr)))
4621+
4622+
HRESULT hr_rt = (*d3d9Device)->CreateRenderTarget(surface.Width, surface.Height, Format, surface.MultiSampleType, surface.MultiSampleQuality, IsLockable, &surface.Surface, nullptr);
4623+
4624+
// Failover format if needed
4625+
if (FAILED(hr_rt))
4626+
{
4627+
hr_rt = (*d3d9Device)->CreateRenderTarget(surface.Width, surface.Height, GetFailoverFormat(Format), surface.MultiSampleType, surface.MultiSampleQuality, IsLockable, &surface.Surface, nullptr);
4628+
}
4629+
4630+
if (FAILED(hr_rt))
46004631
{
46014632
LOG_LIMIT(100, __FUNCTION__ << " Error: failed to create render target surface. Size: " << surface.Width << "x" << surface.Height << " Format: " << Format << " dwCaps: " << surfaceDesc2.ddsCaps);
46024633
hr = DDERR_GENERIC;
@@ -4614,58 +4645,77 @@ HRESULT m_IDirectDrawSurfaceX::CreateD9Surface()
46144645
else if (IsTexture)
46154646
{
46164647
surface.Type = D3DTYPE_TEXTURE;
4617-
DWORD MipMapLevel = IsMipMapEnabled && !CreateSurfaceEmulated ? surfaceDesc2.dwMipMapCount : 1;
4618-
HRESULT hr_t;
4619-
do {
4620-
surface.Usage = (Config.DdrawForceMipMapAutoGen && MipMapLevel != 1 && (surface.Pool == D3DPOOL_DEFAULT || surface.Pool == D3DPOOL_MANAGED)) ? D3DUSAGE_AUTOGENMIPMAP : 0;
4621-
DWORD Level = (surface.Usage & D3DUSAGE_AUTOGENMIPMAP) == 0 ? MipMapLevel : 0;
4622-
// Create texture
4623-
hr_t = (*d3d9Device)->CreateTexture(surface.Width, surface.Height, Level, surface.Usage, Format, surface.Pool, &surface.Texture, nullptr);
4624-
if (FAILED(hr_t))
4625-
{
4626-
hr_t = (*d3d9Device)->CreateTexture(surface.Width, surface.Height, Level, surface.Usage, GetFailoverFormat(Format), surface.Pool, &surface.Texture, nullptr);
4627-
}
4628-
} while (FAILED(hr_t) && ((!MipMapLevel && ++MipMapLevel) || --MipMapLevel > 0));
4648+
4649+
// Determine mip levels
4650+
DWORD MipMapLevel = (IsMipMapEnabled && !CreateSurfaceEmulated) ? surfaceDesc2.dwMipMapCount : 1;
4651+
4652+
// Determine usage
4653+
surface.Usage = 0;
4654+
if (Config.DdrawForceMipMapAutoGen && MipMapLevel > 1 && (surface.Pool == D3DPOOL_DEFAULT || surface.Pool == D3DPOOL_MANAGED))
4655+
{
4656+
surface.Usage = D3DUSAGE_AUTOGENMIPMAP;
4657+
}
4658+
4659+
// Adjust levels for autogen mip
4660+
DWORD Levels = (surface.Usage & D3DUSAGE_AUTOGENMIPMAP) ? 0 : MipMapLevel;
4661+
4662+
HRESULT hr_t = (*d3d9Device)->CreateTexture(surface.Width, surface.Height, Levels, surface.Usage, Format, surface.Pool, &surface.Texture, nullptr);
4663+
4664+
// Failover format if needed
4665+
if (FAILED(hr_t))
4666+
{
4667+
hr_t = (*d3d9Device)->CreateTexture(surface.Width, surface.Height, Levels, surface.Usage, GetFailoverFormat(Format), surface.Pool, &surface.Texture, nullptr);
4668+
}
4669+
46294670
if (FAILED(hr_t))
46304671
{
46314672
LOG_LIMIT(100, __FUNCTION__ << " Error: failed to create surface texture. Size: " << surface.Width << "x" << surface.Height << " Format: " << Format << " dwCaps: " << surfaceDesc2.ddsCaps);
46324673
hr = DDERR_GENERIC;
46334674
break;
46344675
}
4676+
4677+
// Set max mip level
46354678
MaxMipMapLevel = (!IsMipMapEnabled || IsMipMapAutogen() || CreateSurfaceEmulated ? 1 : MipMapLevel > 0 ? MipMapLevel : surface.Texture->GetLevelCount()) - 1;
4679+
4680+
// Ensure MipMaps vector has correct size
46364681
while (MipMaps.size() < MaxMipMapLevel)
46374682
{
4638-
MIPMAP MipMap;
4639-
MipMaps.push_back(MipMap);
4640-
}
4641-
if ((surfaceDesc2.dwFlags & DDSD_MIPMAPCOUNT) && !IsMipMapAutogen())
4642-
{
4643-
surfaceDesc2.dwMipMapCount = MipMapLevel;
4683+
MipMaps.emplace_back();
46444684
}
4685+
46454686
// Set current LOD level
46464687
if (LODLevel != 0)
46474688
{
46484689
surface.Texture->SetLOD(LODLevel);
46494690
}
4691+
46504692
// Set current priority
46514693
if (Priority != 0)
46524694
{
46534695
surface.Texture->SetPriority(Priority);
46544696
}
46554697
}
4698+
// Create offscreen plain surface
46564699
else
46574700
{
46584701
const D3DFORMAT NewFormat = IsDepthStencil() ? GetStencilEmulatedFormat(surface.BitCount) : Format;
46594702
surface.Type = D3DTYPE_OFFPLAINSURFACE;
4660-
if (FAILED((*d3d9Device)->CreateOffscreenPlainSurface(surface.Width, surface.Height, NewFormat, surface.Pool, &surface.Surface, nullptr)) &&
4661-
FAILED((*d3d9Device)->CreateOffscreenPlainSurface(surface.Width, surface.Height, GetFailoverFormat(NewFormat), surface.Pool, &surface.Surface, nullptr)))
4703+
4704+
HRESULT hr_off = (*d3d9Device)->CreateOffscreenPlainSurface(surface.Width, surface.Height, NewFormat, surface.Pool, &surface.Surface, nullptr);
4705+
4706+
// Failover format if needed
4707+
if (FAILED(hr_off))
4708+
{
4709+
hr_off = (*d3d9Device)->CreateOffscreenPlainSurface(surface.Width, surface.Height, GetFailoverFormat(NewFormat), surface.Pool, &surface.Surface, nullptr);
4710+
}
4711+
4712+
if (FAILED(hr_off))
46624713
{
46634714
LOG_LIMIT(100, __FUNCTION__ << " Error: failed to create offplain surface. Size: " << surface.Width << "x" << surface.Height << " Format: " << NewFormat << " dwCaps: " << surfaceDesc2.ddsCaps);
46644715
hr = DDERR_GENERIC;
46654716
break;
46664717
}
46674718
}
4668-
46694719
if (FAILED(CreateD9AuxiliarySurfaces()))
46704720
{
46714721
hr = DDERR_GENERIC;
@@ -6363,40 +6413,15 @@ void m_IDirectDrawSurfaceX::InitSurfaceDesc(DWORD DirectXVersion)
63636413
surfaceDesc2.dwBackBufferCount = 0;
63646414
}
63656415

6366-
// Handle mipmaps
6367-
if ((!(surfaceDesc2.dwFlags & DDSD_MIPMAPCOUNT) || ((surfaceDesc2.dwFlags & DDSD_MIPMAPCOUNT) && surfaceDesc2.dwMipMapCount != 1)) &&
6368-
(surfaceDesc2.ddsCaps.dwCaps & (DDSCAPS_MIPMAP | DDSCAPS_COMPLEX | DDSCAPS_TEXTURE)) == (DDSCAPS_MIPMAP | DDSCAPS_COMPLEX | DDSCAPS_TEXTURE))
6369-
{
6370-
// Compute width and height
6371-
if ((!(surfaceDesc2.dwFlags & (DDSD_WIDTH | DDSD_HEIGHT)) || (!surfaceDesc2.dwWidth && !surfaceDesc2.dwHeight)) &&
6372-
(surfaceDesc2.dwFlags & DDSD_MIPMAPCOUNT) && surfaceDesc2.dwMipMapCount > 0)
6373-
{
6374-
surfaceDesc2.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
6375-
surfaceDesc2.dwWidth = (DWORD)pow(2, surfaceDesc2.dwMipMapCount - 1);
6376-
surfaceDesc2.dwHeight = surfaceDesc2.dwWidth;
6377-
}
6378-
// Compute mipcount
6379-
DWORD MipMapLevelCount = ((surfaceDesc2.dwFlags & DDSD_MIPMAPCOUNT) && surfaceDesc2.dwMipMapCount) ? surfaceDesc2.dwMipMapCount :
6380-
GetMaxMipMapLevel(surfaceDesc2.dwWidth, surfaceDesc2.dwHeight);
6381-
MaxMipMapLevel = MipMapLevelCount - 1;
6382-
surfaceDesc2.dwMipMapCount = MaxMipMapLevel + 1;
6383-
surfaceDesc2.dwFlags |= DDSD_MIPMAPCOUNT;
6384-
}
63856416
// Mipmap textures
6386-
else if (surfaceDesc2.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
6417+
if ((surfaceDesc2.dwFlags & DDSD_MIPMAPCOUNT) && (surfaceDesc2.dwMipMapCount > 1) &&
6418+
((surfaceDesc2.ddsCaps.dwCaps & (DDSCAPS_MIPMAP | DDSCAPS_COMPLEX | DDSCAPS_TEXTURE)) == (DDSCAPS_MIPMAP | DDSCAPS_COMPLEX | DDSCAPS_TEXTURE)))
63876419
{
6388-
if (surfaceDesc2.dwFlags & DDSD_MIPMAPCOUNT)
6389-
{
6390-
surfaceDesc2.dwMipMapCount = 1;
6391-
}
6420+
MaxMipMapLevel = surfaceDesc2.dwMipMapCount - 1;
63926421
}
63936422
// No mipmaps
63946423
else
63956424
{
6396-
if (surfaceDesc2.dwFlags & DDSD_MIPMAPCOUNT)
6397-
{
6398-
surfaceDesc2.dwMipMapCount = 0;
6399-
}
64006425
surfaceDesc2.dwFlags &= ~DDSD_MIPMAPCOUNT;
64016426
surfaceDesc2.ddsCaps.dwCaps &= ~DDSCAPS_MIPMAP;
64026427
}

0 commit comments

Comments
 (0)