wined3d: Validate and handle query size parameter.
This commit is contained in:
parent
7162820845
commit
b42fe709d6
|
@ -153,8 +153,11 @@ static HRESULT WINAPI d3d9_query_GetData(IDirect3DQuery9 *iface, void *data, DWO
|
|||
{
|
||||
struct wined3d_query_data_timestamp_disjoint data_disjoint;
|
||||
|
||||
if (size > sizeof(data_disjoint.disjoint))
|
||||
size = sizeof(data_disjoint.disjoint);
|
||||
|
||||
hr = wined3d_query_get_data(query->wined3d_query, &data_disjoint, sizeof(data_disjoint), flags);
|
||||
*(BOOL *)data = data_disjoint.disjoint;
|
||||
memcpy(data, &data_disjoint.disjoint, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -4631,7 +4631,7 @@ static void test_occlusion_query_states(void)
|
|||
if (!broken_occlusion)
|
||||
ok(data.word[0] == (WORD)expected,
|
||||
"Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
|
||||
todo_wine ok(data.word[1] == 0xffff,
|
||||
ok(data.word[1] == 0xffff,
|
||||
"data was modified outside of the expected size (0x%.8x).\n", data.dword[0]);
|
||||
|
||||
memset(&data, 0xf0, sizeof(data));
|
||||
|
@ -4652,7 +4652,7 @@ static void test_occlusion_query_states(void)
|
|||
memset(&data, 0xff, sizeof(data));
|
||||
hr = IDirect3DQuery9_GetData(query, &data, 0, D3DGETDATA_FLUSH);
|
||||
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
||||
todo_wine ok(data.dword[0] == 0xffffffff, "Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
|
||||
ok(data.dword[0] == 0xffffffff, "Occlusion query returned an unexpected result (0x%.8x).\n", data.dword[0]);
|
||||
|
||||
/* This crashes on Windows. */
|
||||
if (0)
|
||||
|
@ -4744,7 +4744,7 @@ static void test_timestamp_query(void)
|
|||
memset(freq, 0xff, sizeof(freq));
|
||||
hr = IDirect3DQuery9_GetData(freq_query, freq, sizeof(DWORD), D3DGETDATA_FLUSH);
|
||||
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
||||
todo_wine ok(freq[1] == 0xffffffff,
|
||||
ok(freq[1] == 0xffffffff,
|
||||
"freq was modified outside of the expected size (0x%.8x).\n", freq[1]);
|
||||
hr = IDirect3DQuery9_GetData(freq_query, &freq, sizeof(freq), D3DGETDATA_FLUSH);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
@ -4788,7 +4788,7 @@ static void test_timestamp_query(void)
|
|||
memset(timestamp, 0xff, sizeof(timestamp));
|
||||
hr = IDirect3DQuery9_GetData(query, timestamp, sizeof(DWORD), D3DGETDATA_FLUSH);
|
||||
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
||||
todo_wine ok(timestamp[1] == 0xffffffff,
|
||||
ok(timestamp[1] == 0xffffffff,
|
||||
"timestamp was modified outside of the expected size (0x%.8x).\n",
|
||||
timestamp[1]);
|
||||
|
||||
|
@ -4812,7 +4812,7 @@ static void test_timestamp_query(void)
|
|||
memset(disjoint, 0xff, sizeof(disjoint));
|
||||
hr = IDirect3DQuery9_GetData(disjoint_query, disjoint, sizeof(WORD), D3DGETDATA_FLUSH);
|
||||
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
||||
todo_wine ok(disjoint[1] == 0xffff,
|
||||
ok(disjoint[1] == 0xffff,
|
||||
"disjoint was modified outside of the expected size (0x%.4hx).\n", disjoint[1]);
|
||||
hr = IDirect3DQuery9_GetData(disjoint_query, disjoint, sizeof(disjoint), D3DGETDATA_FLUSH);
|
||||
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
|
|
@ -295,19 +295,23 @@ HRESULT CDECL wined3d_query_issue(struct wined3d_query *query, DWORD flags)
|
|||
return query->query_ops->query_issue(query, flags);
|
||||
}
|
||||
|
||||
static void fill_query_data(void *out, unsigned int out_size, const void *result, unsigned int result_size)
|
||||
{
|
||||
memcpy(out, result, min(out_size, result_size));
|
||||
}
|
||||
|
||||
static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query,
|
||||
void *pData, DWORD dwSize, DWORD flags)
|
||||
void *data, DWORD size, DWORD flags)
|
||||
{
|
||||
struct wined3d_occlusion_query *oq = query->extendedData;
|
||||
struct wined3d_device *device = query->device;
|
||||
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
|
||||
struct wined3d_context *context;
|
||||
DWORD* data = pData;
|
||||
GLuint available;
|
||||
GLuint samples;
|
||||
HRESULT res;
|
||||
|
||||
TRACE("(%p) : type D3DQUERY_OCCLUSION, pData %p, dwSize %#x, flags %#x.\n", query, pData, dwSize, flags);
|
||||
TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags);
|
||||
|
||||
if (!oq->context)
|
||||
query->state = QUERY_CREATED;
|
||||
|
@ -316,7 +320,8 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query,
|
|||
{
|
||||
/* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves */
|
||||
TRACE("Query wasn't yet started, returning S_OK\n");
|
||||
if(data) *data = 0;
|
||||
samples = 0;
|
||||
fill_query_data(data, size, &samples, sizeof(samples));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -330,14 +335,16 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query,
|
|||
if (!gl_info->supported[ARB_OCCLUSION_QUERY])
|
||||
{
|
||||
WARN("%p Occlusion queries not supported. Returning 1.\n", query);
|
||||
*data = 1;
|
||||
samples = 1;
|
||||
fill_query_data(data, size, &samples, sizeof(samples));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (oq->context->tid != GetCurrentThreadId())
|
||||
{
|
||||
FIXME("%p Wrong thread, returning 1.\n", query);
|
||||
*data = 1;
|
||||
samples = 1;
|
||||
fill_query_data(data, size, &samples, sizeof(samples));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -349,12 +356,12 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query,
|
|||
|
||||
if (available)
|
||||
{
|
||||
if (data)
|
||||
if (size)
|
||||
{
|
||||
GL_EXTCALL(glGetQueryObjectuivARB(oq->id, GL_QUERY_RESULT_ARB, &samples));
|
||||
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)");
|
||||
TRACE("Returning %d samples.\n", samples);
|
||||
*data = samples;
|
||||
fill_query_data(data, size, &samples, sizeof(samples));
|
||||
}
|
||||
res = S_OK;
|
||||
}
|
||||
|
@ -369,19 +376,20 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query,
|
|||
}
|
||||
|
||||
static HRESULT wined3d_event_query_ops_get_data(struct wined3d_query *query,
|
||||
void *pData, DWORD dwSize, DWORD flags)
|
||||
void *data, DWORD size, DWORD flags)
|
||||
{
|
||||
struct wined3d_event_query *event_query = query->extendedData;
|
||||
BOOL *data = pData;
|
||||
BOOL signaled;
|
||||
enum wined3d_event_query_result ret;
|
||||
|
||||
TRACE("query %p, pData %p, dwSize %#x, flags %#x.\n", query, pData, dwSize, flags);
|
||||
TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags);
|
||||
|
||||
if (!pData || !dwSize) return S_OK;
|
||||
if (!data || !size) return S_OK;
|
||||
if (!event_query)
|
||||
{
|
||||
WARN("Event query not supported by GL, reporting GPU idle.\n");
|
||||
*data = TRUE;
|
||||
signaled = TRUE;
|
||||
fill_query_data(data, size, &signaled, sizeof(signaled));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -390,16 +398,19 @@ static HRESULT wined3d_event_query_ops_get_data(struct wined3d_query *query,
|
|||
{
|
||||
case WINED3D_EVENT_QUERY_OK:
|
||||
case WINED3D_EVENT_QUERY_NOT_STARTED:
|
||||
*data = TRUE;
|
||||
signaled = TRUE;
|
||||
fill_query_data(data, size, &signaled, sizeof(signaled));
|
||||
break;
|
||||
|
||||
case WINED3D_EVENT_QUERY_WAITING:
|
||||
*data = FALSE;
|
||||
signaled = FALSE;
|
||||
fill_query_data(data, size, &signaled, sizeof(signaled));
|
||||
break;
|
||||
|
||||
case WINED3D_EVENT_QUERY_WRONG_THREAD:
|
||||
FIXME("(%p) Wrong thread, reporting GPU idle.\n", query);
|
||||
*data = TRUE;
|
||||
signaled = TRUE;
|
||||
fill_query_data(data, size, &signaled, sizeof(signaled));
|
||||
break;
|
||||
|
||||
case WINED3D_EVENT_QUERY_ERROR:
|
||||
|
@ -534,12 +545,11 @@ static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query,
|
|||
struct wined3d_device *device = query->device;
|
||||
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
|
||||
struct wined3d_context *context;
|
||||
UINT64 *u64data = data;
|
||||
GLuint available;
|
||||
GLuint64 timestamp;
|
||||
HRESULT res;
|
||||
|
||||
TRACE("(%p) : type D3DQUERY_TIMESTAMP, data %p, size %#x, flags %#x.\n", query, data, size, flags);
|
||||
TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags);
|
||||
|
||||
if (!tq->context)
|
||||
query->state = QUERY_CREATED;
|
||||
|
@ -548,16 +558,16 @@ static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query,
|
|||
{
|
||||
/* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves. */
|
||||
TRACE("Query wasn't yet started, returning S_OK.\n");
|
||||
if (u64data)
|
||||
*u64data = 0;
|
||||
timestamp = 0;
|
||||
fill_query_data(data, size, ×tamp, sizeof(timestamp));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (tq->context->tid != GetCurrentThreadId())
|
||||
{
|
||||
FIXME("%p Wrong thread, returning 1.\n", query);
|
||||
if (u64data)
|
||||
*u64data = 1;
|
||||
timestamp = 1;
|
||||
fill_query_data(data, size, ×tamp, sizeof(timestamp));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -569,12 +579,12 @@ static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query,
|
|||
|
||||
if (available)
|
||||
{
|
||||
if (u64data)
|
||||
if (size)
|
||||
{
|
||||
GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT_ARB, ×tamp));
|
||||
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)");
|
||||
TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp));
|
||||
*u64data = timestamp;
|
||||
fill_query_data(data, size, ×tamp, sizeof(timestamp));
|
||||
}
|
||||
res = S_OK;
|
||||
}
|
||||
|
@ -629,11 +639,11 @@ static HRESULT wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DW
|
|||
static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_query *query,
|
||||
void *data, DWORD size, DWORD flags)
|
||||
{
|
||||
TRACE("(%p) : type D3DQUERY_TIMESTAMP_DISJOINT, data %p, size %#x, flags %#x.\n", query, data, size, flags);
|
||||
TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags);
|
||||
|
||||
if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT)
|
||||
{
|
||||
struct wined3d_query_data_timestamp_disjoint *disjoint_data = data;
|
||||
static const struct wined3d_query_data_timestamp_disjoint disjoint_data = {FALSE, 1000 * 1000 * 1000};
|
||||
|
||||
if (query->state == QUERY_BUILDING)
|
||||
{
|
||||
|
@ -641,18 +651,13 @@ static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_quer
|
|||
return S_FALSE;
|
||||
}
|
||||
|
||||
if (disjoint_data)
|
||||
{
|
||||
disjoint_data->disjoint = FALSE;
|
||||
disjoint_data->frequency = 1000 * 1000 * 1000;
|
||||
}
|
||||
fill_query_data(data, size, &disjoint_data, sizeof(disjoint_data));
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT64 *u64data = data;
|
||||
static const UINT64 freq = 1000 * 1000 * 1000;
|
||||
|
||||
if (u64data)
|
||||
*u64data = 1000 * 1000 * 1000;
|
||||
fill_query_data(data, size, &freq, sizeof(freq));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue