Index: reactos/dll/directx/wine/wined3d/arb_program_shader.c =================================================================== --- reactos/dll/directx/wine/wined3d/arb_program_shader.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/arb_program_shader.c (working copy) @@ -1188,6 +1188,8 @@ 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 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) { Index: reactos/dll/directx/wine/wined3d/ati_fragment_shader.c =================================================================== --- reactos/dll/directx/wine/wined3d/ati_fragment_shader.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/ati_fragment_shader.c (working copy) @@ -1346,22 +1346,9 @@ 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) Index: reactos/dll/directx/wine/wined3d/buffer.c =================================================================== --- reactos/dll/directx/wine/wined3d/buffer.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/buffer.c (working copy) @@ -182,10 +182,10 @@ 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 @@ } /* 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 @@ 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; + 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; } - 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; - } - /* 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) @@ -1258,6 +1256,61 @@ return WINED3D_OK; } +/* caller is responsible for tracking state of gl buffer binding */ +HRESULT wined3d_buffer_copy_from_gl_buffer(struct wined3d_buffer *dst_buffer, unsigned int dst_offset, + GLuint src_buffer, GLenum src_target, unsigned int src_offset, unsigned int size) +{ + const struct wined3d_gl_info *gl_info; + struct wined3d_bo_address dst; + struct wined3d_context *context; + struct wined3d_device *device; + DWORD dst_location; + BYTE *dst_ptr; + + buffer_mark_used(dst_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; + + if (dst.buffer_object) + { + if (gl_info->supported[ARB_COPY_BUFFER]) + { + GL_EXTCALL(glBindBuffer(GL_COPY_READ_BUFFER, src_buffer)); + 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 + { + dst_ptr = context_map_bo_address(context, &dst, size, dst_buffer->buffer_type_hint, 0); + + GL_EXTCALL(glBindBuffer(src_target, src_buffer)); + GL_EXTCALL(glGetBufferSubData(src_target, src_offset, size, dst_ptr)); + checkGLcall("buffer download"); + + context_unmap_bo_address(context, &dst, dst_buffer->buffer_type_hint); + } + } + else + { + GL_EXTCALL(glBindBuffer(src_target, src_buffer)); + GL_EXTCALL(glGetBufferSubData(src_target, src_offset, size, dst.addr)); + checkGLcall("buffer download"); + } + + 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, const struct wined3d_box *box, const void *data) { Index: reactos/dll/directx/wine/wined3d/context.c =================================================================== --- reactos/dll/directx/wine/wined3d/context.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/context.c (working copy) @@ -793,13 +793,13 @@ } /* 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 { @@ -806,50 +806,50 @@ 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 @@ 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 @@ return TRUE; success: - if (dc == context->hdc && context->hdc_is_private) + if (private) context->hdc_has_format = TRUE; return TRUE; } @@ -1165,7 +1171,7 @@ 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 @@ 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 @@ 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_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 @@ 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, &event_query->object.id)); - else if (gl_info->supported[NV_FENCE]) GL_EXTCALL(glDeleteFencesNV(1, &event_query->object.id)); + 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)); + } } - 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } /* 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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,7 +2755,6 @@ return; gl_info = context->gl_info; - context_bind_bo(context, binding, data->buffer_object); GL_EXTCALL(glUnmapBuffer(binding)); context_bind_bo(context, binding, 0); @@ -3496,7 +3500,7 @@ 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 +3541,8 @@ 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); } Index: reactos/dll/directx/wine/wined3d/cs.c =================================================================== --- reactos/dll/directx/wine/wined3d/cs.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/cs.c (working copy) @@ -68,6 +68,8 @@ WINED3D_CS_OP_UPDATE_SUB_RESOURCE, WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION, WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW, + WINED3D_CS_OP_COPY_SUB_RESOURCE, + WINED3D_CS_OP_COPY_STRUCTURE_COUNT, WINED3D_CS_OP_STOP, }; @@ -109,9 +111,7 @@ 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 @@ 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 @@ 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_uvec4 clear_value; }; +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_copy_structure_count +{ + enum wined3d_cs_op opcode; + struct wined3d_buffer *dst_buffer; + unsigned int offset; + struct wined3d_unordered_access_view *src_view; +}; + struct wined3d_cs_stop { enum wined3d_cs_op opcode; @@ -696,9 +711,11 @@ 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]); @@ -712,9 +729,10 @@ 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], @@ -723,6 +741,27 @@ 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; + + wined3d_resource_acquire(&buffer->resource); + + 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]); + + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); +} + static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) { struct wined3d_state *state = &cs->state; @@ -729,13 +768,6 @@ 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 +776,27 @@ } 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 +837,13 @@ 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); @@ -826,12 +876,62 @@ 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); + 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); +} + 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); } @@ -1284,10 +1384,13 @@ InterlockedDecrement(&prev->resource->bind_count); device_invalidate_state(cs->device, STATE_UNORDERED_ACCESS_VIEW_BINDING(op->pipeline)); + + if (op->view && op->initial_count != ~0u) + wined3d_unordered_access_view_set_counter(op->view, op->initial_count); } 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 +1399,7 @@ op->pipeline = pipeline; op->view_idx = view_idx; op->view = view; + op->initial_count = initial_count; cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } @@ -2139,10 +2243,7 @@ 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 +2264,8 @@ 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,7 +2273,6 @@ 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; @@ -2177,25 +2279,17 @@ 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 +2303,11 @@ wined3d_resource_acquire(resource); cs->ops->submit(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); -#endif /* STAGING_CSMT */ } static void wined3d_cs_exec_add_dirty_texture_region(struct wined3d_cs *cs, const void *data) @@ -2277,6 +2374,180 @@ 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) + { + if (FAILED(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"); + } + 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_exec_copy_structure_count(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_copy_structure_count *op = data; + + if (op->src_view->counter_bo) + { + wined3d_buffer_copy_from_gl_buffer(op->dst_buffer, op->offset, + op->src_view->counter_bo, GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint)); + } + + wined3d_resource_release(&op->dst_buffer->resource); + wined3d_resource_release(op->src_view->resource); +} + +void wined3d_cs_emit_copy_structure_count(struct wined3d_cs *cs, struct wined3d_buffer *dst_buffer, + unsigned int offset, struct wined3d_unordered_access_view *src_view) +{ + struct wined3d_cs_copy_structure_count *op; + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_COPY_STRUCTURE_COUNT; + op->dst_buffer = dst_buffer; + op->offset = offset; + op->src_view = src_view; + + wined3d_resource_acquire(&dst_buffer->resource); + wined3d_resource_acquire(src_view->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 @@ /* 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_SUB_RESOURCE */ wined3d_cs_exec_copy_sub_resource, + /* WINED3D_CS_OP_COPY_STRUCTURE_COUNT */ wined3d_cs_exec_copy_structure_count, }; #if defined(STAGING_CSMT) Index: reactos/dll/directx/wine/wined3d/device.c =================================================================== --- reactos/dll/directx/wine/wined3d/device.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/device.c (working copy) @@ -374,10 +374,8 @@ } 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 @@ 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 @@ { 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 @@ } 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,7 +3006,7 @@ } prev = device->update_state->unordered_access_view[pipeline][idx]; - if (uav == prev) + if (uav == prev && initial_count == ~0u) return; if (uav) @@ -3003,7 +3013,7 @@ 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 @@ } 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); - 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 @@ } 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); - 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,82 +3520,6 @@ 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) { TRACE("device %p, caps %p.\n", device, caps); @@ -3762,6 +3696,14 @@ 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 +3747,15 @@ 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 +3786,15 @@ 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) { @@ -4103,7 +4063,10 @@ 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 +4077,7 @@ 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 +4103,7 @@ { 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 +4134,10 @@ 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 +4253,8 @@ 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,9 +4317,29 @@ 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); } +HRESULT CDECL wined3d_device_copy_structure_count(struct wined3d_device *device, struct wined3d_buffer *dst_buffer, + unsigned int offset, struct wined3d_unordered_access_view *src_view) +{ + TRACE("device %p, dst_buffer %p, offset %u, src_view %p.\n", + device, dst_buffer, offset, src_view); + + if (offset + sizeof(GLuint) > dst_buffer->resource.size) + { + WARN("Offset %u too large.\n", offset); + return WINED3DERR_INVALIDCALL; + } + + wined3d_cs_emit_copy_structure_count(device->cs, dst_buffer, offset, src_view); + return WINED3D_OK; +} + HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *device, struct wined3d_rendertarget_view *view, const RECT *rect, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) Index: reactos/dll/directx/wine/wined3d/directx.c =================================================================== --- reactos/dll/directx/wine/wined3d/directx.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/directx.c (working copy) @@ -106,6 +106,7 @@ {"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 }, @@ -112,13 +113,17 @@ {"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 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 @@ || 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", @@ -2692,6 +2698,9 @@ /* 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 +2719,8 @@ 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 +2733,9 @@ 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) @@ -3873,6 +3887,7 @@ {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 +3909,7 @@ {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 +3925,8 @@ {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 +4043,6 @@ 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. */ @@ -4364,7 +4380,7 @@ 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 +5171,8 @@ /* 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 +5202,6 @@ } } } - 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 +5267,9 @@ 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 +5282,26 @@ 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 +5316,7 @@ 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 +5330,11 @@ | 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,9 +5355,15 @@ | 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: FIXME("Unhandled resource type %s.\n", debug_d3dresourcetype(resource_type)); return WINED3DERR_NOTAVAILABLE; @@ -5353,13 +5391,6 @@ 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"); @@ -5366,26 +5397,40 @@ return WINED3DERR_NOTAVAILABLE; } - if ((usage & WINED3DUSAGE_DEPTHSTENCIL) - && !CheckDepthStencilCapability(adapter, adapter_format, format, gl_type)) + if ((usage & WINED3DUSAGE_AUTOGENMIPMAP) && !gl_info->supported[SGIS_GENERATE_MIPMAP]) { - TRACE("Requested WINED3DUSAGE_DEPTHSTENCIL, but format %s is not supported for depth / stencil buffers.\n", - debug_d3dformat(check_format_id)); - return WINED3DERR_NOTAVAILABLE; + TRACE("No WINED3DUSAGE_AUTOGENMIPMAP support, returning WINED3DOK_NOAUTOGEN.\n"); + return WINED3DOK_NOAUTOGEN; } - if ((usage & WINED3DUSAGE_RENDERTARGET) - && !CheckRenderTargetCapability(adapter, adapter_format, format, gl_type)) + for (; gl_type <= gl_type_end; ++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 ((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_AUTOGENMIPMAP) && !gl_info->supported[SGIS_GENERATE_MIPMAP]) - { - TRACE("No WINED3DUSAGE_AUTOGENMIPMAP support, returning WINED3DOK_NOAUTOGEN.\n"); - return WINED3DOK_NOAUTOGEN; + 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; @@ -6490,6 +6535,18 @@ } } +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 +6556,9 @@ }; struct wined3d_gl_info *gl_info = &adapter->gl_info; struct wined3d_caps_gl_ctx caps_gl_ctx = {0}; + DWORD max_gl_version = wined3d_settings.max_gl_version; + DISPLAY_DEVICEW display_device; unsigned int i; - DISPLAY_DEVICEW display_device; TRACE("adapter %p, ordinal %u.\n", adapter, ordinal); @@ -6545,15 +6603,25 @@ 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; } Index: reactos/dll/directx/wine/wined3d/drawprim.c =================================================================== --- reactos/dll/directx/wine/wined3d/drawprim.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/drawprim.c (working copy) @@ -66,7 +66,7 @@ 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]) @@ -73,11 +73,25 @@ { 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,38 @@ } } +/* 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 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) { @@ -457,21 +503,20 @@ /* 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 +541,7 @@ 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 +583,8 @@ } 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 +593,7 @@ } else { - ib_query = index_buffer->query; + ib_fence = index_buffer->fence; idx_data = NULL; } idx_data = (const BYTE *)idx_data + state->index_offset; @@ -628,13 +671,30 @@ 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) { GL_EXTCALL(glMemoryBarrier(GL_ALL_BARRIER_BITS)); @@ -649,10 +709,10 @@ 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 +723,7 @@ } 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,9 +753,23 @@ return; } - GL_EXTCALL(glDispatchCompute(group_count_x, group_count_y, group_count_z)); - checkGLcall("glDispatchCompute"); + if (!parameters->indirect) + { + GL_EXTCALL(glDispatchCompute(parameters->u.direct.group_count_x, + parameters->u.direct.group_count_y, parameters->u.direct.group_count_z)); + checkGLcall("dispatch compute"); + } + else + { + struct wined3d_buffer *buffer = parameters->u.indirect.buffer; + wined3d_buffer_load(buffer, context, state); + GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, buffer->buffer_object)); + GL_EXTCALL(glDispatchComputeIndirect((GLintptr)0 + parameters->u.indirect.offset)); + GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0)); + checkGLcall("dispatch compute indirect"); + } + GL_EXTCALL(glMemoryBarrier(GL_ALL_BARRIER_BITS)); checkGLcall("glMemoryBarrier"); Index: reactos/dll/directx/wine/wined3d/glsl_shader.c =================================================================== --- reactos/dll/directx/wine/wined3d/glsl_shader.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/glsl_shader.c (working copy) @@ -82,6 +82,7 @@ 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 @@ -2707,6 +2708,17 @@ } } +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, @@ -2890,6 +2902,8 @@ 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 +3043,14 @@ 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 +3067,8 @@ 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 +3410,7 @@ 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 +3423,7 @@ 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,8 +3435,31 @@ 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 +3498,7 @@ 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 +3619,7 @@ 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 +3688,26 @@ 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 +4169,8 @@ 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 +4184,21 @@ 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 +4208,13 @@ 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 +4418,58 @@ } } +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 +5616,14 @@ 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); @@ -7168,10 +7303,20 @@ * 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 +7385,7 @@ { 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); } @@ -7305,6 +7450,9 @@ 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 @@ -10509,15 +10657,15 @@ 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 +10676,23 @@ && 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 +10735,8 @@ 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 +10943,7 @@ /* 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, Index: reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c =================================================================== --- reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c (working copy) @@ -756,21 +756,8 @@ 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[] = Index: reactos/dll/directx/wine/wined3d/query.c =================================================================== --- reactos/dll/directx/wine/wined3d/query.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/query.c (working copy) @@ -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 @@ 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 @@ 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,37 +123,41 @@ { 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); @@ -149,23 +164,23 @@ 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 @@ -172,8 +187,8 @@ */ 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); } @@ -184,7 +199,8 @@ /* 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)); + GLenum gl_ret = GL_EXTCALL(glClientWaitSync(fence->object.sync, + GL_SYNC_FLUSH_COMMANDS_BIT, ~(GLuint64)0xffff)); checkGLcall("glClientWaitSync"); switch (gl_ret) @@ -191,31 +207,31 @@ { 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 */ 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); @@ -222,35 +238,36 @@ 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"); } @@ -257,6 +274,52 @@ 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 +340,7 @@ * 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 +440,15 @@ 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 +457,25 @@ 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 +507,7 @@ { 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 +693,8 @@ 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 +774,6 @@ 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 +787,58 @@ 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; + 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); } - 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; - } -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 +855,7 @@ { 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 +895,7 @@ { 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 +910,47 @@ 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 +959,21 @@ { 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)) + 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"); - return WINED3DERR_NOTAVAILABLE; + HeapFree(GetProcessHeap(), 0, object); + return hr; } - if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) - return E_OUTOFMEMORY; - wined3d_query_init(&object->query, device, type, &object->signalled, sizeof(object->signalled), &event_query_ops, parent, parent_ops); @@ -1030,10 +983,20 @@ 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 +1027,20 @@ 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 +1071,16 @@ 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 +1123,20 @@ 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,7 +1145,13 @@ { 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 +1169,52 @@ if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) return E_OUTOFMEMORY; - switch (type) + 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; + + 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]) { - 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; + 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), &so_statistics_query_ops, parent, parent_ops); + sizeof(object->statistics), &pipeline_query_ops, parent, parent_ops); TRACE("Created query %p.\n", object); *query = &object->query; @@ -1202,10 +1222,16 @@ 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 +1255,16 @@ 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 +1288,6 @@ 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,6 +1315,9 @@ 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); @@ -1323,9 +1324,6 @@ 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; Index: reactos/dll/directx/wine/wined3d/shader.c =================================================================== --- reactos/dll/directx/wine/wined3d/shader.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/shader.c (working copy) @@ -1078,6 +1078,21 @@ 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 @@ 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 @@ { 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 @@ 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 @@ 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; Index: reactos/dll/directx/wine/wined3d/shader_sm4.c =================================================================== --- reactos/dll/directx/wine/wined3d/shader_sm4.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/shader_sm4.c (working copy) @@ -168,6 +168,7 @@ 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 @@ 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,9 +508,9 @@ /* 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, @@ -514,7 +517,7 @@ 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 @@ 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 @@ 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,7 +608,7 @@ 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, @@ -612,7 +615,8 @@ 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,7 +672,7 @@ 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, @@ -675,7 +679,8 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ {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 @@ /* 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 @@ *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 @@ 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,14 +1368,20 @@ 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) || register_type_table[register_type] == ~0u) @@ -1379,8 +1397,15 @@ 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) { case 0x41: @@ -1413,7 +1438,7 @@ 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 @@ 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,6 +1469,11 @@ { 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; @@ -1450,6 +1480,11 @@ 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,13 +1500,20 @@ 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,14 +1551,21 @@ 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 @@ 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 @@ 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; Index: reactos/dll/directx/wine/wined3d/state.c =================================================================== --- reactos/dll/directx/wine/wined3d/state.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/state.c (working copy) @@ -293,11 +293,11 @@ 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; - } } } @@ -1493,9 +1493,6 @@ 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 +1506,7 @@ 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 +1519,20 @@ 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 +1705,7 @@ union { DWORD d; + INT i; float f; } scale_bias, const_bias; @@ -1733,6 +1721,11 @@ 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 +1756,28 @@ } } +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]) @@ -5190,22 +5205,32 @@ { 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 +5865,8 @@ 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) Index: reactos/dll/directx/wine/wined3d/stateblock.c =================================================================== --- reactos/dll/directx/wine/wined3d/stateblock.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/stateblock.c (working copy) @@ -43,6 +43,10 @@ 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 @@ WINED3D_RS_ZENABLE, WINED3D_RS_ZFUNC, WINED3D_RS_ZWRITEENABLE, + WINED3D_RS_DEPTHCLIP, }; static const DWORD pixel_states_texture[] = @@ -1209,7 +1214,6 @@ 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 @@ 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 @@ 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) Index: reactos/dll/directx/wine/wined3d/surface.c =================================================================== --- reactos/dll/directx/wine/wined3d/surface.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/surface.c (working copy) @@ -365,6 +365,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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,24 +2731,15 @@ 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; + next_flags |= WINED3DCLEAR_TARGET; + flags &= ~WINED3DCLEAR_TARGET; + break; } - else if (!(resource->usage & WINED3DUSAGE_RENDERTARGET)) - { - goto next; - } /* FIXME: We should reject colour fills on formats with fixups, * but this would break P8 colour fills for example. */ @@ -2752,22 +2746,22 @@ } } - 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; + if (flags) + device_clear_render_targets(device, rt_count, fb, rect_count, + clear_rects, draw_rect, flags, colour, depth, stencil); -next: - if ((next = blitter->next)) + if (next_flags && (next = blitter->next)) next->ops->blitter_clear(next, device, rt_count, fb, rect_count, - clear_rects, draw_rect, flags, colour, depth, stencil); + 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 @@ 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 @@ 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 @@ } } - if ((flags & WINED3DCLEAR_ZBUFFER) && (view = fb->depth_stencil)) + 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)); + surface_cpu_blt_colour_fill(view, &box, &c); + } } - - if (flags & ~(WINED3DCLEAR_TARGET | WINED3DCLEAR_ZBUFFER)) - FIXME("flags %#x not implemented.\n", flags); } static void cpu_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, @@ -3771,16 +3776,6 @@ goto cpu; } - /* We want to avoid invalidating the sysmem location for converted - * surfaces, since otherwise we'd have to convert the data back when - * locking them. */ - if (dst_texture->flags & WINED3D_TEXTURE_CONVERTED || dst_texture->resource.format->convert - || wined3d_format_get_color_key_conversion(dst_texture, TRUE)) - { - WARN_(d3d_perf)("Converted surface, using CPU blit.\n"); - goto cpu; - } - if (flags & ~simple_blit) { WARN_(d3d_perf)("Using fallback for complex blit (%#x).\n", flags); Index: reactos/dll/directx/wine/wined3d/utils.c =================================================================== --- reactos/dll/directx/wine/wined3d/utils.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/utils.c (working copy) @@ -229,6 +229,7 @@ {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 @@ 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 @@ 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,10 +2137,12 @@ 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)); @@ -2146,7 +2149,7 @@ 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 @@ 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 @@ 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 @@ 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,7 +3126,7 @@ 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]; @@ -3127,7 +3133,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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}}, }; Index: reactos/dll/directx/wine/wined3d/view.c =================================================================== --- reactos/dll/directx/wine/wined3d/view.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/view.c (working copy) @@ -906,6 +906,24 @@ checkGLcall("clear unordered access view"); } +void wined3d_unordered_access_view_set_counter(struct wined3d_unordered_access_view *view, + unsigned int initial_count) +{ + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; + GLuint value = initial_count; + + 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); +} + static void wined3d_unordered_access_view_cs_init(void *object) { struct wined3d_unordered_access_view *view = object; @@ -923,7 +941,7 @@ 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 +986,6 @@ 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) Index: reactos/dll/directx/wine/wined3d/wined3d.spec =================================================================== --- reactos/dll/directx/wine/wined3d/wined3d.spec (revision 75633) +++ reactos/dll/directx/wine/wined3d/wined3d.spec (working copy) @@ -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) @@ -38,14 +37,18 @@ @ cdecl wined3d_device_clear_rendertarget_view(ptr ptr ptr long ptr float long) @ cdecl wined3d_device_clear_unordered_access_view_uint(ptr ptr ptr) @ cdecl wined3d_device_copy_resource(ptr ptr ptr) +@ cdecl wined3d_device_copy_structure_count(ptr ptr long ptr) @ cdecl wined3d_device_copy_sub_resource_region(ptr ptr long long long long 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) Index: reactos/dll/directx/wine/wined3d/wined3d_gl.h =================================================================== --- reactos/dll/directx/wine/wined3d/wined3d_gl.h (revision 75633) +++ reactos/dll/directx/wine/wined3d/wined3d_gl.h (working copy) @@ -43,6 +43,7 @@ APPLE_FLUSH_BUFFER_RANGE, APPLE_YCBCR_422, /* ARB */ + ARB_BASE_INSTANCE, ARB_BLEND_FUNC_EXTENDED, ARB_CLEAR_BUFFER_OBJECT, ARB_CLEAR_TEXTURE, @@ -49,13 +50,17 @@ 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 @@ 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, Index: reactos/dll/directx/wine/wined3d/wined3d_main.c =================================================================== --- reactos/dll/directx/wine/wined3d/wined3d_main.c (revision 75633) +++ reactos/dll/directx/wine/wined3d/wined3d_main.c (working copy) @@ -293,7 +293,7 @@ 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; } Index: reactos/dll/directx/wine/wined3d/wined3d_private.h =================================================================== --- reactos/dll/directx/wine/wined3d/wined3d_private.h (revision 75633) +++ reactos/dll/directx/wine/wined3d/wined3d_private.h (working copy) @@ -283,6 +283,7 @@ #define MAX_TGSM_REGISTERS 8192 #define MAX_VERTEX_BLENDS 4 #define MAX_MULTISAMPLE_TYPES 8 +#define MAX_RENDER_TARGETS 8 struct min_lookup { @@ -501,6 +502,8 @@ WINED3DSPR_COVERAGE, WINED3DSPR_SAMPLEMASK, WINED3DSPR_GSINSTID, + WINED3DSPR_DEPTHOUT_GREATER_EQUAL, + WINED3DSPR_DEPTHOUT_LESS_EQUAL, }; enum wined3d_data_type @@ -570,6 +573,7 @@ enum wined3d_shader_global_flags { WINED3DSGF_REFACTORING_ALLOWED = 0x1, + WINED3DSGF_FORCE_EARLY_DEPTH_STENCIL = 0x4, WINED3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS = 0x8, }; @@ -1489,11 +1493,59 @@ 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 +1670,34 @@ 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 +1712,7 @@ { 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 +1732,14 @@ 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; @@ -1887,10 +1945,10 @@ 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 +1968,8 @@ 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 +2116,7 @@ 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; @@ -2083,7 +2140,7 @@ 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; @@ -3458,9 +3515,13 @@ struct wined3d_unordered_access_view *view, const struct wined3d_uvec4 *clear_value) 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 +3570,7 @@ 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 +3578,11 @@ 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_structure_count(struct wined3d_cs *cs, struct wined3d_buffer *dst_buffer, + unsigned int offset, struct wined3d_unordered_access_view *src_view) 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 +3638,7 @@ 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; @@ -3597,6 +3663,8 @@ 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, struct wined3d_buffer *src_buffer, unsigned int src_offset, unsigned int size) DECLSPEC_HIDDEN; +HRESULT wined3d_buffer_copy_from_gl_buffer(struct wined3d_buffer *dst_buffer, unsigned int dst_offset, + GLuint src_buffer, GLenum src_target, 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; @@ -3680,6 +3748,8 @@ const struct wined3d_uvec4 *clear_value, 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 initial_count) DECLSPEC_HIDDEN; struct wined3d_swapchain_ops { @@ -3900,6 +3970,9 @@ /* 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 +4063,8 @@ 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 */ Index: reactos/sdk/include/reactos/wine/wined3d.h =================================================================== --- reactos/sdk/include/reactos/wine/wined3d.h (revision 75633) +++ reactos/sdk/include/reactos/wine/wined3d.h (working copy) @@ -32,6 +32,8 @@ #include +DEFINE_GUID(IID_IWineD3DDevice, 0xd56e2a4c, 0x5127, 0x8437, 0x65, 0x8a, 0x98, 0xc5, 0xbb, 0x78, 0x94, 0x98); + #define WINED3D_OK S_OK #define _FACWINED3D 0x876 @@ -381,9 +383,22 @@ 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 { WINED3D_BLEND_ZERO = 1, @@ -670,6 +685,7 @@ enum wined3d_resource_type { + WINED3D_RTYPE_NONE = 0, WINED3D_RTYPE_BUFFER = 1, WINED3D_RTYPE_TEXTURE_1D = 2, WINED3D_RTYPE_TEXTURE_2D = 3, @@ -705,12 +721,12 @@ 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 +744,13 @@ 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 +848,6 @@ 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 +1323,8 @@ #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_RESZ_CODE 0x7fa05000 @@ -2186,8 +2173,6 @@ 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); @@ -2255,12 +2240,18 @@ 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 +2378,7 @@ 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 +2449,7 @@ 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); @@ -2483,6 +2474,8 @@ HRESULT __cdecl wined3d_device_update_texture(struct wined3d_device *device, struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture); HRESULT __cdecl wined3d_device_validate_device(const struct wined3d_device *device, DWORD *num_passes); +HRESULT __cdecl wined3d_device_copy_structure_count(struct wined3d_device *device, struct wined3d_buffer *dst_buffer, + unsigned int offset, struct wined3d_unordered_access_view *src_view); HRESULT __cdecl wined3d_palette_create(struct wined3d_device *device, DWORD flags, unsigned int entry_count, const PALETTEENTRY *entries, struct wined3d_palette **palette);