Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- dlls/wined3d/adapter_vk.c | 35 +++- dlls/wined3d/context_gl.c | 11 +- dlls/wined3d/context_vk.c | 335 +++++++++++++++++++++++++++++++-- dlls/wined3d/texture.c | 14 +- dlls/wined3d/view.c | 1 + dlls/wined3d/wined3d_private.h | 36 ++++ 6 files changed, 392 insertions(+), 40 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 253c3da7264..4552eed4b79 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -859,6 +859,8 @@ static void *adapter_vk_map_bo_address(struct wined3d_context *context, return NULL; }
+ wined3d_context_vk_end_current_render_pass(context_vk); + vk_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; vk_barrier.pNext = NULL; vk_barrier.srcAccessMask = vk_access_mask_from_buffer_usage(bo->usage); @@ -956,6 +958,8 @@ static void adapter_vk_copy_bo_address(struct wined3d_context *context, return; }
+ wined3d_context_vk_end_current_render_pass(context_vk); + src_access_mask = vk_access_mask_from_buffer_usage(src_bo->usage); dst_access_mask = vk_access_mask_from_buffer_usage(dst_bo->usage);
@@ -1517,7 +1521,36 @@ static void adapter_vk_flush_context(struct wined3d_context *context) static void adapter_vk_draw_primitive(struct wined3d_device *device, const struct wined3d_state *state, const struct wined3d_draw_parameters *parameters) { - FIXME("device %p, state %p, parameters %p.\n", device, state, parameters); + const struct wined3d_vk_info *vk_info; + struct wined3d_context_vk *context_vk; + VkCommandBuffer vk_command_buffer; + uint32_t instance_count; + + TRACE("device %p, state %p, parameters %p.\n", device, state, parameters); + + context_vk = wined3d_context_vk(context_acquire(device, NULL, 0)); + vk_info = context_vk->vk_info; + + if (!(vk_command_buffer = wined3d_context_vk_apply_draw_state(context_vk, state))) + { + ERR("Failed to apply draw state.\n"); + context_release(&context_vk->c); + return; + } + + if (!parameters->indirect && !parameters->indexed) + { + instance_count = parameters->u.direct.instance_count; + if (context_vk->c.instance_count) + instance_count = context_vk->c.instance_count; + if (!instance_count) + instance_count = 1; + + VK_CALL(vkCmdDraw(vk_command_buffer, parameters->u.direct.index_count, instance_count, + parameters->u.direct.start_idx, parameters->u.direct.start_instance)); + } + + context_release(&context_vk->c); }
static void adapter_vk_dispatch_compute(struct wined3d_device *device, diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index b168e6026a6..f08f138e848 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -4367,15 +4367,6 @@ static GLenum gl_tfb_primitive_type_from_d3d(enum wined3d_primitive_type primiti } }
-static unsigned int get_render_target_writemask(const struct wined3d_blend_state *state, unsigned int index) -{ - if (!state) - return 0xf; - if (!state->desc.independent) - index = 0; - return state->desc.rt[index].writemask; -} - /* Routine common to the draw primitive and draw indexed primitive routines */ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state, const struct wined3d_draw_parameters *parameters) @@ -4433,7 +4424,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s if (!(rtv = fb->render_targets[i]) || rtv->format->id == WINED3DFMT_NULL) continue;
- if (get_render_target_writemask(state->blend_state, i)) + if (wined3d_blend_state_get_writemask(state->blend_state, i)) { wined3d_rendertarget_view_load_location(rtv, context, rtv->resource->draw_binding); wined3d_rendertarget_view_invalidate_location(rtv, ~rtv->resource->draw_binding); diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 2eaf9319790..8bb2457e1ad 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -976,6 +976,28 @@ VkRenderPass wined3d_context_vk_get_render_pass(struct wined3d_context_vk *conte return pass->vk_render_pass; }
+void wined3d_context_vk_end_current_render_pass(struct wined3d_context_vk *context_vk) +{ + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + VkCommandBuffer vk_command_buffer; + + if (context_vk->vk_render_pass) + { + vk_command_buffer = context_vk->current_command_buffer.vk_command_buffer; + VK_CALL(vkCmdEndRenderPass(vk_command_buffer)); + context_vk->vk_render_pass = VK_NULL_HANDLE; + VK_CALL(vkCmdPipelineBarrier(vk_command_buffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, NULL, 0, NULL, 0, NULL)); + } + + if (context_vk->vk_framebuffer) + { + wined3d_context_vk_destroy_framebuffer(context_vk, + context_vk->vk_framebuffer, context_vk->current_command_buffer.id); + context_vk->vk_framebuffer = VK_NULL_HANDLE; + } +} + static void wined3d_context_vk_destroy_render_pass(struct wine_rb_entry *entry, void *ctx) { struct wined3d_render_pass_vk *pass = WINE_RB_ENTRY_VALUE(entry, @@ -1002,14 +1024,17 @@ void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) context_vk->vk_command_pool, 1, &buffer->vk_command_buffer)); buffer->vk_command_buffer = VK_NULL_HANDLE; } - VK_CALL(vkDestroyCommandPool(device_vk->vk_device, context_vk->vk_command_pool, NULL));
wined3d_context_vk_wait_command_buffer(context_vk, buffer->id - 1); context_vk->completed_command_buffer_id = buffer->id;
heap_free(context_vk->compute.bindings.bindings); + heap_free(context_vk->graphics.bindings.bindings); if (context_vk->vk_descriptor_pool) VK_CALL(vkDestroyDescriptorPool(device_vk->vk_device, context_vk->vk_descriptor_pool, NULL)); + if (context_vk->vk_framebuffer) + VK_CALL(vkDestroyFramebuffer(device_vk->vk_device, context_vk->vk_framebuffer, NULL)); + VK_CALL(vkDestroyCommandPool(device_vk->vk_device, context_vk->vk_command_pool, NULL)); wined3d_context_vk_cleanup_resources(context_vk); wine_rb_destroy(&context_vk->bo_slab_available, wined3d_context_vk_destroy_bo_slab, context_vk); heap_free(context_vk->submitted.buffers); @@ -1094,8 +1119,12 @@ void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context TRACE("Submitting command buffer %p with id 0x%s.\n", buffer->vk_command_buffer, wine_dbgstr_longlong(buffer->id));
+ wined3d_context_vk_end_current_render_pass(context_vk); + context_vk->graphics.vk_pipeline = VK_NULL_HANDLE; context_vk->update_compute_pipeline = 1; + context_vk->c.update_shader_resource_bindings = 1; context_vk->c.update_compute_shader_resource_bindings = 1; + context_vk->c.update_unordered_access_view_bindings = 1; context_vk->c.update_compute_unordered_access_view_bindings = 1;
VK_CALL(vkEndCommandBuffer(buffer->vk_command_buffer)); @@ -1169,6 +1198,8 @@ void wined3d_context_vk_image_barrier(struct wined3d_context_vk *context_vk, const struct wined3d_vk_info *vk_info = context_vk->vk_info; VkImageMemoryBarrier barrier;
+ wined3d_context_vk_end_current_render_pass(context_vk); + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.pNext = NULL; barrier.srcAccessMask = src_access_mask; @@ -1219,6 +1250,102 @@ static int wined3d_bo_slab_vk_compare(const void *key, const struct wine_rb_entr return k->size - slab->bo.size; }
+static bool wined3d_context_vk_begin_render_pass(struct wined3d_context_vk *context_vk, + VkCommandBuffer vk_command_buffer, const struct wined3d_state *state, const struct wined3d_vk_info *vk_info) +{ + struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); + VkImageView vk_views[WINED3D_MAX_RENDER_TARGETS + 1]; + unsigned int fb_width, fb_height, fb_layer_count; + struct wined3d_rendertarget_view_vk *rtv_vk; + struct wined3d_rendertarget_view *view; + const VkPhysicalDeviceLimits *limits; + VkRenderPassBeginInfo begin_info; + unsigned int attachment_count, i; + VkFramebufferCreateInfo fb_desc; + VkResult vr; + + if (context_vk->vk_render_pass) + return true; + + limits = &wined3d_adapter_vk(device_vk->d.adapter)->device_limits; + fb_width = limits->maxFramebufferWidth; + fb_height = limits->maxFramebufferHeight; + fb_layer_count = limits->maxFramebufferLayers; + attachment_count = 0; + + for (i = 0; i < ARRAY_SIZE(state->fb.render_targets); ++i) + { + if (!(view = state->fb.render_targets[i]) || view->format->id == WINED3DFMT_NULL) + continue; + + rtv_vk = wined3d_rendertarget_view_vk(view); + vk_views[attachment_count] = wined3d_rendertarget_view_vk_get_image_view(rtv_vk, context_vk); + wined3d_context_vk_reference_rendertarget_view(context_vk, rtv_vk); + + if (view->width < fb_width) + fb_width = view->width; + if (view->height < fb_height) + fb_height = view->height; + if (view->layer_count < fb_layer_count) + fb_layer_count = view->layer_count; + ++attachment_count; + } + + if ((state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE]) + && (view = state->fb.depth_stencil)) + { + rtv_vk = wined3d_rendertarget_view_vk(view); + vk_views[attachment_count] = wined3d_rendertarget_view_vk_get_image_view(rtv_vk, context_vk); + wined3d_context_vk_reference_rendertarget_view(context_vk, rtv_vk); + + if (view->width < fb_width) + fb_width = view->width; + if (view->height < fb_height) + fb_height = view->height; + if (view->layer_count < fb_layer_count) + fb_layer_count = view->layer_count; + ++attachment_count; + } + + if (!(context_vk->vk_render_pass = wined3d_context_vk_get_render_pass(context_vk, &state->fb, + ARRAY_SIZE(state->fb.render_targets), state->render_states[WINED3D_RS_ZWRITEENABLE] + || state->render_states[WINED3D_RS_ZENABLE], 0))) + { + ERR("Failed to get render pass.\n"); + return false; + } + + fb_desc.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + fb_desc.pNext = NULL; + fb_desc.flags = 0; + fb_desc.renderPass = context_vk->vk_render_pass; + fb_desc.attachmentCount = attachment_count; + fb_desc.pAttachments = vk_views; + fb_desc.width = fb_width; + fb_desc.height = fb_height; + fb_desc.layers = fb_layer_count; + + if ((vr = VK_CALL(vkCreateFramebuffer(device_vk->vk_device, &fb_desc, NULL, &context_vk->vk_framebuffer))) < 0) + { + WARN("Failed to create Vulkan framebuffer, vr %s.\n", wined3d_debug_vkresult(vr)); + return false; + } + + begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + begin_info.pNext = NULL; + begin_info.renderPass = context_vk->vk_render_pass; + begin_info.framebuffer = context_vk->vk_framebuffer; + begin_info.renderArea.offset.x = 0; + begin_info.renderArea.offset.y = 0; + begin_info.renderArea.extent.width = fb_width; + begin_info.renderArea.extent.height = fb_height; + begin_info.clearValueCount = 0; + begin_info.pClearValues = NULL; + VK_CALL(vkCmdBeginRenderPass(vk_command_buffer, &begin_info, VK_SUBPASS_CONTENTS_INLINE)); + + return true; +} + static VkResult wined3d_context_vk_create_descriptor_pool(struct wined3d_device_vk *device_vk, const struct wined3d_vk_info *vk_info, VkDescriptorPool *vk_pool) { @@ -1371,7 +1498,7 @@ static bool wined3d_shader_resource_bindings_add_null_srv_binding(struct wined3d }
static bool wined3d_context_vk_update_descriptors(struct wined3d_context_vk *context_vk, - VkCommandBuffer vk_command_buffer, const struct wined3d_state *state) + VkCommandBuffer vk_command_buffer, const struct wined3d_state *state, enum wined3d_pipeline pipeline) { struct wined3d_shader_descriptor_writes_vk *writes = &context_vk->descriptor_writes; struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); @@ -1385,7 +1512,10 @@ static bool wined3d_context_vk_update_descriptors(struct wined3d_context_vk *con struct wined3d_shader_resource_view *srv; const VkDescriptorImageInfo *image_info; struct wined3d_buffer_vk *buffer_vk; + VkDescriptorSetLayout vk_set_layout; + VkPipelineLayout vk_pipeline_layout; struct wined3d_resource *resource; + VkPipelineBindPoint vk_bind_point; VkDescriptorSet vk_descriptor_set; struct wined3d_view_vk *view_vk; struct wined3d_sampler *sampler; @@ -1395,9 +1525,28 @@ static bool wined3d_context_vk_update_descriptors(struct wined3d_context_vk *con VkResult vr; size_t i;
- bindings = &context_vk->compute.bindings; - if ((vr = wined3d_context_vk_create_descriptor_set(context_vk, - context_vk->compute.vk_set_layout, &vk_descriptor_set))) + switch (pipeline) + { + case WINED3D_PIPELINE_GRAPHICS: + bindings = &context_vk->graphics.bindings; + vk_bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS; + vk_set_layout = context_vk->graphics.vk_set_layout; + vk_pipeline_layout = context_vk->graphics.vk_pipeline_layout; + break; + + case WINED3D_PIPELINE_COMPUTE: + bindings = &context_vk->compute.bindings; + vk_bind_point = VK_PIPELINE_BIND_POINT_COMPUTE; + vk_set_layout = context_vk->compute.vk_set_layout; + vk_pipeline_layout = context_vk->compute.vk_pipeline_layout; + break; + + default: + ERR("Invalid pipeline %#x.\n", pipeline); + return false; + } + + if ((vr = wined3d_context_vk_create_descriptor_set(context_vk, vk_set_layout, &vk_descriptor_set))) { WARN("Failed to create descriptor set, vr %s.\n", wined3d_debug_vkresult(vr)); return false; @@ -1461,7 +1610,7 @@ static bool wined3d_context_vk_update_descriptors(struct wined3d_context_vk *con break;
case WINED3D_SHADER_DESCRIPTOR_TYPE_UAV: - if (!(uav = state->unordered_access_view[WINED3D_PIPELINE_COMPUTE][binding->resource_idx])) + if (!(uav = state->unordered_access_view[pipeline][binding->resource_idx])) { FIXME("NULL unordered access views not implemented.\n"); return false; @@ -1495,7 +1644,7 @@ static bool wined3d_context_vk_update_descriptors(struct wined3d_context_vk *con break;
case WINED3D_SHADER_DESCRIPTOR_TYPE_UAV_COUNTER: - if (!(uav = state->unordered_access_view[WINED3D_PIPELINE_COMPUTE][binding->resource_idx])) + if (!(uav = state->unordered_access_view[pipeline][binding->resource_idx])) { FIXME("NULL unordered access view counters not implemented.\n"); return false; @@ -1524,8 +1673,8 @@ static bool wined3d_context_vk_update_descriptors(struct wined3d_context_vk *con }
VK_CALL(vkUpdateDescriptorSets(device_vk->vk_device, writes->count, writes->writes, 0, NULL)); - VK_CALL(vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, - context_vk->compute.vk_pipeline_layout, 0, 1, &vk_descriptor_set, 0, NULL)); + VK_CALL(vkCmdBindDescriptorSets(vk_command_buffer, vk_bind_point, + vk_pipeline_layout, 0, 1, &vk_descriptor_set, 0, NULL));
return true; } @@ -1614,11 +1763,18 @@ fail: return NULL; }
+static VkPipeline wined3d_context_vk_get_graphics_pipeline(struct wined3d_context_vk *context_vk) +{ + FIXME("Not implemented.\n"); + + return VK_NULL_HANDLE; +} + static void wined3d_context_vk_load_shader_resources(struct wined3d_context_vk *context_vk, - const struct wined3d_state *state) + const struct wined3d_state *state, enum wined3d_pipeline pipeline) { - const struct wined3d_shader_resource_bindings *bindings = &context_vk->compute.bindings; struct wined3d_shader_descriptor_writes_vk *writes = &context_vk->descriptor_writes; + const struct wined3d_shader_resource_bindings *bindings; const struct wined3d_shader_resource_binding *binding; struct wined3d_unordered_access_view_vk *uav_vk; struct wined3d_shader_resource_view_vk *srv_vk; @@ -1629,6 +1785,21 @@ static void wined3d_context_vk_load_shader_resources(struct wined3d_context_vk * struct wined3d_buffer *buffer; size_t i;
+ switch (pipeline) + { + case WINED3D_PIPELINE_GRAPHICS: + bindings = &context_vk->graphics.bindings; + break; + + case WINED3D_PIPELINE_COMPUTE: + bindings = &context_vk->compute.bindings; + break; + + default: + ERR("Invalid pipeline %#x.\n", pipeline); + return; + } + writes->count = 0; for (i = 0; i < bindings->count; ++i) { @@ -1643,7 +1814,12 @@ static void wined3d_context_vk_load_shader_resources(struct wined3d_context_vk * buffer_vk = wined3d_buffer_vk(buffer); wined3d_buffer_load(buffer, &context_vk->c, state); if (!buffer_vk->bo_user.valid) - context_invalidate_compute_state(&context_vk->c, STATE_COMPUTE_CONSTANT_BUFFER); + { + if (pipeline == WINED3D_PIPELINE_GRAPHICS) + context_invalidate_state(&context_vk->c, STATE_GRAPHICS_CONSTANT_BUFFER(binding->shader_type)); + else + context_invalidate_compute_state(&context_vk->c, STATE_COMPUTE_CONSTANT_BUFFER); + } break;
case WINED3D_SHADER_DESCRIPTOR_TYPE_SRV: @@ -1656,7 +1832,10 @@ static void wined3d_context_vk_load_shader_resources(struct wined3d_context_vk * if (!srv_vk->view_vk.bo_user.valid) { wined3d_shader_resource_view_vk_update(srv_vk, context_vk); - context_invalidate_compute_state(&context_vk->c, STATE_COMPUTE_SHADER_RESOURCE_BINDING); + if (pipeline == WINED3D_PIPELINE_GRAPHICS) + context_invalidate_state(&context_vk->c, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); + else + context_invalidate_compute_state(&context_vk->c, STATE_COMPUTE_SHADER_RESOURCE_BINDING); } wined3d_buffer_load(buffer_from_resource(srv->resource), &context_vk->c, state); } @@ -1667,7 +1846,7 @@ static void wined3d_context_vk_load_shader_resources(struct wined3d_context_vk * break;
case WINED3D_SHADER_DESCRIPTOR_TYPE_UAV: - if (!(uav = state->unordered_access_view[WINED3D_PIPELINE_COMPUTE][binding->resource_idx])) + if (!(uav = state->unordered_access_view[pipeline][binding->resource_idx])) break;
uav_vk = wined3d_unordered_access_view_vk(uav); @@ -1676,7 +1855,11 @@ static void wined3d_context_vk_load_shader_resources(struct wined3d_context_vk * if (!uav_vk->view_vk.bo_user.valid) { wined3d_unordered_access_view_vk_update(uav_vk, context_vk); - context_invalidate_compute_state(&context_vk->c, STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING); + if (pipeline == WINED3D_PIPELINE_GRAPHICS) + context_invalidate_state(&context_vk->c, STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING); + else + context_invalidate_compute_state(&context_vk->c, + STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING); } wined3d_buffer_load(buffer_from_resource(uav->resource), &context_vk->c, state); wined3d_unordered_access_view_invalidate_location(uav, ~WINED3D_LOCATION_BUFFER); @@ -1703,6 +1886,122 @@ static void wined3d_context_vk_load_shader_resources(struct wined3d_context_vk * } }
+VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *context_vk, + const struct wined3d_state *state) +{ + struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + struct wined3d_rendertarget_view *dsv; + VkCommandBuffer vk_command_buffer; + unsigned int i; + + if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)) + || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_FRAMEBUFFER)) + context_vk->c.shader_update_mask |= (1u << WINED3D_SHADER_TYPE_PIXEL); + if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX))) + context_vk->c.shader_update_mask |= (1u << WINED3D_SHADER_TYPE_VERTEX); + if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY))) + context_vk->c.shader_update_mask |= (1u << WINED3D_SHADER_TYPE_GEOMETRY); + if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_SHADER(WINED3D_SHADER_TYPE_HULL))) + context_vk->c.shader_update_mask |= (1u << WINED3D_SHADER_TYPE_HULL) | (1u << WINED3D_SHADER_TYPE_DOMAIN); + if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_SHADER(WINED3D_SHADER_TYPE_DOMAIN))) + context_vk->c.shader_update_mask |= (1u << WINED3D_SHADER_TYPE_DOMAIN); + + for (i = 0; i < ARRAY_SIZE(state->fb.render_targets); ++i) + { + struct wined3d_rendertarget_view *rtv; + + if (!(rtv = state->fb.render_targets[i]) || rtv->format->id == WINED3DFMT_NULL) + continue; + + if (wined3d_blend_state_get_writemask(state->blend_state, i)) + { + wined3d_rendertarget_view_load_location(rtv, &context_vk->c, rtv->resource->draw_binding); + wined3d_rendertarget_view_invalidate_location(rtv, ~rtv->resource->draw_binding); + } + else + { + wined3d_rendertarget_view_prepare_location(rtv, &context_vk->c, rtv->resource->draw_binding); + } + } + + if ((dsv = state->fb.depth_stencil)) + { + if (state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE]) + wined3d_rendertarget_view_load_location(dsv, &context_vk->c, dsv->resource->draw_binding); + else + wined3d_rendertarget_view_prepare_location(dsv, &context_vk->c, dsv->resource->draw_binding); + if (state->render_states[WINED3D_RS_ZWRITEENABLE]) + wined3d_rendertarget_view_invalidate_location(dsv, ~dsv->resource->draw_binding); + } + + if (context_vk->c.shader_update_mask & ~(1u << WINED3D_SHADER_TYPE_COMPUTE)) + { + device_vk->d.shader_backend->shader_select(device_vk->d.shader_priv, &context_vk->c, state); + if (!context_vk->graphics.vk_pipeline_layout) + { + ERR("No pipeline layout set.\n"); + return VK_NULL_HANDLE; + } + context_vk->c.shader_update_mask &= 1u << WINED3D_SHADER_TYPE_COMPUTE; + context_vk->c.update_shader_resource_bindings = 1; + context_vk->c.update_unordered_access_view_bindings = 1; + } + + wined3d_context_vk_load_shader_resources(context_vk, state, WINED3D_PIPELINE_GRAPHICS); + + if (!(vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk))) + { + ERR("Failed to get command buffer.\n"); + return VK_NULL_HANDLE; + } + + if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_FRAMEBUFFER)) + wined3d_context_vk_end_current_render_pass(context_vk); + if (!wined3d_context_vk_begin_render_pass(context_vk, vk_command_buffer, state, vk_info)) + { + ERR("Failed to begin render pass.\n"); + return VK_NULL_HANDLE; + } + + if (!(context_vk->graphics.vk_pipeline = wined3d_context_vk_get_graphics_pipeline(context_vk))) + { + ERR("Failed to get graphics pipeline.\n"); + return VK_NULL_HANDLE; + } + VK_CALL(vkCmdBindPipeline(vk_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, context_vk->graphics.vk_pipeline)); + + if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL)) + || wined3d_context_is_graphics_state_dirty(&context_vk->c, + STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX)) + || wined3d_context_is_graphics_state_dirty(&context_vk->c, + STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY)) + || wined3d_context_is_graphics_state_dirty(&context_vk->c, + STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_HULL)) + || wined3d_context_is_graphics_state_dirty(&context_vk->c, + STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_DOMAIN)) + || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_GRAPHICS_SHADER_RESOURCE_BINDING)) + context_vk->c.update_shader_resource_bindings = 1; + if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING)) + context_vk->c.update_unordered_access_view_bindings = 1; + + if (context_vk->c.update_shader_resource_bindings || context_vk->c.update_unordered_access_view_bindings) + { + if (!wined3d_context_vk_update_descriptors(context_vk, vk_command_buffer, state, WINED3D_PIPELINE_GRAPHICS)) + { + ERR("Failed to update shader descriptors.\n"); + return VK_NULL_HANDLE; + } + + context_vk->c.update_shader_resource_bindings = 0; + context_vk->c.update_unordered_access_view_bindings = 0; + } + + memset(context_vk->c.dirty_graphics_states, 0, sizeof(context_vk->c.dirty_graphics_states)); + + return vk_command_buffer; +} + VkCommandBuffer wined3d_context_vk_apply_compute_state(struct wined3d_context_vk *context_vk, const struct wined3d_state *state, struct wined3d_buffer_vk *indirect_vk) { @@ -1710,6 +2009,8 @@ VkCommandBuffer wined3d_context_vk_apply_compute_state(struct wined3d_context_vk const struct wined3d_vk_info *vk_info = context_vk->vk_info; VkCommandBuffer vk_command_buffer;
+ wined3d_context_vk_end_current_render_pass(context_vk); + if (wined3d_context_is_compute_state_dirty(&context_vk->c, STATE_COMPUTE_SHADER)) context_vk->c.shader_update_mask |= 1u << WINED3D_SHADER_TYPE_COMPUTE;
@@ -1727,7 +2028,7 @@ VkCommandBuffer wined3d_context_vk_apply_compute_state(struct wined3d_context_vk context_vk->update_compute_pipeline = 1; }
- wined3d_context_vk_load_shader_resources(context_vk, state); + wined3d_context_vk_load_shader_resources(context_vk, state, WINED3D_PIPELINE_COMPUTE);
if (indirect_vk) wined3d_buffer_load_location(&indirect_vk->b, &context_vk->c, WINED3D_LOCATION_BUFFER); @@ -1754,7 +2055,7 @@ VkCommandBuffer wined3d_context_vk_apply_compute_state(struct wined3d_context_vk if (context_vk->c.update_compute_shader_resource_bindings || context_vk->c.update_compute_unordered_access_view_bindings) { - if (!wined3d_context_vk_update_descriptors(context_vk, vk_command_buffer, state)) + if (!wined3d_context_vk_update_descriptors(context_vk, vk_command_buffer, state, WINED3D_PIPELINE_COMPUTE)) { ERR("Failed to update shader descriptors.\n"); return VK_NULL_HANDLE; diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index de6999105d1..e8a92acab9c 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -6082,18 +6082,6 @@ static void vk_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_c heap_free(blitter); }
-static inline VkImageView wined3d_rendertarget_view_vk_get_image_view(struct wined3d_rendertarget_view_vk *rtv_vk, - struct wined3d_context_vk *context_vk) -{ - struct wined3d_texture_vk *texture_vk; - - if (rtv_vk->vk_image_view) - return rtv_vk->vk_image_view; - - texture_vk = wined3d_texture_vk(wined3d_texture_from_resource(rtv_vk->v.resource)); - return wined3d_texture_vk_get_default_image_info(texture_vk, context_vk)->imageView; -} - static void vk_blitter_clear_rendertargets(struct wined3d_context_vk *context_vk, unsigned int rt_count, const struct wined3d_fb_state *fb, unsigned int rect_count, const RECT *clear_rects, const RECT *draw_rect, uint32_t flags, const struct wined3d_color *colour, float depth, unsigned int stencil) @@ -6225,6 +6213,8 @@ static void vk_blitter_clear_rendertargets(struct wined3d_context_vk *context_vk begin_desc.clearValueCount = attachment_count; begin_desc.pClearValues = clear_values;
+ wined3d_context_vk_end_current_render_pass(context_vk); + for (i = 0; i < rect_count; ++i) { r.left = max(clear_rects[i].left, draw_rect->left); diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index 10fcd695135..28028a76395 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -1547,6 +1547,7 @@ static void wined3d_unordered_access_view_vk_cs_init(void *object) return; }
+ wined3d_context_vk_end_current_render_pass(context_vk); VK_CALL(vkCmdFillBuffer(wined3d_context_vk_get_command_buffer(context_vk), uav_vk->counter_bo.vk_buffer, uav_vk->counter_bo.buffer_offset, sizeof(uint32_t), 0)); wined3d_context_vk_reference_bo(context_vk, &uav_vk->counter_bo); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index fff944f7773..903057fb0ef 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2360,6 +2360,15 @@ struct wined3d_context_vk uint32_t update_compute_pipeline : 1; uint32_t padding : 31;
+ struct + { + VkShaderModule vk_modules[WINED3D_SHADER_TYPE_GRAPHICS_COUNT]; + VkPipeline vk_pipeline; + VkPipelineLayout vk_pipeline_layout; + VkDescriptorSetLayout vk_set_layout; + struct wined3d_shader_resource_bindings bindings; + } graphics; + struct { VkPipeline vk_pipeline; @@ -2381,6 +2390,8 @@ struct wined3d_context_vk
struct wined3d_shader_descriptor_writes_vk descriptor_writes;
+ VkFramebuffer vk_framebuffer; + VkRenderPass vk_render_pass; VkDescriptorPool vk_descriptor_pool;
struct wined3d_retired_objects_vk retired; @@ -2400,6 +2411,8 @@ VkDeviceMemory wined3d_context_vk_allocate_vram_chunk_memory(struct wined3d_cont unsigned int pool, size_t size) DECLSPEC_HIDDEN; VkCommandBuffer wined3d_context_vk_apply_compute_state(struct wined3d_context_vk *context_vk, const struct wined3d_state *state, struct wined3d_buffer_vk *indirect_vk) DECLSPEC_HIDDEN; +VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *context_vk, + const struct wined3d_state *state) DECLSPEC_HIDDEN; void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN; BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type, struct wined3d_bo_vk *bo) DECLSPEC_HIDDEN; @@ -2419,6 +2432,7 @@ void wined3d_context_vk_destroy_memory(struct wined3d_context_vk *context_vk, VkDeviceMemory vk_memory, uint64_t command_buffer_id) DECLSPEC_HIDDEN; void wined3d_context_vk_destroy_sampler(struct wined3d_context_vk *context_vk, VkSampler vk_sampler, uint64_t command_buffer_id) DECLSPEC_HIDDEN; +void wined3d_context_vk_end_current_render_pass(struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN; VkCommandBuffer wined3d_context_vk_get_command_buffer(struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN; struct wined3d_pipeline_layout_vk *wined3d_context_vk_get_pipeline_layout(struct wined3d_context_vk *context_vk, VkDescriptorSetLayoutBinding *bindings, SIZE_T binding_count) DECLSPEC_HIDDEN; @@ -3387,6 +3401,16 @@ struct wined3d_blend_state struct wine_rb_entry entry; };
+static inline unsigned int wined3d_blend_state_get_writemask(const struct wined3d_blend_state *state, + unsigned int index) +{ + if (!state) + return 0xf; + if (!state->desc.independent) + index = 0; + return state->desc.rt[index].writemask; +} + struct wined3d_rasterizer_state { LONG refcount; @@ -4704,6 +4728,18 @@ static inline struct wined3d_rendertarget_view_vk *wined3d_rendertarget_view_vk( return CONTAINING_RECORD(view, struct wined3d_rendertarget_view_vk, v); }
+static inline VkImageView wined3d_rendertarget_view_vk_get_image_view(struct wined3d_rendertarget_view_vk *rtv_vk, + struct wined3d_context_vk *context_vk) +{ + struct wined3d_texture_vk *texture_vk; + + if (rtv_vk->vk_image_view) + return rtv_vk->vk_image_view; + + texture_vk = wined3d_texture_vk(wined3d_texture_from_resource(rtv_vk->v.resource)); + return wined3d_texture_vk_get_default_image_info(texture_vk, context_vk)->imageView; +} + HRESULT wined3d_rendertarget_view_vk_init(struct wined3d_rendertarget_view_vk *view_vk, const struct wined3d_view_desc *desc, struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;