mirror of
https://github.com/reactos/wine.git
synced 2024-11-24 20:30:01 +00:00
d3dx9: Search for a compatible pixel format in D3DXCheckTextureRequirements.
This commit is contained in:
parent
b29e111260
commit
ebbf519b78
@ -48,7 +48,7 @@ HRESULT map_view_of_file(LPCWSTR filename, LPVOID *buffer, DWORD *length);
|
|||||||
HRESULT load_resource_into_memory(HMODULE module, HRSRC resinfo, LPVOID *buffer, DWORD *length);
|
HRESULT load_resource_into_memory(HMODULE module, HRSRC resinfo, LPVOID *buffer, DWORD *length);
|
||||||
|
|
||||||
const PixelFormatDesc *get_format_info(D3DFORMAT format);
|
const PixelFormatDesc *get_format_info(D3DFORMAT format);
|
||||||
|
const PixelFormatDesc *get_format_info_idx(int idx);
|
||||||
|
|
||||||
extern const ID3DXBufferVtbl D3DXBuffer_Vtbl;
|
extern const ID3DXBufferVtbl D3DXBuffer_Vtbl;
|
||||||
|
|
||||||
|
@ -27,9 +27,12 @@
|
|||||||
static void test_D3DXCheckTextureRequirements(IDirect3DDevice9 *device)
|
static void test_D3DXCheckTextureRequirements(IDirect3DDevice9 *device)
|
||||||
{
|
{
|
||||||
UINT width, height, mipmaps;
|
UINT width, height, mipmaps;
|
||||||
D3DFORMAT format;
|
D3DFORMAT format, expected;
|
||||||
D3DCAPS9 caps;
|
D3DCAPS9 caps;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
IDirect3D9 *d3d;
|
||||||
|
D3DDEVICE_CREATION_PARAMETERS params;
|
||||||
|
D3DDISPLAYMODE mode;
|
||||||
|
|
||||||
IDirect3DDevice9_GetDeviceCaps(device, &caps);
|
IDirect3DDevice9_GetDeviceCaps(device, &caps);
|
||||||
|
|
||||||
@ -145,15 +148,51 @@ static void test_D3DXCheckTextureRequirements(IDirect3DDevice9 *device)
|
|||||||
ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
|
ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
|
||||||
|
|
||||||
/* format */
|
/* format */
|
||||||
|
hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
|
||||||
|
ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
|
||||||
|
|
||||||
format = D3DFMT_UNKNOWN;
|
format = D3DFMT_UNKNOWN;
|
||||||
hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
|
hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
|
||||||
ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
|
ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
|
||||||
ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
|
ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
|
||||||
|
|
||||||
format = 0;
|
format = D3DX_DEFAULT;
|
||||||
hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
|
hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
|
||||||
ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
|
ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
|
||||||
ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
|
ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
|
||||||
|
|
||||||
|
format = D3DFMT_R8G8B8;
|
||||||
|
hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
|
||||||
|
ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
|
||||||
|
ok(format == D3DFMT_X8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_X8R8G8B8);
|
||||||
|
|
||||||
|
IDirect3DDevice9_GetDirect3D(device, &d3d);
|
||||||
|
IDirect3DDevice9_GetCreationParameters(device, ¶ms);
|
||||||
|
IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
|
||||||
|
|
||||||
|
if(SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
|
||||||
|
mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_R3G3B2)))
|
||||||
|
expected = D3DFMT_R3G3B2;
|
||||||
|
else
|
||||||
|
expected = D3DFMT_X4R4G4B4;
|
||||||
|
|
||||||
|
format = D3DFMT_R3G3B2;
|
||||||
|
hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
|
||||||
|
ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
|
||||||
|
ok(format == expected, "Returned format %u, expected %u\n", format, expected);
|
||||||
|
|
||||||
|
if(SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
|
||||||
|
mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R3G3B2)))
|
||||||
|
expected = D3DFMT_A8R3G3B2;
|
||||||
|
else
|
||||||
|
expected = D3DFMT_A8R8G8B8;
|
||||||
|
|
||||||
|
format = D3DFMT_A8R3G3B2;
|
||||||
|
hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
|
||||||
|
ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
|
||||||
|
ok(format == expected, "Returned format %u, expected %u\n", format, expected);
|
||||||
|
|
||||||
|
IDirect3D9_Release(d3d);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_D3DXCreateTexture(IDirect3DDevice9 *device)
|
static void test_D3DXCreateTexture(IDirect3DDevice9 *device)
|
||||||
|
@ -122,6 +122,11 @@ HRESULT WINAPI D3DXCheckTextureRequirements(LPDIRECT3DDEVICE9 device,
|
|||||||
UINT w = (width && *width) ? *width : 1;
|
UINT w = (width && *width) ? *width : 1;
|
||||||
UINT h = (height && *height) ? *height : 1;
|
UINT h = (height && *height) ? *height : 1;
|
||||||
D3DCAPS9 caps;
|
D3DCAPS9 caps;
|
||||||
|
D3DDEVICE_CREATION_PARAMETERS params;
|
||||||
|
IDirect3D9 *d3d = NULL;
|
||||||
|
D3DDISPLAYMODE mode;
|
||||||
|
HRESULT hr;
|
||||||
|
D3DFORMAT usedformat = D3DFMT_UNKNOWN;
|
||||||
|
|
||||||
TRACE("(%p, %p, %p, %p, %u, %p, %u)\n", device, width, height, miplevels, usage, format, pool);
|
TRACE("(%p, %p, %p, %p, %u, %p, %u)\n", device, width, height, miplevels, usage, format, pool);
|
||||||
|
|
||||||
@ -129,8 +134,9 @@ HRESULT WINAPI D3DXCheckTextureRequirements(LPDIRECT3DDEVICE9 device,
|
|||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
/* usage */
|
/* usage */
|
||||||
if ((usage != D3DX_DEFAULT) &&
|
if (usage == D3DX_DEFAULT)
|
||||||
(usage & (D3DUSAGE_WRITEONLY | D3DUSAGE_DONOTCLIP | D3DUSAGE_POINTS | D3DUSAGE_RTPATCHES | D3DUSAGE_NPATCHES)))
|
usage = 0;
|
||||||
|
if (usage & (D3DUSAGE_WRITEONLY | D3DUSAGE_DONOTCLIP | D3DUSAGE_POINTS | D3DUSAGE_RTPATCHES | D3DUSAGE_NPATCHES))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
/* pool */
|
/* pool */
|
||||||
@ -202,44 +208,106 @@ HRESULT WINAPI D3DXCheckTextureRequirements(LPDIRECT3DDEVICE9 device,
|
|||||||
/* format */
|
/* format */
|
||||||
if (format)
|
if (format)
|
||||||
{
|
{
|
||||||
D3DDEVICE_CREATION_PARAMETERS params;
|
TRACE("Requested format %x\n", *format);
|
||||||
IDirect3D9 *d3d = NULL;
|
usedformat = *format;
|
||||||
D3DDISPLAYMODE mode;
|
}
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
|
hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
hr = IDirect3DDevice9_GetCreationParameters(device, ¶ms);
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
hr = IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if ((usedformat == D3DFMT_UNKNOWN) || (usedformat == D3DX_DEFAULT))
|
||||||
|
usedformat = D3DFMT_A8R8G8B8;
|
||||||
|
|
||||||
|
hr = IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType, mode.Format,
|
||||||
|
usage, D3DRTYPE_TEXTURE, usedformat);
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
/* Heuristic to choose the fallback format */
|
||||||
|
const PixelFormatDesc *fmt = get_format_info(usedformat);
|
||||||
|
BOOL allow_24bits;
|
||||||
|
int bestscore = INT_MIN, i = 0, j;
|
||||||
|
unsigned int channels;
|
||||||
|
const PixelFormatDesc *curfmt;
|
||||||
|
|
||||||
|
if (!fmt)
|
||||||
|
{
|
||||||
|
FIXME("Pixel format %x not handled\n", usedformat);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
hr = IDirect3DDevice9_GetCreationParameters(device, ¶ms);
|
allow_24bits = fmt->bytes_per_pixel == 3;
|
||||||
|
channels = (fmt->bits[0] ? 1 : 0) + (fmt->bits[1] ? 1 : 0)
|
||||||
|
+ (fmt->bits[2] ? 1 : 0) + (fmt->bits[3] ? 1 : 0);
|
||||||
|
usedformat = D3DFMT_UNKNOWN;
|
||||||
|
|
||||||
if (FAILED(hr))
|
while ((curfmt = get_format_info_idx(i)))
|
||||||
goto cleanup;
|
{
|
||||||
|
unsigned int curchannels = (curfmt->bits[0] ? 1 : 0) + (curfmt->bits[1] ? 1 : 0)
|
||||||
|
+ (curfmt->bits[2] ? 1 : 0) + (curfmt->bits[3] ? 1 : 0);
|
||||||
|
int score;
|
||||||
|
|
||||||
hr = IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
|
i++;
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (curchannels < channels)
|
||||||
goto cleanup;
|
continue;
|
||||||
|
if (curfmt->bytes_per_pixel == 3 && !allow_24bits)
|
||||||
|
continue;
|
||||||
|
|
||||||
if ((*format == D3DFMT_UNKNOWN) || (*format == D3DX_DEFAULT))
|
hr = IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
|
||||||
*format = D3DFMT_A8R8G8B8;
|
mode.Format, usage, D3DRTYPE_TEXTURE, curfmt->format);
|
||||||
|
if (FAILED(hr))
|
||||||
|
continue;
|
||||||
|
|
||||||
hr = IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType, mode.Format, usage,
|
/* This format can be used, let's evaluate it.
|
||||||
D3DRTYPE_TEXTURE, *format);
|
Weights chosen quite arbitrarily... */
|
||||||
|
score = 16 - 4 * (curchannels - channels);
|
||||||
|
|
||||||
if (FAILED(hr))
|
for (j = 0; j < 4; j++)
|
||||||
FIXME("Pixel format adjustment not implemented yet\n");
|
{
|
||||||
|
int diff = curfmt->bits[j] - fmt->bits[j];
|
||||||
|
score += 16 - (diff < 0 ? -diff * 4 : diff);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (score > bestscore)
|
||||||
|
{
|
||||||
|
bestscore = score;
|
||||||
|
usedformat = curfmt->format;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hr = D3D_OK;
|
||||||
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
|
||||||
if (d3d)
|
if (d3d)
|
||||||
IDirect3D9_Release(d3d);
|
IDirect3D9_Release(d3d);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return D3DERR_INVALIDCALL;
|
return hr;
|
||||||
|
|
||||||
|
if (usedformat == D3DFMT_UNKNOWN)
|
||||||
|
{
|
||||||
|
WARN("Couldn't find a suitable pixel format\n");
|
||||||
|
return D3DERR_NOTAVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("Format chosen: %x\n", usedformat);
|
||||||
|
if (format)
|
||||||
|
*format = usedformat;
|
||||||
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,3 +152,12 @@ const PixelFormatDesc *get_format_info(D3DFORMAT format)
|
|||||||
while(formats[i].format != format && formats[i].format != D3DFMT_UNKNOWN) i++;
|
while(formats[i].format != format && formats[i].format != D3DFMT_UNKNOWN) i++;
|
||||||
return &formats[i];
|
return &formats[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PixelFormatDesc *get_format_info_idx(int idx)
|
||||||
|
{
|
||||||
|
if(idx >= sizeof(formats) / sizeof(formats[0]))
|
||||||
|
return NULL;
|
||||||
|
if(formats[idx].format == D3DFMT_UNKNOWN)
|
||||||
|
return NULL;
|
||||||
|
return &formats[idx];
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user