Commit bbcf9820 authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

wined3d: No bounds checking is done on sampler / texture numbers.

parent 1f1d0cda
......@@ -942,6 +942,64 @@ cleanup:
if(hwnd) DestroyWindow(hwnd);
}
static void test_limits(void)
{
HRESULT hr;
HWND hwnd = NULL;
IDirect3D8 *pD3d = NULL;
IDirect3DDevice8 *pDevice = NULL;
D3DPRESENT_PARAMETERS d3dpp;
D3DDISPLAYMODE d3ddm;
IDirect3DTexture8 *pTexture = NULL;
int i;
pD3d = pDirect3DCreate8( D3D_SDK_VERSION );
ok(pD3d != NULL, "Failed to create IDirect3D8 object\n");
hwnd = CreateWindow( "static", "d3d8_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
ok(hwnd != NULL, "Failed to create window\n");
if (!pD3d || !hwnd) goto cleanup;
IDirect3D8_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferWidth = 800;
d3dpp.BackBufferHeight = 600;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
hr = IDirect3D8_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
ok(hr == D3D_OK, "IDirect3D8_CreateDevice failed with %s\n", DXGetErrorString8(hr));
if(!pDevice) goto cleanup;
hr = IDirect3DDevice8_CreateTexture(pDevice, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTexture);
ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed with %s\n", DXGetErrorString8(hr));
if(!pTexture) goto cleanup;
/* There are 8 texture stages. We should be able to access all of them */
for(i = 0; i < 8; i++) {
hr = IDirect3DDevice8_SetTexture(pDevice, i, (IDirect3DBaseTexture8 *) pTexture);
ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %s\n", i, DXGetErrorString8(hr));
hr = IDirect3DDevice8_SetTexture(pDevice, i, NULL);
ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %s\n", i, DXGetErrorString8(hr));
hr = IDirect3DDevice8_SetTextureStageState(pDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %s\n", i, DXGetErrorString8(hr));
}
/* Investigations show that accessing higher textures stage states does not return an error either. Writing
* to too high texture stages(approximately texture 40) causes memory corruption in windows, so there is no
* bounds checking but how do I test that?
*/
cleanup:
if(pTexture) IDirect3DTexture8_Release(pTexture);
if(pD3d) IDirect3D8_Release(pD3d);
if(pDevice) IDirect3D8_Release(pDevice);
if(hwnd) DestroyWindow(hwnd);
}
START_TEST(device)
{
HMODULE d3d8_handle = LoadLibraryA( "d3d8.dll" );
......@@ -964,5 +1022,6 @@ START_TEST(device)
test_states();
test_scene();
test_shader();
test_limits();
}
}
......@@ -1094,6 +1094,69 @@ cleanup:
if(hwnd) DestroyWindow(hwnd);
}
static void test_limits(void)
{
HRESULT hr;
HWND hwnd = NULL;
IDirect3D9 *pD3d = NULL;
IDirect3DDevice9 *pDevice = NULL;
D3DPRESENT_PARAMETERS d3dpp;
D3DDISPLAYMODE d3ddm;
IDirect3DTexture9 *pTexture = NULL;
int i;
pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
ok(hwnd != NULL, "Failed to create window\n");
if (!pD3d || !hwnd) goto cleanup;
IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferWidth = 800;
d3dpp.BackBufferHeight = 600;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
ok(hr == D3D_OK, "IDirect3D9_CreateDevice failed with %s\n", DXGetErrorString9(hr));
if(!pDevice) goto cleanup;
hr = IDirect3DDevice9_CreateTexture(pDevice, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTexture, NULL);
ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
if(!pTexture) goto cleanup;
/* There are 16 pixel samplers. We should be able to access all of them */
for(i = 0; i < 16; i++) {
hr = IDirect3DDevice9_SetTexture(pDevice, i, (IDirect3DBaseTexture9 *) pTexture);
ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %s\n", i, DXGetErrorString9(hr));
hr = IDirect3DDevice9_SetTexture(pDevice, i, NULL);
ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %s\n", i, DXGetErrorString9(hr));
hr = IDirect3DDevice9_SetSamplerState(pDevice, i, D3DSAMP_SRGBTEXTURE, TRUE);
ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState for sampler %d failed with %s\n", i, DXGetErrorString9(hr));
}
/* Now test all 8 textures stage states */
for(i = 0; i < 8; i++) {
hr = IDirect3DDevice9_SetTextureStageState(pDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState for texture %d failed with %s\n", i, DXGetErrorString9(hr));
}
/* Investigations show that accessing higher samplers / textures stage states does not return an error either. Writing
* to too high samplers(approximately sampler 40) causes memory corruption in windows, so there is no bounds checking
* but how do I test that?
*/
cleanup:
if(pTexture) IDirect3DTexture9_Release(pTexture);
if(pD3d) IDirect3D9_Release(pD3d);
if(pDevice) IDirect3D9_Release(pDevice);
if(hwnd) DestroyWindow(hwnd);
}
START_TEST(device)
{
HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" );
......@@ -1114,5 +1177,6 @@ START_TEST(device)
test_cursor();
test_reset();
test_scene();
test_limits();
}
}
......@@ -521,6 +521,35 @@ static void SceneTest(void)
/* TODO: Verify that blitting works in the same way as in d3d9 */
}
static void LimitTest(void)
{
IDirectDrawSurface7 *pTexture = NULL;
HRESULT hr;
int i;
DDSURFACEDESC2 ddsd;
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
ddsd.dwWidth = 16;
ddsd.dwHeight = 16;
hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL);
ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
if(!pTexture) return;
for(i = 0; i < 8; i++) {
hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture);
ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL);
ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr);
hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD);
ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr);
}
IDirectDrawSurface7_Release(pTexture);
}
START_TEST(d3d)
{
init_function_pointers();
......@@ -537,5 +566,6 @@ START_TEST(d3d)
ProcessVerticesTest();
StateTest();
SceneTest();
LimitTest();
ReleaseDirect3D();
}
......@@ -2695,12 +2695,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetSamplerState(IWineD3DDevice *iface,
* GL_MAX_TEXTURE_COORDS_ARB.
* Ok GForce say it's ok to use glTexParameter/glGetTexParameter(...).
******************/
/** NOTE: States are applied in IWineD3DBaseTextre ApplyStateChanges the sampler state handler**/
if(Sampler > GL_LIMITS(sampler_stages) || Sampler < 0 || Type > WINED3D_HIGHEST_SAMPLER_STATE || Type < 0) {
FIXME("sampler %d type %s(%u) is out of range [max_samplers=%d, highest_state=%d]\n",
Sampler, debug_d3dsamplerstate(Type), Type, GL_LIMITS(sampler_stages), WINED3D_HIGHEST_SAMPLER_STATE);
return WINED3DERR_INVALIDCALL;
}
TRACE("(%p) : Sampler=%d, Type=%s(%d), Value=%d\n", This, Sampler,
debug_d3dsamplerstate(Type), Type, Value);
......@@ -2726,7 +2720,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetSamplerState(IWineD3DDevice *iface,
static HRESULT WINAPI IWineD3DDeviceImpl_GetSamplerState(IWineD3DDevice *iface, DWORD Sampler, WINED3DSAMPLERSTATETYPE Type, DWORD* Value) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
/** TODO: check that sampler is in range **/
*Value = This->stateBlock->samplerState[Sampler][Type];
TRACE("(%p) : Sampler %d Type %u Returning %d\n", This, Sampler, Type, *Value);
......@@ -3685,12 +3678,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTextureStageState(IWineD3DDevice *if
TRACE("(%p) : Stage=%d, Type=%s(%d), Value=%d\n", This, Stage, debug_d3dtexturestate(Type), Type, Value);
/* Reject invalid texture units */
if (Stage >= GL_LIMITS(texture_stages)) {
TRACE("Attempt to access invalid texture rejected\n");
return WINED3DERR_INVALIDCALL;
}
This->updateStateBlock->changed.textureState[Stage][Type] = TRUE;
This->updateStateBlock->set.textureState[Stage][Type] = TRUE;
This->updateStateBlock->textureState[Stage][Type] = Value;
......@@ -3789,12 +3776,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTexture(IWineD3DDevice *iface, DWORD
}
#endif
/* Reject invalid texture units */
if (Stage >= GL_LIMITS(sampler_stages) || Stage < 0) {
WARN("Attempt to access invalid texture rejected\n");
return WINED3DERR_INVALIDCALL;
}
if(pTexture != NULL) {
/* SetTexture isn't allowed on textures in WINED3DPOOL_SCRATCH;
*/
......@@ -3888,11 +3869,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetTexture(IWineD3DDevice *iface, DWORD
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
TRACE("(%p) : (%d /* Stage */,%p /* ppTexture */)\n", This, Stage, ppTexture);
/* Reject invalid texture units */
if (Stage >= GL_LIMITS(sampler_stages)) {
TRACE("Attempt to access invalid texture rejected\n");
return WINED3DERR_INVALIDCALL;
}
*ppTexture=This->stateBlock->textures[Stage];
if (*ppTexture)
IWineD3DBaseTexture_AddRef(*ppTexture);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment