From 3d13ed394efdd0ce0aef4e10965b1d08334394ec Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Sat, 16 Sep 2017 20:43:40 +0000 Subject: [PATCH] [WINED3D] Sync with Wine Staging 2.16. CORE-13762 svn path=/trunk/; revision=75847 --- .../directx/wine/wined3d/arb_program_shader.c | 17 +- .../wine/wined3d/ati_fragment_shader.c | 17 +- reactos/dll/directx/wine/wined3d/buffer.c | 122 +-- reactos/dll/directx/wine/wined3d/context.c | 216 ++++-- reactos/dll/directx/wine/wined3d/cs.c | 396 ++++++++-- reactos/dll/directx/wine/wined3d/device.c | 202 +++-- reactos/dll/directx/wine/wined3d/directx.c | 169 +++-- reactos/dll/directx/wine/wined3d/drawprim.c | 225 +++++- .../dll/directx/wine/wined3d/glsl_shader.c | 709 ++++++++---------- .../wine/wined3d/nvidia_texture_shader.c | 15 +- reactos/dll/directx/wine/wined3d/query.c | 649 ++++++++-------- reactos/dll/directx/wine/wined3d/resource.c | 93 +++ reactos/dll/directx/wine/wined3d/shader.c | 56 +- reactos/dll/directx/wine/wined3d/shader_sm4.c | 119 ++- reactos/dll/directx/wine/wined3d/state.c | 145 ++-- reactos/dll/directx/wine/wined3d/stateblock.c | 12 +- reactos/dll/directx/wine/wined3d/surface.c | 89 +-- reactos/dll/directx/wine/wined3d/utils.c | 329 +++++++- .../directx/wine/wined3d/vertexdeclaration.c | 9 + reactos/dll/directx/wine/wined3d/view.c | 43 +- reactos/dll/directx/wine/wined3d/wined3d.spec | 10 +- reactos/dll/directx/wine/wined3d/wined3d_gl.h | 6 +- .../dll/directx/wine/wined3d/wined3d_main.c | 2 +- .../directx/wine/wined3d/wined3d_private.h | 220 ++++-- reactos/sdk/include/reactos/wine/wined3d.h | 86 +-- 25 files changed, 2538 insertions(+), 1418 deletions(-) diff --git a/reactos/dll/directx/wine/wined3d/arb_program_shader.c b/reactos/dll/directx/wine/wined3d/arb_program_shader.c index 3bdbac35df9..ba5ccb38ca7 100644 --- a/reactos/dll/directx/wine/wined3d/arb_program_shader.c +++ b/reactos/dll/directx/wine/wined3d/arb_program_shader.c @@ -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) { diff --git a/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c b/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c index 0ba5c5b40b5..bf36f937bf5 100644 --- a/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c +++ b/reactos/dll/directx/wine/wined3d/ati_fragment_shader.c @@ -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) diff --git a/reactos/dll/directx/wine/wined3d/buffer.c b/reactos/dll/directx/wine/wined3d/buffer.c index d8b6263eb30..02d081d9383 100644 --- a/reactos/dll/directx/wine/wined3d/buffer.c +++ b/reactos/dll/directx/wine/wined3d/buffer.c @@ -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, diff --git a/reactos/dll/directx/wine/wined3d/context.c b/reactos/dll/directx/wine/wined3d/context.c index a1925f8f565..80164c00118 100644 --- a/reactos/dll/directx/wine/wined3d/context.c +++ b/reactos/dll/directx/wine/wined3d/context.c @@ -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); } diff --git a/reactos/dll/directx/wine/wined3d/cs.c b/reactos/dll/directx/wine/wined3d/cs.c index 8818d9a0d38..2ef67aaade1 100644 --- a/reactos/dll/directx/wine/wined3d/cs.c +++ b/reactos/dll/directx/wine/wined3d/cs.c @@ -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); } diff --git a/reactos/dll/directx/wine/wined3d/device.c b/reactos/dll/directx/wine/wined3d/device.c index 14d4422cc7c..224324ebdee 100644 --- a/reactos/dll/directx/wine/wined3d/device.c +++ b/reactos/dll/directx/wine/wined3d/device.c @@ -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); } diff --git a/reactos/dll/directx/wine/wined3d/directx.c b/reactos/dll/directx/wine/wined3d/directx.c index 0d5a71f915f..fa09d60b62c 100644 --- a/reactos/dll/directx/wine/wined3d/directx.c +++ b/reactos/dll/directx/wine/wined3d/directx.c @@ -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; } diff --git a/reactos/dll/directx/wine/wined3d/drawprim.c b/reactos/dll/directx/wine/wined3d/drawprim.c index cd7dcab0de5..e876ba33688 100644 --- a/reactos/dll/directx/wine/wined3d/drawprim.c +++ b/reactos/dll/directx/wine/wined3d/drawprim.c @@ -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 = ¶meters->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 = ¶meters->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"); diff --git a/reactos/dll/directx/wine/wined3d/glsl_shader.c b/reactos/dll/directx/wine/wined3d/glsl_shader.c index 5ce0863a1d1..6d17358dacb 100644 --- a/reactos/dll/directx/wine/wined3d/glsl_shader.c +++ b/reactos/dll/directx/wine/wined3d/glsl_shader.c @@ -82,6 +82,7 @@ struct glsl_sample_function enum wined3d_data_type data_type; BOOL output_single_component; unsigned int offset_size; + enum wined3d_shader_resource_type emulate_lod; }; enum heap_node_op @@ -134,9 +135,9 @@ struct glsl_vs_program GLint uniform_b_locations[WINED3D_MAX_CONSTS_B]; GLint pos_fixup_location; - GLint modelview_matrix_location[MAX_VERTEX_BLENDS]; + GLint modelview_matrix_location[MAX_VERTEX_INDEX_BLENDS]; + GLint normal_matrix_location[MAX_VERTEX_INDEX_BLENDS]; GLint projection_matrix_location; - GLint normal_matrix_location; GLint texture_matrix_location[MAX_TEXTURES]; GLint material_ambient_location; GLint material_diffuse_location; @@ -1211,308 +1212,6 @@ static void shader_glsl_load_np2fixup_constants(const struct glsl_ps_program *ps GL_EXTCALL(glUniform4fv(ps->np2_fixup_location, ps->np2_fixup_info->num_consts, &np2fixup_constants[0].sx)); } -/* Taken and adapted from Mesa. */ -static 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; -} - -static 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; -} - -static void shader_glsl_ffp_vertex_normalmatrix_uniform(const struct wined3d_context *context, - const struct wined3d_state *state, struct glsl_shader_prog_link *prog) -{ - const struct wined3d_gl_info *gl_info = context->gl_info; - float mat[3 * 3]; - struct wined3d_matrix mv; - unsigned int i, j; - - if (prog->vs.normal_matrix_location == -1) - return; - - get_modelview_matrix(context, state, 0, &mv); - if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_FFP_LIGHTING) - invert_matrix_3d(&mv, &mv); - else - invert_matrix(&mv, &mv); - /* Tests show that singular modelview matrices are used unchanged as normal - * matrices on D3D3 and older. There seems to be no clearly consistent - * behavior on newer D3D versions so always follow older ddraw behavior. */ - for (i = 0; i < 3; ++i) - for (j = 0; j < 3; ++j) - mat[i * 3 + j] = (&mv._11)[j * 4 + i]; - - GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location, 1, FALSE, mat)); - checkGLcall("glUniformMatrix3fv"); -} - static void shader_glsl_ffp_vertex_texmatrix_uniform(const struct wined3d_context *context, const struct wined3d_state *state, unsigned int tex, struct glsl_shader_prog_link *prog) { @@ -1705,6 +1404,23 @@ static void shader_glsl_load_color_key_constant(const struct glsl_ps_program *ps GL_EXTCALL(glUniform4fv(ps->color_key_location, 2, &float_key[0].r)); } +/* Context activation is done by the caller. */ +static void get_normal_matrix(struct wined3d_context *context, struct wined3d_matrix *mat, float *normal) +{ + int i, j; + + if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_FFP_LIGHTING) + invert_matrix_3d(mat, mat); + else + invert_matrix(mat, mat); + /* Tests show that singular modelview matrices are used unchanged as normal + * matrices on D3D3 and older. There seems to be no clearly consistent + * behavior on newer D3D versions so always follow older ddraw behavior. */ + for (i = 0; i < 3; ++i) + for (j = 0; j < 3; ++j) + normal[i * 3 + j] = (&mat->_11)[j * 4 + i]; +} + /* Context activation is done by the caller (state handler). */ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state) @@ -1715,6 +1431,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context const struct wined3d_gl_info *gl_info = context->gl_info; struct shader_glsl_priv *priv = shader_priv; float position_fixup[4]; + float normal[3 * 3]; DWORD update_mask; struct glsl_shader_prog_link *prog = ctx_data->glsl_program; @@ -1769,21 +1486,29 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[0], 1, FALSE, &mat._11)); checkGLcall("glUniformMatrix4fv"); - shader_glsl_ffp_vertex_normalmatrix_uniform(context, state, prog); + get_normal_matrix(context, &mat, normal); + GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location[0], 1, FALSE, normal)); + checkGLcall("glUniformMatrix3fv"); } if (update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND) { struct wined3d_matrix mat; - for (i = 1; i < MAX_VERTEX_BLENDS; ++i) + for (i = 1; i < MAX_VERTEX_INDEX_BLENDS; ++i) { if (prog->vs.modelview_matrix_location[i] == -1) break; + if (!(update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i))) + continue; get_modelview_matrix(context, state, i, &mat); GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11)); checkGLcall("glUniformMatrix4fv"); + + get_normal_matrix(context, &mat, normal); + GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location[i], 1, FALSE, normal)); + checkGLcall("glUniformMatrix3fv"); } } @@ -2132,11 +1857,6 @@ static void shader_glsl_declare_shader_outputs(const struct wined3d_gl_info *gl_ declare_out_varying(gl_info, buffer, FALSE, "vec4 ps_link[%u];\n", element_count); } -static const char *get_fragment_output(const struct wined3d_gl_info *gl_info) -{ - return needs_legacy_glsl_syntax(gl_info) ? "gl_FragData" : "ps_out"; -} - static const char *glsl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) { switch (primitive_type) @@ -2707,6 +2427,17 @@ static void shader_glsl_gen_modifier(enum wined3d_shader_src_modifier src_modifi } } +static void shader_glsl_fixup_scalar_register_variable(char *register_name, + const char *glsl_variable, const struct wined3d_gl_info *gl_info) +{ + /* The ARB_shading_language_420pack extension allows swizzle operations on + * scalars. */ + if (gl_info->supported[ARB_SHADING_LANGUAGE_420PACK]) + sprintf(register_name, "%s", glsl_variable); + else + sprintf(register_name, "ivec2(%s, 0)", glsl_variable); +} + /** Writes the GLSL variable name that corresponds to the register that the * DX opcode parameter is trying to access */ static void shader_glsl_get_register_name(const struct wined3d_shader_register *reg, @@ -2879,17 +2610,21 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * break; case WINED3DSPR_COLOROUT: + /* FIXME: should check dual_buffers when dual blending is enabled */ if (reg->idx[0].offset >= gl_info->limits.buffers) WARN("Write to render target %u, only %d supported.\n", reg->idx[0].offset, gl_info->limits.buffers); - sprintf(register_name, "%s[%u]", get_fragment_output(gl_info), reg->idx[0].offset); + sprintf(register_name, needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[%u]" : "ps_out%u", + reg->idx[0].offset); break; case WINED3DSPR_RASTOUT: sprintf(register_name, "%s", hwrastout_reg_names[reg->idx[0].offset]); break; + case WINED3DSPR_DEPTHOUT_GREATER_EQUAL: + case WINED3DSPR_DEPTHOUT_LESS_EQUAL: case WINED3DSPR_DEPTHOUT: sprintf(register_name, "gl_FragDepth"); break; @@ -3029,18 +2764,14 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * break; case WINED3DSPR_LOCALTHREADINDEX: - if (gl_info->supported[ARB_SHADING_LANGUAGE_420PACK]) - sprintf(register_name, "int(gl_LocalInvocationIndex)"); - else - sprintf(register_name, "ivec2(gl_LocalInvocationIndex, 0)"); + shader_glsl_fixup_scalar_register_variable(register_name, + "int(gl_LocalInvocationIndex)", gl_info); break; case WINED3DSPR_GSINSTID: case WINED3DSPR_OUTPOINTID: - if (gl_info->supported[ARB_SHADING_LANGUAGE_420PACK]) - sprintf(register_name, "gl_InvocationID"); - else - sprintf(register_name, "ivec2(gl_InvocationID, 0)"); + shader_glsl_fixup_scalar_register_variable(register_name, + "gl_InvocationID", gl_info); break; case WINED3DSPR_THREADID: @@ -3057,7 +2788,8 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * case WINED3DSPR_FORKINSTID: case WINED3DSPR_JOININSTID: - sprintf(register_name, "phase_instance_id"); + shader_glsl_fixup_scalar_register_variable(register_name, + "phase_instance_id", gl_info); break; case WINED3DSPR_TESSCOORD: @@ -3399,6 +3131,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context enum wined3d_shader_resource_type resource_type = ctx->reg_maps->resource_info[resource_idx].type; struct shader_glsl_ctx_priv *priv = ctx->backend_data; const struct wined3d_gl_info *gl_info = ctx->gl_info; + BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info); BOOL shadow = glsl_is_shadow_sampler(ctx->shader, priv->cur_ps_args, resource_idx, sampler_idx); BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED; BOOL texrect = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL @@ -3411,6 +3144,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context unsigned int coord_size, deriv_size; sample_function->data_type = ctx->reg_maps->resource_info[resource_idx].data_type; + sample_function->emulate_lod = WINED3D_SHADER_RESOURCE_NONE; if (resource_type >= ARRAY_SIZE(resource_type_info)) { @@ -3422,7 +3156,30 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context if (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_CUBE) projected = FALSE; - if (needs_legacy_glsl_syntax(gl_info)) + if (shadow && lod) + { + switch (resource_type) + { + /* emulate textureLod(sampler2DArrayShadow, ...) using textureGradOffset */ + case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY: + sample_function->emulate_lod = resource_type; + grad = offset = TRUE; + lod = FALSE; + break; + + /* emulate textureLod(samplerCubeShadow, ...) using shadowCubeGrad */ + case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE: + sample_function->emulate_lod = resource_type; + grad = legacy_syntax = TRUE; + lod = FALSE; + break; + + default: + break; + } + } + + if (legacy_syntax) { if (shadow) base = "shadow"; @@ -3462,7 +3219,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context sample_function->offset_size = offset ? deriv_size : 0; sample_function->coord_mask = (1u << coord_size) - 1; sample_function->deriv_mask = (1u << deriv_size) - 1; - sample_function->output_single_component = shadow && !needs_legacy_glsl_syntax(gl_info); + sample_function->output_single_component = shadow && !legacy_syntax; } static void shader_glsl_release_sample_function(const struct wined3d_shader_context *ctx, @@ -3583,6 +3340,7 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_ const char *dx, const char *dy, const char *bias, const struct wined3d_shader_texel_offset *offset, const char *coord_reg_fmt, ...) { + static const struct wined3d_shader_texel_offset dummy_offset = {0, 0, 0}; const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version; char dst_swizzle[6]; struct color_fixup_desc fixup; @@ -3651,6 +3409,26 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_ break; } } + if (sample_function->emulate_lod) + { + if (strcmp(bias, "0")) FIXME("Don't know how to emulate lod level %s\n", bias); + switch (sample_function->emulate_lod) + { + case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY: + if (!dx) dx = "vec2(0.0, 0.0)"; + if (!dy) dy = "vec2(0.0, 0.0)"; + break; + + case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE: + if (!dx) dx = "vec3(0.0, 0.0, 0.0)"; + if (!dy) dy = "vec3(0.0, 0.0, 0.0)"; + break; + + default: + break; + } + if (!offset) offset = &dummy_offset; + } if (dx && dy) shader_addline(ins->ctx->buffer, ", %s, %s", dx, dy); else if (bias) @@ -4112,6 +3890,8 @@ static void shader_glsl_bitwise_op(const struct wined3d_shader_instruction *ins) struct wined3d_shader_dst_param dst; struct glsl_src_param src[4]; const char *instruction; + BOOL tmp_dst = FALSE; + char mask_char[6]; unsigned int i, j; DWORD write_mask; @@ -4125,12 +3905,21 @@ static void shader_glsl_bitwise_op(const struct wined3d_shader_instruction *ins) return; } + for (i = 0; i < ins->src_count; ++i) + { + if (ins->dst[0].reg.idx[0].offset == ins->src[i].reg.idx[0].offset + && ins->dst[0].reg.type == ins->src[i].reg.type) + tmp_dst = TRUE; + } + dst = ins->dst[0]; for (i = 0; i < 4; ++i) { dst.write_mask = ins->dst[0].write_mask & (WINED3DSP_WRITEMASK_0 << i); - if (!(write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, - &dst, dst.reg.data_type))) + if (tmp_dst && (write_mask = shader_glsl_get_write_mask(&dst, mask_char))) + shader_addline(buffer, "tmp0%s = %sBitsToFloat(", mask_char, + dst.reg.data_type == WINED3D_DATA_INT ? "int" : "uint"); + else if (!(write_mask = shader_glsl_append_dst_ext(buffer, ins, &dst, dst.reg.data_type))) continue; for (j = 0; j < ins->src_count; ++j) @@ -4140,6 +3929,13 @@ static void shader_glsl_bitwise_op(const struct wined3d_shader_instruction *ins) shader_addline(buffer, "%s, ", src[ins->src_count - j - 1].param_str); shader_addline(buffer, "%s & 0x1f, %s & 0x1f));\n", src[1].param_str, src[0].param_str); } + + if (tmp_dst) + { + shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], WINED3D_DATA_FLOAT); + shader_glsl_get_write_mask(&ins->dst[0], mask_char); + shader_addline(buffer, "tmp0%s);\n", mask_char); + } } static void shader_glsl_nop(const struct wined3d_shader_instruction *ins) {} @@ -4343,6 +4139,58 @@ static void shader_glsl_compare(const struct wined3d_shader_instruction *ins) } } +static void shader_glsl_swapc(const struct wined3d_shader_instruction *ins) +{ + struct wined3d_string_buffer *buffer = ins->ctx->buffer; + struct wined3d_shader_dst_param dst[2]; + struct glsl_src_param src[3]; + unsigned int i, j, k; + char mask_char[6]; + DWORD write_mask; + BOOL tmp_dst[2]; + + for (i = 0; i < ins->dst_count; ++i) + { + tmp_dst[i] = FALSE; + for (j = 0; j < ins->src_count; ++j) + { + if (ins->dst[i].reg.idx[0].offset == ins->src[j].reg.idx[0].offset + && ins->dst[i].reg.type == ins->src[j].reg.type) + tmp_dst[i] = TRUE; + } + } + + dst[0] = ins->dst[0]; + dst[1] = ins->dst[1]; + for (i = 0; i < 4; ++i) + { + for (j = 0; j < ARRAY_SIZE(dst); ++j) + { + dst[j].write_mask = ins->dst[j].write_mask & (WINED3DSP_WRITEMASK_0 << i); + if (tmp_dst[j] && (write_mask = shader_glsl_get_write_mask(&dst[j], mask_char))) + shader_addline(buffer, "tmp%u%s = (", j, mask_char); + else if (!(write_mask = shader_glsl_append_dst_ext(buffer, ins, &dst[j], dst[j].reg.data_type))) + continue; + + for (k = 0; k < ARRAY_SIZE(src); ++k) + shader_glsl_add_src_param(ins, &ins->src[k], write_mask, &src[k]); + + shader_addline(buffer, "%sbool(%s) ? %s : %s);\n", !j ? "!" : "", + src[0].param_str, src[1].param_str, src[2].param_str); + } + } + + for (i = 0; i < ARRAY_SIZE(tmp_dst); ++i) + { + if (tmp_dst[i]) + { + shader_glsl_get_write_mask(&ins->dst[i], mask_char); + shader_glsl_append_dst_ext(buffer, ins, &ins->dst[i], ins->dst[i].reg.data_type); + shader_addline(buffer, "tmp%u%s);\n", i, mask_char); + } + } +} + static void shader_glsl_conditional_move(const struct wined3d_shader_instruction *ins) { const char *condition_prefix, *condition_suffix; @@ -5489,6 +5337,14 @@ static void shader_glsl_ld_raw_structured(const struct wined3d_shader_instructio shader_addline(address, "%s / 4", offset.param_str); dst = ins->dst[0]; + if (shader_glsl_get_write_mask_size(dst.write_mask) > 1) + { + /* The instruction is split into multiple lines. The first lines may + * overwrite source parameters of the following lines. */ + shader_addline(buffer, "tmp0.x = intBitsToFloat(%s);\n", address->buffer); + string_buffer_sprintf(address, "floatBitsToInt(tmp0.x)"); + } + for (i = 0; i < 4; ++i) { dst.write_mask = ins->dst[0].write_mask & (WINED3DSP_WRITEMASK_0 << i); @@ -7009,20 +6865,20 @@ static void shader_glsl_generate_patch_constant_setup(struct wined3d_string_buff static void shader_glsl_generate_srgb_write_correction(struct wined3d_string_buffer *buffer, const struct wined3d_gl_info *gl_info) { - const char *output = get_fragment_output(gl_info); + const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0"; - shader_addline(buffer, "tmp0.xyz = pow(%s[0].xyz, vec3(srgb_const0.x));\n", output); + shader_addline(buffer, "tmp0.xyz = pow(%s.xyz, vec3(srgb_const0.x));\n", output); shader_addline(buffer, "tmp0.xyz = tmp0.xyz * vec3(srgb_const0.y) - vec3(srgb_const0.z);\n"); - shader_addline(buffer, "tmp1.xyz = %s[0].xyz * vec3(srgb_const0.w);\n", output); - shader_addline(buffer, "bvec3 srgb_compare = lessThan(%s[0].xyz, vec3(srgb_const1.x));\n", output); - shader_addline(buffer, "%s[0].xyz = mix(tmp0.xyz, tmp1.xyz, vec3(srgb_compare));\n", output); - shader_addline(buffer, "%s[0] = clamp(%s[0], 0.0, 1.0);\n", output, output); + shader_addline(buffer, "tmp1.xyz = %s.xyz * vec3(srgb_const0.w);\n", output); + shader_addline(buffer, "bvec3 srgb_compare = lessThan(%s.xyz, vec3(srgb_const1.x));\n", output); + shader_addline(buffer, "%s.xyz = mix(tmp0.xyz, tmp1.xyz, vec3(srgb_compare));\n", output); + shader_addline(buffer, "%s = clamp(%s, 0.0, 1.0);\n", output, output); } static void shader_glsl_generate_fog_code(struct wined3d_string_buffer *buffer, const struct wined3d_gl_info *gl_info, enum wined3d_ffp_ps_fog_mode mode) { - const char *output = get_fragment_output(gl_info); + const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0"; switch (mode) { @@ -7047,13 +6903,15 @@ static void shader_glsl_generate_fog_code(struct wined3d_string_buffer *buffer, return; } - shader_addline(buffer, "%s[0].xyz = mix(ffp_fog.color.xyz, %s[0].xyz, clamp(fog, 0.0, 1.0));\n", + shader_addline(buffer, "%s.xyz = mix(ffp_fog.color.xyz, %s.xyz, clamp(fog, 0.0, 1.0));\n", output, output); } static void shader_glsl_generate_alpha_test(struct wined3d_string_buffer *buffer, const struct wined3d_gl_info *gl_info, enum wined3d_cmp_func alpha_func) { + const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0"; + /* alpha_func is the PASS condition, not the DISCARD condition. Instead of * flipping all the operators here, just negate the comparison below. */ static const char * const comparison_operator[] = @@ -7072,8 +6930,8 @@ static void shader_glsl_generate_alpha_test(struct wined3d_string_buffer *buffer return; if (alpha_func != WINED3D_CMP_NEVER) - shader_addline(buffer, "if (!(%s[0].a %s alpha_test_ref))\n", - get_fragment_output(gl_info), comparison_operator[alpha_func - WINED3D_CMP_NEVER]); + shader_addline(buffer, "if (!(%s.a %s alpha_test_ref))\n", + output, comparison_operator[alpha_func - WINED3D_CMP_NEVER]); shader_addline(buffer, " discard;\n"); } @@ -7115,10 +6973,11 @@ static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_in const struct ps_compile_args *args) { const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps; + const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0"; /* Pixel shaders < 2.0 place the resulting color in R0 implicitly. */ if (reg_maps->shader_version.major < 2) - shader_addline(buffer, "%s[0] = R0;\n", get_fragment_output(gl_info)); + shader_addline(buffer, "%s = R0;\n", output); if (args->srgb_correction) shader_glsl_generate_srgb_write_correction(buffer, gl_info); @@ -7168,10 +7027,20 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context * nvidia drivers write a warning if we don't do so. */ if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) shader_addline(buffer, "#extension GL_ARB_texture_rectangle : enable\n"); + if (gl_info->supported[ARB_CONSERVATIVE_DEPTH] && shader->u.ps.depth_compare) + shader_addline(buffer, "#extension GL_ARB_conservative_depth : enable\n"); /* Base Declarations */ shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx); + if (gl_info->supported[ARB_CONSERVATIVE_DEPTH]) + { + if (shader->u.ps.depth_compare == WINED3DSPR_DEPTHOUT_GREATER_EQUAL) + shader_addline(buffer, "layout (depth_greater) out float gl_FragDepth;\n"); + else if (shader->u.ps.depth_compare == WINED3DSPR_DEPTHOUT_LESS_EQUAL) + shader_addline(buffer, "layout (depth_less) out float gl_FragDepth;\n"); + } + /* Declare uniforms for NP2 texcoord fixup: * This is NOT done inside the loop that declares the texture samplers * since the NP2 fixup code is currently only used for the GeforceFX @@ -7240,7 +7109,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context { unsigned int in_count = min(vec4_varyings(version->major, gl_info), shader->limits->packed_input); - if (args->vp_mode == vertexshader) + if (args->vp_mode == vertexshader && reg_maps->input_registers) shader_glsl_declare_shader_inputs(gl_info, buffer, in_count); shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count); } @@ -7297,14 +7166,32 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context if (!needs_legacy_glsl_syntax(gl_info)) { - if (shader_glsl_use_explicit_attrib_location(gl_info)) - shader_addline(buffer, "layout(location = 0) "); - shader_addline(buffer, "out vec4 ps_out[%u];\n", gl_info->limits.buffers); + if (args->dual_source_blend) + { + for (i = 0; i < gl_info->limits.dual_buffers * 2; i++) + { + if (shader_glsl_use_explicit_attrib_location(gl_info)) + shader_addline(buffer, "layout(location = %u, index = %u) ", i / 2, i % 2); + shader_addline(buffer, "out vec4 ps_out%u;\n", i); + } + } + else + { + for (i = 0; i < gl_info->limits.buffers; i++) + { + if (shader_glsl_use_explicit_attrib_location(gl_info)) + shader_addline(buffer, "layout(location = %u) ", i); + shader_addline(buffer, "out vec4 ps_out%u;\n", i); + } + } } if (shader->limits->constant_float + extra_constants_needed >= gl_info->limits.glsl_ps_float_constants) FIXME("Insufficient uniforms to run this shader.\n"); + if (shader->u.ps.force_early_depth_stencil) + shader_addline(buffer, "layout(early_fragment_tests) in;\n"); + shader_addline(buffer, "void main()\n{\n"); /* Direct3D applications expect integer vPos values, while OpenGL drivers @@ -8347,8 +8234,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr { {"vec4", "ffp_attrib_position"}, /* WINED3D_FFP_POSITION */ {"vec4", "ffp_attrib_blendweight"}, /* WINED3D_FFP_BLENDWEIGHT */ - /* TODO: Indexed vertex blending */ - {"float", ""}, /* WINED3D_FFP_BLENDINDICES */ + {"vec4", "ffp_attrib_blendindices"}, /* WINED3D_FFP_BLENDINDICES */ {"vec3", "ffp_attrib_normal"}, /* WINED3D_FFP_NORMAL */ {"float", "ffp_attrib_psize"}, /* WINED3D_FFP_PSIZE */ {"vec4", "ffp_attrib_diffuse"}, /* WINED3D_FFP_DIFFUSE */ @@ -8360,6 +8246,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr BOOL legacy_lighting = priv->legacy_lighting; GLuint shader_obj; unsigned int i; + char var[64]; string_buffer_clear(buffer); @@ -8378,9 +8265,9 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr } shader_addline(buffer, "\n"); - shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n", MAX_VERTEX_BLENDS); + shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n", MAX_VERTEX_INDEX_BLENDS); + shader_addline(buffer, "uniform mat3 ffp_normal_matrix[%u];\n", MAX_VERTEX_INDEX_BLENDS); shader_addline(buffer, "uniform mat4 ffp_projection_matrix;\n"); - shader_addline(buffer, "uniform mat3 ffp_normal_matrix;\n"); shader_addline(buffer, "uniform mat4 ffp_texture_matrix[%u];\n", MAX_TEXTURES); shader_addline(buffer, "uniform struct\n{\n"); @@ -8465,12 +8352,22 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr } else { - for (i = 0; i < settings->vertexblends; ++i) - shader_addline(buffer, "ffp_attrib_blendweight[%u] -= ffp_attrib_blendweight[%u];\n", settings->vertexblends, i); + if (!settings->sw_blending) + { + for (i = 0; i < settings->vertexblends; ++i) + shader_addline(buffer, "ffp_attrib_blendweight[%u] -= ffp_attrib_blendweight[%u];\n", settings->vertexblends, i); - shader_addline(buffer, "vec4 ec_pos = vec4(0.0);\n"); - for (i = 0; i < settings->vertexblends + 1; ++i) - shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * (ffp_modelview_matrix[%u] * ffp_attrib_position);\n", i, i); + shader_addline(buffer, "vec4 ec_pos = vec4(0.0);\n"); + for (i = 0; i < settings->vertexblends + 1; ++i) + { + sprintf(var, settings->vb_indices ? "int(ffp_attrib_blendindices[%u] + 0.1)" : "%u", i); + shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * (ffp_modelview_matrix[%s] * ffp_attrib_position);\n", i, var); + } + } + else + { + shader_addline(buffer, "vec4 ec_pos = ffp_attrib_position;\n"); + } shader_addline(buffer, "gl_Position = ffp_projection_matrix * ec_pos;\n"); if (settings->clipping) @@ -8487,14 +8384,17 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr shader_addline(buffer, "vec3 normal = vec3(0.0);\n"); if (settings->normal) { - if (!settings->vertexblends) + if (!settings->sw_blending) { - shader_addline(buffer, "normal = ffp_normal_matrix * ffp_attrib_normal;\n"); + for (i = 0; i < settings->vertexblends + 1; ++i) + { + sprintf(var, settings->vb_indices ? "int(ffp_attrib_blendindices[%u] + 0.1)" : "%u", i); + shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * (ffp_normal_matrix[%s] * ffp_attrib_normal);\n", i, var); + } } else { - for (i = 0; i < settings->vertexblends + 1; ++i) - shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * (mat3(ffp_modelview_matrix[%u]) * ffp_attrib_normal);\n", i, i); + shader_addline(buffer, "normal = ffp_attrib_normal;\n"); } if (settings->normalize) @@ -8860,6 +8760,7 @@ static void shader_glsl_ffp_fragment_op(struct wined3d_string_buffer *buffer, un static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *priv, const struct ffp_frag_settings *settings, const struct wined3d_context *context) { + const char *output = needs_legacy_glsl_syntax(context->gl_info) ? "gl_FragData[0]" : "ps_out0"; struct wined3d_string_buffer *tex_reg_name = string_buffer_get(&priv->string_buffers); enum wined3d_cmp_func alpha_test_func = settings->alpha_test_func + 1; struct wined3d_string_buffer *buffer = &priv->shader_buffer; @@ -8948,7 +8849,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * { if (shader_glsl_use_explicit_attrib_location(gl_info)) shader_addline(buffer, "layout(location = 0) "); - shader_addline(buffer, "out vec4 ps_out[1];\n"); + shader_addline(buffer, "out vec4 ps_out0;\n"); } shader_addline(buffer, "vec4 tmp0, tmp1;\n"); @@ -9279,8 +9180,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv * } } - shader_addline(buffer, "%s[0] = ffp_varying_specular * specular_enable + ret;\n", - get_fragment_output(gl_info)); + shader_addline(buffer, "%s = ffp_varying_specular * specular_enable + ret;\n", output); if (settings->sRGB_write) shader_glsl_generate_srgb_write_correction(buffer, gl_info); @@ -9367,13 +9267,17 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info * vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "pos_fixup")); - for (i = 0; i < MAX_VERTEX_BLENDS; ++i) + for (i = 0; i < MAX_VERTEX_INDEX_BLENDS; ++i) { string_buffer_sprintf(name, "ffp_modelview_matrix[%u]", i); vs->modelview_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); } + for (i = 0; i < MAX_VERTEX_INDEX_BLENDS; ++i) + { + string_buffer_sprintf(name, "ffp_normal_matrix[%u]", i); + vs->normal_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); + } vs->projection_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_projection_matrix")); - vs->normal_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_normal_matrix")); for (i = 0; i < MAX_TEXTURES; ++i) { string_buffer_sprintf(name, "ffp_texture_matrix[%u]", i); @@ -9824,8 +9728,26 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const if (!needs_legacy_glsl_syntax(gl_info)) { - GL_EXTCALL(glBindFragDataLocation(program_id, 0, "ps_out")); - checkGLcall("glBindFragDataLocation"); + char var[12]; + + if (wined3d_dualblend_enabled(state, gl_info)) + { + for (i = 0; i < gl_info->limits.dual_buffers * 2; i++) + { + sprintf(var, "ps_out%u", i); + GL_EXTCALL(glBindFragDataLocationIndexed(program_id, i / 2, i % 2, var)); + checkGLcall("glBindFragDataLocationIndexed"); + } + } + else + { + for (i = 0; i < gl_info->limits.buffers; i++) + { + sprintf(var, "ps_out%u", i); + GL_EXTCALL(glBindFragDataLocation(program_id, i, var)); + checkGLcall("glBindFragDataLocation"); + } + } } } @@ -9924,7 +9846,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW | WINED3D_SHADER_CONST_FFP_PROJ; - for (i = 1; i < MAX_VERTEX_BLENDS; ++i) + for (i = 1; i < MAX_VERTEX_INDEX_BLENDS; ++i) { if (entry->vs.modelview_matrix_location[i] != -1) { @@ -10509,15 +10431,15 @@ static void shader_glsl_init_context_state(struct wined3d_context *context) checkGLcall("GL_PROGRAM_POINT_SIZE"); } -static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps) +static unsigned int shader_glsl_get_shader_model(const struct wined3d_gl_info *gl_info) { - unsigned int shader_model; + BOOL shader_model_4 = gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50) + && gl_info->supported[WINED3D_GL_VERSION_3_2] + && gl_info->supported[ARB_SAMPLER_OBJECTS] + && gl_info->supported[ARB_SHADER_BIT_ENCODING] + && gl_info->supported[ARB_TEXTURE_SWIZZLE]; - /* FIXME: Check for the specific extensions required for SM5 support - * (ARB_compute_shader, ARB_tessellation_shader, ARB_gpu_shader5, ...) as - * soon as we introduce them, adjusting the GL / GLSL version checks - * accordingly. */ - if (gl_info->glsl_version >= MAKEDWORD_VERSION(4, 30) && gl_info->supported[WINED3D_GL_VERSION_4_3] + if (shader_model_4 && gl_info->supported[ARB_COMPUTE_SHADER] && gl_info->supported[ARB_DERIVATIVE_CONTROL] && gl_info->supported[ARB_GPU_SHADER5] @@ -10528,17 +10450,23 @@ static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct s && gl_info->supported[ARB_TESSELLATION_SHADER] && gl_info->supported[ARB_TEXTURE_GATHER] && gl_info->supported[ARB_TRANSFORM_FEEDBACK3]) - shader_model = 5; - else if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50) && gl_info->supported[WINED3D_GL_VERSION_3_2] - && gl_info->supported[ARB_SHADER_BIT_ENCODING] && gl_info->supported[ARB_SAMPLER_OBJECTS] - && gl_info->supported[ARB_TEXTURE_SWIZZLE]) - shader_model = 4; + return 5; + + if (shader_model_4) + return 4; + /* Support for texldd and texldl instructions in pixel shaders is required * for SM3. */ - else if (shader_glsl_has_core_grad(gl_info) || gl_info->supported[ARB_SHADER_TEXTURE_LOD]) - shader_model = 3; - else - shader_model = 2; + if (shader_glsl_has_core_grad(gl_info) || gl_info->supported[ARB_SHADER_TEXTURE_LOD]) + return 3; + + return 2; +} + +static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps) +{ + unsigned int shader_model = shader_glsl_get_shader_model(gl_info); + TRACE("Shader model %u.\n", shader_model); caps->vs_version = min(wined3d_settings.max_sm_vs, shader_model); @@ -10581,21 +10509,8 @@ static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct s static BOOL shader_glsl_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 support everything except YUV conversions. */ - if (!is_complex_fixup(fixup)) - { - TRACE("[OK]\n"); - return TRUE; - } - - TRACE("[FAILED]\n"); - return FALSE; + return !is_complex_fixup(fixup); } static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TABLE_SIZE] = @@ -10802,7 +10717,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_STORE_STRUCTURED */ shader_glsl_store_raw_structured, /* WINED3DSIH_STORE_UAV_TYPED */ shader_glsl_store_uav, /* WINED3DSIH_SUB */ shader_glsl_binop, - /* WINED3DSIH_SWAPC */ NULL, + /* WINED3DSIH_SWAPC */ shader_glsl_swapc, /* WINED3DSIH_SWITCH */ shader_glsl_switch, /* WINED3DSIH_SYNC */ shader_glsl_sync, /* WINED3DSIH_TEX */ shader_glsl_tex, @@ -10893,7 +10808,7 @@ static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info, caps->ffp_generic_attributes = TRUE; caps->max_active_lights = MAX_ACTIVE_LIGHTS; caps->max_vertex_blend_matrices = MAX_VERTEX_BLENDS; - caps->max_vertex_blend_matrix_index = 0; + caps->max_vertex_blend_matrix_index = MAX_VERTEX_INDEX_BLENDS - 1; caps->vertex_processing_caps = WINED3DVTXPCAPS_TEXGEN | WINED3DVTXPCAPS_MATERIALSOURCE7 | WINED3DVTXPCAPS_VERTEXFOG @@ -11080,7 +10995,8 @@ static void glsl_vertex_pipe_world(struct wined3d_context *context, static void glsl_vertex_pipe_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND; + int i = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)); + context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i); } static void glsl_vertex_pipe_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -11311,6 +11227,11 @@ static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] = {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, + {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, diff --git a/reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c b/reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c index 9449a52d35c..1033ec885e9 100644 --- a/reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c +++ b/reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c @@ -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[] = diff --git a/reactos/dll/directx/wine/wined3d/query.c b/reactos/dll/directx/wine/wined3d/query.c index 3060432ff42..428e841d4e9 100644 --- a/reactos/dll/directx/wine/wined3d/query.c +++ b/reactos/dll/directx/wine/wined3d/query.c @@ -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; diff --git a/reactos/dll/directx/wine/wined3d/resource.c b/reactos/dll/directx/wine/wined3d/resource.c index 8b310d21854..ffce0125033 100644 --- a/reactos/dll/directx/wine/wined3d/resource.c +++ b/reactos/dll/directx/wine/wined3d/resource.c @@ -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); diff --git a/reactos/dll/directx/wine/wined3d/shader.c b/reactos/dll/directx/wine/wined3d/shader.c index 1545d28882a..5245cb657ab 100644 --- a/reactos/dll/directx/wine/wined3d/shader.c +++ b/reactos/dll/directx/wine/wined3d/shader.c @@ -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, diff --git a/reactos/dll/directx/wine/wined3d/shader_sm4.c b/reactos/dll/directx/wine/wined3d/shader_sm4.c index 3619685eb03..ad59da05ecf 100644 --- a/reactos/dll/directx/wine/wined3d/shader_sm4.c +++ b/reactos/dll/directx/wine/wined3d/shader_sm4.c @@ -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, ¶m->idx[0]))) + if (!(shader_sm4_read_reg_idx(priv, ptr, end, addressing, ¶m->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, ¶m->idx[1]))) + if (!(shader_sm4_read_reg_idx(priv, ptr, end, addressing, ¶m->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; diff --git a/reactos/dll/directx/wine/wined3d/state.c b/reactos/dll/directx/wine/wined3d/state.c index 36fc877d67e..c3c3bd99aa9 100644 --- a/reactos/dll/directx/wine/wined3d/state.c +++ b/reactos/dll/directx/wine/wined3d/state.c @@ -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) diff --git a/reactos/dll/directx/wine/wined3d/stateblock.c b/reactos/dll/directx/wine/wined3d/stateblock.c index 27d14c94919..b3cb7ae9dc4 100644 --- a/reactos/dll/directx/wine/wined3d/stateblock.c +++ b/reactos/dll/directx/wine/wined3d/stateblock.c @@ -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) diff --git a/reactos/dll/directx/wine/wined3d/surface.c b/reactos/dll/directx/wine/wined3d/surface.c index 91718e579b6..35ebe42aaed 100644 --- a/reactos/dll/directx/wine/wined3d/surface.c +++ b/reactos/dll/directx/wine/wined3d/surface.c @@ -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, diff --git a/reactos/dll/directx/wine/wined3d/utils.c b/reactos/dll/directx/wine/wined3d/utils.c index 979ce88a7f2..20a88d6b29c 100644 --- a/reactos/dll/directx/wine/wined3d/utils.c +++ b/reactos/dll/directx/wine/wined3d/utils.c @@ -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)); diff --git a/reactos/dll/directx/wine/wined3d/vertexdeclaration.c b/reactos/dll/directx/wine/wined3d/vertexdeclaration.c index 990aab00498..456a0fa2b4b 100644 --- a/reactos/dll/directx/wine/wined3d/vertexdeclaration.c +++ b/reactos/dll/directx/wine/wined3d/vertexdeclaration.c @@ -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) { diff --git a/reactos/dll/directx/wine/wined3d/view.c b/reactos/dll/directx/wine/wined3d/view.c index 1f39dd18ee1..6028ebe99d2 100644 --- a/reactos/dll/directx/wine/wined3d/view.c +++ b/reactos/dll/directx/wine/wined3d/view.c @@ -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) diff --git a/reactos/dll/directx/wine/wined3d/wined3d.spec b/reactos/dll/directx/wine/wined3d/wined3d.spec index 8dc4fb432e9..e4d5f2ed9ac 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d.spec +++ b/reactos/dll/directx/wine/wined3d/wined3d.spec @@ -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) diff --git a/reactos/dll/directx/wine/wined3d/wined3d_gl.h b/reactos/dll/directx/wine/wined3d/wined3d_gl.h index 80fc6809238..4f73478a3b4 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_gl.h +++ b/reactos/dll/directx/wine/wined3d/wined3d_gl.h @@ -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, diff --git a/reactos/dll/directx/wine/wined3d/wined3d_main.c b/reactos/dll/directx/wine/wined3d/wined3d_main.c index 91cf61bdc17..a4b5e3398f7 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_main.c +++ b/reactos/dll/directx/wine/wined3d/wined3d_main.c @@ -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; } diff --git a/reactos/dll/directx/wine/wined3d/wined3d_private.h b/reactos/dll/directx/wine/wined3d/wined3d_private.h index 5da23728105..838434df3da 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_private.h +++ b/reactos/dll/directx/wine/wined3d/wined3d_private.h @@ -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()); diff --git a/reactos/sdk/include/reactos/wine/wined3d.h b/reactos/sdk/include/reactos/wine/wined3d.h index 7025bc0db25..99f130b042d 100644 --- a/reactos/sdk/include/reactos/wine/wined3d.h +++ b/reactos/sdk/include/reactos/wine/wined3d.h @@ -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,