wined3d: Implement Vulkan draws.
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a282a8e765
commit
eccff1add8
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 void wined3d_context_vk_load_shader_resources(struct wined3d_context_vk *context_vk,
|
||||
const struct wined3d_state *state)
|
||||
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, 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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue