wined3d: No bounds checking is done on sampler / texture numbers.
This commit is contained in:
parent
1f1d0cda22
commit
bbcf98209c
|
@ -942,6 +942,64 @@ cleanup:
|
||||||
if(hwnd) DestroyWindow(hwnd);
|
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)
|
START_TEST(device)
|
||||||
{
|
{
|
||||||
HMODULE d3d8_handle = LoadLibraryA( "d3d8.dll" );
|
HMODULE d3d8_handle = LoadLibraryA( "d3d8.dll" );
|
||||||
|
@ -964,5 +1022,6 @@ START_TEST(device)
|
||||||
test_states();
|
test_states();
|
||||||
test_scene();
|
test_scene();
|
||||||
test_shader();
|
test_shader();
|
||||||
|
test_limits();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1094,6 +1094,69 @@ cleanup:
|
||||||
if(hwnd) DestroyWindow(hwnd);
|
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)
|
START_TEST(device)
|
||||||
{
|
{
|
||||||
HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" );
|
HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" );
|
||||||
|
@ -1114,5 +1177,6 @@ START_TEST(device)
|
||||||
test_cursor();
|
test_cursor();
|
||||||
test_reset();
|
test_reset();
|
||||||
test_scene();
|
test_scene();
|
||||||
|
test_limits();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -521,6 +521,35 @@ static void SceneTest(void)
|
||||||
/* TODO: Verify that blitting works in the same way as in d3d9 */
|
/* 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)
|
START_TEST(d3d)
|
||||||
{
|
{
|
||||||
init_function_pointers();
|
init_function_pointers();
|
||||||
|
@ -537,5 +566,6 @@ START_TEST(d3d)
|
||||||
ProcessVerticesTest();
|
ProcessVerticesTest();
|
||||||
StateTest();
|
StateTest();
|
||||||
SceneTest();
|
SceneTest();
|
||||||
|
LimitTest();
|
||||||
ReleaseDirect3D();
|
ReleaseDirect3D();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2695,12 +2695,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetSamplerState(IWineD3DDevice *iface,
|
||||||
* GL_MAX_TEXTURE_COORDS_ARB.
|
* GL_MAX_TEXTURE_COORDS_ARB.
|
||||||
* Ok GForce say it's ok to use glTexParameter/glGetTexParameter(...).
|
* 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,
|
TRACE("(%p) : Sampler=%d, Type=%s(%d), Value=%d\n", This, Sampler,
|
||||||
debug_d3dsamplerstate(Type), Type, Value);
|
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) {
|
static HRESULT WINAPI IWineD3DDeviceImpl_GetSamplerState(IWineD3DDevice *iface, DWORD Sampler, WINED3DSAMPLERSTATETYPE Type, DWORD* Value) {
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||||
/** TODO: check that sampler is in range **/
|
|
||||||
*Value = This->stateBlock->samplerState[Sampler][Type];
|
*Value = This->stateBlock->samplerState[Sampler][Type];
|
||||||
TRACE("(%p) : Sampler %d Type %u Returning %d\n", This, Sampler, Type, *Value);
|
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);
|
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->changed.textureState[Stage][Type] = TRUE;
|
||||||
This->updateStateBlock->set.textureState[Stage][Type] = TRUE;
|
This->updateStateBlock->set.textureState[Stage][Type] = TRUE;
|
||||||
This->updateStateBlock->textureState[Stage][Type] = Value;
|
This->updateStateBlock->textureState[Stage][Type] = Value;
|
||||||
|
@ -3789,12 +3776,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTexture(IWineD3DDevice *iface, DWORD
|
||||||
}
|
}
|
||||||
#endif
|
#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) {
|
if(pTexture != NULL) {
|
||||||
/* SetTexture isn't allowed on textures in WINED3DPOOL_SCRATCH;
|
/* 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;
|
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||||
TRACE("(%p) : (%d /* Stage */,%p /* ppTexture */)\n", This, Stage, ppTexture);
|
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];
|
*ppTexture=This->stateBlock->textures[Stage];
|
||||||
if (*ppTexture)
|
if (*ppTexture)
|
||||||
IWineD3DBaseTexture_AddRef(*ppTexture);
|
IWineD3DBaseTexture_AddRef(*ppTexture);
|
||||||
|
|
Loading…
Reference in New Issue