Signed-off-by: Henri Verbeet <hverbeet(a)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;
--
2.20.1