diff --git a/libs/vkd3d/meson.build b/libs/vkd3d/meson.build index 46ad8ee0..45594369 100644 --- a/libs/vkd3d/meson.build +++ b/libs/vkd3d/meson.build @@ -20,6 +20,7 @@ vkd3d_shaders =[ 'shaders/vs_swapchain_fullscreen.vert', 'shaders/fs_swapchain_fullscreen.frag', + 'shaders/cs_swapchain_fullscreen.comp', ] vkd3d_src = [ diff --git a/libs/vkd3d/meta.c b/libs/vkd3d/meta.c index 8bbd624e..a4be6a43 100644 --- a/libs/vkd3d/meta.c +++ b/libs/vkd3d/meta.c @@ -923,7 +923,9 @@ static void vkd3d_meta_ops_common_cleanup(struct vkd3d_meta_ops_common *meta_ops HRESULT vkd3d_swapchain_ops_init(struct vkd3d_swapchain_ops *meta_swapchain_ops, struct d3d12_device *device) { - VkDescriptorSetLayoutBinding set_binding; + VkDescriptorSetLayoutBinding set_binding_srv, set_binding_uav; + VkDescriptorSetLayout set_layouts[2]; + VkPushConstantRange push_range; unsigned int i; VkResult vr; int rc; @@ -936,10 +938,26 @@ HRESULT vkd3d_swapchain_ops_init(struct vkd3d_swapchain_ops *meta_swapchain_ops, return hresult_from_errno(rc); } - set_binding.binding = 0; - set_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - set_binding.descriptorCount = 1; - set_binding.stageFlags = VK_SHADER_STAGE_ALL; /* Could be compute or graphics, so just use ALL. */ + set_binding_srv.binding = 0; + set_binding_srv.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + set_binding_srv.descriptorCount = 1; + set_binding_srv.stageFlags = VK_SHADER_STAGE_ALL; /* Could be compute or graphics, so just use ALL. */ + + set_binding_uav.binding = 0; + set_binding_uav.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + set_binding_uav.descriptorCount = 1; + set_binding_uav.stageFlags = VK_SHADER_STAGE_ALL; /* Could be compute or graphics, so just use ALL. */ + + push_range.stageFlags = VK_SHADER_STAGE_ALL; + push_range.offset = 0; + push_range.size = sizeof(struct vkd3d_swapchain_push_parameters); + + if ((vr = vkd3d_meta_create_descriptor_set_layout(device, 1, &set_binding_uav, + &meta_swapchain_ops->vk_set_layout_uav)) < 0) + { + ERR("Failed to create descriptor set layout, vr %d.\n", vr); + goto fail; + } for (i = 0; i < 2; i++) { @@ -949,16 +967,18 @@ HRESULT vkd3d_swapchain_ops_init(struct vkd3d_swapchain_ops *meta_swapchain_ops, goto fail; } - set_binding.pImmutableSamplers = &meta_swapchain_ops->vk_samplers[i]; - if ((vr = vkd3d_meta_create_descriptor_set_layout(device, 1, &set_binding, - &meta_swapchain_ops->vk_set_layouts[i])) < 0) + set_binding_srv.pImmutableSamplers = &meta_swapchain_ops->vk_samplers[i]; + if ((vr = vkd3d_meta_create_descriptor_set_layout(device, 1, &set_binding_srv, + &meta_swapchain_ops->vk_set_layouts_srv[i])) < 0) { ERR("Failed to create descriptor set layout, vr %d.\n", vr); goto fail; } - if ((vr = vkd3d_meta_create_pipeline_layout(device, 1, &meta_swapchain_ops->vk_set_layouts[i], - 0, NULL, &meta_swapchain_ops->vk_pipeline_layouts[i]))) + set_layouts[0] = meta_swapchain_ops->vk_set_layouts_srv[i]; + set_layouts[1] = meta_swapchain_ops->vk_set_layout_uav; + if ((vr = vkd3d_meta_create_pipeline_layout(device, 2, set_layouts, + 1, &push_range, &meta_swapchain_ops->vk_pipeline_layouts[i]))) { ERR("Failed to create pipeline layout, vr %d.\n", vr); goto fail; @@ -999,10 +1019,11 @@ void vkd3d_swapchain_ops_cleanup(struct vkd3d_swapchain_ops *meta_swapchain_ops, for (i = 0; i < 2; i++) { - VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, meta_swapchain_ops->vk_set_layouts[i], NULL)); + VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, meta_swapchain_ops->vk_set_layouts_srv[i], NULL)); VK_CALL(vkDestroyPipelineLayout(device->vk_device, meta_swapchain_ops->vk_pipeline_layouts[i], NULL)); VK_CALL(vkDestroySampler(device->vk_device, meta_swapchain_ops->vk_samplers[i], NULL)); } + VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, meta_swapchain_ops->vk_set_layout_uav, NULL)); VK_CALL(vkDestroyShaderModule(device->vk_device, meta_swapchain_ops->vk_vs_module, NULL)); VK_CALL(vkDestroyShaderModule(device->vk_device, meta_swapchain_ops->vk_fs_module, NULL)); @@ -1026,7 +1047,8 @@ HRESULT vkd3d_meta_get_swapchain_pipeline(struct vkd3d_meta_ops *meta_ops, return hresult_from_errno(rc); } - info->vk_set_layout = meta_swapchain_ops->vk_set_layouts[key->filter]; + info->vk_set_layout_srv = meta_swapchain_ops->vk_set_layouts_srv[key->filter]; + info->vk_set_layout_uav = meta_swapchain_ops->vk_set_layout_uav; info->vk_pipeline_layout = meta_swapchain_ops->vk_pipeline_layouts[key->filter]; for (i = 0; i < meta_swapchain_ops->pipeline_count; i++) @@ -1059,8 +1081,6 @@ HRESULT vkd3d_meta_get_swapchain_pipeline(struct vkd3d_meta_ops *meta_ops, info->vk_render_pass = pipeline->vk_render_pass; info->vk_pipeline = pipeline->vk_pipeline; - info->vk_set_layout = meta_swapchain_ops->vk_set_layouts[key->filter]; - info->vk_pipeline_layout = meta_swapchain_ops->vk_pipeline_layouts[key->filter]; pthread_mutex_unlock(&meta_swapchain_ops->mutex); return S_OK; diff --git a/libs/vkd3d/shaders/cs_swapchain_fullscreen.comp b/libs/vkd3d/shaders/cs_swapchain_fullscreen.comp new file mode 100644 index 00000000..df91214a --- /dev/null +++ b/libs/vkd3d/shaders/cs_swapchain_fullscreen.comp @@ -0,0 +1,21 @@ +#version 450 +layout(local_size_x = 8, local_size_y = 8) in; + +layout(set = 1, binding = 0) writeonly uniform image2D FragColor; +layout(set = 0, binding = 0) uniform sampler2D Tex; + +layout(push_constant, std430) uniform Registers +{ + uvec2 output_resolution; + vec2 coord_scale; +} registers; + +void main() +{ + if (any(greaterThanEqual(gl_GlobalInvocationID.xy, registers.output_resolution))) + return; + vec2 frag_coord = vec2(gl_GlobalInvocationID.xy) + 0.5; + vec2 tex_coord = frag_coord * registers.coord_scale; + vec4 color = textureLod(Tex, tex_coord, 0.0); + imageStore(FragColor, ivec2(gl_GlobalInvocationID.xy), color); +} diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 8596e1cf..c6941a46 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -1725,7 +1725,8 @@ struct vkd3d_swapchain_pipeline_key struct vkd3d_swapchain_info { - VkDescriptorSetLayout vk_set_layout; + VkDescriptorSetLayout vk_set_layout_srv; + VkDescriptorSetLayout vk_set_layout_uav; VkPipelineLayout vk_pipeline_layout; VkRenderPass vk_render_pass; VkPipeline vk_pipeline; @@ -1740,7 +1741,8 @@ struct vkd3d_swapchain_pipeline struct vkd3d_swapchain_ops { - VkDescriptorSetLayout vk_set_layouts[2]; + VkDescriptorSetLayout vk_set_layouts_srv[2]; + VkDescriptorSetLayout vk_set_layout_uav; VkPipelineLayout vk_pipeline_layouts[2]; VkShaderModule vk_vs_module; VkShaderModule vk_fs_module; @@ -1753,6 +1755,12 @@ struct vkd3d_swapchain_ops size_t pipeline_count; }; +struct vkd3d_swapchain_push_parameters +{ + uint32_t output_width, output_height; + float coord_scale_x, coord_scale_y; +}; + HRESULT vkd3d_swapchain_ops_init(struct vkd3d_swapchain_ops *meta_swapchain_ops, struct d3d12_device *device); void vkd3d_swapchain_ops_cleanup(struct vkd3d_swapchain_ops *meta_swapchain_ops, diff --git a/libs/vkd3d/vkd3d_shaders.h b/libs/vkd3d/vkd3d_shaders.h index 6b5e2720..a62f1f9b 100644 --- a/libs/vkd3d/vkd3d_shaders.h +++ b/libs/vkd3d/vkd3d_shaders.h @@ -46,5 +46,6 @@ enum vkd3d_meta_copy_mode #include #include #include +#include #endif /* __VKD3D_SPV_SHADERS_H */