[WINED3D] Sync with Wine Staging 2.16. CORE-13762

svn path=/trunk/; revision=75847
This commit is contained in:
Amine Khaldi 2017-09-16 20:43:40 +00:00
parent e42a504524
commit 3d13ed394e
25 changed files with 2538 additions and 1418 deletions

View file

@ -1188,6 +1188,8 @@ static void shader_arb_get_register_name(const struct wined3d_shader_instruction
sprintf(register_name, "%s", rastout_reg_names[reg->idx[0].offset]);
break;
case WINED3DSPR_DEPTHOUT_GREATER_EQUAL:
case WINED3DSPR_DEPTHOUT_LESS_EQUAL:
case WINED3DSPR_DEPTHOUT:
strcpy(register_name, "result.depth");
break;
@ -4971,21 +4973,8 @@ static void shader_arb_get_caps(const struct wined3d_gl_info *gl_info, struct sh
static BOOL shader_arb_color_fixup_supported(struct color_fixup_desc fixup)
{
if (TRACE_ON(d3d_shader) && TRACE_ON(d3d))
{
TRACE("Checking support for color_fixup:\n");
dump_color_fixup_desc(fixup);
}
/* We support everything except complex conversions. */
if (!is_complex_fixup(fixup))
{
TRACE("[OK]\n");
return TRUE;
}
TRACE("[FAILED]\n");
return FALSE;
return !is_complex_fixup(fixup);
}
static void shader_arb_add_instruction_modifiers(const struct wined3d_shader_instruction *ins) {

View file

@ -1346,22 +1346,9 @@ static void atifs_free(struct wined3d_device *device)
static BOOL atifs_color_fixup_supported(struct color_fixup_desc fixup)
{
if (TRACE_ON(d3d_shader) && TRACE_ON(d3d))
{
TRACE("Checking support for fixup:\n");
dump_color_fixup_desc(fixup);
}
/* We only support sign fixup of the first two channels. */
if (is_identity_fixup(fixup) || is_same_fixup(fixup, color_fixup_rg)
|| is_same_fixup(fixup, color_fixup_rgl) || is_same_fixup(fixup, color_fixup_rgba))
{
TRACE("[OK]\n");
return TRUE;
}
TRACE("[FAILED]\n");
return FALSE;
return is_identity_fixup(fixup) || is_same_fixup(fixup, color_fixup_rg)
|| is_same_fixup(fixup, color_fixup_rgl) || is_same_fixup(fixup, color_fixup_rgba);
}
static BOOL atifs_alloc_context_data(struct wined3d_context *context)

View file

@ -182,10 +182,10 @@ static void buffer_destroy_buffer_object(struct wined3d_buffer *buffer, struct w
checkGLcall("glDeleteBuffers");
buffer->buffer_object = 0;
if (buffer->query)
if (buffer->fence)
{
wined3d_event_query_destroy(buffer->query);
buffer->query = NULL;
wined3d_fence_destroy(buffer->fence);
buffer->fence = NULL;
}
buffer->flags &= ~WINED3D_BUFFER_APPLESYNC;
}
@ -808,9 +808,10 @@ void * CDECL wined3d_buffer_get_parent(const struct wined3d_buffer *buffer)
}
/* The caller provides a context and binds the buffer */
static void buffer_sync_apple(struct wined3d_buffer *This, DWORD flags, const struct wined3d_gl_info *gl_info)
static void buffer_sync_apple(struct wined3d_buffer *buffer, DWORD flags, const struct wined3d_gl_info *gl_info)
{
enum wined3d_event_query_result ret;
enum wined3d_fence_result ret;
HRESULT hr;
/* No fencing needs to be done if the app promises not to overwrite
* existing data. */
@ -819,61 +820,58 @@ static void buffer_sync_apple(struct wined3d_buffer *This, DWORD flags, const st
if (flags & WINED3D_MAP_DISCARD)
{
GL_EXTCALL(glBufferData(This->buffer_type_hint, This->resource.size, NULL, This->buffer_object_usage));
GL_EXTCALL(glBufferData(buffer->buffer_type_hint, buffer->resource.size, NULL, buffer->buffer_object_usage));
checkGLcall("glBufferData");
return;
}
if(!This->query)
if (!buffer->fence)
{
TRACE("Creating event query for buffer %p\n", This);
TRACE("Creating fence for buffer %p.\n", buffer);
if (!wined3d_event_query_supported(gl_info))
if (FAILED(hr = wined3d_fence_create(buffer->resource.device, &buffer->fence)))
{
FIXME("Event queries not supported, dropping async buffer locks.\n");
goto drop_query;
}
This->query = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This->query));
if (!This->query)
{
ERR("Failed to allocate event query memory, dropping async buffer locks.\n");
goto drop_query;
if (hr == WINED3DERR_NOTAVAILABLE)
FIXME("Fences not supported, dropping async buffer locks.\n");
else
ERR("Failed to create fence, hr %#x.\n", hr);
goto drop_fence;
}
/* Since we don't know about old draws a glFinish is needed once */
gl_info->gl_ops.gl.p_glFinish();
return;
}
TRACE("Synchronizing buffer %p\n", This);
ret = wined3d_event_query_finish(This->query, This->resource.device);
switch(ret)
TRACE("Synchronizing buffer %p.\n", buffer);
ret = wined3d_fence_wait(buffer->fence, buffer->resource.device);
switch (ret)
{
case WINED3D_EVENT_QUERY_NOT_STARTED:
case WINED3D_EVENT_QUERY_OK:
case WINED3D_FENCE_NOT_STARTED:
case WINED3D_FENCE_OK:
/* All done */
return;
case WINED3D_EVENT_QUERY_WRONG_THREAD:
WARN("Cannot synchronize buffer lock due to a thread conflict\n");
goto drop_query;
case WINED3D_FENCE_WRONG_THREAD:
WARN("Cannot synchronize buffer lock due to a thread conflict.\n");
goto drop_fence;
default:
ERR("wined3d_event_query_finish returned %u, dropping async buffer locks\n", ret);
goto drop_query;
ERR("wined3d_fence_wait() returned %u, dropping async buffer locks.\n", ret);
goto drop_fence;
}
drop_query:
if(This->query)
drop_fence:
if (buffer->fence)
{
wined3d_event_query_destroy(This->query);
This->query = NULL;
wined3d_fence_destroy(buffer->fence);
buffer->fence = NULL;
}
gl_info->gl_ops.gl.p_glFinish();
GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE));
checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)");
This->flags &= ~WINED3D_BUFFER_APPLESYNC;
GL_EXTCALL(glBufferParameteriAPPLE(buffer->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE));
checkGLcall("glBufferParameteriAPPLE(buffer->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)");
buffer->flags &= ~WINED3D_BUFFER_APPLESYNC;
}
static void buffer_mark_used(struct wined3d_buffer *buffer)
@ -1190,72 +1188,28 @@ static void wined3d_buffer_unmap(struct wined3d_buffer *buffer)
}
}
HRESULT wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_offset,
void wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_offset,
struct wined3d_buffer *src_buffer, unsigned int src_offset, unsigned int size)
{
const struct wined3d_gl_info *gl_info;
struct wined3d_bo_address dst, src;
struct wined3d_context *context;
struct wined3d_device *device;
BYTE *dst_ptr, *src_ptr;
DWORD dst_location;
buffer_mark_used(dst_buffer);
buffer_mark_used(src_buffer);
device = dst_buffer->resource.device;
context = context_acquire(device, NULL, 0);
gl_info = context->gl_info;
dst_location = wined3d_buffer_get_memory(dst_buffer, &dst, dst_buffer->locations);
dst.addr += dst_offset;
wined3d_buffer_get_memory(src_buffer, &src, src_buffer->locations);
src.addr += src_offset;
if (dst.buffer_object && src.buffer_object)
{
if (gl_info->supported[ARB_COPY_BUFFER])
{
GL_EXTCALL(glBindBuffer(GL_COPY_READ_BUFFER, src.buffer_object));
GL_EXTCALL(glBindBuffer(GL_COPY_WRITE_BUFFER, dst.buffer_object));
GL_EXTCALL(glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER,
src_offset, dst_offset, size));
checkGLcall("direct buffer copy");
}
else
{
src_ptr = context_map_bo_address(context, &src, size, src_buffer->buffer_type_hint, WINED3D_MAP_READONLY);
dst_ptr = context_map_bo_address(context, &dst, size, dst_buffer->buffer_type_hint, 0);
memcpy(dst_ptr, src_ptr, size);
context_unmap_bo_address(context, &dst, dst_buffer->buffer_type_hint);
context_unmap_bo_address(context, &src, src_buffer->buffer_type_hint);
}
}
else if (!dst.buffer_object && src.buffer_object)
{
buffer_bind(src_buffer, context);
GL_EXTCALL(glGetBufferSubData(src_buffer->buffer_type_hint, src_offset, size, dst.addr));
checkGLcall("buffer download");
}
else if (dst.buffer_object && !src.buffer_object)
{
buffer_bind(dst_buffer, context);
GL_EXTCALL(glBufferSubData(dst_buffer->buffer_type_hint, dst_offset, size, src.addr));
checkGLcall("buffer upload");
}
else
{
memcpy(dst.addr, src.addr, size);
}
context = context_acquire(dst_buffer->resource.device, NULL, 0);
context_copy_bo_address(context, &dst, dst_buffer->buffer_type_hint,
&src, src_buffer->buffer_type_hint, size);
context_release(context);
wined3d_buffer_invalidate_range(dst_buffer, ~dst_location, dst_offset, size);
context_release(context);
return WINED3D_OK;
}
HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer,

View file

@ -793,63 +793,63 @@ void context_free_occlusion_query(struct wined3d_occlusion_query *query)
}
/* Context activation is done by the caller. */
void context_alloc_event_query(struct wined3d_context *context, struct wined3d_event_query *query)
void context_alloc_fence(struct wined3d_context *context, struct wined3d_fence *fence)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
if (context->free_event_query_count)
if (context->free_fence_count)
{
query->object = context->free_event_queries[--context->free_event_query_count];
fence->object = context->free_fences[--context->free_fence_count];
}
else
{
if (gl_info->supported[ARB_SYNC])
{
/* Using ARB_sync, not much to do here. */
query->object.sync = NULL;
TRACE("Allocated event query %p in context %p.\n", query->object.sync, context);
fence->object.sync = NULL;
TRACE("Allocated sync object in context %p.\n", context);
}
else if (gl_info->supported[APPLE_FENCE])
{
GL_EXTCALL(glGenFencesAPPLE(1, &query->object.id));
GL_EXTCALL(glGenFencesAPPLE(1, &fence->object.id));
checkGLcall("glGenFencesAPPLE");
TRACE("Allocated event query %u in context %p.\n", query->object.id, context);
TRACE("Allocated fence %u in context %p.\n", fence->object.id, context);
}
else if(gl_info->supported[NV_FENCE])
{
GL_EXTCALL(glGenFencesNV(1, &query->object.id));
GL_EXTCALL(glGenFencesNV(1, &fence->object.id));
checkGLcall("glGenFencesNV");
TRACE("Allocated event query %u in context %p.\n", query->object.id, context);
TRACE("Allocated fence %u in context %p.\n", fence->object.id, context);
}
else
{
WARN("Event queries not supported, not allocating query id.\n");
query->object.id = 0;
WARN("Fences not supported, not allocating fence.\n");
fence->object.id = 0;
}
}
query->context = context;
list_add_head(&context->event_queries, &query->entry);
fence->context = context;
list_add_head(&context->fences, &fence->entry);
}
void context_free_event_query(struct wined3d_event_query *query)
void context_free_fence(struct wined3d_fence *fence)
{
struct wined3d_context *context = query->context;
struct wined3d_context *context = fence->context;
list_remove(&query->entry);
query->context = NULL;
list_remove(&fence->entry);
fence->context = NULL;
if (!wined3d_array_reserve((void **)&context->free_event_queries,
&context->free_event_query_size, context->free_event_query_count + 1,
sizeof(*context->free_event_queries)))
if (!wined3d_array_reserve((void **)&context->free_fences,
&context->free_fence_size, context->free_fence_count + 1,
sizeof(*context->free_fences)))
{
ERR("Failed to grow free list, leaking query %u in context %p.\n", query->object.id, context);
ERR("Failed to grow free list, leaking fence %u in context %p.\n", fence->object.id, context);
return;
}
context->free_event_queries[context->free_event_query_count++] = query->object;
context->free_fences[context->free_fence_count++] = fence->object;
}
/* Context activation is done by the caller. */
@ -1093,14 +1093,20 @@ static BOOL context_restore_pixel_format(struct wined3d_context *ctx)
return ret;
}
static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BOOL private, int format)
static BOOL context_set_pixel_format(struct wined3d_context *context)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
BOOL private = context->hdc_is_private;
int format = context->pixel_format;
HDC dc = context->hdc;
int current;
if (dc == context->hdc && context->hdc_is_private && context->hdc_has_format)
if (private && context->hdc_has_format)
return TRUE;
if (!private && WindowFromDC(dc) != context->win_handle)
return FALSE;
current = gl_info->gl_ops.wgl.p_wglGetPixelFormat(dc);
if (current == format) goto success;
@ -1155,7 +1161,7 @@ static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BO
return TRUE;
success:
if (dc == context->hdc && context->hdc_is_private)
if (private)
context->hdc_has_format = TRUE;
return TRUE;
}
@ -1165,7 +1171,7 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx)
struct wined3d_swapchain *swapchain = ctx->swapchain;
BOOL backup = FALSE;
if (!context_set_pixel_format(ctx, ctx->hdc, ctx->hdc_is_private, ctx->pixel_format))
if (!context_set_pixel_format(ctx))
{
WARN("Failed to set pixel format %d on device context %p.\n",
ctx->pixel_format, ctx->hdc);
@ -1174,8 +1180,6 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx)
if (backup || !wglMakeCurrent(ctx->hdc, ctx->glCtx))
{
HDC dc;
WARN("Failed to make GL context %p current on device context %p, last error %#x.\n",
ctx->glCtx, ctx->hdc, GetLastError());
ctx->valid = 0;
@ -1192,24 +1196,27 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx)
return FALSE;
}
if (!(dc = swapchain_get_backup_dc(swapchain)))
if (!(ctx->hdc = swapchain_get_backup_dc(swapchain)))
{
context_set_current(NULL);
return FALSE;
}
if (!context_set_pixel_format(ctx, dc, TRUE, ctx->pixel_format))
ctx->hdc_is_private = TRUE;
ctx->hdc_has_format = FALSE;
if (!context_set_pixel_format(ctx))
{
ERR("Failed to set pixel format %d on device context %p.\n",
ctx->pixel_format, dc);
ctx->pixel_format, ctx->hdc);
context_set_current(NULL);
return FALSE;
}
if (!wglMakeCurrent(dc, ctx->glCtx))
if (!wglMakeCurrent(ctx->hdc, ctx->glCtx))
{
ERR("Fallback to backup window (dc %p) failed too, last error %#x.\n",
dc, GetLastError());
ctx->hdc, GetLastError());
context_set_current(NULL);
return FALSE;
}
@ -1259,13 +1266,13 @@ static void context_update_window(struct wined3d_context *context)
static void context_destroy_gl_resources(struct wined3d_context *context)
{
struct wined3d_pipeline_statistics_query *pipeline_statistics_query;
const struct wined3d_gl_info *gl_info = context->gl_info;
struct wined3d_so_statistics_query *so_statistics_query;
struct wined3d_pipeline_statistics_query *pipeline_statistics_query;
struct wined3d_timestamp_query *timestamp_query;
struct wined3d_occlusion_query *occlusion_query;
struct wined3d_event_query *event_query;
struct fbo_entry *entry, *entry2;
struct wined3d_fence *fence;
HGLRC restore_ctx;
HDC restore_dc;
unsigned int i;
@ -1308,18 +1315,25 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
occlusion_query->context = NULL;
}
LIST_FOR_EACH_ENTRY(event_query, &context->event_queries, struct wined3d_event_query, entry)
LIST_FOR_EACH_ENTRY(fence, &context->fences, struct wined3d_fence, entry)
{
if (context->valid)
{
if (gl_info->supported[ARB_SYNC])
{
if (event_query->object.sync) GL_EXTCALL(glDeleteSync(event_query->object.sync));
if (fence->object.sync)
GL_EXTCALL(glDeleteSync(fence->object.sync));
}
else if (gl_info->supported[APPLE_FENCE])
{
GL_EXTCALL(glDeleteFencesAPPLE(1, &fence->object.id));
}
else if (gl_info->supported[NV_FENCE])
{
GL_EXTCALL(glDeleteFencesNV(1, &fence->object.id));
}
else if (gl_info->supported[APPLE_FENCE]) GL_EXTCALL(glDeleteFencesAPPLE(1, &event_query->object.id));
else if (gl_info->supported[NV_FENCE]) GL_EXTCALL(glDeleteFencesNV(1, &event_query->object.id));
}
event_query->context = NULL;
fence->context = NULL;
}
LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_destroy_list, struct fbo_entry, entry)
@ -1367,23 +1381,23 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
if (gl_info->supported[ARB_SYNC])
{
for (i = 0; i < context->free_event_query_count; ++i)
for (i = 0; i < context->free_fence_count; ++i)
{
GL_EXTCALL(glDeleteSync(context->free_event_queries[i].sync));
GL_EXTCALL(glDeleteSync(context->free_fences[i].sync));
}
}
else if (gl_info->supported[APPLE_FENCE])
{
for (i = 0; i < context->free_event_query_count; ++i)
for (i = 0; i < context->free_fence_count; ++i)
{
GL_EXTCALL(glDeleteFencesAPPLE(1, &context->free_event_queries[i].id));
GL_EXTCALL(glDeleteFencesAPPLE(1, &context->free_fences[i].id));
}
}
else if (gl_info->supported[NV_FENCE])
{
for (i = 0; i < context->free_event_query_count; ++i)
for (i = 0; i < context->free_fence_count; ++i)
{
GL_EXTCALL(glDeleteFencesNV(1, &context->free_event_queries[i].id));
GL_EXTCALL(glDeleteFencesNV(1, &context->free_fences[i].id));
}
}
@ -1394,7 +1408,7 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
HeapFree(GetProcessHeap(), 0, context->free_pipeline_statistics_queries);
HeapFree(GetProcessHeap(), 0, context->free_timestamp_queries);
HeapFree(GetProcessHeap(), 0, context->free_occlusion_queries);
HeapFree(GetProcessHeap(), 0, context->free_event_queries);
HeapFree(GetProcessHeap(), 0, context->free_fences);
context_restore_pixel_format(context);
if (restore_ctx)
@ -1812,14 +1826,11 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
const struct wined3d_format *color_format;
struct wined3d_context *ret;
BOOL hdc_is_private = FALSE;
BOOL auxBuffers = FALSE;
HGLRC ctx, share_ctx;
DWORD target_usage;
int pixel_format;
unsigned int i;
DWORD state;
HDC hdc = 0;
TRACE("swapchain %p, target %p, window %p.\n", swapchain, target, swapchain->win_handle);
@ -1852,11 +1863,10 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
goto out;
list_init(&ret->occlusion_queries);
ret->free_event_query_size = 4;
if (!(ret->free_event_queries = wined3d_calloc(ret->free_event_query_size,
sizeof(*ret->free_event_queries))))
ret->free_fence_size = 4;
if (!(ret->free_fences = wined3d_calloc(ret->free_fence_size, sizeof(*ret->free_fences))))
goto out;
list_init(&ret->event_queries);
list_init(&ret->fences);
list_init(&ret->so_statistics_queries);
@ -1914,12 +1924,12 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
sizeof(*ret->texture_type))))
goto out;
if (!(hdc = GetDCEx(swapchain->win_handle, 0, DCX_USESTYLE | DCX_CACHE)))
if (!(ret->hdc = GetDCEx(swapchain->win_handle, 0, DCX_USESTYLE | DCX_CACHE)))
{
WARN("Failed to retrieve device context, trying swapchain backup.\n");
if ((hdc = swapchain_get_backup_dc(swapchain)))
hdc_is_private = TRUE;
if ((ret->hdc = swapchain_get_backup_dc(swapchain)))
ret->hdc_is_private = TRUE;
else
{
ERR("Failed to retrieve a device context.\n");
@ -1966,16 +1976,17 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
}
/* Try to find a pixel format which matches our requirements. */
if (!(pixel_format = context_choose_pixel_format(device, hdc, color_format, ds_format, auxBuffers)))
if (!(ret->pixel_format = context_choose_pixel_format(device, ret->hdc, color_format, ds_format, auxBuffers)))
goto out;
ret->gl_info = gl_info;
ret->win_handle = swapchain->win_handle;
context_enter(ret);
if (!context_set_pixel_format(ret, hdc, hdc_is_private, pixel_format))
if (!context_set_pixel_format(ret))
{
ERR("Failed to set pixel format %d on device context %p.\n", pixel_format, hdc);
ERR("Failed to set pixel format %d on device context %p.\n", ret->pixel_format, ret->hdc);
context_release(ret);
goto out;
}
@ -1983,12 +1994,12 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
share_ctx = device->context_count ? device->contexts[0]->glCtx : NULL;
if (gl_info->p_wglCreateContextAttribsARB)
{
if (!(ctx = context_create_wgl_attribs(gl_info, hdc, share_ctx)))
if (!(ctx = context_create_wgl_attribs(gl_info, ret->hdc, share_ctx)))
goto out;
}
else
{
if (!(ctx = wglCreateContext(hdc)))
if (!(ctx = wglCreateContext(ret->hdc)))
{
ERR("Failed to create a WGL context.\n");
context_release(ret);
@ -2036,11 +2047,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
ret->valid = 1;
ret->glCtx = ctx;
ret->win_handle = swapchain->win_handle;
ret->hdc = hdc;
ret->hdc_is_private = hdc_is_private;
ret->hdc_has_format = TRUE;
ret->pixel_format = pixel_format;
ret->needs_set = 1;
/* Set up the context defaults */
@ -2210,11 +2217,12 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
return ret;
out:
if (hdc) wined3d_release_dc(swapchain->win_handle, hdc);
if (ret->hdc)
wined3d_release_dc(swapchain->win_handle, ret->hdc);
device->shader_backend->shader_free_context_data(ret);
device->adapter->fragment_pipe->free_context_data(ret);
HeapFree(GetProcessHeap(), 0, ret->texture_type);
HeapFree(GetProcessHeap(), 0, ret->free_event_queries);
HeapFree(GetProcessHeap(), 0, ret->free_fences);
HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries);
HeapFree(GetProcessHeap(), 0, ret->free_timestamp_queries);
HeapFree(GetProcessHeap(), 0, ret->fbo_key);
@ -2504,10 +2512,8 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con
}
gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE);
checkGLcall("glColorMask");
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE));
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1));
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2));
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3));
for (i = 0; i < MAX_RENDER_TARGETS; ++i)
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i)));
if (gl_info->supported[EXT_SECONDARY_COLOR])
{
gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT);
@ -2721,7 +2727,6 @@ void *context_map_bo_address(struct wined3d_context *context,
return data->addr;
gl_info = context->gl_info;
context_bind_bo(context, binding, data->buffer_object);
if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
@ -2750,13 +2755,60 @@ void context_unmap_bo_address(struct wined3d_context *context,
return;
gl_info = context->gl_info;
context_bind_bo(context, binding, data->buffer_object);
GL_EXTCALL(glUnmapBuffer(binding));
context_bind_bo(context, binding, 0);
checkGLcall("Unmap buffer object");
}
void context_copy_bo_address(struct wined3d_context *context,
const struct wined3d_bo_address *dst, GLenum dst_binding,
const struct wined3d_bo_address *src, GLenum src_binding, size_t size)
{
const struct wined3d_gl_info *gl_info;
BYTE *dst_ptr, *src_ptr;
gl_info = context->gl_info;
if (dst->buffer_object && src->buffer_object)
{
if (gl_info->supported[ARB_COPY_BUFFER])
{
GL_EXTCALL(glBindBuffer(GL_COPY_READ_BUFFER, src->buffer_object));
GL_EXTCALL(glBindBuffer(GL_COPY_WRITE_BUFFER, dst->buffer_object));
GL_EXTCALL(glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER,
(GLintptr)src->addr, (GLintptr)dst->addr, size));
checkGLcall("direct buffer copy");
}
else
{
src_ptr = context_map_bo_address(context, src, size, src_binding, WINED3D_MAP_READONLY);
dst_ptr = context_map_bo_address(context, dst, size, dst_binding, 0);
memcpy(dst_ptr, src_ptr, size);
context_unmap_bo_address(context, dst, dst_binding);
context_unmap_bo_address(context, src, src_binding);
}
}
else if (!dst->buffer_object && src->buffer_object)
{
context_bind_bo(context, src_binding, src->buffer_object);
GL_EXTCALL(glGetBufferSubData(src_binding, (GLintptr)src->addr, size, dst->addr));
checkGLcall("buffer download");
}
else if (dst->buffer_object && !src->buffer_object)
{
context_bind_bo(context, dst_binding, dst->buffer_object);
GL_EXTCALL(glBufferSubData(dst_binding, (GLintptr)dst->addr, size, src->addr));
checkGLcall("buffer upload");
}
else
{
memcpy(dst->addr, src->addr, size);
}
}
static void context_set_render_offscreen(struct wined3d_context *context, BOOL offscreen)
{
if (context->render_offscreen == offscreen)
@ -3034,8 +3086,16 @@ static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const
else if (!context->render_offscreen)
return context_generate_rt_mask_from_resource(rts[0]->resource);
/* If we attach more buffers than supported in dual blend mode, the NVIDIA
* driver generates the following error:
* GL_INVALID_OPERATION error generated. State(s) are invalid: blend.
* DX11 does not treat this configuration as invalid, so disable the unused ones.
*/
rt_mask = ps ? ps->reg_maps.rt_mask : 1;
rt_mask &= context->d3d_info->valid_rt_mask;
if (wined3d_dualblend_enabled(state, context->gl_info))
rt_mask &= context->d3d_info->valid_dual_rt_mask;
else
rt_mask &= context->d3d_info->valid_rt_mask;
rt_mask_bits = rt_mask;
i = 0;
while (rt_mask_bits)
@ -3496,7 +3556,7 @@ static void context_update_stream_info(struct wined3d_context *context, const st
wined3d_stream_info_from_declaration(stream_info, state, gl_info, d3d_info);
stream_info->all_vbo = 1;
context->num_buffer_queries = 0;
context->buffer_fence_count = 0;
for (i = 0, map = stream_info->use_map; map; map >>= 1, ++i)
{
struct wined3d_stream_info_element *element;
@ -3537,8 +3597,8 @@ static void context_update_stream_info(struct wined3d_context *context, const st
if (!element->data.buffer_object)
stream_info->all_vbo = 0;
if (buffer->query)
context->buffer_queries[context->num_buffer_queries++] = buffer->query;
if (buffer->fence)
context->buffer_fences[context->buffer_fence_count++] = buffer->fence;
TRACE("Load array %u {%#x:%p}.\n", i, element->data.buffer_object, element->data.addr);
}

View file

@ -68,6 +68,8 @@ enum wined3d_cs_op
WINED3D_CS_OP_UPDATE_SUB_RESOURCE,
WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION,
WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW,
WINED3D_CS_OP_COPY_UAV_COUNTER,
WINED3D_CS_OP_COPY_SUB_RESOURCE,
WINED3D_CS_OP_STOP,
};
@ -109,9 +111,7 @@ struct wined3d_cs_clear
struct wined3d_cs_dispatch
{
enum wined3d_cs_op opcode;
unsigned int group_count_x;
unsigned int group_count_y;
unsigned int group_count_z;
struct wined3d_dispatch_parameters parameters;
};
struct wined3d_cs_draw
@ -119,12 +119,7 @@ struct wined3d_cs_draw
enum wined3d_cs_op opcode;
GLenum primitive_type;
GLint patch_vertex_count;
int base_vertex_idx;
unsigned int start_idx;
unsigned int index_count;
unsigned int start_instance;
unsigned int instance_count;
BOOL indexed;
struct wined3d_draw_parameters parameters;
};
struct wined3d_cs_flush
@ -241,6 +236,7 @@ struct wined3d_cs_set_unordered_access_view
enum wined3d_pipeline pipeline;
unsigned int view_idx;
struct wined3d_unordered_access_view *view;
unsigned int initial_count;
};
struct wined3d_cs_set_sampler
@ -419,6 +415,25 @@ struct wined3d_cs_clear_unordered_access_view
struct wined3d_uvec4 clear_value;
};
struct wined3d_cs_copy_uav_counter
{
enum wined3d_cs_op opcode;
struct wined3d_buffer *buffer;
unsigned int offset;
struct wined3d_unordered_access_view *view;
};
struct wined3d_cs_copy_sub_resource
{
enum wined3d_cs_op opcode;
struct wined3d_resource *dst_resource;
unsigned int dst_sub_resource_idx;
struct wined3d_box dst_box;
struct wined3d_resource *src_resource;
unsigned int src_sub_resource_idx;
struct wined3d_box src_box;
};
struct wined3d_cs_stop
{
enum wined3d_cs_op opcode;
@ -696,14 +711,23 @@ static void wined3d_cs_exec_dispatch(struct wined3d_cs *cs, const void *data)
const struct wined3d_cs_dispatch *op = data;
struct wined3d_state *state = &cs->state;
dispatch_compute(cs->device, state,
op->group_count_x, op->group_count_y, op->group_count_z);
dispatch_compute(cs->device, state, &op->parameters);
if (op->parameters.indirect)
wined3d_resource_release(&op->parameters.u.indirect.buffer->resource);
release_shader_resources(state, 1u << WINED3D_SHADER_TYPE_COMPUTE);
release_unordered_access_resources(state->shader[WINED3D_SHADER_TYPE_COMPUTE],
state->unordered_access_view[WINED3D_PIPELINE_COMPUTE]);
}
static void acquire_compute_pipeline_resources(const struct wined3d_state *state)
{
acquire_shader_resources(state, 1u << WINED3D_SHADER_TYPE_COMPUTE);
acquire_unordered_access_resources(state->shader[WINED3D_SHADER_TYPE_COMPUTE],
state->unordered_access_view[WINED3D_PIPELINE_COMPUTE]);
}
void wined3d_cs_emit_dispatch(struct wined3d_cs *cs,
unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z)
{
@ -712,13 +736,30 @@ void wined3d_cs_emit_dispatch(struct wined3d_cs *cs,
op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
op->opcode = WINED3D_CS_OP_DISPATCH;
op->group_count_x = group_count_x;
op->group_count_y = group_count_y;
op->group_count_z = group_count_z;
op->parameters.indirect = FALSE;
op->parameters.u.direct.group_count_x = group_count_x;
op->parameters.u.direct.group_count_y = group_count_y;
op->parameters.u.direct.group_count_z = group_count_z;
acquire_shader_resources(state, 1u << WINED3D_SHADER_TYPE_COMPUTE);
acquire_unordered_access_resources(state->shader[WINED3D_SHADER_TYPE_COMPUTE],
state->unordered_access_view[WINED3D_PIPELINE_COMPUTE]);
acquire_compute_pipeline_resources(state);
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
}
void wined3d_cs_emit_dispatch_indirect(struct wined3d_cs *cs,
struct wined3d_buffer *buffer, unsigned int offset)
{
const struct wined3d_state *state = &cs->device->state;
struct wined3d_cs_dispatch *op;
op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
op->opcode = WINED3D_CS_OP_DISPATCH;
op->parameters.indirect = TRUE;
op->parameters.u.indirect.buffer = buffer;
op->parameters.u.indirect.offset = offset;
acquire_compute_pipeline_resources(state);
wined3d_resource_acquire(&buffer->resource);
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
}
@ -729,13 +770,6 @@ static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data)
const struct wined3d_cs_draw *op = data;
unsigned int i;
if (!cs->device->adapter->gl_info.supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]
&& state->load_base_vertex_index != op->base_vertex_idx)
{
state->load_base_vertex_index = op->base_vertex_idx;
device_invalidate_state(cs->device, STATE_BASEVERTEXINDEX);
}
if (state->gl_primitive_type != op->primitive_type)
{
if (state->gl_primitive_type == GL_POINTS || op->primitive_type == GL_POINTS)
@ -744,10 +778,27 @@ static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data)
}
state->gl_patch_vertices = op->patch_vertex_count;
draw_primitive(cs->device, state, op->base_vertex_idx, op->start_idx,
op->index_count, op->start_instance, op->instance_count, op->indexed);
if (!op->parameters.indirect)
{
const struct wined3d_direct_draw_parameters *p = &op->parameters.u.direct;
if (op->indexed)
if (!cs->device->adapter->gl_info.supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]
&& state->load_base_vertex_index != p->base_vertex_idx)
{
state->load_base_vertex_index = p->base_vertex_idx;
device_invalidate_state(cs->device, STATE_BASEVERTEXINDEX);
}
}
draw_primitive(cs->device, state, &op->parameters);
if (op->parameters.indirect)
{
const struct wined3d_indirect_draw_parameters *p = &op->parameters.u.indirect;
wined3d_resource_release(&p->buffer->resource);
}
if (op->parameters.indexed)
wined3d_resource_release(&state->index_buffer->resource);
for (i = 0; i < ARRAY_SIZE(state->streams); ++i)
{
@ -788,12 +839,62 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum primitive_type, unsigned
op->opcode = WINED3D_CS_OP_DRAW;
op->primitive_type = primitive_type;
op->patch_vertex_count = patch_vertex_count;
op->base_vertex_idx = base_vertex_idx;
op->start_idx = start_idx;
op->index_count = index_count;
op->start_instance = start_instance;
op->instance_count = instance_count;
op->indexed = indexed;
op->parameters.indirect = FALSE;
op->parameters.u.direct.base_vertex_idx = base_vertex_idx;
op->parameters.u.direct.start_idx = start_idx;
op->parameters.u.direct.index_count = index_count;
op->parameters.u.direct.start_instance = start_instance;
op->parameters.u.direct.instance_count = instance_count;
op->parameters.indexed = indexed;
if (indexed)
wined3d_resource_acquire(&state->index_buffer->resource);
for (i = 0; i < ARRAY_SIZE(state->streams); ++i)
{
if (state->streams[i].buffer)
wined3d_resource_acquire(&state->streams[i].buffer->resource);
}
for (i = 0; i < ARRAY_SIZE(state->stream_output); ++i)
{
if (state->stream_output[i].buffer)
wined3d_resource_acquire(&state->stream_output[i].buffer->resource);
}
for (i = 0; i < ARRAY_SIZE(state->textures); ++i)
{
if (state->textures[i])
wined3d_resource_acquire(&state->textures[i]->resource);
}
for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; ++i)
{
if (state->fb->render_targets[i])
wined3d_resource_acquire(state->fb->render_targets[i]->resource);
}
if (state->fb->depth_stencil)
wined3d_resource_acquire(state->fb->depth_stencil->resource);
acquire_shader_resources(state, ~(1u << WINED3D_SHADER_TYPE_COMPUTE));
acquire_unordered_access_resources(state->shader[WINED3D_SHADER_TYPE_PIXEL],
state->unordered_access_view[WINED3D_PIPELINE_GRAPHICS]);
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
}
void wined3d_cs_emit_draw_indirect(struct wined3d_cs *cs, GLenum primitive_type, unsigned int patch_vertex_count,
struct wined3d_buffer *buffer, unsigned int offset, BOOL indexed)
{
const struct wined3d_state *state = &cs->device->state;
struct wined3d_cs_draw *op;
unsigned int i;
op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
op->opcode = WINED3D_CS_OP_DRAW;
op->primitive_type = primitive_type;
op->patch_vertex_count = patch_vertex_count;
op->parameters.indirect = TRUE;
op->parameters.u.indirect.buffer = buffer;
op->parameters.u.indirect.offset = offset;
op->parameters.indexed = indexed;
wined3d_resource_acquire(&buffer->resource);
if (indexed)
wined3d_resource_acquire(&state->index_buffer->resource);
@ -831,7 +932,8 @@ static void wined3d_cs_exec_flush(struct wined3d_cs *cs, const void *data)
struct wined3d_context *context;
context = context_acquire(cs->device, NULL, 0);
context->gl_info->gl_ops.gl.p_glFlush();
if (context->valid)
context->gl_info->gl_ops.gl.p_glFlush();
context_release(context);
}
@ -1283,11 +1385,14 @@ static void wined3d_cs_exec_set_unordered_access_view(struct wined3d_cs *cs, con
if (prev)
InterlockedDecrement(&prev->resource->bind_count);
if (op->view && op->initial_count != ~0u)
wined3d_unordered_access_view_set_counter(op->view, op->initial_count);
device_invalidate_state(cs->device, STATE_UNORDERED_ACCESS_VIEW_BINDING(op->pipeline));
}
void wined3d_cs_emit_set_unordered_access_view(struct wined3d_cs *cs, enum wined3d_pipeline pipeline,
unsigned int view_idx, struct wined3d_unordered_access_view *view)
unsigned int view_idx, struct wined3d_unordered_access_view *view, unsigned int initial_count)
{
struct wined3d_cs_set_unordered_access_view *op;
@ -1296,6 +1401,7 @@ void wined3d_cs_emit_set_unordered_access_view(struct wined3d_cs *cs, enum wined
op->pipeline = pipeline;
op->view_idx = view_idx;
op->view = view;
op->initial_count = initial_count;
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
}
@ -1938,10 +2044,9 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void *
if (op->dst_resource->type == WINED3D_RTYPE_BUFFER)
{
if (FAILED(wined3d_buffer_copy(buffer_from_resource(op->dst_resource), op->dst_box.left,
wined3d_buffer_copy(buffer_from_resource(op->dst_resource), op->dst_box.left,
buffer_from_resource(op->src_resource), op->src_box.left,
op->src_box.right - op->src_box.left)))
ERR("Failed to copy buffer.\n");
op->src_box.right - op->src_box.left);
}
else if (op->dst_resource->type == WINED3D_RTYPE_TEXTURE_2D)
{
@ -2139,10 +2244,7 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r
unsigned int slice_pitch)
{
struct wined3d_cs_update_sub_resource *op;
#if !defined(STAGING_CSMT)
op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
#else /* STAGING_CSMT */
#if defined(STAGING_CSMT)
size_t data_size, size;
if (resource->type != WINED3D_RTYPE_BUFFER && resource->format_flags & WINED3DFMT_FLAG_BLOCKS)
@ -2163,6 +2265,8 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r
case WINED3D_RTYPE_BUFFER:
data_size = box->right - box->left;
break;
case WINED3D_RTYPE_NONE:
return;
}
size = FIELD_OFFSET(struct wined3d_cs_update_sub_resource, copy_data[data_size]);
@ -2170,32 +2274,23 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r
goto no_async;
op = cs->ops->require_space(cs, size, WINED3D_CS_QUEUE_DEFAULT);
#endif /* STAGING_CSMT */
op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE;
op->resource = resource;
op->sub_resource_idx = sub_resource_idx;
op->box = *box;
op->data.row_pitch = row_pitch;
op->data.slice_pitch = slice_pitch;
#if !defined(STAGING_CSMT)
op->data.data = data;
#else /* STAGING_CSMT */
op->data.data = op->copy_data;
memcpy(op->copy_data, data, data_size);
#endif /* STAGING_CSMT */
wined3d_resource_acquire(resource);
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
#if !defined(STAGING_CSMT)
/* The data pointer may go away, so we need to wait until it is read.
* Copying the data may be faster if it's small. */
cs->ops->finish(cs, WINED3D_CS_QUEUE_DEFAULT);
#else /* STAGING_CSMT */
return;
no_async:
wined3d_resource_wait_idle(resource);
#endif /* STAGING_CSMT */
op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_MAP);
op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE;
@ -2209,8 +2304,11 @@ no_async:
wined3d_resource_acquire(resource);
cs->ops->submit(cs, WINED3D_CS_QUEUE_MAP);
cs->ops->finish(cs, WINED3D_CS_QUEUE_MAP);
#if !defined(STAGING_CSMT)
/* The data pointer may go away, so we need to wait until it is read.
* Copying the data may be faster if it's small. */
#endif /* STAGING_CSMT */
cs->ops->finish(cs, WINED3D_CS_QUEUE_MAP);
}
static void wined3d_cs_exec_add_dirty_texture_region(struct wined3d_cs *cs, const void *data)
@ -2277,6 +2375,179 @@ void wined3d_cs_emit_clear_unordered_access_view_uint(struct wined3d_cs *cs,
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
}
static void wined3d_cs_exec_copy_uav_counter(struct wined3d_cs *cs, const void *data)
{
const struct wined3d_cs_copy_uav_counter *op = data;
struct wined3d_unordered_access_view *view = op->view;
struct wined3d_context *context;
context = context_acquire(cs->device, NULL, 0);
wined3d_unordered_access_view_copy_counter(view, op->buffer, op->offset, context);
context_release(context);
wined3d_resource_release(&op->buffer->resource);
wined3d_resource_release(view->resource);
}
void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buffer *dst_buffer,
unsigned int offset, struct wined3d_unordered_access_view *uav)
{
struct wined3d_cs_copy_uav_counter *op;
op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
op->opcode = WINED3D_CS_OP_COPY_UAV_COUNTER;
op->buffer = dst_buffer;
op->offset = offset;
op->view = uav;
wined3d_resource_acquire(&dst_buffer->resource);
wined3d_resource_acquire(uav->resource);
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
}
static void wined3d_cs_exec_copy_sub_resource(struct wined3d_cs *cs, const void *data)
{
struct wined3d_cs_copy_sub_resource *op = (void*)data;
if (op->dst_resource->type == WINED3D_RTYPE_BUFFER)
{
wined3d_buffer_copy(buffer_from_resource(op->dst_resource), op->dst_box.left,
buffer_from_resource(op->src_resource), op->src_box.left,
op->src_box.right - op->src_box.left);
}
else if (op->dst_resource->type == WINED3D_RTYPE_TEXTURE_1D ||
op->dst_resource->type == WINED3D_RTYPE_TEXTURE_2D ||
op->dst_resource->type == WINED3D_RTYPE_TEXTURE_3D)
{
struct wined3d_texture *dst_texture, *src_texture;
struct gl_texture *gl_tex_src, *gl_tex_dst;
unsigned int update_w, update_h, update_d;
const struct wined3d_gl_info *gl_info;
unsigned int src_level, src_layer;
unsigned int dst_level, dst_layer;
struct wined3d_context *context;
BOOL partial_update = FALSE;
update_w = op->dst_box.right - op->dst_box.left;
update_h = op->dst_box.bottom - op->dst_box.top;
update_d = op->dst_box.back - op->dst_box.front;
dst_texture = texture_from_resource(op->dst_resource);
src_texture = texture_from_resource(op->src_resource);
context = context_acquire(cs->device, NULL, 0);
gl_info = context->gl_info;
if (!wined3d_texture_load_location(src_texture, op->src_sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB))
{
FIXME("Failed to load source sub-resource into WINED3D_LOCATION_TEXTURE_RGB.\n");
context_release(context);
goto error;
}
src_level = op->src_sub_resource_idx % src_texture->level_count;
src_layer = op->src_sub_resource_idx / src_texture->level_count;
dst_level = op->dst_sub_resource_idx % dst_texture->level_count;
dst_layer = op->dst_sub_resource_idx / dst_texture->level_count;
switch (op->dst_resource->type)
{
case WINED3D_RTYPE_TEXTURE_3D:
partial_update |= (update_d != wined3d_texture_get_level_depth(dst_texture, dst_level));
case WINED3D_RTYPE_TEXTURE_2D:
partial_update |= (update_h != wined3d_texture_get_level_height(dst_texture, dst_level));
case WINED3D_RTYPE_TEXTURE_1D:
partial_update |= (update_w != wined3d_texture_get_level_width(dst_texture, dst_level));
default:
break;
}
if (!partial_update)
{
wined3d_texture_prepare_texture(dst_texture, context, FALSE);
}
else if (!wined3d_texture_load_location(dst_texture, op->dst_sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB))
{
FIXME("Failed to load destination sub-resource.\n");
context_release(context);
goto error;
}
switch (op->dst_resource->type)
{
case WINED3D_RTYPE_TEXTURE_1D:
op->src_box.top = src_layer;
op->dst_box.top = dst_layer;
break;
case WINED3D_RTYPE_TEXTURE_2D:
op->src_box.front = src_layer;
op->dst_box.front = dst_layer;
break;
default:
break;
}
gl_tex_src = wined3d_texture_get_gl_texture(src_texture, FALSE);
gl_tex_dst = wined3d_texture_get_gl_texture(dst_texture, FALSE);
GL_EXTCALL(glCopyImageSubData(gl_tex_src->name, src_texture->target, src_level,
op->src_box.left, op->src_box.top, op->src_box.front,
gl_tex_dst->name, dst_texture->target, dst_level,
op->dst_box.left, op->dst_box.top, op->dst_box.front,
update_w, update_h, update_d));
checkGLcall("Copy texture content");
wined3d_texture_validate_location(dst_texture, op->dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB);
wined3d_texture_invalidate_location(dst_texture, op->dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB);
context_release(context);
}
else
{
FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(op->dst_resource->type));
}
error:
wined3d_resource_release(op->src_resource);
wined3d_resource_release(op->dst_resource);
}
void wined3d_cs_emit_copy_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *dst_resource,
unsigned int dst_sub_resource_idx, const struct wined3d_box *dst_box, struct wined3d_resource *src_resource,
unsigned int src_sub_resource_idx, const struct wined3d_box *src_box)
{
const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info;
struct wined3d_cs_blt_sub_resource *op;
if (!gl_info->supported[ARB_TEXTURE_VIEW] && src_resource->format->id != dst_resource->format->id)
{
FIXME("ARB_TEXTURE_VIEW not supported, cannot copy sub-resource.\n");
return;
}
if (!gl_info->supported[ARB_COPY_IMAGE])
{
wined3d_cs_emit_blt_sub_resource(cs, dst_resource, dst_sub_resource_idx, dst_box,
src_resource, src_sub_resource_idx, src_box, 0, NULL, WINED3D_TEXF_POINT);
return;
}
op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
op->opcode = WINED3D_CS_OP_COPY_SUB_RESOURCE;
op->dst_resource = dst_resource;
op->dst_sub_resource_idx = dst_sub_resource_idx;
op->dst_box = *dst_box;
op->src_resource = src_resource;
op->src_sub_resource_idx = src_sub_resource_idx;
op->src_box = *src_box;
wined3d_resource_acquire(dst_resource);
wined3d_resource_acquire(src_resource);
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
}
static void wined3d_cs_emit_stop(struct wined3d_cs *cs)
{
struct wined3d_cs_stop *op;
@ -2334,6 +2605,8 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
/* WINED3D_CS_OP_UPDATE_SUB_RESOURCE */ wined3d_cs_exec_update_sub_resource,
/* WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION */ wined3d_cs_exec_add_dirty_texture_region,
/* WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW */ wined3d_cs_exec_clear_unordered_access_view,
/* WINED3D_CS_OP_COPY_UAV_COUNTER */ wined3d_cs_exec_copy_uav_counter,
/* WINED3D_CS_OP_COPY_SUB_RESOURCE */ wined3d_cs_exec_copy_sub_resource,
};
#if defined(STAGING_CSMT)
@ -2405,8 +2678,9 @@ static const struct wined3d_cs_ops wined3d_cs_st_ops =
wined3d_cs_st_push_constants,
};
static BOOL wined3d_cs_queue_is_empty(const struct wined3d_cs_queue *queue)
static BOOL wined3d_cs_queue_is_empty(const struct wined3d_cs *cs, const struct wined3d_cs_queue *queue)
{
wined3d_from_cs(cs);
return *(volatile LONG *)&queue->head == queue->tail;
}
@ -2536,7 +2810,7 @@ static void wined3d_cs_mt_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id
return;
}
while (!wined3d_cs_queue_is_empty(&cs->queue[queue_id]))
while (cs->queue[queue_id].head != *(volatile LONG *)&cs->queue[queue_id].tail)
wined3d_pause();
}
@ -2577,8 +2851,8 @@ static void wined3d_cs_wait_event(struct wined3d_cs *cs)
* Likewise, we can race with the main thread when resetting
* "waiting_for_event", in which case we would need to call
* WaitForSingleObject() because the main thread called SetEvent(). */
if (!(wined3d_cs_queue_is_empty(&cs->queue[WINED3D_CS_QUEUE_DEFAULT])
&& wined3d_cs_queue_is_empty(&cs->queue[WINED3D_CS_QUEUE_MAP]))
if (!(wined3d_cs_queue_is_empty(cs, &cs->queue[WINED3D_CS_QUEUE_DEFAULT])
&& wined3d_cs_queue_is_empty(cs, &cs->queue[WINED3D_CS_QUEUE_MAP]))
&& InterlockedCompareExchange(&cs->waiting_for_event, FALSE, TRUE))
return;
@ -2608,10 +2882,10 @@ static DWORD WINAPI wined3d_cs_run(void *ctx)
}
queue = &cs->queue[WINED3D_CS_QUEUE_MAP];
if (wined3d_cs_queue_is_empty(queue))
if (wined3d_cs_queue_is_empty(cs, queue))
{
queue = &cs->queue[WINED3D_CS_QUEUE_DEFAULT];
if (wined3d_cs_queue_is_empty(queue))
if (wined3d_cs_queue_is_empty(cs, queue))
{
if (++spin_count >= WINED3D_CS_SPIN_COUNT && list_empty(&cs->query_poll_list))
wined3d_cs_wait_event(cs);
@ -2641,8 +2915,8 @@ static DWORD WINAPI wined3d_cs_run(void *ctx)
InterlockedExchange(&queue->tail, tail);
}
cs->queue[WINED3D_CS_QUEUE_MAP].tail = cs->queue[WINED3D_CS_QUEUE_MAP].head = 0;
cs->queue[WINED3D_CS_QUEUE_DEFAULT].tail = cs->queue[WINED3D_CS_QUEUE_DEFAULT].head = 0;
cs->queue[WINED3D_CS_QUEUE_MAP].tail = cs->queue[WINED3D_CS_QUEUE_MAP].head;
cs->queue[WINED3D_CS_QUEUE_DEFAULT].tail = cs->queue[WINED3D_CS_QUEUE_DEFAULT].head;
TRACE("Stopped.\n");
FreeLibraryAndExitThread(cs->wined3d_module, 0);
}

View file

@ -374,10 +374,8 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c
}
gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE));
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1));
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2));
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3));
for (i = 0; i < MAX_RENDER_TARGETS; ++i)
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i)));
gl_info->gl_ops.gl.p_glClearColor(color->r, color->g, color->b, color->a);
checkGLcall("glClearColor");
clear_mask = clear_mask | GL_COLOR_BUFFER_BIT;
@ -1182,6 +1180,15 @@ HRESULT CDECL wined3d_device_init_gdi(struct wined3d_device *device,
goto err_out;
}
device->swapchains[0] = swapchain;
if (!(device->blitter = wined3d_cpu_blitter_create()))
{
ERR("Failed to create CPU blitter.\n");
HeapFree(GetProcessHeap(), 0, device->swapchains);
device->swapchain_count = 0;
goto err_out;
}
return WINED3D_OK;
err_out:
@ -1273,6 +1280,8 @@ HRESULT CDECL wined3d_device_uninit_gdi(struct wined3d_device *device)
{
unsigned int i;
device->blitter->ops->blitter_destroy(device->blitter, NULL);
for (i = 0; i < device->swapchain_count; ++i)
{
TRACE("Releasing the implicit swapchain %u.\n", i);
@ -2985,7 +2994,8 @@ struct wined3d_sampler * CDECL wined3d_device_get_cs_sampler(const struct wined3
}
static void wined3d_device_set_pipeline_unordered_access_view(struct wined3d_device *device,
enum wined3d_pipeline pipeline, unsigned int idx, struct wined3d_unordered_access_view *uav)
enum wined3d_pipeline pipeline, unsigned int idx, struct wined3d_unordered_access_view *uav,
unsigned int initial_count)
{
struct wined3d_unordered_access_view *prev;
@ -2996,14 +3006,14 @@ static void wined3d_device_set_pipeline_unordered_access_view(struct wined3d_dev
}
prev = device->update_state->unordered_access_view[pipeline][idx];
if (uav == prev)
if (uav == prev && initial_count == ~0u)
return;
if (uav)
wined3d_unordered_access_view_incref(uav);
device->update_state->unordered_access_view[pipeline][idx] = uav;
if (!device->recording)
wined3d_cs_emit_set_unordered_access_view(device->cs, pipeline, idx, uav);
wined3d_cs_emit_set_unordered_access_view(device->cs, pipeline, idx, uav, initial_count);
if (prev)
wined3d_unordered_access_view_decref(prev);
}
@ -3021,11 +3031,11 @@ static struct wined3d_unordered_access_view *wined3d_device_get_pipeline_unorder
}
void CDECL wined3d_device_set_cs_uav(struct wined3d_device *device, unsigned int idx,
struct wined3d_unordered_access_view *uav)
struct wined3d_unordered_access_view *uav, unsigned int initial_count)
{
TRACE("device %p, idx %u, uav %p.\n", device, idx, uav);
TRACE("device %p, idx %u, uav %p, initial_count %#x.\n", device, idx, uav, initial_count);
wined3d_device_set_pipeline_unordered_access_view(device, WINED3D_PIPELINE_COMPUTE, idx, uav);
wined3d_device_set_pipeline_unordered_access_view(device, WINED3D_PIPELINE_COMPUTE, idx, uav, initial_count);
}
struct wined3d_unordered_access_view * CDECL wined3d_device_get_cs_uav(const struct wined3d_device *device,
@ -3037,11 +3047,11 @@ struct wined3d_unordered_access_view * CDECL wined3d_device_get_cs_uav(const str
}
void CDECL wined3d_device_set_unordered_access_view(struct wined3d_device *device,
unsigned int idx, struct wined3d_unordered_access_view *uav)
unsigned int idx, struct wined3d_unordered_access_view *uav, unsigned int initial_count)
{
TRACE("device %p, idx %u, uav %p.\n", device, idx, uav);
TRACE("device %p, idx %u, uav %p, initial_count %#x.\n", device, idx, uav, initial_count);
wined3d_device_set_pipeline_unordered_access_view(device, WINED3D_PIPELINE_GRAPHICS, idx, uav);
wined3d_device_set_pipeline_unordered_access_view(device, WINED3D_PIPELINE_GRAPHICS, idx, uav, initial_count);
}
struct wined3d_unordered_access_view * CDECL wined3d_device_get_unordered_access_view(
@ -3510,88 +3520,19 @@ struct wined3d_texture * CDECL wined3d_device_get_texture(const struct wined3d_d
return device->state.textures[stage];
}
void CDECL wined3d_check_device_format_support(struct wined3d_device *device,
enum wined3d_format_id check_format_id, UINT *support)
{
const struct wined3d_format *format = wined3d_get_format(&device->adapter->gl_info, check_format_id, 0);
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
UINT support_flags = 0;
if (format->flags[WINED3D_GL_RES_TYPE_BUFFER] & WINED3DFMT_FLAG_TEXTURE)
{
support_flags |= WINED3D_FORMAT_SUPPORT_BUFFER;
support_flags |= WINED3D_FORMAT_SUPPORT_IA_VERTEX_BUFFER;
support_flags |= WINED3D_FORMAT_SUPPORT_IA_INDEX_BUFFER;
support_flags |= WINED3D_FORMAT_SUPPORT_SO_BUFFER;
}
if (format->flags[WINED3D_GL_RES_TYPE_TEX_1D] & WINED3DFMT_FLAG_TEXTURE)
support_flags |= WINED3D_FORMAT_SUPPORT_TEXTURE1D;
if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_TEXTURE)
{
support_flags |= WINED3D_FORMAT_SUPPORT_TEXTURE2D;
if (gl_info->supported[EXT_TEXTURE_ARRAY])
support_flags |= WINED3D_FORMAT_SUPPORT_TEXTURECUBE;
/* OpenGL requires that all officially supported formats support mip mapping */
support_flags |= WINED3D_FORMAT_SUPPORT_MIP;
if (support_flags & gl_info->supported[SGIS_GENERATE_MIPMAP])
support_flags |= WINED3D_FORMAT_SUPPORT_MIP_AUTOGEN;
/* For the following flags it should be sufficient to check only 2d textures */
if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_RENDERTARGET)
support_flags |= WINED3D_FORMAT_SUPPORT_RENDER_TARGET;
if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
support_flags |= WINED3D_FORMAT_SUPPORT_BLENDABLE;
if ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_DEPTH) &&
(format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_STENCIL))
support_flags |= WINED3D_FORMAT_SUPPORT_DEPTH_STENCIL;
if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
support_flags |= WINED3D_FORMAT_SUPPORT_BLENDABLE;
/* not sure how to test the following flags - assuming yes */
support_flags |= WINED3D_FORMAT_SUPPORT_SHADER_LOAD;
support_flags |= WINED3D_FORMAT_SUPPORT_SHADER_SAMPLE;
support_flags |= WINED3D_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON;
support_flags |= WINED3D_FORMAT_SUPPORT_SHADER_GATHER;
support_flags |= WINED3D_FORMAT_SUPPORT_SHADER_GATHER_COMPARISON;
support_flags |= WINED3D_FORMAT_SUPPORT_CPU_LOCKABLE;
support_flags |= WINED3D_FORMAT_SUPPORT_DISPLAY;
support_flags |= WINED3D_FORMAT_SUPPORT_BACK_BUFFER_CAST;
support_flags |= WINED3D_FORMAT_SUPPORT_TYPED_UNORDERED_ACCESS_VIEW;
support_flags |= WINED3D_FORMAT_SUPPORT_SHADER_GATHER_COMPARISON;
}
if (format->flags[WINED3D_GL_RES_TYPE_TEX_3D] & WINED3DFMT_FLAG_TEXTURE)
support_flags |= WINED3D_FORMAT_SUPPORT_TEXTURE3D;
if (gl_info->supported[ARB_MULTISAMPLE])
{
/* TODO: check if multisampling for this format is supported */
support_flags |= WINED3D_FORMAT_SUPPORT_MULTISAMPLE_LOAD;
support_flags |= WINED3D_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE;
if (support_flags & WINED3D_FORMAT_SUPPORT_RENDER_TARGET)
support_flags |= WINED3D_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET;
}
*support = support_flags;
}
HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device, WINED3DCAPS *caps)
{
HRESULT hr;
TRACE("device %p, caps %p.\n", device, caps);
return wined3d_get_device_caps(device->wined3d, device->adapter->ordinal,
hr = wined3d_get_device_caps(device->wined3d, device->adapter->ordinal,
device->create_parms.device_type, caps);
if (SUCCEEDED(hr) && use_software_vertex_processing(device))
caps->MaxVertexBlendMatrixIndex = 255;
return hr;
}
HRESULT CDECL wined3d_device_get_display_mode(const struct wined3d_device *device, UINT swapchain_idx,
@ -3762,6 +3703,14 @@ void CDECL wined3d_device_dispatch_compute(struct wined3d_device *device,
wined3d_cs_emit_dispatch(device->cs, group_count_x, group_count_y, group_count_z);
}
void CDECL wined3d_device_dispatch_compute_indirect(struct wined3d_device *device,
struct wined3d_buffer *buffer, unsigned int offset)
{
TRACE("device %p, buffer %p, offset %u.\n", device, buffer, offset);
wined3d_cs_emit_dispatch_indirect(device->cs, buffer, offset);
}
void CDECL wined3d_device_set_primitive_type(struct wined3d_device *device,
enum wined3d_primitive_type primitive_type, unsigned int patch_vertex_count)
{
@ -3805,6 +3754,15 @@ void CDECL wined3d_device_draw_primitive_instanced(struct wined3d_device *device
0, start_vertex, vertex_count, start_instance, instance_count, FALSE);
}
void CDECL wined3d_device_draw_primitive_instanced_indirect(struct wined3d_device *device,
struct wined3d_buffer *buffer, unsigned int offset)
{
TRACE("device %p, buffer %p, offset %u.\n", device, buffer, offset);
wined3d_cs_emit_draw_indirect(device->cs, device->state.gl_primitive_type, device->state.gl_patch_vertices,
buffer, offset, FALSE);
}
HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count)
{
TRACE("device %p, start_idx %u, index_count %u.\n", device, start_idx, index_count);
@ -3835,6 +3793,15 @@ void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device
device->state.base_vertex_index, start_idx, index_count, start_instance, instance_count, TRUE);
}
void CDECL wined3d_device_draw_indexed_primitive_instanced_indirect(struct wined3d_device *device,
struct wined3d_buffer *buffer, unsigned int offset)
{
TRACE("device %p, buffer %p, offset %u.\n", device, buffer, offset);
wined3d_cs_emit_draw_indirect(device->cs, device->state.gl_primitive_type, device->state.gl_patch_vertices,
buffer, offset, TRUE);
}
HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device,
struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture)
{
@ -3995,31 +3962,15 @@ HRESULT CDECL wined3d_device_validate_device(const struct wined3d_device *device
void CDECL wined3d_device_set_software_vertex_processing(struct wined3d_device *device, BOOL software)
{
static BOOL warned;
TRACE("device %p, software %#x.\n", device, software);
if (!warned)
{
FIXME("device %p, software %#x stub!\n", device, software);
warned = TRUE;
}
device->softwareVertexProcessing = software;
}
BOOL CDECL wined3d_device_get_software_vertex_processing(const struct wined3d_device *device)
{
static BOOL warned;
TRACE("device %p.\n", device);
if (!warned)
{
TRACE("device %p stub!\n", device);
warned = TRUE;
}
return device->softwareVertexProcessing;
}
@ -4070,6 +4021,21 @@ float CDECL wined3d_device_get_npatch_mode(const struct wined3d_device *device)
return 0.0f;
}
void CDECL wined3d_device_copy_uav_counter(struct wined3d_device *device,
struct wined3d_buffer *dst_buffer, unsigned int offset, struct wined3d_unordered_access_view *uav)
{
TRACE("device %p, dst_buffer %p, offset %u, uav %p.\n",
device, dst_buffer, offset, uav);
if (offset + sizeof(GLuint) > dst_buffer->resource.size)
{
WARN("Offset %u too large.\n", offset);
return;
}
wined3d_cs_emit_copy_uav_counter(device->cs, dst_buffer, offset, uav);
}
void CDECL wined3d_device_copy_resource(struct wined3d_device *device,
struct wined3d_resource *dst_resource, struct wined3d_resource *src_resource)
{
@ -4103,7 +4069,10 @@ void CDECL wined3d_device_copy_resource(struct wined3d_device *device,
return;
}
if (src_resource->format->id != dst_resource->format->id)
if (src_resource->format->id != dst_resource->format->id &&
(src_resource->format->typeless_id != dst_resource->format->typeless_id ||
src_resource->format->gl_view_class != dst_resource->format->gl_view_class ||
!src_resource->format->typeless_id))
{
WARN("Resource formats (%s / %s) don't match.\n",
debug_d3dformat(dst_resource->format->id),
@ -4114,8 +4083,7 @@ void CDECL wined3d_device_copy_resource(struct wined3d_device *device,
if (dst_resource->type == WINED3D_RTYPE_BUFFER)
{
wined3d_box_set(&box, 0, 0, src_resource->size, 1, 0, 1);
wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, 0, &box,
src_resource, 0, &box, 0, NULL, WINED3D_TEXF_POINT);
wined3d_cs_emit_copy_sub_resource(device->cs, dst_resource, 0, &box, src_resource, 0, &box);
return;
}
@ -4141,8 +4109,7 @@ void CDECL wined3d_device_copy_resource(struct wined3d_device *device,
{
unsigned int idx = j * dst_texture->level_count + i;
wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, idx, &box,
src_resource, idx, &box, 0, NULL, WINED3D_TEXF_POINT);
wined3d_cs_emit_copy_sub_resource(device->cs, dst_resource, idx, &box, src_resource, idx, &box);
}
}
}
@ -4173,7 +4140,10 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev
return WINED3DERR_INVALIDCALL;
}
if (src_resource->format->id != dst_resource->format->id)
if (src_resource->format->id != dst_resource->format->id &&
(src_resource->format->typeless_id != dst_resource->format->typeless_id ||
src_resource->format->gl_view_class != dst_resource->format->gl_view_class ||
!src_resource->format->typeless_id))
{
WARN("Resource formats (%s / %s) don't match.\n",
debug_d3dformat(dst_resource->format->id),
@ -4289,8 +4259,8 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev
return WINED3DERR_INVALIDCALL;
}
wined3d_cs_emit_blt_sub_resource(device->cs, dst_resource, dst_sub_resource_idx, &dst_box,
src_resource, src_sub_resource_idx, src_box, 0, NULL, WINED3D_TEXF_POINT);
wined3d_cs_emit_copy_sub_resource(device->cs, dst_resource, dst_sub_resource_idx, &dst_box,
src_resource, src_sub_resource_idx, src_box);
return WINED3D_OK;
}
@ -4353,6 +4323,10 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str
return;
}
#if !defined(STAGING_CSMT)
wined3d_resource_wait_idle(resource);
#endif /* STAGING_CSMT */
wined3d_cs_emit_update_sub_resource(device->cs, resource, sub_resource_idx, box, data, row_pitch, depth_pitch);
}

View file

@ -106,19 +106,24 @@ static const struct wined3d_extension_map gl_extension_map[] =
{"GL_APPLE_ycbcr_422", APPLE_YCBCR_422 },
/* ARB */
{"GL_ARB_base_instance", ARB_BASE_INSTANCE },
{"GL_ARB_blend_func_extended", ARB_BLEND_FUNC_EXTENDED },
{"GL_ARB_clear_buffer_object", ARB_CLEAR_BUFFER_OBJECT },
{"GL_ARB_clear_texture", ARB_CLEAR_TEXTURE },
{"GL_ARB_clip_control", ARB_CLIP_CONTROL },
{"GL_ARB_color_buffer_float", ARB_COLOR_BUFFER_FLOAT },
{"GL_ARB_compute_shader", ARB_COMPUTE_SHADER },
{"GL_ARB_conservative_depth", ARB_CONSERVATIVE_DEPTH },
{"GL_ARB_copy_buffer", ARB_COPY_BUFFER },
{"GL_ARB_copy_image", ARB_COPY_IMAGE },
{"GL_ARB_debug_output", ARB_DEBUG_OUTPUT },
{"GL_ARB_depth_buffer_float", ARB_DEPTH_BUFFER_FLOAT },
{"GL_ARB_depth_clamp", ARB_DEPTH_CLAMP },
{"GL_ARB_depth_texture", ARB_DEPTH_TEXTURE },
{"GL_ARB_derivative_control", ARB_DERIVATIVE_CONTROL },
{"GL_ARB_draw_buffers", ARB_DRAW_BUFFERS },
{"GL_ARB_draw_elements_base_vertex", ARB_DRAW_ELEMENTS_BASE_VERTEX },
{"GL_ARB_draw_indirect", ARB_DRAW_INDIRECT },
{"GL_ARB_draw_instanced", ARB_DRAW_INSTANCED },
{"GL_ARB_ES2_compatibility", ARB_ES2_COMPATIBILITY },
{"GL_ARB_ES3_compatibility", ARB_ES3_COMPATIBILITY },
@ -1771,7 +1776,7 @@ static DWORD wined3d_parse_gl_version(const char *gl_version)
}
static enum wined3d_gl_vendor wined3d_guess_gl_vendor(const struct wined3d_gl_info *gl_info,
const char *gl_vendor_string, const char *gl_renderer)
const char *gl_vendor_string, const char *gl_renderer, const char *gl_version)
{
/* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
* the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
@ -1803,7 +1808,8 @@ static enum wined3d_gl_vendor wined3d_guess_gl_vendor(const struct wined3d_gl_in
|| strstr(gl_vendor_string, "Intel")
|| strstr(gl_renderer, "Mesa")
|| strstr(gl_renderer, "Gallium")
|| strstr(gl_renderer, "Intel"))
|| strstr(gl_renderer, "Intel")
|| strstr(gl_version, "Mesa"))
return GL_VENDOR_MESA;
FIXME("Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_UNKNOWN.\n",
@ -1823,6 +1829,8 @@ static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_s
|| strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
|| strstr(gl_vendor_string, "X.Org R300 Project")
|| strstr(gl_renderer, "AMD")
|| strstr(gl_renderer, "FirePro")
|| strstr(gl_renderer, "Radeon")
|| strstr(gl_renderer, "R100")
|| strstr(gl_renderer, "R200")
|| strstr(gl_renderer, "R300")
@ -2692,6 +2700,9 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
/* GL_APPLE_flush_buffer_range */
USE_GL_FUNC(glBufferParameteriAPPLE)
USE_GL_FUNC(glFlushMappedBufferRangeAPPLE)
/* GL_ARB_base_instance */
USE_GL_FUNC(glDrawArraysInstancedBaseInstance)
USE_GL_FUNC(glDrawElementsInstancedBaseVertexBaseInstance)
/* GL_ARB_blend_func_extended */
USE_GL_FUNC(glBindFragDataLocationIndexed)
USE_GL_FUNC(glGetFragDataIndex)
@ -2710,6 +2721,8 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
USE_GL_FUNC(glDispatchComputeIndirect)
/* GL_ARB_copy_buffer */
USE_GL_FUNC(glCopyBufferSubData)
/* GL_ARB_copy_image */
USE_GL_FUNC(glCopyImageSubData)
/* GL_ARB_debug_output */
USE_GL_FUNC(glDebugMessageCallbackARB)
USE_GL_FUNC(glDebugMessageControlARB)
@ -2722,6 +2735,9 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
USE_GL_FUNC(glDrawElementsInstancedBaseVertex)
USE_GL_FUNC(glDrawRangeElementsBaseVertex)
USE_GL_FUNC(glMultiDrawElementsBaseVertex)
/* GL_ARB_draw_indirect */
USE_GL_FUNC(glDrawArraysIndirect)
USE_GL_FUNC(glDrawElementsIndirect)
/* GL_ARB_draw_instanced */
USE_GL_FUNC(glDrawArraysInstancedARB)
USE_GL_FUNC(glDrawElementsInstancedARB)
@ -3508,6 +3524,12 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info)
gl_info->limits.buffers = gl_max;
TRACE("Max draw buffers: %u.\n", gl_max);
}
if (gl_info->supported[ARB_BLEND_FUNC_EXTENDED])
{
gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, &gl_max);
gl_info->limits.dual_buffers = gl_max;
TRACE("Max dual source draw buffers: %u.\n", gl_max);
}
if (gl_info->supported[ARB_MULTITEXTURE])
{
if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
@ -3873,6 +3895,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
{ARB_TIMER_QUERY, MAKEDWORD_VERSION(3, 3)},
{ARB_VERTEX_TYPE_2_10_10_10_REV, MAKEDWORD_VERSION(3, 3)},
{ARB_DRAW_INDIRECT, MAKEDWORD_VERSION(4, 0)},
{ARB_GPU_SHADER5, MAKEDWORD_VERSION(4, 0)},
{ARB_TESSELLATION_SHADER, MAKEDWORD_VERSION(4, 0)},
{ARB_TEXTURE_CUBE_MAP_ARRAY, MAKEDWORD_VERSION(4, 0)},
@ -3894,6 +3917,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
{ARB_CLEAR_BUFFER_OBJECT, MAKEDWORD_VERSION(4, 3)},
{ARB_COMPUTE_SHADER, MAKEDWORD_VERSION(4, 3)},
{ARB_COPY_IMAGE, MAKEDWORD_VERSION(4, 3)},
{ARB_DEBUG_OUTPUT, MAKEDWORD_VERSION(4, 3)},
{ARB_ES3_COMPATIBILITY, MAKEDWORD_VERSION(4, 3)},
{ARB_FRAGMENT_LAYER_VIEWPORT, MAKEDWORD_VERSION(4, 3)},
@ -3909,6 +3933,8 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
{ARB_CLIP_CONTROL, MAKEDWORD_VERSION(4, 5)},
{ARB_DERIVATIVE_CONTROL, MAKEDWORD_VERSION(4, 5)},
{ARB_PIPELINE_STATISTICS_QUERY, MAKEDWORD_VERSION(4, 6)},
};
struct wined3d_driver_info *driver_info = &adapter->driver_info;
const char *gl_vendor_str, *gl_renderer_str, *gl_version_str;
@ -4025,8 +4051,6 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
gl_info->supported[WINED3D_GL_VERSION_2_0] = TRUE;
if (gl_version >= MAKEDWORD_VERSION(3, 2))
gl_info->supported[WINED3D_GL_VERSION_3_2] = TRUE;
if (gl_version >= MAKEDWORD_VERSION(4, 3))
gl_info->supported[WINED3D_GL_VERSION_4_3] = TRUE;
/* All the points are actually point sprites in core contexts, the APIs from
* ARB_point_sprite are not supported anymore. */
@ -4269,6 +4293,10 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
for (i = 0; i < gl_info->limits.buffers; ++i)
adapter->d3d_info.valid_rt_mask |= (1u << i);
adapter->d3d_info.valid_dual_rt_mask = 0;
for (i = 0; i < gl_info->limits.dual_buffers; ++i)
adapter->d3d_info.valid_dual_rt_mask |= (1u << i);
if (!adapter->d3d_info.shader_color_key)
{
/* We do not want to deal with re-creating immutable texture storage for color keying emulation. */
@ -4364,7 +4392,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
checkGLcall("creating VAO");
}
gl_vendor = wined3d_guess_gl_vendor(gl_info, gl_vendor_str, gl_renderer_str);
gl_vendor = wined3d_guess_gl_vendor(gl_info, gl_vendor_str, gl_renderer_str, gl_version_str);
TRACE("Guessed GL vendor %#x.\n", gl_vendor);
if (!(gpu_description = query_gpu_description(gl_info, &vram_bytes)))
@ -5155,6 +5183,8 @@ static BOOL CheckRenderTargetCapability(const struct wined3d_adapter *adapter,
/* Filter out non-RT formats */
if (!(check_format->flags[gl_type] & WINED3DFMT_FLAG_RENDERTARGET))
return FALSE;
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
return TRUE;
if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER)
{
const struct wined3d_pixel_format *cfgs = adapter->cfgs;
@ -5184,12 +5214,6 @@ static BOOL CheckRenderTargetCapability(const struct wined3d_adapter *adapter,
}
}
}
else if(wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{
/* For now return TRUE for FBOs until we have some proper checks.
* Note that this function will only be called when the format is around for texturing. */
return TRUE;
}
return FALSE;
}
@ -5255,9 +5279,9 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
const struct wined3d_format *adapter_format = wined3d_get_format(gl_info, adapter_format_id,
WINED3DUSAGE_RENDERTARGET);
const struct wined3d_format *format = wined3d_get_format(gl_info, check_format_id, usage);
enum wined3d_gl_resource_type gl_type, gl_type_end;
DWORD format_flags = 0;
DWORD allowed_usage;
enum wined3d_gl_resource_type gl_type;
TRACE("wined3d %p, adapter_idx %u, device_type %s, adapter_format %s, usage %s, %s, "
"resource_type %s, check_format %s.\n",
@ -5270,6 +5294,26 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
switch (resource_type)
{
case WINED3D_RTYPE_NONE:
allowed_usage = WINED3DUSAGE_DEPTHSTENCIL
| WINED3DUSAGE_RENDERTARGET;
gl_type = WINED3D_GL_RES_TYPE_TEX_1D;
gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D;
break;
case WINED3D_RTYPE_TEXTURE_1D:
allowed_usage = WINED3DUSAGE_DYNAMIC
| WINED3DUSAGE_SOFTWAREPROCESSING
| WINED3DUSAGE_TEXTURE
| WINED3DUSAGE_QUERY_FILTER
| WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
| WINED3DUSAGE_QUERY_SRGBREAD
| WINED3DUSAGE_QUERY_SRGBWRITE
| WINED3DUSAGE_QUERY_VERTEXTEXTURE
| WINED3DUSAGE_QUERY_WRAPANDMIP;
gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_1D;
break;
case WINED3D_RTYPE_TEXTURE_2D:
allowed_usage = WINED3DUSAGE_DEPTHSTENCIL
| WINED3DUSAGE_RENDERTARGET
@ -5284,7 +5328,7 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
return WINED3DERR_NOTAVAILABLE;
}
gl_type = WINED3D_GL_RES_TYPE_RB;
gl_type = gl_type_end = WINED3D_GL_RES_TYPE_RB;
break;
}
allowed_usage |= WINED3DUSAGE_AUTOGENMIPMAP
@ -5298,11 +5342,11 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
| WINED3DUSAGE_QUERY_SRGBWRITE
| WINED3DUSAGE_QUERY_VERTEXTEXTURE
| WINED3DUSAGE_QUERY_WRAPANDMIP;
gl_type = WINED3D_GL_RES_TYPE_TEX_2D;
gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_2D;
if (usage & WINED3DUSAGE_LEGACY_CUBEMAP)
{
allowed_usage &= ~(WINED3DUSAGE_DEPTHSTENCIL | WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
gl_type = WINED3D_GL_RES_TYPE_TEX_CUBE;
gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_CUBE;
}
else if ((usage & WINED3DUSAGE_DEPTHSTENCIL)
&& (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_SHADOW)
@ -5323,7 +5367,13 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
| WINED3DUSAGE_QUERY_SRGBWRITE
| WINED3DUSAGE_QUERY_VERTEXTEXTURE
| WINED3DUSAGE_QUERY_WRAPANDMIP;
gl_type = WINED3D_GL_RES_TYPE_TEX_3D;
gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D;
break;
case WINED3D_RTYPE_BUFFER:
allowed_usage = WINED3DUSAGE_DYNAMIC
| WINED3DUSAGE_QUERY_VERTEXTEXTURE;
gl_type = gl_type_end = WINED3D_GL_RES_TYPE_BUFFER;
break;
default:
@ -5353,41 +5403,48 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
if (usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP)
format_flags |= WINED3DFMT_FLAG_BUMPMAP;
if ((format->flags[gl_type] & format_flags) != format_flags)
{
TRACE("Requested format flags %#x, but format %s only has %#x.\n",
format_flags, debug_d3dformat(check_format_id), format->flags[gl_type]);
return WINED3DERR_NOTAVAILABLE;
}
if ((format_flags & WINED3DFMT_FLAG_TEXTURE) && (wined3d->flags & WINED3D_NO3D))
{
TRACE("Requested texturing support, but wined3d was created with WINED3D_NO3D.\n");
return WINED3DERR_NOTAVAILABLE;
}
if ((usage & WINED3DUSAGE_DEPTHSTENCIL)
&& !CheckDepthStencilCapability(adapter, adapter_format, format, gl_type))
{
TRACE("Requested WINED3DUSAGE_DEPTHSTENCIL, but format %s is not supported for depth / stencil buffers.\n",
debug_d3dformat(check_format_id));
return WINED3DERR_NOTAVAILABLE;
}
if ((usage & WINED3DUSAGE_RENDERTARGET)
&& !CheckRenderTargetCapability(adapter, adapter_format, format, gl_type))
{
TRACE("Requested WINED3DUSAGE_RENDERTARGET, but format %s is not supported for render targets.\n",
debug_d3dformat(check_format_id));
return WINED3DERR_NOTAVAILABLE;
}
if ((usage & WINED3DUSAGE_AUTOGENMIPMAP) && !gl_info->supported[SGIS_GENERATE_MIPMAP])
{
TRACE("No WINED3DUSAGE_AUTOGENMIPMAP support, returning WINED3DOK_NOAUTOGEN.\n");
return WINED3DOK_NOAUTOGEN;
}
for (; gl_type <= gl_type_end; ++gl_type)
{
if ((format->flags[gl_type] & format_flags) != format_flags)
{
TRACE("Requested format flags %#x, but format %s only has %#x.\n",
format_flags, debug_d3dformat(check_format_id), format->flags[gl_type]);
return WINED3DERR_NOTAVAILABLE;
}
if ((usage & WINED3DUSAGE_RENDERTARGET)
&& !CheckRenderTargetCapability(adapter, adapter_format, format, gl_type))
{
TRACE("Requested WINED3DUSAGE_RENDERTARGET, but format %s is not supported for render targets.\n",
debug_d3dformat(check_format_id));
return WINED3DERR_NOTAVAILABLE;
}
/* 3D depth / stencil textures are never supported. */
if (usage == WINED3DUSAGE_DEPTHSTENCIL && gl_type == WINED3D_GL_RES_TYPE_TEX_3D)
continue;
if ((usage & WINED3DUSAGE_DEPTHSTENCIL)
&& !CheckDepthStencilCapability(adapter, adapter_format, format, gl_type))
{
TRACE("Requested WINED3DUSAGE_DEPTHSTENCIL, but format %s is not supported for depth / stencil buffers.\n",
debug_d3dformat(check_format_id));
return WINED3DERR_NOTAVAILABLE;
}
}
return WINED3D_OK;
}
@ -5921,7 +5978,10 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte
caps->MaxUserClipPlanes = vertex_caps.max_user_clip_planes;
caps->MaxActiveLights = vertex_caps.max_active_lights;
caps->MaxVertexBlendMatrices = vertex_caps.max_vertex_blend_matrices;
caps->MaxVertexBlendMatrixIndex = vertex_caps.max_vertex_blend_matrix_index;
if (device_type == WINED3D_DEVICE_TYPE_HAL)
caps->MaxVertexBlendMatrixIndex = vertex_caps.max_vertex_blend_matrix_index;
else
caps->MaxVertexBlendMatrixIndex = 255;
caps->VertexProcessingCaps = vertex_caps.vertex_processing_caps;
caps->FVFCaps = vertex_caps.fvf_caps;
caps->RasterCaps |= vertex_caps.raster_caps;
@ -6490,6 +6550,18 @@ static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter *adapter, HDC dc
}
}
static BOOL has_extension(const char *list, const char *ext)
{
size_t len = strlen(ext);
while (list)
{
while (*list == ' ') list++;
if (!strncmp(list, ext, len) && (!list[len] || list[len] == ' ')) return TRUE;
list = strchr(list, ' ');
}
return FALSE;
}
static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal, DWORD wined3d_creation_flags)
{
static const DWORD supported_gl_versions[] =
@ -6499,8 +6571,9 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal,
};
struct wined3d_gl_info *gl_info = &adapter->gl_info;
struct wined3d_caps_gl_ctx caps_gl_ctx = {0};
unsigned int i;
DWORD max_gl_version = wined3d_settings.max_gl_version;
DISPLAY_DEVICEW display_device;
unsigned int i;
TRACE("adapter %p, ordinal %u.\n", adapter, ordinal);
@ -6545,15 +6618,25 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal,
return FALSE;
}
if (wined3d_creation_flags & WINED3D_REQUEST_D3D10)
{
const char *gl_extensions = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_EXTENSIONS);
if (!has_extension(gl_extensions, "GL_ARB_compatibility"))
{
ERR_(winediag)("GL_ARB_compatibility not supported, requesting context with GL version 3.2.\n");
max_gl_version = MAKEDWORD_VERSION(3, 2);
}
}
for (i = 0; i < ARRAY_SIZE(supported_gl_versions); ++i)
{
if (supported_gl_versions[i] <= wined3d_settings.max_gl_version)
if (supported_gl_versions[i] <= max_gl_version)
break;
}
if (i == ARRAY_SIZE(supported_gl_versions))
{
ERR_(winediag)("Requested invalid GL version %u.%u.\n",
wined3d_settings.max_gl_version >> 16, wined3d_settings.max_gl_version & 0xffff);
max_gl_version >> 16, max_gl_version & 0xffff);
i = ARRAY_SIZE(supported_gl_versions) - 1;
}

View file

@ -66,18 +66,32 @@ static void draw_primitive_arrays(struct wined3d_context *context, const struct
return;
}
if (start_instance)
if (start_instance && !(gl_info->supported[ARB_BASE_INSTANCE] && gl_info->supported[ARB_INSTANCED_ARRAYS]))
FIXME("Start instance (%u) not supported.\n", start_instance);
if (gl_info->supported[ARB_INSTANCED_ARRAYS])
{
if (!idx_size)
{
if (gl_info->supported[ARB_BASE_INSTANCE])
{
GL_EXTCALL(glDrawArraysInstancedBaseInstance(state->gl_primitive_type, start_idx, count, instance_count, start_instance));
checkGLcall("glDrawArraysInstancedBaseInstance");
return;
}
GL_EXTCALL(glDrawArraysInstanced(state->gl_primitive_type, start_idx, count, instance_count));
checkGLcall("glDrawArraysInstanced");
return;
}
if (gl_info->supported[ARB_BASE_INSTANCE])
{
GL_EXTCALL(glDrawElementsInstancedBaseVertexBaseInstance(state->gl_primitive_type, count, idx_type,
(const char *)idx_data + (idx_size * start_idx), instance_count, base_vertex_idx, start_instance));
checkGLcall("glDrawElementsInstancedBaseVertexBaseInstance");
return;
}
if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX])
{
GL_EXTCALL(glDrawElementsInstancedBaseVertex(state->gl_primitive_type, count, idx_type,
@ -148,6 +162,133 @@ static void draw_primitive_arrays(struct wined3d_context *context, const struct
}
}
/* Context activation is done by the caller. */
static void draw_primitive_arrays_indirect(struct wined3d_context *context, const struct wined3d_state *state,
const void *idx_data, unsigned int idx_size, struct wined3d_buffer *buffer, unsigned int offset)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
if (!gl_info->supported[ARB_DRAW_INDIRECT])
{
FIXME("Indirect draw not supported.\n");
return;
}
wined3d_buffer_load(buffer, context, state);
GL_EXTCALL(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer->buffer_object));
if (idx_size)
{
GLenum idx_type = (idx_size == 2) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
GL_EXTCALL(glDrawElementsIndirect(state->gl_primitive_type, idx_type,
(const BYTE *)NULL + offset));
}
else
{
GL_EXTCALL(glDrawArraysIndirect(state->gl_primitive_type,
(const BYTE *)NULL + offset));
}
GL_EXTCALL(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0));
checkGLcall("draw indirect");
}
static const BYTE *software_vertex_blending(struct wined3d_context *context,
const struct wined3d_state *state, const struct wined3d_stream_info *si,
unsigned int element_idx, unsigned int stride_idx, float *result)
{
#define SI_FORMAT(idx) (si->elements[(idx)].format->emit_idx)
#define SI_PTR(idx1, idx2) (si->elements[(idx1)].data.addr + si->elements[(idx1)].stride * (idx2))
const float *data = (const float *)SI_PTR(element_idx, stride_idx);
float vector[4] = {0.0f, 0.0f, 0.0f, 1.0f};
float cur_weight, weight_sum = 0.0f;
struct wined3d_matrix m;
const BYTE *blend_index;
const float *weights;
int i, num_weights;
if (element_idx != WINED3D_FFP_POSITION && element_idx != WINED3D_FFP_NORMAL)
return (BYTE *)data;
if (!use_indexed_vertex_blending(state, si) || !use_software_vertex_processing(context->device))
return (BYTE *)data;
if (!si->elements[WINED3D_FFP_BLENDINDICES].data.addr ||
!si->elements[WINED3D_FFP_BLENDWEIGHT].data.addr)
{
FIXME("no blend indices / weights set\n");
return (BYTE *)data;
}
if (SI_FORMAT(WINED3D_FFP_BLENDINDICES) != WINED3D_FFP_EMIT_UBYTE4)
{
FIXME("unsupported blend index format: %u\n", SI_FORMAT(WINED3D_FFP_BLENDINDICES));
return (BYTE *)data;
}
/* FIXME: validate weight format */
switch (state->render_states[WINED3D_RS_VERTEXBLEND])
{
case WINED3D_VBF_0WEIGHTS: num_weights = 0; break;
case WINED3D_VBF_1WEIGHTS: num_weights = 1; break;
case WINED3D_VBF_2WEIGHTS: num_weights = 2; break;
case WINED3D_VBF_3WEIGHTS: num_weights = 3; break;
default:
FIXME("unsupported vertex blend render state: %u\n", state->render_states[WINED3D_RS_VERTEXBLEND]);
return (BYTE *)data;
}
switch (SI_FORMAT(element_idx))
{
case WINED3D_FFP_EMIT_FLOAT4: vector[3] = data[3];
case WINED3D_FFP_EMIT_FLOAT3: vector[2] = data[2];
case WINED3D_FFP_EMIT_FLOAT2: vector[1] = data[1];
case WINED3D_FFP_EMIT_FLOAT1: vector[0] = data[0]; break;
default:
FIXME("unsupported value format: %u\n", SI_FORMAT(element_idx));
return (BYTE *)data;
}
blend_index = SI_PTR(WINED3D_FFP_BLENDINDICES, stride_idx);
weights = (const float *)SI_PTR(WINED3D_FFP_BLENDWEIGHT, stride_idx);
result[0] = result[1] = result[2] = result[3] = 0.0f;
for (i = 0; i < num_weights + 1; i++)
{
cur_weight = (i < num_weights) ? weights[i] : 1.0f - weight_sum;
get_modelview_matrix(context, state, blend_index[i], &m);
if (element_idx == WINED3D_FFP_POSITION)
{
result[0] += cur_weight * (vector[0] * m._11 + vector[1] * m._21 + vector[2] * m._31 + vector[3] * m._41);
result[1] += cur_weight * (vector[0] * m._12 + vector[1] * m._22 + vector[2] * m._32 + vector[3] * m._42);
result[2] += cur_weight * (vector[0] * m._13 + vector[1] * m._23 + vector[2] * m._33 + vector[3] * m._43);
result[3] += cur_weight * (vector[0] * m._14 + vector[1] * m._24 + vector[2] * m._34 + vector[3] * m._44);
}
else
{
if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_FFP_LIGHTING)
invert_matrix_3d(&m, &m);
else
invert_matrix(&m, &m);
/* multiply with transposed M */
result[0] += cur_weight * (vector[0] * m._11 + vector[1] * m._12 + vector[2] * m._13);
result[1] += cur_weight * (vector[0] * m._21 + vector[1] * m._22 + vector[2] * m._23);
result[2] += cur_weight * (vector[0] * m._31 + vector[1] * m._32 + vector[2] * m._33);
}
weight_sum += weights[i];
}
#undef SI_FORMAT
#undef SI_PTR
return (BYTE *)result;
}
static unsigned int get_stride_idx(const void *idx_data, unsigned int idx_size,
unsigned int base_vertex_idx, unsigned int start_idx, unsigned int vertex_idx)
{
@ -176,6 +317,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const
BOOL specular_fog = FALSE;
BOOL ps = use_ps(state);
const void *ptr;
float tmp[4];
static unsigned int once;
@ -212,7 +354,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const
if (!(use_map & 1u << element_idx))
continue;
ptr = si->elements[element_idx].data.addr + si->elements[element_idx].stride * stride_idx;
ptr = software_vertex_blending(context, state, si, element_idx, stride_idx, tmp);
ops->generic[si->elements[element_idx].format->emit_idx](element_idx, ptr);
}
}
@ -324,7 +466,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const
if (normal)
{
ptr = normal + stride_idx * si->elements[WINED3D_FFP_NORMAL].stride;
ptr = software_vertex_blending(context, state, si, WINED3D_FFP_NORMAL, stride_idx, tmp);
ops->normal[si->elements[WINED3D_FFP_NORMAL].format->emit_idx](ptr);
}
@ -369,7 +511,7 @@ static void draw_primitive_immediate_mode(struct wined3d_context *context, const
if (position)
{
ptr = position + stride_idx * si->elements[WINED3D_FFP_POSITION].stride;
ptr = software_vertex_blending(context, state, si, WINED3D_FFP_POSITION, stride_idx, tmp);
ops->position[si->elements[WINED3D_FFP_POSITION].format->emit_idx](ptr);
}
}
@ -457,21 +599,20 @@ static GLenum gl_tfb_primitive_type_from_d3d(enum wined3d_primitive_type primiti
/* Routine common to the draw primitive and draw indexed primitive routines */
void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state,
int base_vertex_idx, unsigned int start_idx, unsigned int index_count,
unsigned int start_instance, unsigned int instance_count, BOOL indexed)
const struct wined3d_draw_parameters *parameters)
{
BOOL emulation = FALSE, rasterizer_discard = FALSE;
const struct wined3d_fb_state *fb = state->fb;
const struct wined3d_stream_info *stream_info;
struct wined3d_event_query *ib_query = NULL;
struct wined3d_rendertarget_view *dsv, *rtv;
struct wined3d_stream_info si_emulated;
struct wined3d_fence *ib_fence = NULL;
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
unsigned int i, idx_size = 0;
const void *idx_data = NULL;
if (!index_count)
if (!parameters->indirect && !parameters->u.direct.index_count)
return;
if (!(rtv = fb->render_targets[0]))
@ -496,7 +637,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
if (!(rtv = fb->render_targets[i]) || rtv->format->id == WINED3DFMT_NULL)
continue;
if (state->render_states[WINED3D_RS_COLORWRITEENABLE])
if (state->render_states[WINED3D_RS_COLORWRITE(i)])
{
wined3d_rendertarget_view_load_location(rtv, context, rtv->resource->draw_binding);
wined3d_rendertarget_view_invalidate_location(rtv, ~rtv->resource->draw_binding);
@ -538,10 +679,8 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
}
stream_info = &context->stream_info;
if (context->instance_count)
instance_count = context->instance_count;
if (indexed)
if (parameters->indexed)
{
struct wined3d_buffer *index_buffer = state->index_buffer;
if (!index_buffer->buffer_object || !stream_info->all_vbo)
@ -550,7 +689,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
}
else
{
ib_query = index_buffer->query;
ib_fence = index_buffer->fence;
idx_data = NULL;
}
idx_data = (const BYTE *)idx_data + state->index_offset;
@ -587,6 +726,11 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
WARN_(d3d_perf)("Using software emulation because manual fog coordinates are provided.\n");
emulation = TRUE;
}
else if (use_indexed_vertex_blending(state, stream_info) && use_software_vertex_processing(context->device))
{
WARN_(d3d_perf)("Using software emulation because application requested SVP.\n");
emulation = TRUE;
}
if (emulation)
{
@ -628,12 +772,29 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
checkGLcall("glPatchParameteri");
}
if (context->use_immediate_mode_draw || emulation)
draw_primitive_immediate_mode(context, state, stream_info, idx_data,
idx_size, base_vertex_idx, start_idx, index_count, instance_count);
if (parameters->indirect)
{
if (context->use_immediate_mode_draw || emulation)
FIXME("Indirect draw with immediate mode/emulation is not supported.\n");
else
draw_primitive_arrays_indirect(context, state, idx_data, idx_size,
parameters->u.indirect.buffer, parameters->u.indirect.offset);
}
else
draw_primitive_arrays(context, state, idx_data, idx_size, base_vertex_idx,
start_idx, index_count, start_instance, instance_count);
{
unsigned int instance_count = parameters->u.direct.instance_count;
if (context->instance_count)
instance_count = context->instance_count;
if (context->use_immediate_mode_draw || emulation)
draw_primitive_immediate_mode(context, state, stream_info, idx_data,
idx_size, parameters->u.direct.base_vertex_idx,
parameters->u.direct.start_idx, parameters->u.direct.index_count, instance_count);
else
draw_primitive_arrays(context, state, idx_data, idx_size, parameters->u.direct.base_vertex_idx,
parameters->u.direct.start_idx, parameters->u.direct.index_count,
parameters->u.direct.start_instance, instance_count);
}
if (context->uses_uavs)
{
@ -649,10 +810,10 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
checkGLcall("disable rasterizer discard");
}
if (ib_query)
wined3d_event_query_issue(ib_query, device);
for (i = 0; i < context->num_buffer_queries; ++i)
wined3d_event_query_issue(context->buffer_queries[i], device);
if (ib_fence)
wined3d_fence_issue(ib_fence, device);
for (i = 0; i < context->buffer_fence_count; ++i)
wined3d_fence_issue(context->buffer_fences[i], device);
if (wined3d_settings.strict_draw_ordering)
gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
@ -663,7 +824,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
}
void dispatch_compute(struct wined3d_device *device, const struct wined3d_state *state,
unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z)
const struct wined3d_dispatch_parameters *parameters)
{
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
@ -693,8 +854,22 @@ void dispatch_compute(struct wined3d_device *device, const struct wined3d_state
return;
}
GL_EXTCALL(glDispatchCompute(group_count_x, group_count_y, group_count_z));
checkGLcall("glDispatchCompute");
if (parameters->indirect)
{
const struct wined3d_indirect_dispatch_parameters *indirect = &parameters->u.indirect;
struct wined3d_buffer *buffer = indirect->buffer;
wined3d_buffer_load(buffer, context, state);
GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, buffer->buffer_object));
GL_EXTCALL(glDispatchComputeIndirect((GLintptr)indirect->offset));
GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0));
}
else
{
const struct wined3d_direct_dispatch_parameters *direct = &parameters->u.direct;
GL_EXTCALL(glDispatchCompute(direct->group_count_x, direct->group_count_y, direct->group_count_z));
}
checkGLcall("dispatch compute");
GL_EXTCALL(glMemoryBarrier(GL_ALL_BARRIER_BITS));
checkGLcall("glMemoryBarrier");

File diff suppressed because it is too large Load diff

View file

@ -756,21 +756,8 @@ static void nvrc_fragment_free(struct wined3d_device *device) {}
static BOOL nvts_color_fixup_supported(struct color_fixup_desc fixup)
{
if (TRACE_ON(d3d))
{
TRACE("Checking support for fixup:\n");
dump_color_fixup_desc(fixup);
}
/* We only support identity conversions. */
if (is_identity_fixup(fixup))
{
TRACE("[OK]\n");
return TRUE;
}
TRACE("[FAILED]\n");
return FALSE;
return is_identity_fixup(fixup);
}
static const struct StateEntryTemplate nvrc_fragmentstate_template[] =

View file

@ -23,6 +23,22 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
static UINT64 get_query_result64(GLuint id, const struct wined3d_gl_info *gl_info)
{
if (gl_info->supported[ARB_TIMER_QUERY])
{
GLuint64 result;
GL_EXTCALL(glGetQueryObjectui64v(id, GL_QUERY_RESULT, &result));
return result;
}
else
{
GLuint result;
GL_EXTCALL(glGetQueryObjectuiv(id, GL_QUERY_RESULT, &result));
return result;
}
}
static void wined3d_query_init(struct wined3d_query *query, struct wined3d_device *device,
enum wined3d_query_type type, const void *data, DWORD data_size,
const struct wined3d_query_ops *query_ops, void *parent, const struct wined3d_parent_ops *parent_ops)
@ -59,44 +75,39 @@ static struct wined3d_so_statistics_query *wined3d_so_statistics_query_from_quer
return CONTAINING_RECORD(query, struct wined3d_so_statistics_query, query);
}
static struct wined3d_pipeline_statistics_query *wined3d_pipeline_statistics_query_from_query(struct wined3d_query *query)
static struct wined3d_pipeline_statistics_query *wined3d_pipeline_statistics_query_from_query(
struct wined3d_query *query)
{
return CONTAINING_RECORD(query, struct wined3d_pipeline_statistics_query, query);
}
BOOL wined3d_event_query_supported(const struct wined3d_gl_info *gl_info)
static BOOL wined3d_fence_supported(const struct wined3d_gl_info *gl_info)
{
return gl_info->supported[ARB_SYNC] || gl_info->supported[NV_FENCE] || gl_info->supported[APPLE_FENCE];
}
void wined3d_event_query_destroy(struct wined3d_event_query *query)
{
if (query->context) context_free_event_query(query);
HeapFree(GetProcessHeap(), 0, query);
}
static enum wined3d_event_query_result wined3d_event_query_test(const struct wined3d_event_query *query,
static enum wined3d_fence_result wined3d_fence_test(const struct wined3d_fence *fence,
const struct wined3d_device *device, DWORD flags)
{
const struct wined3d_gl_info *gl_info;
enum wined3d_event_query_result ret;
struct wined3d_context *context;
enum wined3d_fence_result ret;
BOOL fence_result;
TRACE("query %p, device %p, flags %#x.\n", query, device, flags);
TRACE("fence %p, device %p, flags %#x.\n", fence, device, flags);
if (!query->context)
if (!fence->context)
{
TRACE("Query not started.\n");
return WINED3D_EVENT_QUERY_NOT_STARTED;
TRACE("Fence not issued.\n");
return WINED3D_FENCE_NOT_STARTED;
}
if (!(context = context_reacquire(device, query->context)))
if (!(context = context_reacquire(device, fence->context)))
{
if (!query->context->gl_info->supported[ARB_SYNC])
if (!fence->context->gl_info->supported[ARB_SYNC])
{
WARN("Event query tested from wrong thread.\n");
return WINED3D_EVENT_QUERY_WRONG_THREAD;
WARN("Fence tested from wrong thread.\n");
return WINED3D_FENCE_WRONG_THREAD;
}
context = context_acquire(device, NULL, 0);
}
@ -104,7 +115,7 @@ static enum wined3d_event_query_result wined3d_event_query_test(const struct win
if (gl_info->supported[ARB_SYNC])
{
GLenum gl_ret = GL_EXTCALL(glClientWaitSync(query->object.sync,
GLenum gl_ret = GL_EXTCALL(glClientWaitSync(fence->object.sync,
(flags & WINED3DGETDATA_FLUSH) ? GL_SYNC_FLUSH_COMMANDS_BIT : 0, 0));
checkGLcall("glClientWaitSync");
@ -112,68 +123,72 @@ static enum wined3d_event_query_result wined3d_event_query_test(const struct win
{
case GL_ALREADY_SIGNALED:
case GL_CONDITION_SATISFIED:
ret = WINED3D_EVENT_QUERY_OK;
ret = WINED3D_FENCE_OK;
break;
case GL_TIMEOUT_EXPIRED:
ret = WINED3D_EVENT_QUERY_WAITING;
ret = WINED3D_FENCE_WAITING;
break;
case GL_WAIT_FAILED:
default:
ERR("glClientWaitSync returned %#x.\n", gl_ret);
ret = WINED3D_EVENT_QUERY_ERROR;
ret = WINED3D_FENCE_ERROR;
}
}
else if (gl_info->supported[APPLE_FENCE])
{
fence_result = GL_EXTCALL(glTestFenceAPPLE(query->object.id));
fence_result = GL_EXTCALL(glTestFenceAPPLE(fence->object.id));
checkGLcall("glTestFenceAPPLE");
if (fence_result) ret = WINED3D_EVENT_QUERY_OK;
else ret = WINED3D_EVENT_QUERY_WAITING;
if (fence_result)
ret = WINED3D_FENCE_OK;
else
ret = WINED3D_FENCE_WAITING;
}
else if (gl_info->supported[NV_FENCE])
{
fence_result = GL_EXTCALL(glTestFenceNV(query->object.id));
fence_result = GL_EXTCALL(glTestFenceNV(fence->object.id));
checkGLcall("glTestFenceNV");
if (fence_result) ret = WINED3D_EVENT_QUERY_OK;
else ret = WINED3D_EVENT_QUERY_WAITING;
if (fence_result)
ret = WINED3D_FENCE_OK;
else
ret = WINED3D_FENCE_WAITING;
}
else
{
ERR("Event query created despite lack of GL support\n");
ret = WINED3D_EVENT_QUERY_ERROR;
ERR("Fence created despite lack of GL support.\n");
ret = WINED3D_FENCE_ERROR;
}
context_release(context);
return ret;
}
enum wined3d_event_query_result wined3d_event_query_finish(const struct wined3d_event_query *query,
enum wined3d_fence_result wined3d_fence_wait(const struct wined3d_fence *fence,
const struct wined3d_device *device)
{
const struct wined3d_gl_info *gl_info;
enum wined3d_event_query_result ret;
struct wined3d_context *context;
enum wined3d_fence_result ret;
TRACE("query %p, device %p.\n", query, device);
TRACE("fence %p, device %p.\n", fence, device);
if (!query->context)
if (!fence->context)
{
TRACE("Query not started.\n");
return WINED3D_EVENT_QUERY_NOT_STARTED;
TRACE("Fence not issued.\n");
return WINED3D_FENCE_NOT_STARTED;
}
gl_info = query->context->gl_info;
gl_info = fence->context->gl_info;
if (!(context = context_reacquire(device, query->context)))
if (!(context = context_reacquire(device, fence->context)))
{
/* A glFinish does not reliably wait for draws in other contexts. The caller has
* to find its own way to cope with the thread switch
*/
if (!gl_info->supported[ARB_SYNC])
{
WARN("Event query finished from wrong thread.\n");
return WINED3D_EVENT_QUERY_WRONG_THREAD;
WARN("Fence finished from wrong thread.\n");
return WINED3D_FENCE_WRONG_THREAD;
}
context = context_acquire(device, NULL, 0);
}
@ -181,82 +196,131 @@ enum wined3d_event_query_result wined3d_event_query_finish(const struct wined3d_
if (gl_info->supported[ARB_SYNC])
{
/* Apple seems to be into arbitrary limits, and timeouts larger than
* 0xfffffffffffffbff immediately return GL_TIMEOUT_EXPIRED. We don't
* really care and can live with waiting a few μs less. (OS X 10.7.4). */
GLenum gl_ret = GL_EXTCALL(glClientWaitSync(query->object.sync, GL_SYNC_FLUSH_COMMANDS_BIT, ~(GLuint64)0xffff));
/* Timeouts near 0xffffffffffffffff may immediately return GL_TIMEOUT_EXPIRED,
* possibly because macOS internally adds some slop to the timer. To avoid this,
* we use a large number that isn't near the point of overflow (macOS 10.12.5).
*/
GLenum gl_ret = GL_EXTCALL(glClientWaitSync(fence->object.sync,
GL_SYNC_FLUSH_COMMANDS_BIT, ~(GLuint64)0 >> 1));
checkGLcall("glClientWaitSync");
switch (gl_ret)
{
case GL_ALREADY_SIGNALED:
case GL_CONDITION_SATISFIED:
ret = WINED3D_EVENT_QUERY_OK;
ret = WINED3D_FENCE_OK;
break;
/* We don't expect a timeout for a ~584 year wait */
/* We don't expect a timeout for a ~292 year wait */
default:
ERR("glClientWaitSync returned %#x.\n", gl_ret);
ret = WINED3D_EVENT_QUERY_ERROR;
ret = WINED3D_FENCE_ERROR;
}
}
else if (context->gl_info->supported[APPLE_FENCE])
{
GL_EXTCALL(glFinishFenceAPPLE(query->object.id));
GL_EXTCALL(glFinishFenceAPPLE(fence->object.id));
checkGLcall("glFinishFenceAPPLE");
ret = WINED3D_EVENT_QUERY_OK;
ret = WINED3D_FENCE_OK;
}
else if (context->gl_info->supported[NV_FENCE])
{
GL_EXTCALL(glFinishFenceNV(query->object.id));
GL_EXTCALL(glFinishFenceNV(fence->object.id));
checkGLcall("glFinishFenceNV");
ret = WINED3D_EVENT_QUERY_OK;
ret = WINED3D_FENCE_OK;
}
else
{
ERR("Event query created without GL support\n");
ret = WINED3D_EVENT_QUERY_ERROR;
ERR("Fence created without GL support.\n");
ret = WINED3D_FENCE_ERROR;
}
context_release(context);
return ret;
}
void wined3d_event_query_issue(struct wined3d_event_query *query, const struct wined3d_device *device)
void wined3d_fence_issue(struct wined3d_fence *fence, const struct wined3d_device *device)
{
struct wined3d_context *context = NULL;
const struct wined3d_gl_info *gl_info;
if (query->context && !(context = context_reacquire(device, query->context))
&& !query->context->gl_info->supported[ARB_SYNC])
context_free_event_query(query);
if (fence->context && !(context = context_reacquire(device, fence->context))
&& !fence->context->gl_info->supported[ARB_SYNC])
context_free_fence(fence);
if (!context)
context = context_acquire(device, NULL, 0);
gl_info = context->gl_info;
if (!query->context)
context_alloc_event_query(context, query);
if (!fence->context)
context_alloc_fence(context, fence);
if (gl_info->supported[ARB_SYNC])
{
if (query->object.sync) GL_EXTCALL(glDeleteSync(query->object.sync));
if (fence->object.sync)
GL_EXTCALL(glDeleteSync(fence->object.sync));
checkGLcall("glDeleteSync");
query->object.sync = GL_EXTCALL(glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
fence->object.sync = GL_EXTCALL(glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
checkGLcall("glFenceSync");
}
else if (gl_info->supported[APPLE_FENCE])
{
GL_EXTCALL(glSetFenceAPPLE(query->object.id));
GL_EXTCALL(glSetFenceAPPLE(fence->object.id));
checkGLcall("glSetFenceAPPLE");
}
else if (gl_info->supported[NV_FENCE])
{
GL_EXTCALL(glSetFenceNV(query->object.id, GL_ALL_COMPLETED_NV));
GL_EXTCALL(glSetFenceNV(fence->object.id, GL_ALL_COMPLETED_NV));
checkGLcall("glSetFenceNV");
}
context_release(context);
}
static void wined3d_fence_free(struct wined3d_fence *fence)
{
if (fence->context)
context_free_fence(fence);
}
void wined3d_fence_destroy(struct wined3d_fence *fence)
{
wined3d_fence_free(fence);
HeapFree(GetProcessHeap(), 0, fence);
}
static HRESULT wined3d_fence_init(struct wined3d_fence *fence, const struct wined3d_gl_info *gl_info)
{
if (!wined3d_fence_supported(gl_info))
{
WARN("Fences not supported.\n");
return WINED3DERR_NOTAVAILABLE;
}
return WINED3D_OK;
}
HRESULT wined3d_fence_create(struct wined3d_device *device, struct wined3d_fence **fence)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct wined3d_fence *object;
HRESULT hr;
TRACE("device %p, fence %p.\n", device, fence);
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY;
if (FAILED(hr = wined3d_fence_init(object, gl_info)))
{
HeapFree(GetProcessHeap(), 0, object);
return hr;
}
TRACE("Created fence %p.\n", object);
*fence = object;
return WINED3D_OK;
}
ULONG CDECL wined3d_query_incref(struct wined3d_query *query)
{
ULONG refcount = InterlockedIncrement(&query->ref);
@ -277,60 +341,7 @@ static void wined3d_query_destroy_object(void *object)
* deleting the query will obviously leak it, but that's still better
* than potentially deleting a different query with the same id in this
* context, and (still) leaking the actual query. */
if (query->type == WINED3D_QUERY_TYPE_EVENT)
{
wined3d_event_query_destroy(wined3d_event_query_from_query(query));
}
else if (query->type == WINED3D_QUERY_TYPE_OCCLUSION)
{
struct wined3d_occlusion_query *oq = wined3d_occlusion_query_from_query(query);
if (oq->context)
context_free_occlusion_query(oq);
HeapFree(GetProcessHeap(), 0, oq);
}
else if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP)
{
struct wined3d_timestamp_query *tq = wined3d_timestamp_query_from_query(query);
if (tq->context)
context_free_timestamp_query(tq);
HeapFree(GetProcessHeap(), 0, tq);
}
else if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT
|| query->type == WINED3D_QUERY_TYPE_TIMESTAMP_FREQ)
{
HeapFree(GetProcessHeap(), 0, query);
}
else if (query->type == WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM0
|| query->type == WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM1
|| query->type == WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM2
|| query->type == WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM3)
{
struct wined3d_so_statistics_query *pq = wined3d_so_statistics_query_from_query(query);
if (pq->context)
context_free_so_statistics_query(pq);
HeapFree(GetProcessHeap(), 0, pq);
}
else if (query->type == WINED3D_QUERY_TYPE_SO_STATISTICS)
{
HeapFree(GetProcessHeap(), 0, query);
}
else if (query->type == WINED3D_QUERY_TYPE_SO_OVERFLOW)
{
HeapFree(GetProcessHeap(), 0, query);
}
else if (query->type == WINED3D_QUERY_TYPE_PIPELINE_STATISTICS)
{
struct wined3d_pipeline_statistics_query *pq = wined3d_pipeline_statistics_query_from_query(query);
if (pq->context)
context_free_pipeline_statistics_query(pq);
HeapFree(GetProcessHeap(), 0, query);
}
else
{
ERR("Query %p has invalid type %#x.\n", query, query->type);
}
query->query_ops->query_destroy(query);
}
ULONG CDECL wined3d_query_decref(struct wined3d_query *query)
@ -430,28 +441,15 @@ static BOOL wined3d_occlusion_query_ops_poll(struct wined3d_query *query, DWORD
gl_info = context->gl_info;
GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT_AVAILABLE, &available));
checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)");
TRACE("available %#x.\n", available);
TRACE("Available %#x.\n", available);
if (available)
{
if (gl_info->supported[ARB_TIMER_QUERY])
{
GLuint64 result;
GL_EXTCALL(glGetQueryObjectui64v(oq->id, GL_QUERY_RESULT, &result));
checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)");
oq->samples = result;
}
else
{
GLuint result;
GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT, &result));
checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT)");
oq->samples = result;
}
oq->samples = get_query_result64(oq->id, gl_info);
TRACE("Returning 0x%s samples.\n", wine_dbgstr_longlong(oq->samples));
}
checkGLcall("poll occlusion query");
context_release(context);
return available;
@ -460,25 +458,25 @@ static BOOL wined3d_occlusion_query_ops_poll(struct wined3d_query *query, DWORD
static BOOL wined3d_event_query_ops_poll(struct wined3d_query *query, DWORD flags)
{
struct wined3d_event_query *event_query = wined3d_event_query_from_query(query);
enum wined3d_event_query_result ret;
enum wined3d_fence_result ret;
TRACE("query %p, flags %#x.\n", query, flags);
ret = wined3d_event_query_test(event_query, query->device, flags);
ret = wined3d_fence_test(&event_query->fence, query->device, flags);
switch (ret)
{
case WINED3D_EVENT_QUERY_OK:
case WINED3D_EVENT_QUERY_NOT_STARTED:
case WINED3D_FENCE_OK:
case WINED3D_FENCE_NOT_STARTED:
return event_query->signalled = TRUE;
case WINED3D_EVENT_QUERY_WAITING:
case WINED3D_FENCE_WAITING:
return event_query->signalled = FALSE;
case WINED3D_EVENT_QUERY_WRONG_THREAD:
case WINED3D_FENCE_WRONG_THREAD:
FIXME("(%p) Wrong thread, reporting GPU idle.\n", query);
return event_query->signalled = TRUE;
case WINED3D_EVENT_QUERY_ERROR:
case WINED3D_FENCE_ERROR:
ERR("The GL event query failed.\n");
return event_query->signalled = TRUE;
@ -510,7 +508,7 @@ static BOOL wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD fla
{
struct wined3d_event_query *event_query = wined3d_event_query_from_query(query);
wined3d_event_query_issue(event_query, query->device);
wined3d_fence_issue(&event_query->fence, query->device);
return TRUE;
}
else if (flags & WINED3DISSUE_BEGIN)
@ -696,22 +694,8 @@ static BOOL wined3d_so_statistics_query_ops_poll(struct wined3d_query *query, DW
if (written_available && generated_available)
{
if (gl_info->supported[ARB_TIMER_QUERY])
{
GLuint64 result;
GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.written, GL_QUERY_RESULT, &result));
pq->statistics.primitives_written = result;
GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.generated, GL_QUERY_RESULT, &result));
pq->statistics.primitives_generated = result;
}
else
{
GLuint result;
GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.written, GL_QUERY_RESULT, &result));
pq->statistics.primitives_written = result;
GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.generated, GL_QUERY_RESULT, &result));
pq->statistics.primitives_generated = result;
}
pq->statistics.primitives_written = get_query_result64(pq->u.query.written, gl_info);
pq->statistics.primitives_generated = get_query_result64(pq->u.query.generated, gl_info);
TRACE("Returning %s, %s primitives.\n",
wine_dbgstr_longlong(pq->statistics.primitives_written),
wine_dbgstr_longlong(pq->statistics.primitives_generated));
@ -791,34 +775,6 @@ static BOOL wined3d_so_statistics_query_ops_issue(struct wined3d_query *query, D
return poll;
}
static BOOL wined3d_statistics_query_ops_poll(struct wined3d_query *query, DWORD flags)
{
TRACE("query %p, flags %#x.\n", query, flags);
return TRUE;
}
static BOOL wined3d_statistics_query_ops_issue(struct wined3d_query *query, DWORD flags)
{
FIXME("query %p, flags %#x.\n", query, flags);
return FALSE;
}
static BOOL wined3d_overflow_query_ops_poll(struct wined3d_query *query, DWORD flags)
{
TRACE("query %p, flags %#x.\n", query, flags);
return TRUE;
}
static BOOL wined3d_overflow_query_ops_issue(struct wined3d_query *query, DWORD flags)
{
FIXME("query %p, flags %#x.\n", query, flags);
return FALSE;
}
static BOOL wined3d_pipeline_query_ops_poll(struct wined3d_query *query, DWORD flags)
{
struct wined3d_pipeline_statistics_query *pq = wined3d_pipeline_statistics_query_from_query(query);
@ -832,77 +788,58 @@ static BOOL wined3d_pipeline_query_ops_poll(struct wined3d_query *query, DWORD f
if (!(context = context_reacquire(device, pq->context)))
{
FIXME("%p Wrong thread, returning 0 primitives.\n", query);
FIXME("%p Wrong thread.\n", query);
memset(&pq->statistics, 0, sizeof(pq->statistics));
return TRUE;
}
gl_info = context->gl_info;
for (i = 0; i < ARRAY_SIZE(pq->u.id); i++)
for (i = 0; i < ARRAY_SIZE(pq->u.id); ++i)
{
GL_EXTCALL(glGetQueryObjectuiv(pq->u.id[i], GL_QUERY_RESULT_AVAILABLE, &available));
if (!available) goto done;
if (!available)
break;
}
if (gl_info->supported[ARB_TIMER_QUERY])
if (available)
{
GLuint64 result;
GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.vertices, GL_QUERY_RESULT, &result));
pq->statistics.ia_vertices = result;
GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.primitives, GL_QUERY_RESULT, &result));
pq->statistics.ia_primitives = result;
GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.vertex_shader, GL_QUERY_RESULT, &result));
pq->statistics.vs_invocations = result;
GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.tess_control_shader, GL_QUERY_RESULT, &result));
pq->statistics.hs_invocations = result;
GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.tess_eval_shader, GL_QUERY_RESULT, &result));
pq->statistics.ds_invocations = result;
GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.geometry_shader, GL_QUERY_RESULT, &result));
pq->statistics.gs_invocations = result;
GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.geometry_primitives, GL_QUERY_RESULT, &result));
pq->statistics.gs_primitives = result;
GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.fragment_shader, GL_QUERY_RESULT, &result));
pq->statistics.ps_invocations = result;
GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.compute_shader, GL_QUERY_RESULT, &result));
pq->statistics.cs_invocations = result;
GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.clipping_input, GL_QUERY_RESULT, &result));
pq->statistics.c_invocations = result;
GL_EXTCALL(glGetQueryObjectui64v(pq->u.query.clipping_output, GL_QUERY_RESULT, &result));
pq->statistics.c_primitives = result;
}
else
{
GLuint result;
GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.vertices, GL_QUERY_RESULT, &result));
pq->statistics.ia_vertices = result;
GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.primitives, GL_QUERY_RESULT, &result));
pq->statistics.ia_primitives = result;
GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.vertex_shader, GL_QUERY_RESULT, &result));
pq->statistics.vs_invocations = result;
GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.tess_control_shader, GL_QUERY_RESULT, &result));
pq->statistics.hs_invocations = result;
GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.tess_eval_shader, GL_QUERY_RESULT, &result));
pq->statistics.ds_invocations = result;
GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.geometry_shader, GL_QUERY_RESULT, &result));
pq->statistics.gs_invocations = result;
GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.geometry_primitives, GL_QUERY_RESULT, &result));
pq->statistics.gs_primitives = result;
GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.fragment_shader, GL_QUERY_RESULT, &result));
pq->statistics.ps_invocations = result;
GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.compute_shader, GL_QUERY_RESULT, &result));
pq->statistics.cs_invocations = result;
GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.clipping_input, GL_QUERY_RESULT, &result));
pq->statistics.c_invocations = result;
GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.clipping_output, GL_QUERY_RESULT, &result));
pq->statistics.c_primitives = result;
pq->statistics.vertices_submitted = get_query_result64(pq->u.query.vertices, gl_info);
pq->statistics.primitives_submitted = get_query_result64(pq->u.query.primitives, gl_info);
pq->statistics.vs_invocations = get_query_result64(pq->u.query.vertex_shader, gl_info);
pq->statistics.hs_invocations = get_query_result64(pq->u.query.tess_control_shader, gl_info);
pq->statistics.ds_invocations = get_query_result64(pq->u.query.tess_eval_shader, gl_info);
pq->statistics.gs_invocations = get_query_result64(pq->u.query.geometry_shader, gl_info);
pq->statistics.gs_primitives = get_query_result64(pq->u.query.geometry_primitives, gl_info);
pq->statistics.ps_invocations = get_query_result64(pq->u.query.fragment_shader, gl_info);
pq->statistics.cs_invocations = get_query_result64(pq->u.query.compute_shader, gl_info);
pq->statistics.clipping_input_primitives = get_query_result64(pq->u.query.clipping_input, gl_info);
pq->statistics.clipping_output_primitives = get_query_result64(pq->u.query.clipping_output, gl_info);
}
done:
checkGLcall("poll pipeline statistics query");
context_release(context);
return available;
}
static void wined3d_pipeline_statistics_query_end(struct wined3d_pipeline_statistics_query *query,
struct wined3d_context *context)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
GL_EXTCALL(glEndQuery(GL_VERTICES_SUBMITTED_ARB));
GL_EXTCALL(glEndQuery(GL_PRIMITIVES_SUBMITTED_ARB));
GL_EXTCALL(glEndQuery(GL_VERTEX_SHADER_INVOCATIONS_ARB));
GL_EXTCALL(glEndQuery(GL_TESS_CONTROL_SHADER_PATCHES_ARB));
GL_EXTCALL(glEndQuery(GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB));
GL_EXTCALL(glEndQuery(GL_GEOMETRY_SHADER_INVOCATIONS));
GL_EXTCALL(glEndQuery(GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB));
GL_EXTCALL(glEndQuery(GL_FRAGMENT_SHADER_INVOCATIONS_ARB));
GL_EXTCALL(glEndQuery(GL_COMPUTE_SHADER_INVOCATIONS_ARB));
GL_EXTCALL(glEndQuery(GL_CLIPPING_INPUT_PRIMITIVES_ARB));
GL_EXTCALL(glEndQuery(GL_CLIPPING_OUTPUT_PRIMITIVES_ARB));
checkGLcall("end query");
}
static BOOL wined3d_pipeline_query_ops_issue(struct wined3d_query *query, DWORD flags)
{
struct wined3d_pipeline_statistics_query *pq = wined3d_pipeline_statistics_query_from_query(query);
@ -919,17 +856,7 @@ static BOOL wined3d_pipeline_query_ops_issue(struct wined3d_query *query, DWORD
{
if ((context = context_reacquire(device, pq->context)))
{
GL_EXTCALL(glEndQuery(GL_VERTICES_SUBMITTED_ARB));
GL_EXTCALL(glEndQuery(GL_PRIMITIVES_SUBMITTED_ARB));
GL_EXTCALL(glEndQuery(GL_VERTEX_SHADER_INVOCATIONS_ARB));
GL_EXTCALL(glEndQuery(GL_TESS_CONTROL_SHADER_PATCHES_ARB));
GL_EXTCALL(glEndQuery(GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB));
GL_EXTCALL(glEndQuery(GL_GEOMETRY_SHADER_INVOCATIONS));
GL_EXTCALL(glEndQuery(GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB));
GL_EXTCALL(glEndQuery(GL_FRAGMENT_SHADER_INVOCATIONS_ARB));
GL_EXTCALL(glEndQuery(GL_COMPUTE_SHADER_INVOCATIONS_ARB));
GL_EXTCALL(glEndQuery(GL_CLIPPING_INPUT_PRIMITIVES_ARB));
GL_EXTCALL(glEndQuery(GL_CLIPPING_OUTPUT_PRIMITIVES_ARB));
wined3d_pipeline_statistics_query_end(pq, context);
}
else
{
@ -969,19 +896,7 @@ static BOOL wined3d_pipeline_query_ops_issue(struct wined3d_query *query, DWORD
{
if ((context = context_reacquire(device, pq->context)))
{
GL_EXTCALL(glEndQuery(GL_VERTICES_SUBMITTED_ARB));
GL_EXTCALL(glEndQuery(GL_PRIMITIVES_SUBMITTED_ARB));
GL_EXTCALL(glEndQuery(GL_VERTEX_SHADER_INVOCATIONS_ARB));
GL_EXTCALL(glEndQuery(GL_TESS_CONTROL_SHADER_PATCHES_ARB));
GL_EXTCALL(glEndQuery(GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB));
GL_EXTCALL(glEndQuery(GL_GEOMETRY_SHADER_INVOCATIONS));
GL_EXTCALL(glEndQuery(GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB));
GL_EXTCALL(glEndQuery(GL_FRAGMENT_SHADER_INVOCATIONS_ARB));
GL_EXTCALL(glEndQuery(GL_COMPUTE_SHADER_INVOCATIONS_ARB));
GL_EXTCALL(glEndQuery(GL_CLIPPING_INPUT_PRIMITIVES_ARB));
GL_EXTCALL(glEndQuery(GL_CLIPPING_OUTPUT_PRIMITIVES_ARB));
checkGLcall("end query");
wined3d_pipeline_statistics_query_end(pq, context);
context_release(context);
poll = TRUE;
}
@ -996,10 +911,47 @@ static BOOL wined3d_pipeline_query_ops_issue(struct wined3d_query *query, DWORD
return poll;
}
static BOOL wined3d_statistics_query_ops_poll(struct wined3d_query *query, DWORD flags)
{
TRACE("query %p, flags %#x.\n", query, flags);
return TRUE;
}
static BOOL wined3d_statistics_query_ops_issue(struct wined3d_query *query, DWORD flags)
{
FIXME("query %p, flags %#x.\n", query, flags);
return FALSE;
}
static BOOL wined3d_overflow_query_ops_poll(struct wined3d_query *query, DWORD flags)
{
TRACE("query %p, flags %#x.\n", query, flags);
return TRUE;
}
static BOOL wined3d_overflow_query_ops_issue(struct wined3d_query *query, DWORD flags)
{
FIXME("query %p, flags %#x.\n", query, flags);
return FALSE;
}
static void wined3d_event_query_ops_destroy(struct wined3d_query *query)
{
struct wined3d_event_query *event_query = wined3d_event_query_from_query(query);
wined3d_fence_free(&event_query->fence);
HeapFree(GetProcessHeap(), 0, event_query);
}
static const struct wined3d_query_ops event_query_ops =
{
wined3d_event_query_ops_poll,
wined3d_event_query_ops_issue,
wined3d_event_query_ops_destroy,
};
static HRESULT wined3d_event_query_create(struct wined3d_device *device,
@ -1008,19 +960,21 @@ static HRESULT wined3d_event_query_create(struct wined3d_device *device,
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct wined3d_event_query *object;
HRESULT hr;
TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
device, type, parent, parent_ops, query);
if (!wined3d_event_query_supported(gl_info))
{
WARN("Event queries not supported.\n");
return WINED3DERR_NOTAVAILABLE;
}
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY;
if (FAILED(hr = wined3d_fence_init(&object->fence, gl_info)))
{
WARN("Event queries not supported.\n");
HeapFree(GetProcessHeap(), 0, object);
return hr;
}
wined3d_query_init(&object->query, device, type, &object->signalled,
sizeof(object->signalled), &event_query_ops, parent, parent_ops);
@ -1030,10 +984,20 @@ static HRESULT wined3d_event_query_create(struct wined3d_device *device,
return WINED3D_OK;
}
static void wined3d_occlusion_query_ops_destroy(struct wined3d_query *query)
{
struct wined3d_occlusion_query *oq = wined3d_occlusion_query_from_query(query);
if (oq->context)
context_free_occlusion_query(oq);
HeapFree(GetProcessHeap(), 0, oq);
}
static const struct wined3d_query_ops occlusion_query_ops =
{
wined3d_occlusion_query_ops_poll,
wined3d_occlusion_query_ops_issue,
wined3d_occlusion_query_ops_destroy,
};
static HRESULT wined3d_occlusion_query_create(struct wined3d_device *device,
@ -1064,10 +1028,20 @@ static HRESULT wined3d_occlusion_query_create(struct wined3d_device *device,
return WINED3D_OK;
}
static void wined3d_timestamp_query_ops_destroy(struct wined3d_query *query)
{
struct wined3d_timestamp_query *tq = wined3d_timestamp_query_from_query(query);
if (tq->context)
context_free_timestamp_query(tq);
HeapFree(GetProcessHeap(), 0, tq);
}
static const struct wined3d_query_ops timestamp_query_ops =
{
wined3d_timestamp_query_ops_poll,
wined3d_timestamp_query_ops_issue,
wined3d_timestamp_query_ops_destroy,
};
static HRESULT wined3d_timestamp_query_create(struct wined3d_device *device,
@ -1098,10 +1072,16 @@ static HRESULT wined3d_timestamp_query_create(struct wined3d_device *device,
return WINED3D_OK;
}
static void wined3d_timestamp_disjoint_query_ops_destroy(struct wined3d_query *query)
{
HeapFree(GetProcessHeap(), 0, query);
}
static const struct wined3d_query_ops timestamp_disjoint_query_ops =
{
wined3d_timestamp_disjoint_query_ops_poll,
wined3d_timestamp_disjoint_query_ops_issue,
wined3d_timestamp_disjoint_query_ops_destroy,
};
static HRESULT wined3d_timestamp_disjoint_query_create(struct wined3d_device *device,
@ -1144,10 +1124,20 @@ static HRESULT wined3d_timestamp_disjoint_query_create(struct wined3d_device *de
return WINED3D_OK;
}
static void wined3d_so_statistics_query_ops_destroy(struct wined3d_query *query)
{
struct wined3d_so_statistics_query *pq = wined3d_so_statistics_query_from_query(query);
if (pq->context)
context_free_so_statistics_query(pq);
HeapFree(GetProcessHeap(), 0, pq);
}
static const struct wined3d_query_ops so_statistics_query_ops =
{
wined3d_so_statistics_query_ops_poll,
wined3d_so_statistics_query_ops_issue,
wined3d_so_statistics_query_ops_destroy,
};
static HRESULT wined3d_so_statistics_query_create(struct wined3d_device *device,
@ -1156,6 +1146,12 @@ static HRESULT wined3d_so_statistics_query_create(struct wined3d_device *device,
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct wined3d_so_statistics_query *object;
unsigned int stream_idx;
if (WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM0 <= type && type <= WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM3)
stream_idx = type - WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM0;
else
return WINED3DERR_NOTAVAILABLE;
TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
device, type, parent, parent_ops, query);
@ -1174,27 +1170,9 @@ static HRESULT wined3d_so_statistics_query_create(struct wined3d_device *device,
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY;
switch (type)
{
case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM0:
object->stream_idx = 0;
break;
case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM1:
object->stream_idx = 1;
break;
case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM2:
object->stream_idx = 2;
break;
case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM3:
object->stream_idx = 3;
break;
default:
HeapFree(GetProcessHeap(), 0, object);
return WINED3DERR_NOTAVAILABLE;
}
wined3d_query_init(&object->query, device, type, &object->statistics,
sizeof(object->statistics), &so_statistics_query_ops, parent, parent_ops);
object->stream_idx = stream_idx;
TRACE("Created query %p.\n", object);
*query = &object->query;
@ -1202,10 +1180,59 @@ static HRESULT wined3d_so_statistics_query_create(struct wined3d_device *device,
return WINED3D_OK;
}
static void wined3d_pipeline_query_ops_destroy(struct wined3d_query *query)
{
struct wined3d_pipeline_statistics_query *pq = wined3d_pipeline_statistics_query_from_query(query);
if (pq->context)
context_free_pipeline_statistics_query(pq);
HeapFree(GetProcessHeap(), 0, pq);
}
static const struct wined3d_query_ops pipeline_query_ops =
{
wined3d_pipeline_query_ops_poll,
wined3d_pipeline_query_ops_issue,
wined3d_pipeline_query_ops_destroy,
};
static HRESULT wined3d_pipeline_query_create(struct wined3d_device *device,
enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_query **query)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct wined3d_pipeline_statistics_query *object;
TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
device, type, parent, parent_ops, query);
if (!gl_info->supported[ARB_PIPELINE_STATISTICS_QUERY])
{
WARN("OpenGL implementation does not support pipeline statistics queries.\n");
return WINED3DERR_NOTAVAILABLE;
}
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY;
wined3d_query_init(&object->query, device, type, &object->statistics,
sizeof(object->statistics), &pipeline_query_ops, parent, parent_ops);
TRACE("Created query %p.\n", object);
*query = &object->query;
return WINED3D_OK;
}
static void wined3d_statistics_query_ops_destroy(struct wined3d_query *query)
{
HeapFree(GetProcessHeap(), 0, query);
}
static const struct wined3d_query_ops statistics_query_ops =
{
wined3d_statistics_query_ops_poll,
wined3d_statistics_query_ops_issue,
wined3d_statistics_query_ops_destroy,
};
static HRESULT wined3d_statistics_query_create(struct wined3d_device *device,
@ -1229,10 +1256,16 @@ static HRESULT wined3d_statistics_query_create(struct wined3d_device *device,
return WINED3D_OK;
}
static void wined3d_overflow_query_ops_destroy(struct wined3d_query *query)
{
HeapFree(GetProcessHeap(), 0, query);
}
static const struct wined3d_query_ops overflow_query_ops =
{
wined3d_overflow_query_ops_poll,
wined3d_overflow_query_ops_issue,
wined3d_overflow_query_ops_destroy,
};
static HRESULT wined3d_overflow_query_create(struct wined3d_device *device,
@ -1256,40 +1289,6 @@ static HRESULT wined3d_overflow_query_create(struct wined3d_device *device,
return WINED3D_OK;
}
static const struct wined3d_query_ops pipeline_query_ops =
{
wined3d_pipeline_query_ops_poll,
wined3d_pipeline_query_ops_issue,
};
static HRESULT wined3d_pipeline_query_create(struct wined3d_device *device,
enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_query **query)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct wined3d_pipeline_statistics_query *object;
TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
device, type, parent, parent_ops, query);
if (!gl_info->supported[ARB_PIPELINE_STATISTICS_QUERY])
{
WARN("OpenGL implementation does not support pipeline statistic queries.\n");
return WINED3DERR_NOTAVAILABLE;
}
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY;
wined3d_query_init(&object->query, device, type, &object->statistics,
sizeof(object->statistics), &pipeline_query_ops, parent, parent_ops);
TRACE("Created query %p.\n", object);
*query = &object->query;
return WINED3D_OK;
}
HRESULT CDECL wined3d_query_create(struct wined3d_device *device, enum wined3d_query_type type,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
{
@ -1317,15 +1316,15 @@ HRESULT CDECL wined3d_query_create(struct wined3d_device *device, enum wined3d_q
case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM3:
return wined3d_so_statistics_query_create(device, type, parent, parent_ops, query);
case WINED3D_QUERY_TYPE_PIPELINE_STATISTICS:
return wined3d_pipeline_query_create(device, type, parent, parent_ops, query);
case WINED3D_QUERY_TYPE_SO_STATISTICS:
return wined3d_statistics_query_create(device, type, parent, parent_ops, query);
case WINED3D_QUERY_TYPE_SO_OVERFLOW:
return wined3d_overflow_query_create(device, type, parent, parent_ops, query);
case WINED3D_QUERY_TYPE_PIPELINE_STATISTICS:
return wined3d_pipeline_query_create(device, type, parent, parent_ops, query);
default:
FIXME("Unhandled query type %#x.\n", type);
return WINED3DERR_NOTAVAILABLE;

View file

@ -380,6 +380,99 @@ HRESULT CDECL wined3d_resource_unmap(struct wined3d_resource *resource, unsigned
return wined3d_cs_unmap(resource->device->cs, resource, sub_resource_idx);
}
UINT CDECL wined3d_resource_update_info(struct wined3d_resource *resource, unsigned int sub_resource_idx,
const struct wined3d_box *box, unsigned int row_pitch, unsigned int depth_pitch)
{
unsigned int width, height, depth;
struct wined3d_box b;
UINT data_size;
TRACE("resource %p, sub_resource_idx %u, box %s, row_pitch %u, depth_pitch %u.\n",
resource, sub_resource_idx, debug_box(box), row_pitch, depth_pitch);
if (resource->type == WINED3D_RTYPE_BUFFER)
{
if (sub_resource_idx > 0)
{
WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx);
return 0;
}
width = resource->size;
height = 1;
depth = 1;
}
else if (resource->type == WINED3D_RTYPE_TEXTURE_1D ||
resource->type == WINED3D_RTYPE_TEXTURE_2D || resource->type == WINED3D_RTYPE_TEXTURE_3D)
{
struct wined3d_texture *texture = texture_from_resource(resource);
unsigned int level;
if (sub_resource_idx >= texture->level_count * texture->layer_count)
{
WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx);
return 0;
}
level = sub_resource_idx % texture->level_count;
width = wined3d_texture_get_level_width(texture, level);
height = wined3d_texture_get_level_height(texture, level);
depth = wined3d_texture_get_level_depth(texture, level);
}
else
{
FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type));
return 0;
}
if (!box)
{
wined3d_box_set(&b, 0, 0, width, height, 0, depth);
box = &b;
}
else if (box->left >= box->right || box->right > width
|| box->top >= box->bottom || box->bottom > height
|| box->front >= box->back || box->back > depth)
{
WARN("Invalid box %s specified.\n", debug_box(box));
return 0;
}
if (resource->format_flags & WINED3DFMT_FLAG_BLOCKS)
{
if (resource->type != WINED3D_RTYPE_TEXTURE_2D)
{
FIXME("Calculation of block formats not implemented for %s resources.\n", debug_d3dresourcetype(resource->type));
return 0;
}
height = (box->bottom - box->top + resource->format->block_height - 1) / resource->format->block_height;
width = (box->right - box->left + resource->format->block_width - 1) / resource->format->block_width;
return (height - 1) * row_pitch + width * resource->format->block_byte_count;
}
data_size = 0;
switch (resource->type)
{
case WINED3D_RTYPE_TEXTURE_3D:
data_size += (box->back - box->front - 1) * depth_pitch;
/* fall-through */
case WINED3D_RTYPE_TEXTURE_2D:
data_size += (box->bottom - box->top - 1) * row_pitch;
/* fall-through */
case WINED3D_RTYPE_TEXTURE_1D:
data_size += (box->right - box->left) * resource->format->byte_count;
break;
case WINED3D_RTYPE_BUFFER:
data_size = box->right - box->left;
break;
case WINED3D_RTYPE_NONE:
break;
}
return data_size;
}
void CDECL wined3d_resource_preload(struct wined3d_resource *resource)
{
wined3d_cs_emit_preload_resource(resource->device->cs, resource);

View file

@ -1078,6 +1078,21 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
else
reg_maps->cb_sizes[reg->idx[0].offset] = reg->idx[1].offset;
}
else if (ins.handler_idx == WINED3DSIH_DCL_GLOBAL_FLAGS)
{
if (ins.flags & WINED3DSGF_FORCE_EARLY_DEPTH_STENCIL)
{
if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
shader->u.ps.force_early_depth_stencil = TRUE;
else
FIXME("Invalid instruction %#x for shader type %#x.\n",
ins.handler_idx, shader_version.type);
}
else
{
WARN("Ignoring global flags %#x.\n", ins.flags);
}
}
else if (ins.handler_idx == WINED3DSIH_DCL_GS_INSTANCES)
{
if (shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY)
@ -1126,6 +1141,17 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
FIXME("Invalid instruction %#x for shader type %#x.\n",
ins.handler_idx, shader_version.type);
}
else if (ins.handler_idx == WINED3DSIH_DCL_OUTPUT)
{
if (ins.declaration.dst.reg.type == WINED3DSPR_DEPTHOUT_GREATER_EQUAL ||
ins.declaration.dst.reg.type == WINED3DSPR_DEPTHOUT_LESS_EQUAL)
{
if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
shader->u.ps.depth_compare = ins.declaration.dst.reg.type;
else
FIXME("Invalid instruction depth declaration for shader type %#x.\n", shader_version.type);
}
}
else if (ins.handler_idx == WINED3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT)
{
if (shader_version.type == WINED3D_SHADER_TYPE_HULL)
@ -1662,14 +1688,22 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
{
for (i = 0; i < input_signature->element_count; ++i)
{
reg_maps->input_registers |= 1u << input_signature->elements[i].register_idx;
if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
if (shader_version.type == WINED3D_SHADER_TYPE_VERTEX)
{
if (input_signature->elements[i].register_idx >= ARRAY_SIZE(shader->u.vs.attributes))
{
WARN("Invalid input signature register index %u.\n", input_signature->elements[i].register_idx);
return WINED3DERR_INVALIDCALL;
}
}
else if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
{
if (input_signature->elements[i].sysval_semantic == WINED3D_SV_POSITION)
reg_maps->vpos = 1;
else if (input_signature->elements[i].sysval_semantic == WINED3D_SV_IS_FRONT_FACE)
reg_maps->usesfacing = 1;
}
reg_maps->input_registers |= 1u << input_signature->elements[i].register_idx;
}
}
else if (!input_signature->elements && reg_maps->input_registers)
@ -1753,6 +1787,14 @@ static void shader_dump_global_flags(struct wined3d_string_buffer *buffer, DWORD
shader_addline(buffer, " | ");
}
if (global_flags & WINED3DSGF_FORCE_EARLY_DEPTH_STENCIL)
{
shader_addline(buffer, "forceEarlyDepthStencil");
global_flags &= ~WINED3DSGF_FORCE_EARLY_DEPTH_STENCIL;
if (global_flags)
shader_addline(buffer, " | ");
}
if (global_flags & WINED3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS)
{
shader_addline(buffer, "enableRawAndStructuredBuffers");
@ -2101,6 +2143,14 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer,
shader_addline(buffer, "oC");
break;
case WINED3DSPR_DEPTHOUT_GREATER_EQUAL:
shader_addline(buffer, "oDepth_greater_equal");
break;
case WINED3DSPR_DEPTHOUT_LESS_EQUAL:
shader_addline(buffer, "oDepth_less_equal");
break;
case WINED3DSPR_DEPTHOUT:
shader_addline(buffer, "oDepth");
break;
@ -3878,6 +3928,8 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
args->render_offscreen = shader->reg_maps.vpos && gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS]
? context->render_offscreen : 0;
args->dual_source_blend = wined3d_dualblend_enabled(state, gl_info);
}
static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_device *device,

View file

@ -168,6 +168,7 @@ enum wined3d_sm4_opcode
WINED3D_SM4_OP_MOVC = 0x37,
WINED3D_SM4_OP_MUL = 0x38,
WINED3D_SM4_OP_NE = 0x39,
WINED3D_SM4_OP_NOP = 0x3a,
WINED3D_SM4_OP_NOT = 0x3b,
WINED3D_SM4_OP_OR = 0x3c,
WINED3D_SM4_OP_RESINFO = 0x3d,
@ -329,6 +330,8 @@ enum wined3d_sm4_register_type
WINED3D_SM5_RT_COVERAGE = 0x23,
WINED3D_SM5_RT_LOCAL_THREAD_INDEX = 0x24,
WINED3D_SM5_RT_GS_INSTANCE_ID = 0x25,
WINED3D_SM5_RT_DEPTHOUT_GREATER_EQUAL = 0x26,
WINED3D_SM5_RT_DEPTHOUT_LESS_EQUAL = 0x27,
};
enum wined3d_sm4_output_primitive_type
@ -505,16 +508,16 @@ static const enum wined3d_data_type data_type_table[] =
/* WINED3D_SM4_DATA_FLOAT */ WINED3D_DATA_FLOAT,
};
static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD **ptr,
static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD **ptr, const DWORD *end,
enum wined3d_data_type data_type, struct wined3d_shader_src_param *src_param);
static BOOL shader_sm4_read_dst_param(struct wined3d_sm4_data *priv, const DWORD **ptr,
static BOOL shader_sm4_read_dst_param(struct wined3d_sm4_data *priv, const DWORD **ptr, const DWORD *end,
enum wined3d_data_type data_type, struct wined3d_shader_dst_param *dst_param);
static void shader_sm4_read_conditional_op(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
shader_sm4_read_src_param(priv, &tokens, WINED3D_DATA_UINT, &priv->src_param[0]);
shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &priv->src_param[0]);
ins->flags = (opcode_token & WINED3D_SM4_CONDITIONAL_NZ) ?
WINED3D_SHADER_CONDITIONAL_OP_NZ : WINED3D_SHADER_CONDITIONAL_OP_Z;
}
@ -568,7 +571,7 @@ static void shader_sm4_read_dcl_resource(struct wined3d_shader_instruction *ins,
ins->declaration.semantic.resource_type = resource_type_table[resource_type];
}
reg_data_type = opcode == WINED3D_SM4_OP_DCL_RESOURCE ? WINED3D_DATA_RESOURCE : WINED3D_DATA_UAV;
shader_sm4_read_dst_param(priv, &tokens, reg_data_type, &ins->declaration.semantic.reg);
shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], reg_data_type, &ins->declaration.semantic.reg);
components = *tokens++;
if ((components & 0xfff0) != (components & 0xf) * 0x1110)
@ -593,7 +596,7 @@ static void shader_sm4_read_dcl_constant_buffer(struct wined3d_shader_instructio
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
shader_sm4_read_src_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.src);
shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT, &ins->declaration.src);
if (opcode_token & WINED3D_SM4_INDEX_TYPE_MASK)
ins->flags |= WINED3DSI_INDEXED_DYNAMIC;
}
@ -605,14 +608,15 @@ static void shader_sm4_read_dcl_sampler(struct wined3d_shader_instruction *ins,
ins->flags = (opcode_token & WINED3D_SM4_SAMPLER_MODE_MASK) >> WINED3D_SM4_SAMPLER_MODE_SHIFT;
if (ins->flags & ~WINED3D_SM4_SAMPLER_COMPARISON)
FIXME("Unhandled sampler mode %#x.\n", ins->flags);
shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_SAMPLER, &ins->declaration.dst);
shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_SAMPLER, &ins->declaration.dst);
}
static void shader_sm4_read_dcl_index_range(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_OPAQUE, &ins->declaration.index_range.first_register);
shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_OPAQUE,
&ins->declaration.index_range.first_register);
ins->declaration.index_range.last_register = *tokens;
}
@ -668,14 +672,15 @@ static void shader_sm4_read_declaration_dst(struct wined3d_shader_instruction *i
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.dst);
shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT, &ins->declaration.dst);
}
static void shader_sm4_read_declaration_register_semantic(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.register_semantic.reg);
shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT,
&ins->declaration.register_semantic.reg);
ins->declaration.register_semantic.sysval_semantic = *tokens;
}
@ -684,7 +689,7 @@ static void shader_sm4_read_dcl_input_ps(struct wined3d_shader_instruction *ins,
struct wined3d_sm4_data *priv)
{
ins->flags = (opcode_token & WINED3D_SM4_INTERPOLATION_MODE_MASK) >> WINED3D_SM4_INTERPOLATION_MODE_SHIFT;
shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.dst);
shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT, &ins->declaration.dst);
}
static void shader_sm4_read_dcl_input_ps_siv(struct wined3d_shader_instruction *ins,
@ -692,7 +697,8 @@ static void shader_sm4_read_dcl_input_ps_siv(struct wined3d_shader_instruction *
struct wined3d_sm4_data *priv)
{
ins->flags = (opcode_token & WINED3D_SM4_INTERPOLATION_MODE_MASK) >> WINED3D_SM4_INTERPOLATION_MODE_SHIFT;
shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.register_semantic.reg);
shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT,
&ins->declaration.register_semantic.reg);
ins->declaration.register_semantic.sysval_semantic = *tokens;
}
@ -717,7 +723,7 @@ static void shader_sm5_read_fcall(struct wined3d_shader_instruction *ins,
struct wined3d_sm4_data *priv)
{
priv->src_param[0].reg.u.fp_body_idx = *tokens++;
shader_sm4_read_src_param(priv, &tokens, WINED3D_DATA_OPAQUE, &priv->src_param[0]);
shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_OPAQUE, &priv->src_param[0]);
}
static void shader_sm5_read_dcl_function_body(struct wined3d_shader_instruction *ins,
@ -798,7 +804,7 @@ static void shader_sm5_read_dcl_uav_raw(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_UAV, &ins->declaration.dst);
shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UAV, &ins->declaration.dst);
ins->flags = (opcode_token & WINED3D_SM5_UAV_FLAGS_MASK) >> WINED3D_SM5_UAV_FLAGS_SHIFT;
}
@ -806,7 +812,8 @@ static void shader_sm5_read_dcl_uav_structured(struct wined3d_shader_instruction
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_UAV, &ins->declaration.structured_resource.reg);
shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UAV,
&ins->declaration.structured_resource.reg);
ins->flags = (opcode_token & WINED3D_SM5_UAV_FLAGS_MASK) >> WINED3D_SM5_UAV_FLAGS_SHIFT;
ins->declaration.structured_resource.byte_stride = *tokens;
if (ins->declaration.structured_resource.byte_stride % 4)
@ -817,7 +824,7 @@ static void shader_sm5_read_dcl_tgsm_raw(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.tgsm_raw.reg);
shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT, &ins->declaration.tgsm_raw.reg);
ins->declaration.tgsm_raw.byte_count = *tokens;
if (ins->declaration.tgsm_raw.byte_count % 4)
FIXME("Byte count %u is not multiple of 4.\n", ins->declaration.tgsm_raw.byte_count);
@ -827,7 +834,8 @@ static void shader_sm5_read_dcl_tgsm_structured(struct wined3d_shader_instructio
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.tgsm_structured.reg);
shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT,
&ins->declaration.tgsm_structured.reg);
ins->declaration.tgsm_structured.byte_stride = *tokens++;
ins->declaration.tgsm_structured.structure_count = *tokens;
if (ins->declaration.tgsm_structured.byte_stride % 4)
@ -838,7 +846,8 @@ static void shader_sm5_read_dcl_resource_structured(struct wined3d_shader_instru
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_RESOURCE, &ins->declaration.structured_resource.reg);
shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_RESOURCE,
&ins->declaration.structured_resource.reg);
ins->declaration.structured_resource.byte_stride = *tokens;
if (ins->declaration.structured_resource.byte_stride % 4)
FIXME("Byte stride %u is not multiple of 4.\n", ins->declaration.structured_resource.byte_stride);
@ -848,7 +857,7 @@ static void shader_sm5_read_dcl_resource_raw(struct wined3d_shader_instruction *
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_RESOURCE, &ins->declaration.dst);
shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_RESOURCE, &ins->declaration.dst);
}
static void shader_sm5_read_sync(struct wined3d_shader_instruction *ins,
@ -928,6 +937,7 @@ static const struct wined3d_sm4_opcode_info opcode_table[] =
{WINED3D_SM4_OP_MOVC, WINED3DSIH_MOVC, "f", "uff"},
{WINED3D_SM4_OP_MUL, WINED3DSIH_MUL, "f", "ff"},
{WINED3D_SM4_OP_NE, WINED3DSIH_NE, "u", "ff"},
{WINED3D_SM4_OP_NOP, WINED3DSIH_NOP, "", ""},
{WINED3D_SM4_OP_NOT, WINED3DSIH_NOT, "u", "u"},
{WINED3D_SM4_OP_OR, WINED3DSIH_OR, "u", "uu"},
{WINED3D_SM4_OP_RESINFO, WINED3DSIH_RESINFO, "f", "iR"},
@ -1137,6 +1147,8 @@ static const enum wined3d_shader_register_type register_type_table[] =
/* WINED3D_SM5_RT_COVERAGE */ WINED3DSPR_COVERAGE,
/* WINED3D_SM5_RT_LOCAL_THREAD_INDEX */ WINED3DSPR_LOCALTHREADINDEX,
/* WINED3D_SM5_RT_GS_INSTANCE_ID */ WINED3DSPR_GSINSTID,
/* WINED3D_SM5_RT_DEPTHOUT_GREATER_EQUAL */ WINED3DSPR_DEPTHOUT_GREATER_EQUAL,
/* WINED3D_SM5_RT_DEPTHOUT_LESS_EQUAL*/ WINED3DSPR_DEPTHOUT_LESS_EQUAL,
};
static const struct wined3d_sm4_opcode_info *get_opcode_info(enum wined3d_sm4_opcode opcode)
@ -1328,7 +1340,7 @@ static void shader_sm4_read_header(void *data, const DWORD **ptr, struct wined3d
*shader_version = priv->shader_version;
}
static BOOL shader_sm4_read_reg_idx(struct wined3d_sm4_data *priv, const DWORD **ptr,
static BOOL shader_sm4_read_reg_idx(struct wined3d_sm4_data *priv, const DWORD **ptr, const DWORD *end,
DWORD addressing, struct wined3d_shader_register_index *reg_idx)
{
if (addressing & WINED3D_SM4_ADDRESSING_RELATIVE)
@ -1345,7 +1357,7 @@ static BOOL shader_sm4_read_reg_idx(struct wined3d_sm4_data *priv, const DWORD *
reg_idx->offset = *(*ptr)++;
else
reg_idx->offset = 0;
shader_sm4_read_src_param(priv, ptr, WINED3D_DATA_INT, rel_addr);
shader_sm4_read_src_param(priv, ptr, end, WINED3D_DATA_INT, rel_addr);
}
else
{
@ -1356,13 +1368,19 @@ static BOOL shader_sm4_read_reg_idx(struct wined3d_sm4_data *priv, const DWORD *
return TRUE;
}
static BOOL shader_sm4_read_param(struct wined3d_sm4_data *priv, const DWORD **ptr,
static BOOL shader_sm4_read_param(struct wined3d_sm4_data *priv, const DWORD **ptr, const DWORD *end,
enum wined3d_data_type data_type, struct wined3d_shader_register *param,
enum wined3d_shader_src_modifier *modifier)
{
enum wined3d_sm4_register_type register_type;
DWORD token = *(*ptr)++;
DWORD order;
DWORD token, order;
if (*ptr >= end)
{
WARN("Invalid ptr %p >= end %p.\n", *ptr, end);
return FALSE;
}
token = *(*ptr)++;
register_type = (token & WINED3D_SM4_REGISTER_TYPE_MASK) >> WINED3D_SM4_REGISTER_TYPE_SHIFT;
if (register_type >= sizeof(register_type_table) / sizeof(*register_type_table)
@ -1379,7 +1397,14 @@ static BOOL shader_sm4_read_param(struct wined3d_sm4_data *priv, const DWORD **p
if (token & WINED3D_SM4_REGISTER_MODIFIER)
{
DWORD m = *(*ptr)++;
DWORD m;
if (*ptr >= end)
{
WARN("Invalid ptr %p >= end %p.\n", *ptr, end);
return FALSE;
}
m = *(*ptr)++;
switch (m)
{
@ -1413,7 +1438,7 @@ static BOOL shader_sm4_read_param(struct wined3d_sm4_data *priv, const DWORD **p
else
{
DWORD addressing = (token & WINED3D_SM4_ADDRESSING_MASK0) >> WINED3D_SM4_ADDRESSING_SHIFT0;
if (!(shader_sm4_read_reg_idx(priv, ptr, addressing, &param->idx[0])))
if (!(shader_sm4_read_reg_idx(priv, ptr, end, addressing, &param->idx[0])))
{
ERR("Failed to read register index.\n");
return FALSE;
@ -1425,7 +1450,7 @@ static BOOL shader_sm4_read_param(struct wined3d_sm4_data *priv, const DWORD **p
else
{
DWORD addressing = (token & WINED3D_SM4_ADDRESSING_MASK1) >> WINED3D_SM4_ADDRESSING_SHIFT1;
if (!(shader_sm4_read_reg_idx(priv, ptr, addressing, &param->idx[1])))
if (!(shader_sm4_read_reg_idx(priv, ptr, end, addressing, &param->idx[1])))
{
ERR("Failed to read register index.\n");
return FALSE;
@ -1444,12 +1469,22 @@ static BOOL shader_sm4_read_param(struct wined3d_sm4_data *priv, const DWORD **p
{
case WINED3D_SM4_IMMCONST_SCALAR:
param->immconst_type = WINED3D_IMMCONST_SCALAR;
if (end - *ptr < 1)
{
WARN("Invalid ptr %p, end %p.\n", *ptr, end);
return FALSE;
}
memcpy(param->u.immconst_data, *ptr, 1 * sizeof(DWORD));
*ptr += 1;
break;
case WINED3D_SM4_IMMCONST_VEC4:
param->immconst_type = WINED3D_IMMCONST_VEC4;
if (end - *ptr < 4)
{
WARN("Invalid ptr %p, end %p.\n", *ptr, end);
return FALSE;
}
memcpy(param->u.immconst_data, *ptr, 4 * sizeof(DWORD));
*ptr += 4;
break;
@ -1465,12 +1500,19 @@ static BOOL shader_sm4_read_param(struct wined3d_sm4_data *priv, const DWORD **p
return TRUE;
}
static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD **ptr,
static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD **ptr, const DWORD *end,
enum wined3d_data_type data_type, struct wined3d_shader_src_param *src_param)
{
DWORD token = **ptr;
DWORD token;
if (!shader_sm4_read_param(priv, ptr, data_type, &src_param->reg, &src_param->modifiers))
if (*ptr >= end)
{
WARN("Invalid ptr %p >= end %p.\n", *ptr, end);
return FALSE;
}
token = **ptr;
if (!shader_sm4_read_param(priv, ptr, end, data_type, &src_param->reg, &src_param->modifiers))
{
ERR("Failed to read parameter.\n");
return FALSE;
@ -1509,13 +1551,20 @@ static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD
return TRUE;
}
static BOOL shader_sm4_read_dst_param(struct wined3d_sm4_data *priv, const DWORD **ptr,
static BOOL shader_sm4_read_dst_param(struct wined3d_sm4_data *priv, const DWORD **ptr, const DWORD *end,
enum wined3d_data_type data_type, struct wined3d_shader_dst_param *dst_param)
{
enum wined3d_shader_src_modifier modifier;
DWORD token = **ptr;
DWORD token;
if (!shader_sm4_read_param(priv, ptr, data_type, &dst_param->reg, &modifier))
if (*ptr >= end)
{
WARN("Invalid ptr %p >= end %p.\n", *ptr, end);
return FALSE;
}
token = **ptr;
if (!shader_sm4_read_param(priv, ptr, end, data_type, &dst_param->reg, &modifier))
{
ERR("Failed to read parameter.\n");
return FALSE;
@ -1656,7 +1705,8 @@ static void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct wi
for (i = 0; i < ins->dst_count; ++i)
{
if (!(shader_sm4_read_dst_param(priv, &p, map_data_type(opcode_info->dst_info[i]), &priv->dst_param[i])))
if (!(shader_sm4_read_dst_param(priv, &p, *ptr, map_data_type(opcode_info->dst_info[i]),
&priv->dst_param[i])))
{
ins->handler_idx = WINED3DSIH_TABLE_SIZE;
return;
@ -1666,7 +1716,8 @@ static void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct wi
for (i = 0; i < ins->src_count; ++i)
{
if (!(shader_sm4_read_src_param(priv, &p, map_data_type(opcode_info->src_info[i]), &priv->src_param[i])))
if (!(shader_sm4_read_src_param(priv, &p, *ptr, map_data_type(opcode_info->src_info[i]),
&priv->src_param[i])))
{
ins->handler_idx = WINED3DSIH_TABLE_SIZE;
return;

View file

@ -293,11 +293,11 @@ GLenum wined3d_gl_compare_func(enum wined3d_cmp_func f)
case WINED3D_CMP_ALWAYS:
return GL_ALWAYS;
default:
{
static int once;
if (f || !once++) FIXME("Unrecognized compare function %#x.\n", f);
if (!f)
WARN("Unrecognized compare function %#x.\n", f);
else
FIXME("Unrecognized compare function %#x.\n", f);
return GL_NONE;
}
}
}
@ -464,10 +464,13 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st
const struct wined3d_format *rt_format;
GLenum src_blend, dst_blend;
unsigned int rt_fmt_flags;
BOOL enable_dual_blend;
BOOL enable_blend;
enable_blend = state->fb->render_targets[0] && state->render_states[WINED3D_RS_ALPHABLENDENABLE];
if (enable_blend)
enable_dual_blend = wined3d_dualblend_enabled(state, context->gl_info);
if (enable_blend && !enable_dual_blend)
{
rt_format = state->fb->render_targets[0]->format;
rt_fmt_flags = state->fb->render_targets[0]->format_flags;
@ -479,6 +482,13 @@ static void state_blend(struct wined3d_context *context, const struct wined3d_st
enable_blend = FALSE;
}
/* Dual state blending changes the assignment of the output variables */
if (context->last_was_dual_blend != enable_dual_blend)
{
context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
context->last_was_dual_blend = enable_dual_blend;
}
if (!enable_blend)
{
gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
@ -1493,9 +1503,6 @@ static void state_debug_monitor(struct wined3d_context *context, const struct wi
static void state_colorwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE];
DWORD mask1 = state->render_states[WINED3D_RS_COLORWRITEENABLE1];
DWORD mask2 = state->render_states[WINED3D_RS_COLORWRITEENABLE2];
DWORD mask3 = state->render_states[WINED3D_RS_COLORWRITEENABLE3];
const struct wined3d_gl_info *gl_info = context->gl_info;
TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
@ -1509,13 +1516,7 @@ static void state_colorwrite(struct wined3d_context *context, const struct wined
mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
checkGLcall("glColorMask(...)");
if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0)
|| (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf)))
{
FIXME("WINED3D_RS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n",
mask0, mask1, mask2, mask3);
FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n");
}
/* FIXME: WINED3D_RS_COLORWRITEENABLE1 .. WINED3D_RS_COLORWRITEENABLE7 not implemented. */
}
static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
@ -1528,24 +1529,20 @@ static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DW
checkGLcall("glColorMaski");
}
static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void state_colorwrite_i(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
set_color_mask(context->gl_info, 0, state->render_states[WINED3D_RS_COLORWRITEENABLE]);
}
const struct wined3d_gl_info *gl_info = context->gl_info;
int index;
static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
set_color_mask(context->gl_info, 1, state->render_states[WINED3D_RS_COLORWRITEENABLE1]);
}
if (state_id == WINED3D_RS_COLORWRITEENABLE) index = 0;
else if (state_id <= WINED3D_RS_COLORWRITEENABLE3) index = state_id - WINED3D_RS_COLORWRITEENABLE1 + 1;
else if (state_id <= WINED3D_RS_COLORWRITEENABLE7) index = state_id - WINED3D_RS_COLORWRITEENABLE4 + 4;
else return;
static void state_colorwrite2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
set_color_mask(context->gl_info, 2, state->render_states[WINED3D_RS_COLORWRITEENABLE2]);
}
if (index >= gl_info->limits.buffers)
WARN("Ignoring color write value for index %d, because gpu only supports %d render targets\n", index, gl_info->limits.buffers);
static void state_colorwrite3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
set_color_mask(context->gl_info, 3, state->render_states[WINED3D_RS_COLORWRITEENABLE3]);
set_color_mask(context->gl_info, index, state->render_states[state_id]);
}
static void state_localviewer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@ -1718,6 +1715,7 @@ static void state_depthbias(struct wined3d_context *context, const struct wined3
union
{
DWORD d;
INT i;
float f;
} scale_bias, const_bias;
@ -1733,6 +1731,11 @@ static void state_depthbias(struct wined3d_context *context, const struct wined3
gl_info->gl_ops.gl.p_glPolygonOffset(bias, bias);
checkGLcall("glPolygonOffset");
}
else if (context->d3d_info->wined3d_creation_flags & WINED3D_FORWARD_DEPTH_BIAS)
{
gl_info->gl_ops.gl.p_glPolygonOffset(scale_bias.f, const_bias.i);
checkGLcall("glPolygonOffset(...)");
}
else
{
if (depth)
@ -1763,6 +1766,28 @@ static void state_depthbias(struct wined3d_context *context, const struct wined3
}
}
static void state_depthclip(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
if (state->render_states[WINED3D_RS_DEPTHCLIP])
{
gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_CLAMP);
checkGLcall("glDisable(GL_DEPTH_CLAMP)");
}
else
{
gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_CLAMP);
checkGLcall("glEnable(GL_DEPTH_CLAMP)");
}
}
static void state_depthclip_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
if (!state->render_states[WINED3D_RS_DEPTHCLIP])
FIXME("Depth clamping not supported by GL.\n");
}
static void state_zvisible(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
if (state->render_states[WINED3D_RS_ZVISIBLE])
@ -4606,11 +4631,13 @@ static void viewport_miscpart(struct wined3d_context *context, const struct wine
if (target)
{
if (vp.width > target->width)
vp.width = target->width;
if (vp.height > target->height)
vp.height = target->height;
if (context->d3d_info->wined3d_creation_flags & WINED3D_LIMIT_VIEWPORT)
{
if (vp.width > target->width)
vp.width = target->width;
if (vp.height > target->height)
vp.height = target->height;
}
wined3d_rendertarget_view_get_drawable_size(target, context, &width, &height);
}
else if (depth_stencil)
@ -4652,10 +4679,13 @@ static void viewport_miscpart_cc(struct wined3d_context *context,
if (target)
{
if (vp.width > target->width)
vp.width = target->width;
if (vp.height > target->height)
vp.height = target->height;
if (context->d3d_info->wined3d_creation_flags & WINED3D_LIMIT_VIEWPORT)
{
if (vp.width > target->width)
vp.width = target->width;
if (vp.height > target->height)
vp.height = target->height;
}
wined3d_rendertarget_view_get_drawable_size(target, context, &width, &height);
}
@ -5190,22 +5220,32 @@ const struct StateEntryTemplate misc_state_template[] =
{ STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite_i }, EXT_DRAW_BUFFERS2 },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite_i }, EXT_DRAW_BUFFERS2 },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite_i }, EXT_DRAW_BUFFERS2 },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite_i }, EXT_DRAW_BUFFERS2 },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE4), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE4), state_colorwrite_i }, EXT_DRAW_BUFFERS2 },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE4), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE5), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE5), state_colorwrite_i }, EXT_DRAW_BUFFERS2 },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE5), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE6), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE6), state_colorwrite_i }, EXT_DRAW_BUFFERS2 },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE6), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE7), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE7), state_colorwrite_i }, EXT_DRAW_BUFFERS2 },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE7), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop }, WINED3D_GL_BLEND_EQUATION },
{ STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 },
{ STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR },
{ STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_DEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE },
{ STATE_RENDER(WINED3D_RS_DEPTHCLIP), { STATE_RENDER(WINED3D_RS_DEPTHCLIP), state_depthclip }, ARB_DEPTH_CLAMP },
{ STATE_RENDER(WINED3D_RS_DEPTHCLIP), { STATE_RENDER(WINED3D_RS_DEPTHCLIP), state_depthclip_w }, WINED3D_GL_EXT_NONE },
/* Samplers */
{ STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE },
{ STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE },
@ -5840,21 +5880,8 @@ static DWORD ffp_fragment_get_emul_mask(const struct wined3d_gl_info *gl_info)
static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
{
if (TRACE_ON(d3d))
{
TRACE("Checking support for fixup:\n");
dump_color_fixup_desc(fixup);
}
/* We only support identity conversions. */
if (is_identity_fixup(fixup))
{
TRACE("[OK]\n");
return TRUE;
}
TRACE("[FAILED]\n");
return FALSE;
return is_identity_fixup(fixup);
}
static BOOL ffp_none_context_alloc(struct wined3d_context *context)

View file

@ -43,6 +43,10 @@ static const DWORD pixel_states_render[] =
WINED3D_RS_COLORWRITEENABLE1,
WINED3D_RS_COLORWRITEENABLE2,
WINED3D_RS_COLORWRITEENABLE3,
WINED3D_RS_COLORWRITEENABLE4,
WINED3D_RS_COLORWRITEENABLE5,
WINED3D_RS_COLORWRITEENABLE6,
WINED3D_RS_COLORWRITEENABLE7,
WINED3D_RS_DEPTHBIAS,
WINED3D_RS_DESTBLEND,
WINED3D_RS_DESTBLENDALPHA,
@ -88,6 +92,7 @@ static const DWORD pixel_states_render[] =
WINED3D_RS_ZENABLE,
WINED3D_RS_ZFUNC,
WINED3D_RS_ZWRITEENABLE,
WINED3D_RS_DEPTHCLIP,
};
static const DWORD pixel_states_texture[] =
@ -1209,7 +1214,6 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d
tmpfloat.f = gl_info->limits.pointsize_max;
state->render_states[WINED3D_RS_POINTSIZE_MAX] = tmpfloat.d;
state->render_states[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] = FALSE;
state->render_states[WINED3D_RS_COLORWRITEENABLE] = 0x0000000f;
tmpfloat.f = 0.0f;
state->render_states[WINED3D_RS_TWEENFACTOR] = tmpfloat.d;
state->render_states[WINED3D_RS_BLENDOP] = WINED3D_BLEND_OP_ADD;
@ -1235,12 +1239,10 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d
state->render_states[WINED3D_RS_BACK_STENCILZFAIL] = WINED3D_STENCIL_OP_KEEP;
state->render_states[WINED3D_RS_BACK_STENCILPASS] = WINED3D_STENCIL_OP_KEEP;
state->render_states[WINED3D_RS_BACK_STENCILFUNC] = WINED3D_CMP_ALWAYS;
state->render_states[WINED3D_RS_COLORWRITEENABLE1] = 0x0000000f;
state->render_states[WINED3D_RS_COLORWRITEENABLE2] = 0x0000000f;
state->render_states[WINED3D_RS_COLORWRITEENABLE3] = 0x0000000f;
state->render_states[WINED3D_RS_BLENDFACTOR] = 0xffffffff;
state->render_states[WINED3D_RS_SRGBWRITEENABLE] = 0;
state->render_states[WINED3D_RS_DEPTHBIAS] = 0;
state->render_states[WINED3D_RS_DEPTHCLIP] = TRUE;
state->render_states[WINED3D_RS_WRAP8] = 0;
state->render_states[WINED3D_RS_WRAP9] = 0;
state->render_states[WINED3D_RS_WRAP10] = 0;
@ -1253,6 +1255,8 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d
state->render_states[WINED3D_RS_SRCBLENDALPHA] = WINED3D_BLEND_ONE;
state->render_states[WINED3D_RS_DESTBLENDALPHA] = WINED3D_BLEND_ZERO;
state->render_states[WINED3D_RS_BLENDOPALPHA] = WINED3D_BLEND_OP_ADD;
for (i = 0; i < MAX_RENDER_TARGETS; ++i)
state->render_states[WINED3D_RS_COLORWRITE(i)] = 0x0000000f;
/* Texture Stage States - Put directly into state block, we will call function below */
for (i = 0; i < MAX_TEXTURES; ++i)

View file

@ -365,6 +365,7 @@ static void surface_blt_fbo(const struct wined3d_device *device,
RECT src_rect, dst_rect;
GLenum gl_filter;
GLenum buffer;
int i;
TRACE("device %p, filter %s,\n", device, debug_d3dtexturefiltertype(filter));
TRACE("src_surface %p, src_location %s, src_rect %s,\n",
@ -462,10 +463,8 @@ static void surface_blt_fbo(const struct wined3d_device *device,
context_invalidate_state(context, STATE_FRAMEBUFFER);
gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE));
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1));
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2));
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3));
for (i = 0; i < MAX_RENDER_TARGETS; ++i)
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITE(i)));
gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE));
@ -2549,6 +2548,8 @@ static void fbo_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_
if ((next = blitter->next))
next->ops->blitter_destroy(next, context);
HeapFree(GetProcessHeap(), 0, blitter);
}
static void fbo_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device,
@ -2631,6 +2632,8 @@ static void ffp_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_
if ((next = blitter->next))
next->ops->blitter_destroy(next, context);
HeapFree(GetProcessHeap(), 0, blitter);
}
static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info,
@ -2703,13 +2706,13 @@ static BOOL ffp_blitter_use_cpu_clear(struct wined3d_rendertarget_view *view)
resource = view->resource;
if (resource->type == WINED3D_RTYPE_BUFFER)
return FALSE;
return resource->pool == WINED3D_POOL_SYSTEM_MEM;
texture = texture_from_resource(resource);
if (!(texture->flags & WINED3D_TEXTURE_PIN_SYSMEM))
return FALSE;
if (texture->sub_resources[view->sub_resource_idx].locations & resource->map_binding)
return resource->pool == WINED3D_POOL_SYSTEM_MEM || (texture->flags & WINED3D_TEXTURE_PIN_SYSMEM);
return texture->sub_resources[view->sub_resource_idx].locations & resource->map_binding;
return resource->pool == WINED3D_POOL_SYSTEM_MEM && !(texture->flags & WINED3D_TEXTURE_CONVERTED);
}
static void ffp_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device,
@ -2717,8 +2720,8 @@ static void ffp_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de
const RECT *draw_rect, DWORD flags, const struct wined3d_color *colour, float depth, DWORD stencil)
{
struct wined3d_rendertarget_view *view;
struct wined3d_resource *resource;
struct wined3d_blitter *next;
DWORD next_flags = 0;
unsigned int i;
if (flags & WINED3DCLEAR_TARGET)
@ -2728,23 +2731,14 @@ static void ffp_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de
if (!(view = fb->render_targets[i]))
continue;
resource = view->resource;
if (resource->pool == WINED3D_POOL_SYSTEM_MEM)
goto next;
if (!(flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL))
&& ffp_blitter_use_cpu_clear(view))
goto next;
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
if (ffp_blitter_use_cpu_clear(view)
|| (!(view->resource->usage & WINED3DUSAGE_RENDERTARGET)
&& (wined3d_settings.offscreen_rendering_mode != ORM_FBO
|| !(view->format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE))))
{
if (!((view->format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE)
|| (resource->usage & WINED3DUSAGE_RENDERTARGET)))
goto next;
}
else if (!(resource->usage & WINED3DUSAGE_RENDERTARGET))
{
goto next;
next_flags |= WINED3DCLEAR_TARGET;
flags &= ~WINED3DCLEAR_TARGET;
break;
}
/* FIXME: We should reject colour fills on formats with fixups,
@ -2752,22 +2746,22 @@ static void ffp_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de
}
}
if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL))
if ((flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) && (view = fb->depth_stencil)
&& (!view->format->depth_size || (flags & WINED3DCLEAR_ZBUFFER))
&& (!view->format->stencil_size || (flags & WINED3DCLEAR_STENCIL))
&& ffp_blitter_use_cpu_clear(view))
{
view = fb->depth_stencil;
if (view && (view->resource->pool == WINED3D_POOL_SYSTEM_MEM
|| ffp_blitter_use_cpu_clear(view)))
goto next;
next_flags |= flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL);
flags &= ~(WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL);
}
device_clear_render_targets(device, rt_count, fb, rect_count,
clear_rects, draw_rect, flags, colour, depth, stencil);
return;
next:
if ((next = blitter->next))
next->ops->blitter_clear(next, device, rt_count, fb, rect_count,
if (flags)
device_clear_render_targets(device, rt_count, fb, rect_count,
clear_rects, draw_rect, flags, colour, depth, stencil);
if (next_flags && (next = blitter->next))
next->ops->blitter_clear(next, device, rt_count, fb, rect_count,
clear_rects, draw_rect, next_flags, colour, depth, stencil);
}
static void ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op,
@ -2921,6 +2915,8 @@ static void cpu_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_
if ((next = blitter->next))
next->ops->blitter_destroy(next, context);
HeapFree(GetProcessHeap(), 0, blitter);
}
static HRESULT surface_cpu_blt_compressed(const BYTE *src_data, BYTE *dst_data,
@ -3493,6 +3489,12 @@ release:
context_unmap_bo_address(context, &dst_data, GL_PIXEL_UNPACK_BUFFER);
if (!same_sub_resource)
context_unmap_bo_address(context, &src_data, GL_PIXEL_UNPACK_BUFFER);
if (SUCCEEDED(hr) && dst_texture->swapchain && dst_texture->swapchain->front_buffer == dst_texture)
{
SetRect(&dst_texture->swapchain->front_buffer_update,
dst_box->left, dst_box->top, dst_box->right, dst_box->bottom);
dst_texture->swapchain->swapchain_ops->swapchain_frontbuffer_updated(dst_texture->swapchain);
}
if (converted_texture)
wined3d_texture_decref(converted_texture);
if (context)
@ -3643,12 +3645,15 @@ static void cpu_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de
}
}
if ((flags & WINED3DCLEAR_ZBUFFER) && (view = fb->depth_stencil))
surface_cpu_blt_colour_fill(view, &box, &c);
}
if ((flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) && (view = fb->depth_stencil))
{
if ((view->format->depth_size && !(flags & WINED3DCLEAR_ZBUFFER))
|| (view->format->stencil_size && !(flags & WINED3DCLEAR_STENCIL)))
FIXME("Clearing %#x on %s.\n", flags, debug_d3dformat(view->format->id));
if (flags & ~(WINED3DCLEAR_TARGET | WINED3DCLEAR_ZBUFFER))
FIXME("flags %#x not implemented.\n", flags);
surface_cpu_blt_colour_fill(view, &box, &c);
}
}
}
static void cpu_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op,

View file

@ -229,6 +229,7 @@ static const struct wined3d_typed_format_info typed_formats[] =
{WINED3DFMT_R8G8B8A8_SINT, WINED3DFMT_R8G8B8A8_TYPELESS, "IIII"},
{WINED3DFMT_R8G8B8A8_UNORM_SRGB, WINED3DFMT_R8G8B8A8_TYPELESS, "uuuu"},
{WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_R8G8B8A8_TYPELESS, "uuuu"},
{WINED3DFMT_R8G8B8A8_SNORM, WINED3DFMT_R8G8B8A8_TYPELESS, "iiii"},
{WINED3DFMT_R16G16_UNORM, WINED3DFMT_R16G16_TYPELESS, "uu"},
{WINED3DFMT_R16G16_SNORM, WINED3DFMT_R16G16_TYPELESS, "ii"},
{WINED3DFMT_R16G16_UINT, WINED3DFMT_R16G16_TYPELESS, "UU"},
@ -1027,7 +1028,7 @@ const struct wined3d_color_key_conversion * wined3d_format_get_color_key_convers
if (need_alpha_ck && (texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY))
{
for (i = 0; i < sizeof(color_key_info) / sizeof(*color_key_info); ++i)
for (i = 0; i < ARRAY_SIZE(color_key_info); ++i)
{
if (color_key_info[i].src_format == format->id)
return &color_key_info[i].conversion;
@ -2121,7 +2122,7 @@ static void draw_test_quad(struct wined3d_caps_gl_ctx *ctx, const struct wined3d
for (i = 0; i < 4; ++i)
gl_info->gl_ops.gl.p_glVertex3fv(&geometry[i].x);
gl_info->gl_ops.gl.p_glEnd();
checkGLcall("Drawing a quad");
checkGLcall("draw quad");
return;
}
@ -2136,17 +2137,19 @@ static void draw_test_quad(struct wined3d_caps_gl_ctx *ctx, const struct wined3d
if (!ctx->test_program_id)
{
BOOL use_glsl_150 = gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50);
ctx->test_program_id = GL_EXTCALL(glCreateProgram());
vs_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER));
source[0] = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? vs_legacy_header : vs_core_header;
source[0] = use_glsl_150 ? vs_core_header : vs_legacy_header;
source[1] = vs_body;
GL_EXTCALL(glShaderSource(vs_id, 2, source, NULL));
GL_EXTCALL(glAttachShader(ctx->test_program_id, vs_id));
GL_EXTCALL(glDeleteShader(vs_id));
fs_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER));
source[0] = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] ? fs_legacy : fs_core;
source[0] = use_glsl_150 ? fs_core : fs_legacy;
GL_EXTCALL(glShaderSource(fs_id, 1, source, NULL));
GL_EXTCALL(glAttachShader(ctx->test_program_id, fs_id));
GL_EXTCALL(glDeleteShader(fs_id));
@ -2154,6 +2157,9 @@ static void draw_test_quad(struct wined3d_caps_gl_ctx *ctx, const struct wined3d
GL_EXTCALL(glBindAttribLocation(ctx->test_program_id, 0, "pos"));
GL_EXTCALL(glBindAttribLocation(ctx->test_program_id, 1, "color"));
if (use_glsl_150)
GL_EXTCALL(glBindFragDataLocation(ctx->test_program_id, 0, "fragment_color"));
GL_EXTCALL(glCompileShader(vs_id));
print_glsl_info_log(gl_info, vs_id, FALSE);
GL_EXTCALL(glCompileShader(fs_id));
@ -2168,7 +2174,7 @@ static void draw_test_quad(struct wined3d_caps_gl_ctx *ctx, const struct wined3d
GL_EXTCALL(glUseProgram(0));
GL_EXTCALL(glDisableVertexAttribArray(0));
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
checkGLcall("Drawing a quad");
checkGLcall("draw quad");
}
/* Context activation is done by the caller. */
@ -3109,9 +3115,9 @@ static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3
filtered = FALSE;
}
if(filtered)
if (filtered)
{
for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
for (i = 0; i < ARRAY_SIZE(fmts16); ++i)
{
fmt_idx = get_format_idx(fmts16[i]);
format_set_flag(&gl_info->formats[fmt_idx], WINED3DFMT_FLAG_FILTERING);
@ -3120,14 +3126,14 @@ static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3
return;
}
for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
for (i = 0; i < ARRAY_SIZE(fmts16); ++i)
{
fmt_idx = get_format_idx(fmts16[i]);
format = &gl_info->formats[fmt_idx];
if (!format->glInternal) continue; /* Not supported by GL */
filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
if(filtered)
if (filtered)
{
TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
format_set_flag(format, WINED3DFMT_FLAG_FILTERING);
@ -3355,9 +3361,21 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
if (!(format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_TEXTURE))
continue;
if (is_identity_fixup(format->color_fixup))
continue;
TRACE("Checking support for fixup:\n");
dump_color_fixup_desc(format->color_fixup);
if (!adapter->shader_backend->shader_color_fixup_supported(format->color_fixup)
|| !adapter->fragment_pipe->color_fixup_supported(format->color_fixup))
{
TRACE("[FAILED]\n");
format_clear_flag(format, WINED3DFMT_FLAG_TEXTURE);
}
else
{
TRACE("[OK]\n");
}
}
/* GL_EXT_texture_compression_s3tc does not support 3D textures. Some Windows drivers
@ -4108,6 +4126,7 @@ const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type)
switch (resource_type)
{
#define WINED3D_TO_STR(x) case x: return #x
WINED3D_TO_STR(WINED3D_RTYPE_NONE);
WINED3D_TO_STR(WINED3D_RTYPE_BUFFER);
WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_1D);
WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_2D);
@ -4236,7 +4255,6 @@ const char *debug_d3drenderstate(enum wined3d_render_state state)
D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN);
D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX);
D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE);
D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE);
D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR);
D3DSTATE_TO_STR(WINED3D_RS_BLENDOP);
D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE);
@ -4256,9 +4274,14 @@ const char *debug_d3drenderstate(enum wined3d_render_state state)
D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILZFAIL);
D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILPASS);
D3DSTATE_TO_STR(WINED3D_RS_BACK_STENCILFUNC);
D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE);
D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1);
D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2);
D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3);
D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE4);
D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE5);
D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE6);
D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE7);
D3DSTATE_TO_STR(WINED3D_RS_BLENDFACTOR);
D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE);
D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS);
@ -4274,6 +4297,7 @@ const char *debug_d3drenderstate(enum wined3d_render_state state)
D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA);
D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA);
D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA);
D3DSTATE_TO_STR(WINED3D_RS_DEPTHCLIP);
#undef D3DSTATE_TO_STR
default:
FIXME("Unrecognized %u render state!\n", state);
@ -5045,7 +5069,7 @@ DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, con
}
double_conv[] =
{
{WINED3DFMT_D24_UNORM_S8_UINT, { 16777215.0, 0.0, 0.0, 0.0}, {0, 0, 0, 0}},
{WINED3DFMT_D24_UNORM_S8_UINT, { 16777215.0, 1.0, 0.0, 0.0}, {8, 0, 0, 0}},
{WINED3DFMT_X8D24_UNORM, { 16777215.0, 0.0, 0.0, 0.0}, {0, 0, 0, 0}},
{WINED3DFMT_D32_UNORM, {4294967295.0, 0.0, 0.0, 0.0}, {0, 0, 0, 0}},
};
@ -5211,6 +5235,281 @@ void multiply_matrix(struct wined3d_matrix *dst, const struct wined3d_matrix *sr
*dst = tmp;
}
/* Taken and adapted from Mesa. */
BOOL invert_matrix_3d(struct wined3d_matrix *out, const struct wined3d_matrix *in)
{
float pos, neg, t, det;
struct wined3d_matrix temp;
/* Calculate the determinant of upper left 3x3 submatrix and
* determine if the matrix is singular. */
pos = neg = 0.0f;
t = in->_11 * in->_22 * in->_33;
if (t >= 0.0f)
pos += t;
else
neg += t;
t = in->_21 * in->_32 * in->_13;
if (t >= 0.0f)
pos += t;
else
neg += t;
t = in->_31 * in->_12 * in->_23;
if (t >= 0.0f)
pos += t;
else
neg += t;
t = -in->_31 * in->_22 * in->_13;
if (t >= 0.0f)
pos += t;
else
neg += t;
t = -in->_21 * in->_12 * in->_33;
if (t >= 0.0f)
pos += t;
else
neg += t;
t = -in->_11 * in->_32 * in->_23;
if (t >= 0.0f)
pos += t;
else
neg += t;
det = pos + neg;
if (fabsf(det) < 1e-25f)
return FALSE;
det = 1.0f / det;
temp._11 = (in->_22 * in->_33 - in->_32 * in->_23) * det;
temp._12 = -(in->_12 * in->_33 - in->_32 * in->_13) * det;
temp._13 = (in->_12 * in->_23 - in->_22 * in->_13) * det;
temp._21 = -(in->_21 * in->_33 - in->_31 * in->_23) * det;
temp._22 = (in->_11 * in->_33 - in->_31 * in->_13) * det;
temp._23 = -(in->_11 * in->_23 - in->_21 * in->_13) * det;
temp._31 = (in->_21 * in->_32 - in->_31 * in->_22) * det;
temp._32 = -(in->_11 * in->_32 - in->_31 * in->_12) * det;
temp._33 = (in->_11 * in->_22 - in->_21 * in->_12) * det;
*out = temp;
return TRUE;
}
static void swap_rows(float **a, float **b)
{
float *tmp = *a;
*a = *b;
*b = tmp;
}
BOOL invert_matrix(struct wined3d_matrix *out, struct wined3d_matrix *m)
{
float wtmp[4][8];
float m0, m1, m2, m3, s;
float *r0, *r1, *r2, *r3;
r0 = wtmp[0];
r1 = wtmp[1];
r2 = wtmp[2];
r3 = wtmp[3];
r0[0] = m->_11;
r0[1] = m->_12;
r0[2] = m->_13;
r0[3] = m->_14;
r0[4] = 1.0f;
r0[5] = r0[6] = r0[7] = 0.0f;
r1[0] = m->_21;
r1[1] = m->_22;
r1[2] = m->_23;
r1[3] = m->_24;
r1[5] = 1.0f;
r1[4] = r1[6] = r1[7] = 0.0f;
r2[0] = m->_31;
r2[1] = m->_32;
r2[2] = m->_33;
r2[3] = m->_34;
r2[6] = 1.0f;
r2[4] = r2[5] = r2[7] = 0.0f;
r3[0] = m->_41;
r3[1] = m->_42;
r3[2] = m->_43;
r3[3] = m->_44;
r3[7] = 1.0f;
r3[4] = r3[5] = r3[6] = 0.0f;
/* Choose pivot - or die. */
if (fabsf(r3[0]) > fabsf(r2[0]))
swap_rows(&r3, &r2);
if (fabsf(r2[0]) > fabsf(r1[0]))
swap_rows(&r2, &r1);
if (fabsf(r1[0]) > fabsf(r0[0]))
swap_rows(&r1, &r0);
if (r0[0] == 0.0f)
return FALSE;
/* Eliminate first variable. */
m1 = r1[0] / r0[0]; m2 = r2[0] / r0[0]; m3 = r3[0] / r0[0];
s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s;
s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s;
s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s;
s = r0[4];
if (s != 0.0f)
{
r1[4] -= m1 * s;
r2[4] -= m2 * s;
r3[4] -= m3 * s;
}
s = r0[5];
if (s != 0.0f)
{
r1[5] -= m1 * s;
r2[5] -= m2 * s;
r3[5] -= m3 * s;
}
s = r0[6];
if (s != 0.0f)
{
r1[6] -= m1 * s;
r2[6] -= m2 * s;
r3[6] -= m3 * s;
}
s = r0[7];
if (s != 0.0f)
{
r1[7] -= m1 * s;
r2[7] -= m2 * s;
r3[7] -= m3 * s;
}
/* Choose pivot - or die. */
if (fabsf(r3[1]) > fabsf(r2[1]))
swap_rows(&r3, &r2);
if (fabsf(r2[1]) > fabsf(r1[1]))
swap_rows(&r2, &r1);
if (r1[1] == 0.0f)
return FALSE;
/* Eliminate second variable. */
m2 = r2[1] / r1[1]; m3 = r3[1] / r1[1];
r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2];
r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3];
s = r1[4];
if (s != 0.0f)
{
r2[4] -= m2 * s;
r3[4] -= m3 * s;
}
s = r1[5];
if (s != 0.0f)
{
r2[5] -= m2 * s;
r3[5] -= m3 * s;
}
s = r1[6];
if (s != 0.0f)
{
r2[6] -= m2 * s;
r3[6] -= m3 * s;
}
s = r1[7];
if (s != 0.0f)
{
r2[7] -= m2 * s;
r3[7] -= m3 * s;
}
/* Choose pivot - or die. */
if (fabsf(r3[2]) > fabsf(r2[2]))
swap_rows(&r3, &r2);
if (r2[2] == 0.0f)
return FALSE;
/* Eliminate third variable. */
m3 = r3[2] / r2[2];
r3[3] -= m3 * r2[3];
r3[4] -= m3 * r2[4];
r3[5] -= m3 * r2[5];
r3[6] -= m3 * r2[6];
r3[7] -= m3 * r2[7];
/* Last check. */
if (r3[3] == 0.0f)
return FALSE;
/* Back substitute row 3. */
s = 1.0f / r3[3];
r3[4] *= s;
r3[5] *= s;
r3[6] *= s;
r3[7] *= s;
/* Back substitute row 2. */
m2 = r2[3];
s = 1.0f / r2[2];
r2[4] = s * (r2[4] - r3[4] * m2);
r2[5] = s * (r2[5] - r3[5] * m2);
r2[6] = s * (r2[6] - r3[6] * m2);
r2[7] = s * (r2[7] - r3[7] * m2);
m1 = r1[3];
r1[4] -= r3[4] * m1;
r1[5] -= r3[5] * m1;
r1[6] -= r3[6] * m1;
r1[7] -= r3[7] * m1;
m0 = r0[3];
r0[4] -= r3[4] * m0;
r0[5] -= r3[5] * m0;
r0[6] -= r3[6] * m0;
r0[7] -= r3[7] * m0;
/* Back substitute row 1. */
m1 = r1[2];
s = 1.0f / r1[1];
r1[4] = s * (r1[4] - r2[4] * m1);
r1[5] = s * (r1[5] - r2[5] * m1);
r1[6] = s * (r1[6] - r2[6] * m1);
r1[7] = s * (r1[7] - r2[7] * m1);
m0 = r0[2];
r0[4] -= r2[4] * m0;
r0[5] -= r2[5] * m0;
r0[6] -= r2[6] * m0;
r0[7] -= r2[7] * m0;
/* Back substitute row 0. */
m0 = r0[1];
s = 1.0f / r0[0];
r0[4] = s * (r0[4] - r1[4] * m0);
r0[5] = s * (r0[5] - r1[5] * m0);
r0[6] = s * (r0[6] - r1[6] * m0);
r0[7] = s * (r0[7] - r1[7] * m0);
out->_11 = r0[4];
out->_12 = r0[5];
out->_13 = r0[6];
out->_14 = r0[7];
out->_21 = r1[4];
out->_22 = r1[5];
out->_23 = r1[6];
out->_24 = r1[7];
out->_31 = r2[4];
out->_32 = r2[5];
out->_33 = r2[6];
out->_34 = r2[7];
out->_41 = r3[4];
out->_42 = r3[5];
out->_43 = r3[6];
out->_44 = r3[7];
return TRUE;
}
DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
DWORD size = 0;
int i;
@ -5787,6 +6086,14 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context,
break;
}
if (use_indexed_vertex_blending(state, si))
{
if (use_software_vertex_processing(context->device))
settings->sw_blending = 1;
else
settings->vb_indices = 1;
}
settings->clipping = state->render_states[WINED3D_RS_CLIPPING]
&& state->render_states[WINED3D_RS_CLIPPLANEENABLE];
settings->normal = !!(si->use_map & (1u << WINED3D_FFP_NORMAL));

View file

@ -117,6 +117,15 @@ static BOOL declaration_element_valid_ffp(const struct wined3d_vertex_element *e
return FALSE;
}
case WINED3D_DECL_USAGE_BLEND_INDICES:
switch(element->format)
{
case WINED3DFMT_R8G8B8A8_UINT:
return TRUE;
default:
return FALSE;
}
case WINED3D_DECL_USAGE_NORMAL:
switch(element->format)
{

View file

@ -906,6 +906,44 @@ void wined3d_unordered_access_view_clear_uint(struct wined3d_unordered_access_vi
checkGLcall("clear unordered access view");
}
void wined3d_unordered_access_view_set_counter(struct wined3d_unordered_access_view *view,
unsigned int value)
{
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
if (!view->counter_bo)
return;
context = context_acquire(view->resource->device, NULL, 0);
gl_info = context->gl_info;
GL_EXTCALL(glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, view->counter_bo));
GL_EXTCALL(glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(value), &value));
checkGLcall("set atomic counter");
context_release(context);
}
void wined3d_unordered_access_view_copy_counter(struct wined3d_unordered_access_view *view,
struct wined3d_buffer *buffer, unsigned int offset, struct wined3d_context *context)
{
struct wined3d_bo_address dst, src;
DWORD dst_location;
if (!view->counter_bo)
return;
dst_location = wined3d_buffer_get_memory(buffer, &dst, buffer->locations);
dst.addr += offset;
src.buffer_object = view->counter_bo;
src.addr = NULL;
context_copy_bo_address(context, &dst, buffer->buffer_type_hint,
&src, GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint));
wined3d_buffer_invalidate_location(buffer, ~dst_location);
}
static void wined3d_unordered_access_view_cs_init(void *object)
{
struct wined3d_unordered_access_view *view = object;
@ -923,7 +961,7 @@ static void wined3d_unordered_access_view_cs_init(void *object)
context = context_acquire(resource->device, NULL, 0);
gl_info = context->gl_info;
create_buffer_view(&view->gl_view, context, desc, buffer, view->format);
if (desc->flags & WINED3D_VIEW_BUFFER_COUNTER)
if (desc->flags & (WINED3D_VIEW_BUFFER_COUNTER | WINED3D_VIEW_BUFFER_APPEND))
{
static const GLuint initial_value = 0;
GL_EXTCALL(glGenBuffers(1, &view->counter_bo));
@ -968,9 +1006,6 @@ static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_acces
return E_INVALIDARG;
view->desc = *desc;
if (desc->flags & WINED3D_VIEW_BUFFER_APPEND)
FIXME("Unhandled view flags %#x.\n", desc->flags);
wined3d_resource_incref(view->resource = resource);
#if defined(STAGING_CSMT)

View file

@ -5,7 +5,6 @@
@ cdecl wined3d_check_depth_stencil_match(ptr long long long long long)
@ cdecl wined3d_check_device_format(ptr long long long long long long)
@ cdecl wined3d_check_device_format_conversion(ptr long long long long)
@ cdecl wined3d_check_device_format_support(ptr long ptr)
@ cdecl wined3d_check_device_multisample_type(ptr long long long long long ptr)
@ cdecl wined3d_check_device_type(ptr long long long long long)
@ cdecl wined3d_create(long)
@ -39,13 +38,17 @@
@ cdecl wined3d_device_clear_unordered_access_view_uint(ptr ptr ptr)
@ cdecl wined3d_device_copy_resource(ptr ptr ptr)
@ cdecl wined3d_device_copy_sub_resource_region(ptr ptr long long long long ptr long ptr)
@ cdecl wined3d_device_copy_uav_counter(ptr ptr long ptr)
@ cdecl wined3d_device_create(ptr long long ptr long long ptr ptr)
@ cdecl wined3d_device_decref(ptr)
@ cdecl wined3d_device_dispatch_compute(ptr long long long)
@ cdecl wined3d_device_dispatch_compute_indirect(ptr ptr long)
@ cdecl wined3d_device_draw_indexed_primitive(ptr long long)
@ cdecl wined3d_device_draw_indexed_primitive_instanced(ptr long long long long)
@ cdecl wined3d_device_draw_indexed_primitive_instanced_indirect(ptr ptr long)
@ cdecl wined3d_device_draw_primitive(ptr long long)
@ cdecl wined3d_device_draw_primitive_instanced(ptr long long long long)
@ cdecl wined3d_device_draw_primitive_instanced_indirect(ptr ptr long)
@ cdecl wined3d_device_end_scene(ptr)
@ cdecl wined3d_device_end_stateblock(ptr ptr)
@ cdecl wined3d_device_evict_managed_resources(ptr)
@ -130,7 +133,7 @@
@ cdecl wined3d_device_set_cs_cb(ptr long ptr)
@ cdecl wined3d_device_set_cs_resource_view(ptr long ptr)
@ cdecl wined3d_device_set_cs_sampler(ptr long ptr)
@ cdecl wined3d_device_set_cs_uav(ptr long ptr)
@ cdecl wined3d_device_set_cs_uav(ptr long ptr long)
@ cdecl wined3d_device_set_cursor_position(ptr long long long)
@ cdecl wined3d_device_set_cursor_properties(ptr long long ptr long)
@ cdecl wined3d_device_set_depth_stencil_view(ptr ptr)
@ -175,7 +178,7 @@
@ cdecl wined3d_device_set_texture(ptr long ptr)
@ cdecl wined3d_device_set_texture_stage_state(ptr long long long)
@ cdecl wined3d_device_set_transform(ptr long ptr)
@ cdecl wined3d_device_set_unordered_access_view(ptr long ptr)
@ cdecl wined3d_device_set_unordered_access_view(ptr long ptr long)
@ cdecl wined3d_device_set_vertex_declaration(ptr ptr)
@ cdecl wined3d_device_set_vertex_shader(ptr ptr)
@ cdecl wined3d_device_set_viewport(ptr ptr)
@ -223,6 +226,7 @@
@ cdecl wined3d_resource_set_parent(ptr ptr)
@ cdecl wined3d_resource_set_priority(ptr long)
@ cdecl wined3d_resource_unmap(ptr long)
@ cdecl wined3d_resource_update_info(ptr long ptr long long)
@ cdecl wined3d_rendertarget_view_create(ptr ptr ptr ptr ptr)
@ cdecl wined3d_rendertarget_view_create_from_sub_resource(ptr long ptr ptr ptr)

View file

@ -43,19 +43,24 @@ enum wined3d_gl_extension
APPLE_FLUSH_BUFFER_RANGE,
APPLE_YCBCR_422,
/* ARB */
ARB_BASE_INSTANCE,
ARB_BLEND_FUNC_EXTENDED,
ARB_CLEAR_BUFFER_OBJECT,
ARB_CLEAR_TEXTURE,
ARB_CLIP_CONTROL,
ARB_COLOR_BUFFER_FLOAT,
ARB_COMPUTE_SHADER,
ARB_CONSERVATIVE_DEPTH,
ARB_COPY_BUFFER,
ARB_COPY_IMAGE,
ARB_DEBUG_OUTPUT,
ARB_DEPTH_BUFFER_FLOAT,
ARB_DEPTH_CLAMP,
ARB_DEPTH_TEXTURE,
ARB_DERIVATIVE_CONTROL,
ARB_DRAW_BUFFERS,
ARB_DRAW_ELEMENTS_BASE_VERTEX,
ARB_DRAW_INDIRECT,
ARB_DRAW_INSTANCED,
ARB_ES2_COMPATIBILITY,
ARB_ES3_COMPATIBILITY,
@ -208,7 +213,6 @@ enum wined3d_gl_extension
WINED3D_GL_PRIMITIVE_QUERY,
WINED3D_GL_VERSION_2_0,
WINED3D_GL_VERSION_3_2,
WINED3D_GL_VERSION_4_3,
WINED3D_GLSL_130,
WINED3D_GL_EXT_COUNT,

View file

@ -293,7 +293,7 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
if (!get_config_key(hkey, appkey, "StrictDrawOrdering", buffer, size)
&& !strcmp(buffer,"enabled"))
{
ERR_(winediag)("\"StrictDrawOrdering\" is deprecated, please use \"csmt\" instead.");
ERR_(winediag)("\"StrictDrawOrdering\" is deprecated, please use \"csmt\" instead.\n");
TRACE("Enforcing strict draw ordering.\n");
wined3d_settings.strict_draw_ordering = TRUE;
}

View file

@ -202,6 +202,7 @@ struct wined3d_d3d_info
BOOL vs_clipping;
BOOL shader_color_key;
DWORD valid_rt_mask;
DWORD valid_dual_rt_mask;
DWORD wined3d_creation_flags;
BOOL shader_double_precision;
};
@ -282,7 +283,9 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup
#define MAX_UNORDERED_ACCESS_VIEWS 8
#define MAX_TGSM_REGISTERS 8192
#define MAX_VERTEX_BLENDS 4
#define MAX_VERTEX_INDEX_BLENDS 9
#define MAX_MULTISAMPLE_TYPES 8
#define MAX_RENDER_TARGETS 8
struct min_lookup
{
@ -443,13 +446,14 @@ enum wined3d_shader_resource_type
#define WINED3D_SHADER_CONST_PS_Y_CORR 0x00001000
#define WINED3D_SHADER_CONST_PS_NP2_FIXUP 0x00002000
#define WINED3D_SHADER_CONST_FFP_MODELVIEW 0x00004000
#define WINED3D_SHADER_CONST_FFP_VERTEXBLEND 0x00008000
#define WINED3D_SHADER_CONST_FFP_PROJ 0x00010000
#define WINED3D_SHADER_CONST_FFP_TEXMATRIX 0x00020000
#define WINED3D_SHADER_CONST_FFP_MATERIAL 0x00040000
#define WINED3D_SHADER_CONST_FFP_LIGHTS 0x00080000
#define WINED3D_SHADER_CONST_FFP_PS 0x00100000
#define WINED3D_SHADER_CONST_FFP_COLOR_KEY 0x00200000
#define WINED3D_SHADER_CONST_FFP_VERTEXBLEND 0xff000000
#define WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i) (0x01000000 << ((i) - 1))
enum wined3d_shader_register_type
{
@ -501,6 +505,8 @@ enum wined3d_shader_register_type
WINED3DSPR_COVERAGE,
WINED3DSPR_SAMPLEMASK,
WINED3DSPR_GSINSTID,
WINED3DSPR_DEPTHOUT_GREATER_EQUAL,
WINED3DSPR_DEPTHOUT_LESS_EQUAL,
};
enum wined3d_data_type
@ -570,6 +576,7 @@ enum wined3d_shader_interpolation_mode
enum wined3d_shader_global_flags
{
WINED3DSGF_REFACTORING_ALLOWED = 0x1,
WINED3DSGF_FORCE_EARLY_DEPTH_STENCIL = 0x4,
WINED3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS = 0x8,
};
@ -1347,7 +1354,8 @@ struct ps_compile_args {
DWORD flatshading : 1;
DWORD alpha_test_func : 3;
DWORD render_offscreen : 1;
DWORD padding : 26;
DWORD dual_source_blend : 1;
DWORD padding : 25;
};
enum fog_src_type {
@ -1489,11 +1497,59 @@ void wined3d_stream_info_from_declaration(struct wined3d_stream_info *stream_inf
const struct wined3d_state *state, const struct wined3d_gl_info *gl_info,
const struct wined3d_d3d_info *d3d_info) DECLSPEC_HIDDEN;
struct wined3d_direct_draw_parameters
{
int base_vertex_idx;
unsigned int start_idx;
unsigned int index_count;
unsigned int start_instance;
unsigned int instance_count;
};
struct wined3d_indirect_draw_parameters
{
struct wined3d_buffer *buffer;
unsigned int offset;
};
struct wined3d_draw_parameters
{
BOOL indirect;
union
{
struct wined3d_direct_draw_parameters direct;
struct wined3d_indirect_draw_parameters indirect;
} u;
BOOL indexed;
};
struct wined3d_direct_dispatch_parameters
{
unsigned int group_count_x;
unsigned int group_count_y;
unsigned int group_count_z;
};
struct wined3d_indirect_dispatch_parameters
{
struct wined3d_buffer *buffer;
unsigned int offset;
};
struct wined3d_dispatch_parameters
{
BOOL indirect;
union
{
struct wined3d_direct_dispatch_parameters direct;
struct wined3d_indirect_dispatch_parameters indirect;
} u;
};
void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state,
int base_vertex_idx, unsigned int start_idx, unsigned int index_count,
unsigned int start_instance, unsigned int instance_count, BOOL indexed) DECLSPEC_HIDDEN;
const struct wined3d_draw_parameters *draw_parameters) DECLSPEC_HIDDEN;
void dispatch_compute(struct wined3d_device *device, const struct wined3d_state *state,
unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z) DECLSPEC_HIDDEN;
const struct wined3d_dispatch_parameters *dispatch_parameters) DECLSPEC_HIDDEN;
DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN;
#define eps 1e-8f
@ -1618,6 +1674,34 @@ enum fogsource {
FOGSOURCE_COORD,
};
union wined3d_gl_fence_object
{
GLuint id;
GLsync sync;
};
enum wined3d_fence_result
{
WINED3D_FENCE_OK,
WINED3D_FENCE_WAITING,
WINED3D_FENCE_NOT_STARTED,
WINED3D_FENCE_WRONG_THREAD,
WINED3D_FENCE_ERROR,
};
struct wined3d_fence
{
struct list entry;
union wined3d_gl_fence_object object;
struct wined3d_context *context;
};
HRESULT wined3d_fence_create(struct wined3d_device *device, struct wined3d_fence **fence) DECLSPEC_HIDDEN;
void wined3d_fence_destroy(struct wined3d_fence *fence) DECLSPEC_HIDDEN;
void wined3d_fence_issue(struct wined3d_fence *fence, const struct wined3d_device *device) DECLSPEC_HIDDEN;
enum wined3d_fence_result wined3d_fence_wait(const struct wined3d_fence *fence,
const struct wined3d_device *device) DECLSPEC_HIDDEN;
/* Direct3D terminology with little modifications. We do not have an issued
* state because only the driver knows about it, but we have a created state
* because D3D allows GetData() on a created query, but OpenGL doesn't. */
@ -1632,6 +1716,7 @@ struct wined3d_query_ops
{
BOOL (*query_poll)(struct wined3d_query *query, DWORD flags);
BOOL (*query_issue)(struct wined3d_query *query, DWORD flags);
void (*query_destroy)(struct wined3d_query *query);
};
struct wined3d_query
@ -1651,37 +1736,14 @@ struct wined3d_query
struct list poll_list_entry;
};
union wined3d_gl_query_object
{
GLuint id;
GLsync sync;
};
struct wined3d_event_query
{
struct wined3d_query query;
struct list entry;
union wined3d_gl_query_object object;
struct wined3d_context *context;
struct wined3d_fence fence;
BOOL signalled;
};
enum wined3d_event_query_result
{
WINED3D_EVENT_QUERY_OK,
WINED3D_EVENT_QUERY_WAITING,
WINED3D_EVENT_QUERY_NOT_STARTED,
WINED3D_EVENT_QUERY_WRONG_THREAD,
WINED3D_EVENT_QUERY_ERROR
};
void wined3d_event_query_destroy(struct wined3d_event_query *query) DECLSPEC_HIDDEN;
enum wined3d_event_query_result wined3d_event_query_finish(const struct wined3d_event_query *query,
const struct wined3d_device *device) DECLSPEC_HIDDEN;
void wined3d_event_query_issue(struct wined3d_event_query *query, const struct wined3d_device *device) DECLSPEC_HIDDEN;
BOOL wined3d_event_query_supported(const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
struct wined3d_occlusion_query
{
struct wined3d_query query;
@ -1840,7 +1902,8 @@ struct wined3d_context
DWORD destroy_delayed : 1;
DWORD transform_feedback_active : 1;
DWORD transform_feedback_paused : 1;
DWORD padding : 7;
DWORD last_was_dual_blend : 1;
DWORD padding : 6;
DWORD last_swizzle_map; /* MAX_ATTRIBS, 16 */
DWORD shader_update_mask;
DWORD constant_update_mask;
@ -1887,10 +1950,10 @@ struct wined3d_context
unsigned int free_occlusion_query_count;
struct list occlusion_queries;
union wined3d_gl_query_object *free_event_queries;
SIZE_T free_event_query_size;
unsigned int free_event_query_count;
struct list event_queries;
union wined3d_gl_fence_object *free_fences;
SIZE_T free_fence_size;
unsigned int free_fence_count;
struct list fences;
GLuint *free_timestamp_queries;
SIZE_T free_timestamp_query_size;
@ -1910,8 +1973,8 @@ struct wined3d_context
struct wined3d_stream_info stream_info;
/* Fences for GL_APPLE_flush_buffer_range */
struct wined3d_event_query *buffer_queries[MAX_ATTRIBS];
unsigned int num_buffer_queries;
struct wined3d_fence *buffer_fences[MAX_ATTRIBS];
unsigned int buffer_fence_count;
DWORD tex_unit_map[MAX_COMBINED_SAMPLERS];
DWORD rev_tex_unit_map[MAX_GL_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS];
@ -2058,8 +2121,7 @@ BOOL wined3d_clip_blit(const RECT *clip_rect, RECT *clipped, RECT *other) DECLSP
struct wined3d_context *context_acquire(const struct wined3d_device *device,
struct wined3d_texture *texture, unsigned int sub_resource_idx) DECLSPEC_HIDDEN;
void context_alloc_event_query(struct wined3d_context *context,
struct wined3d_event_query *query) DECLSPEC_HIDDEN;
void context_alloc_fence(struct wined3d_context *context, struct wined3d_fence *fence) DECLSPEC_HIDDEN;
void context_alloc_occlusion_query(struct wined3d_context *context,
struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;
void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device) DECLSPEC_HIDDEN;
@ -2078,12 +2140,15 @@ void context_bind_dummy_textures(const struct wined3d_device *device,
const struct wined3d_context *context) DECLSPEC_HIDDEN;
void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint name) DECLSPEC_HIDDEN;
void context_check_fbo_status(const struct wined3d_context *context, GLenum target) DECLSPEC_HIDDEN;
void context_copy_bo_address(struct wined3d_context *context,
const struct wined3d_bo_address *dst, GLenum dst_binding,
const struct wined3d_bo_address *src, GLenum src_binding, size_t size) DECLSPEC_HIDDEN;
struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, struct wined3d_texture *target,
const struct wined3d_format *ds_format) DECLSPEC_HIDDEN;
HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc, HGLRC share_ctx) DECLSPEC_HIDDEN;
void context_destroy(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
void context_end_transform_feedback(struct wined3d_context *context) DECLSPEC_HIDDEN;
void context_free_event_query(struct wined3d_event_query *query) DECLSPEC_HIDDEN;
void context_free_fence(struct wined3d_fence *fence) DECLSPEC_HIDDEN;
void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;
struct wined3d_context *context_get_current(void) DECLSPEC_HIDDEN;
GLenum context_get_offscreen_gl_buffer(const struct wined3d_context *context) DECLSPEC_HIDDEN;
@ -2443,6 +2508,7 @@ struct wined3d_fbo_ops
struct wined3d_gl_limits
{
UINT buffers;
UINT dual_buffers;
UINT lights;
UINT textures;
UINT texture_coords;
@ -2670,7 +2736,8 @@ struct wined3d_ffp_vs_settings
DWORD ortho_fog : 1;
DWORD flatshading : 1;
DWORD swizzle_map : 16; /* MAX_ATTRIBS, 16 */
DWORD padding : 2;
DWORD vb_indices : 1;
DWORD sw_blending : 1;
DWORD texgen[MAX_TEXTURES];
};
@ -2777,6 +2844,22 @@ struct wined3d_state
struct wined3d_rasterizer_state *rasterizer_state;
};
static inline BOOL wined3d_dualblend_enabled(const struct wined3d_state *state, const struct wined3d_gl_info *gl_info)
{
if (!state->fb->render_targets[0]) return FALSE;
if (!state->render_states[WINED3D_RS_ALPHABLENDENABLE]) return FALSE;
if (!gl_info->supported[ARB_BLEND_FUNC_EXTENDED]) return FALSE;
#define IS_DUAL_SOURCE_BLEND(x) ((x) >= WINED3D_BLEND_SRC1COLOR && (x) <= WINED3D_BLEND_INVSRC1ALPHA)
if (IS_DUAL_SOURCE_BLEND(state->render_states[WINED3D_RS_SRCBLEND])) return TRUE;
if (IS_DUAL_SOURCE_BLEND(state->render_states[WINED3D_RS_DESTBLEND])) return TRUE;
if (IS_DUAL_SOURCE_BLEND(state->render_states[WINED3D_RS_SRCBLENDALPHA])) return TRUE;
if (IS_DUAL_SOURCE_BLEND(state->render_states[WINED3D_RS_DESTBLENDALPHA])) return TRUE;
#undef IS_DUAL_SOURCE_BLEND
return FALSE;
}
#if defined(STAGING_CSMT)
struct wined3d_gl_bo
{
@ -3456,11 +3539,17 @@ void wined3d_cs_emit_clear_rendertarget_view(struct wined3d_cs *cs, struct wined
const RECT *rect, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN;
void wined3d_cs_emit_clear_unordered_access_view_uint(struct wined3d_cs *cs,
struct wined3d_unordered_access_view *view, const struct wined3d_uvec4 *clear_value) DECLSPEC_HIDDEN;
void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buffer *dst_buffer,
unsigned int offset, struct wined3d_unordered_access_view *uav) DECLSPEC_HIDDEN;
void wined3d_cs_emit_dispatch(struct wined3d_cs *cs,
unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z) DECLSPEC_HIDDEN;
void wined3d_cs_emit_dispatch_indirect(struct wined3d_cs *cs,
struct wined3d_buffer *buffer, unsigned int offset) DECLSPEC_HIDDEN;
void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum primitive_type, unsigned int patch_vertex_count,
int base_vertex_idx, unsigned int start_idx, unsigned int index_count,
unsigned int start_instance, unsigned int instance_count, BOOL indexed) DECLSPEC_HIDDEN;
void wined3d_cs_emit_draw_indirect(struct wined3d_cs *cs, GLenum primitive_type, unsigned int patch_vertex_count,
struct wined3d_buffer *buffer, unsigned int offset, BOOL indexed) DECLSPEC_HIDDEN;
void wined3d_cs_emit_flush(struct wined3d_cs *cs) DECLSPEC_HIDDEN;
void wined3d_cs_emit_preload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain,
@ -3509,7 +3598,8 @@ void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage,
void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform_state state,
const struct wined3d_matrix *matrix) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_unordered_access_view(struct wined3d_cs *cs, enum wined3d_pipeline pipeline,
unsigned int view_idx, struct wined3d_unordered_access_view *view) DECLSPEC_HIDDEN;
unsigned int view_idx, struct wined3d_unordered_access_view *view,
unsigned int initial_count) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs,
struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN;
@ -3517,6 +3607,9 @@ void wined3d_cs_emit_unload_resource(struct wined3d_cs *cs, struct wined3d_resou
void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *resource,
unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch,
unsigned int slice_pitch) DECLSPEC_HIDDEN;
void wined3d_cs_emit_copy_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *dst_resource,
unsigned int dst_sub_resource_idx, const struct wined3d_box *dst_box, struct wined3d_resource *src_resource,
unsigned int src_sub_resource_idx, const struct wined3d_box *src_box) DECLSPEC_HIDDEN;
void wined3d_cs_init_object(struct wined3d_cs *cs,
void (*callback)(void *object), void *object) DECLSPEC_HIDDEN;
HRESULT wined3d_cs_map(struct wined3d_cs *cs, struct wined3d_resource *resource, unsigned int sub_resource_idx,
@ -3572,7 +3665,7 @@ struct wined3d_buffer
struct wined3d_map_range *maps;
SIZE_T maps_size, modified_areas;
struct wined3d_event_query *query;
struct wined3d_fence *fence;
/* conversion stuff */
UINT decl_change_count, full_conversion_count;
@ -3595,7 +3688,7 @@ void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context *
BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer,
struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) DECLSPEC_HIDDEN;
HRESULT wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_offset,
void wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_offset,
struct wined3d_buffer *src_buffer, unsigned int src_offset, unsigned int size) DECLSPEC_HIDDEN;
HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer,
const struct wined3d_box *box, const void *data) DECLSPEC_HIDDEN;
@ -3678,8 +3771,12 @@ struct wined3d_unordered_access_view
void wined3d_unordered_access_view_clear_uint(struct wined3d_unordered_access_view *view,
const struct wined3d_uvec4 *clear_value, struct wined3d_context *context) DECLSPEC_HIDDEN;
void wined3d_unordered_access_view_copy_counter(struct wined3d_unordered_access_view *view,
struct wined3d_buffer *buffer, unsigned int offset, struct wined3d_context *context) DECLSPEC_HIDDEN;
void wined3d_unordered_access_view_invalidate_location(struct wined3d_unordered_access_view *view,
DWORD location) DECLSPEC_HIDDEN;
void wined3d_unordered_access_view_set_counter(struct wined3d_unordered_access_view *view,
unsigned int value) DECLSPEC_HIDDEN;
struct wined3d_swapchain_ops
{
@ -3804,6 +3901,8 @@ GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) DE
/* Math utils */
void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
const struct wined3d_matrix *src2) DECLSPEC_HIDDEN;
BOOL invert_matrix_3d(struct wined3d_matrix *out, const struct wined3d_matrix *in) DECLSPEC_HIDDEN;
BOOL invert_matrix(struct wined3d_matrix *out, struct wined3d_matrix *m) DECLSPEC_HIDDEN;
void wined3d_release_dc(HWND window, HDC dc) DECLSPEC_HIDDEN;
@ -3900,6 +3999,9 @@ struct wined3d_pixel_shader
/* Some information about the shader behavior */
BOOL color0_mov;
DWORD color0_reg;
BOOL force_early_depth_stencil;
DWORD depth_compare;
};
struct wined3d_compute_shader
@ -3990,6 +4092,8 @@ static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg)
return FALSE;
case WINED3DSPR_DEPTHOUT: /* oDepth */
case WINED3DSPR_DEPTHOUT_GREATER_EQUAL:
case WINED3DSPR_DEPTHOUT_LESS_EQUAL:
case WINED3DSPR_CONSTBOOL: /* b# */
case WINED3DSPR_LOOP: /* aL */
case WINED3DSPR_PREDICATE: /* p0 */
@ -4211,6 +4315,34 @@ static inline void *wined3d_calloc(SIZE_T count, SIZE_T size)
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * size);
}
static inline BOOL use_indexed_vertex_blending(const struct wined3d_state *state, const struct wined3d_stream_info *si)
{
if (!state->render_states[WINED3D_RS_INDEXEDVERTEXBLENDENABLE])
return FALSE;
if (state->render_states[WINED3D_RS_VERTEXBLEND] == WINED3D_VBF_DISABLE)
return FALSE;
if (!(si->use_map & (1 << WINED3D_FFP_BLENDINDICES)) || !(si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT)))
return FALSE;
return TRUE;
}
static inline BOOL use_software_vertex_processing(const struct wined3d_device *device)
{
if (device->shader_backend != &glsl_shader_backend)
return FALSE;
if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING)
return TRUE;
if (!(device->create_parms.flags & WINED3DCREATE_MIXED_VERTEXPROCESSING))
return FALSE;
return device->softwareVertexProcessing;
}
static inline BOOL use_vs(const struct wined3d_state *state)
{
/* Check state->vertex_declaration to allow this to be used before the
@ -4273,7 +4405,7 @@ static inline struct wined3d_surface *context_get_rt_surface(const struct wined3
return texture->sub_resources[context->current_rt.sub_resource_idx].u.surface;
}
static inline void wined3d_from_cs(struct wined3d_cs *cs)
static inline void wined3d_from_cs(const struct wined3d_cs *cs)
{
if (cs->thread)
assert(cs->thread_id == GetCurrentThreadId());

View file

@ -381,8 +381,21 @@ enum wined3d_render_state
WINED3D_RS_SRCBLENDALPHA = 207,
WINED3D_RS_DESTBLENDALPHA = 208,
WINED3D_RS_BLENDOPALPHA = 209,
WINED3D_RS_DEPTHCLIP = 210,
WINED3D_RS_COLORWRITEENABLE4 = 211,
WINED3D_RS_COLORWRITEENABLE5 = 212,
WINED3D_RS_COLORWRITEENABLE6 = 213,
WINED3D_RS_COLORWRITEENABLE7 = 214,
};
#define WINEHIGHEST_RENDER_STATE WINED3D_RS_BLENDOPALPHA
#define WINEHIGHEST_RENDER_STATE WINED3D_RS_COLORWRITEENABLE7
static inline enum wined3d_render_state WINED3D_RS_COLORWRITE(int index)
{
if (index == 0) return WINED3D_RS_COLORWRITEENABLE;
if (index <= 3) return WINED3D_RS_COLORWRITEENABLE1 + index - 1;
if (index <= 7) return WINED3D_RS_COLORWRITEENABLE4 + index - 4;
return WINED3D_RS_COLORWRITEENABLE;
}
enum wined3d_blend
{
@ -670,6 +683,7 @@ enum wined3d_texture_filter_type
enum wined3d_resource_type
{
WINED3D_RTYPE_NONE = 0,
WINED3D_RTYPE_BUFFER = 1,
WINED3D_RTYPE_TEXTURE_1D = 2,
WINED3D_RTYPE_TEXTURE_2D = 3,
@ -705,12 +719,12 @@ enum wined3d_query_type
WINED3D_QUERY_TYPE_SO_STATISTICS = 21,
WINED3D_QUERY_TYPE_SO_OVERFLOW = 22,
WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM0 = 23,
WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM0 = 24,
WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM1 = 25,
WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM1 = 26,
WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM2 = 27,
WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM2 = 28,
WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM3 = 29,
WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM1 = 24,
WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM2 = 25,
WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM3 = 26,
WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM0 = 27,
WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM1 = 28,
WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM2 = 29,
WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM3 = 30,
};
@ -728,13 +742,13 @@ struct wined3d_query_data_so_statistics
struct wined3d_query_data_pipeline_statistics
{
UINT64 ia_vertices;
UINT64 ia_primitives;
UINT64 vertices_submitted;
UINT64 primitives_submitted;
UINT64 vs_invocations;
UINT64 gs_invocations;
UINT64 gs_primitives;
UINT64 c_invocations;
UINT64 c_primitives;
UINT64 clipping_input_primitives;
UINT64 clipping_output_primitives;
UINT64 ps_invocations;
UINT64 hs_invocations;
UINT64 ds_invocations;
@ -832,37 +846,6 @@ enum wined3d_shader_byte_code_format
WINED3D_SHADER_BYTE_CODE_FORMAT_SM4 = 1,
};
enum wined3d_format_support
{
WINED3D_FORMAT_SUPPORT_BUFFER = 0x0000001,
WINED3D_FORMAT_SUPPORT_IA_VERTEX_BUFFER = 0x0000002,
WINED3D_FORMAT_SUPPORT_IA_INDEX_BUFFER = 0x0000004,
WINED3D_FORMAT_SUPPORT_SO_BUFFER = 0x0000008,
WINED3D_FORMAT_SUPPORT_TEXTURE1D = 0x0000010,
WINED3D_FORMAT_SUPPORT_TEXTURE2D = 0x0000020,
WINED3D_FORMAT_SUPPORT_TEXTURE3D = 0x0000040,
WINED3D_FORMAT_SUPPORT_TEXTURECUBE = 0x0000080,
WINED3D_FORMAT_SUPPORT_SHADER_LOAD = 0x0000100,
WINED3D_FORMAT_SUPPORT_SHADER_SAMPLE = 0x0000200,
WINED3D_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON = 0x0000400,
WINED3D_FORMAT_SUPPORT_SHADER_SAMPLE_MONO_TEXT = 0x0000800,
WINED3D_FORMAT_SUPPORT_MIP = 0x0001000,
WINED3D_FORMAT_SUPPORT_MIP_AUTOGEN = 0x0002000,
WINED3D_FORMAT_SUPPORT_RENDER_TARGET = 0x0004000,
WINED3D_FORMAT_SUPPORT_BLENDABLE = 0x0008000,
WINED3D_FORMAT_SUPPORT_DEPTH_STENCIL = 0x0010000,
WINED3D_FORMAT_SUPPORT_CPU_LOCKABLE = 0x0020000,
WINED3D_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE = 0x0040000,
WINED3D_FORMAT_SUPPORT_DISPLAY = 0x0080000,
WINED3D_FORMAT_SUPPORT_CAST_WITHIN_BIT_LAYOUT = 0x0100000,
WINED3D_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET = 0x0200000,
WINED3D_FORMAT_SUPPORT_MULTISAMPLE_LOAD = 0x0400000,
WINED3D_FORMAT_SUPPORT_SHADER_GATHER = 0x0800000,
WINED3D_FORMAT_SUPPORT_BACK_BUFFER_CAST = 0x1000000,
WINED3D_FORMAT_SUPPORT_TYPED_UNORDERED_ACCESS_VIEW = 0x2000000,
WINED3D_FORMAT_SUPPORT_SHADER_GATHER_COMPARISON = 0x4000000,
};
#define WINED3DCOLORWRITEENABLE_RED (1u << 0)
#define WINED3DCOLORWRITEENABLE_GREEN (1u << 1)
#define WINED3DCOLORWRITEENABLE_BLUE (1u << 2)
@ -1338,6 +1321,9 @@ enum wined3d_format_support
#define WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR 0x00000400
#define WINED3D_NO_PRIMITIVE_RESTART 0x00000800
#define WINED3D_LEGACY_CUBEMAP_FILTERING 0x00001000
#define WINED3D_FORWARD_DEPTH_BIAS 0x00002000
#define WINED3D_REQUEST_D3D10 0x00004000
#define WINED3D_LIMIT_VIEWPORT 0x00008000
#define WINED3D_RESZ_CODE 0x7fa05000
@ -2186,8 +2172,6 @@ HRESULT __cdecl wined3d_check_device_format(const struct wined3d *wined3d, UINT
HRESULT __cdecl wined3d_check_device_format_conversion(const struct wined3d *wined3d, UINT adapter_idx,
enum wined3d_device_type device_type, enum wined3d_format_id source_format_id,
enum wined3d_format_id target_format_id);
void CDECL wined3d_check_device_format_support(struct wined3d_device *device,
enum wined3d_format_id check_format_id, UINT *support);
HRESULT __cdecl wined3d_check_device_multisample_type(const struct wined3d *wined3d, UINT adapter_idx,
enum wined3d_device_type device_type, enum wined3d_format_id surface_format_id, BOOL windowed,
enum wined3d_multisample_type multisample_type, DWORD *quality_levels);
@ -2249,18 +2233,26 @@ HRESULT __cdecl wined3d_device_copy_sub_resource_region(struct wined3d_device *d
struct wined3d_resource *dst_resource, unsigned int dst_sub_resource_idx, unsigned int dst_x,
unsigned int dst_y, unsigned int dst_z, struct wined3d_resource *src_resource,
unsigned int src_sub_resource_idx, const struct wined3d_box *src_box);
void __cdecl wined3d_device_copy_uav_counter(struct wined3d_device *device,
struct wined3d_buffer *dst_buffer, unsigned int offset, struct wined3d_unordered_access_view *uav);
HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx,
enum wined3d_device_type device_type, HWND focus_window, DWORD behaviour_flags, BYTE surface_alignment,
struct wined3d_device_parent *device_parent, struct wined3d_device **device);
ULONG __cdecl wined3d_device_decref(struct wined3d_device *device);
void __cdecl wined3d_device_dispatch_compute(struct wined3d_device *device,
unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z);
void __cdecl wined3d_device_dispatch_compute_indirect(struct wined3d_device *device,
struct wined3d_buffer *buffer, unsigned int offset);
HRESULT __cdecl wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count);
void __cdecl wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device *device,
UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count);
void __cdecl wined3d_device_draw_indexed_primitive_instanced_indirect(struct wined3d_device *device,
struct wined3d_buffer *buffer, unsigned int offset);
HRESULT __cdecl wined3d_device_draw_primitive(struct wined3d_device *device, UINT start_vertex, UINT vertex_count);
void __cdecl wined3d_device_draw_primitive_instanced(struct wined3d_device *device,
UINT start_vertex, UINT vertex_count, UINT start_instance, UINT instance_count);
void __cdecl wined3d_device_draw_primitive_instanced_indirect(struct wined3d_device *device,
struct wined3d_buffer *buffer, unsigned int offset);
HRESULT __cdecl wined3d_device_end_scene(struct wined3d_device *device);
HRESULT __cdecl wined3d_device_end_stateblock(struct wined3d_device *device, struct wined3d_stateblock **stateblock);
void __cdecl wined3d_device_evict_managed_resources(struct wined3d_device *device);
@ -2387,7 +2379,7 @@ void __cdecl wined3d_device_set_cs_resource_view(struct wined3d_device *device,
void __cdecl wined3d_device_set_cs_sampler(struct wined3d_device *device,
unsigned int idx, struct wined3d_sampler *sampler);
void __cdecl wined3d_device_set_cs_uav(struct wined3d_device *device, unsigned int idx,
struct wined3d_unordered_access_view *uav);
struct wined3d_unordered_access_view *uav, unsigned int initial_count);
void __cdecl wined3d_device_set_cursor_position(struct wined3d_device *device,
int x_screen_space, int y_screen_space, DWORD flags);
HRESULT __cdecl wined3d_device_set_cursor_properties(struct wined3d_device *device,
@ -2458,7 +2450,7 @@ void __cdecl wined3d_device_set_texture_stage_state(struct wined3d_device *devic
void __cdecl wined3d_device_set_transform(struct wined3d_device *device,
enum wined3d_transform_state state, const struct wined3d_matrix *matrix);
void __cdecl wined3d_device_set_unordered_access_view(struct wined3d_device *device,
unsigned int idx, struct wined3d_unordered_access_view *uav);
unsigned int idx, struct wined3d_unordered_access_view *uav, unsigned int initial_count);
void __cdecl wined3d_device_set_vertex_declaration(struct wined3d_device *device,
struct wined3d_vertex_declaration *declaration);
void __cdecl wined3d_device_set_vertex_shader(struct wined3d_device *device, struct wined3d_shader *shader);
@ -2597,6 +2589,8 @@ void __cdecl wined3d_resource_preload(struct wined3d_resource *resource);
void __cdecl wined3d_resource_set_parent(struct wined3d_resource *resource, void *parent);
DWORD __cdecl wined3d_resource_set_priority(struct wined3d_resource *resource, DWORD priority);
HRESULT __cdecl wined3d_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx);
UINT __cdecl wined3d_resource_update_info(struct wined3d_resource *resource, unsigned int sub_resource_idx,
const struct wined3d_box *box, unsigned int row_pitch, unsigned int depth_pitch);
HRESULT __cdecl wined3d_rendertarget_view_create(const struct wined3d_view_desc *desc,
struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,