vkd3d: Implement COLOR -> STENCIL copy if stencil export is supported.
Fallback is a bit more involved. Cleans up the FIXME to not report benign issues. Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
parent
29d956c6c4
commit
81a215d0bf
|
@ -5994,6 +5994,7 @@ static void d3d12_command_list_copy_image(struct d3d12_command_list *list,
|
||||||
pipeline_key.view_type = vkd3d_meta_get_copy_image_view_type(dst_resource->desc.Dimension);
|
pipeline_key.view_type = vkd3d_meta_get_copy_image_view_type(dst_resource->desc.Dimension);
|
||||||
pipeline_key.sample_count = vk_samples_from_dxgi_sample_desc(&dst_resource->desc.SampleDesc);
|
pipeline_key.sample_count = vk_samples_from_dxgi_sample_desc(&dst_resource->desc.SampleDesc);
|
||||||
pipeline_key.layout = dst_layout;
|
pipeline_key.layout = dst_layout;
|
||||||
|
pipeline_key.dst_aspect_mask = region->dstSubresource.aspectMask;
|
||||||
|
|
||||||
if (FAILED(hr = vkd3d_meta_get_copy_image_pipeline(&list->device->meta_ops, &pipeline_key, &pipeline_info)))
|
if (FAILED(hr = vkd3d_meta_get_copy_image_pipeline(&list->device->meta_ops, &pipeline_key, &pipeline_info)))
|
||||||
{
|
{
|
||||||
|
@ -6364,12 +6365,17 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(d3d12_command
|
||||||
&src_resource->desc, &dst_resource->desc, src_format, dst_format,
|
&src_resource->desc, &dst_resource->desc, src_format, dst_format,
|
||||||
src_box, dst_x, dst_y, dst_z);
|
src_box, dst_x, dst_y, dst_z);
|
||||||
|
|
||||||
if ((dst_format->vk_aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT)
|
/* If aspect masks do not match, we have to use fallback copies with a render pass, and there
|
||||||
&& (dst_format->vk_aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT)
|
* is no standard way to write to stencil without fallbacks.
|
||||||
&& (image_copy.dstSubresource.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT))
|
* Checking aspect masks here is equivalent to checking formats. vkCmdCopyImage can only be
|
||||||
|
* used for compatible formats and depth stencil formats are only compatible with themselves. */
|
||||||
|
if (dst_format->vk_aspect_mask != src_format->vk_aspect_mask &&
|
||||||
|
(image_copy.dstSubresource.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) &&
|
||||||
|
!list->device->vk_info.EXT_shader_stencil_export)
|
||||||
{
|
{
|
||||||
FIXME("Destination depth-stencil format %#x is not supported for STENCIL dst copy.\n",
|
FIXME("Destination depth-stencil format %#x is not supported for STENCIL dst copy with render pass fallback.\n",
|
||||||
dst_format->dxgi_format);
|
dst_format->dxgi_format);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
writes_full_subresource = d3d12_image_copy_writes_full_subresource(dst_resource,
|
writes_full_subresource = d3d12_image_copy_writes_full_subresource(dst_resource,
|
||||||
|
|
|
@ -19,6 +19,7 @@ vkd3d_shaders =[
|
||||||
|
|
||||||
'shaders/fs_copy_image_float.frag',
|
'shaders/fs_copy_image_float.frag',
|
||||||
'shaders/fs_copy_image_uint.frag',
|
'shaders/fs_copy_image_uint.frag',
|
||||||
|
'shaders/fs_copy_image_stencil.frag',
|
||||||
|
|
||||||
'shaders/gs_fullscreen.geom',
|
'shaders/gs_fullscreen.geom',
|
||||||
'shaders/vs_fullscreen.vert',
|
'shaders/vs_fullscreen.vert',
|
||||||
|
|
|
@ -606,6 +606,16 @@ HRESULT vkd3d_copy_image_ops_init(struct vkd3d_copy_image_ops *meta_copy_image_o
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (device->vk_info.EXT_shader_stencil_export)
|
||||||
|
{
|
||||||
|
if ((vr = vkd3d_meta_create_shader_module(device, SPIRV_CODE(fs_copy_image_stencil),
|
||||||
|
&meta_copy_image_ops->vk_fs_stencil_module)) < 0)
|
||||||
|
{
|
||||||
|
ERR("Failed to create shader modules, vr %d.\n", vr);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -631,6 +641,7 @@ void vkd3d_copy_image_ops_cleanup(struct vkd3d_copy_image_ops *meta_copy_image_o
|
||||||
VK_CALL(vkDestroyPipelineLayout(device->vk_device, meta_copy_image_ops->vk_pipeline_layout, NULL));
|
VK_CALL(vkDestroyPipelineLayout(device->vk_device, meta_copy_image_ops->vk_pipeline_layout, NULL));
|
||||||
VK_CALL(vkDestroyShaderModule(device->vk_device, meta_copy_image_ops->vk_fs_float_module, NULL));
|
VK_CALL(vkDestroyShaderModule(device->vk_device, meta_copy_image_ops->vk_fs_float_module, NULL));
|
||||||
VK_CALL(vkDestroyShaderModule(device->vk_device, meta_copy_image_ops->vk_fs_uint_module, NULL));
|
VK_CALL(vkDestroyShaderModule(device->vk_device, meta_copy_image_ops->vk_fs_uint_module, NULL));
|
||||||
|
VK_CALL(vkDestroyShaderModule(device->vk_device, meta_copy_image_ops->vk_fs_stencil_module, NULL));
|
||||||
|
|
||||||
pthread_mutex_destroy(&meta_copy_image_ops->mutex);
|
pthread_mutex_destroy(&meta_copy_image_ops->mutex);
|
||||||
|
|
||||||
|
@ -793,13 +804,30 @@ static HRESULT vkd3d_meta_create_copy_image_pipeline(struct vkd3d_meta_ops *meta
|
||||||
ds_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
ds_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||||
ds_state.pNext = NULL;
|
ds_state.pNext = NULL;
|
||||||
ds_state.flags = 0;
|
ds_state.flags = 0;
|
||||||
ds_state.depthTestEnable = VK_TRUE;
|
ds_state.depthTestEnable = (key->dst_aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) ? VK_TRUE : VK_FALSE;
|
||||||
ds_state.depthWriteEnable = VK_TRUE;
|
ds_state.depthWriteEnable = ds_state.depthTestEnable;
|
||||||
ds_state.depthCompareOp = VK_COMPARE_OP_ALWAYS;
|
ds_state.depthCompareOp = VK_COMPARE_OP_ALWAYS;
|
||||||
ds_state.depthBoundsTestEnable = VK_FALSE;
|
ds_state.depthBoundsTestEnable = VK_FALSE;
|
||||||
ds_state.stencilTestEnable = VK_FALSE;
|
|
||||||
memset(&ds_state.front, 0, sizeof(ds_state.front));
|
if (key->dst_aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT)
|
||||||
memset(&ds_state.back, 0, sizeof(ds_state.back));
|
{
|
||||||
|
ds_state.stencilTestEnable = VK_TRUE;
|
||||||
|
ds_state.front.reference = 0;
|
||||||
|
ds_state.front.writeMask = 0xff;
|
||||||
|
ds_state.front.compareMask = 0xff;
|
||||||
|
ds_state.front.passOp = VK_STENCIL_OP_REPLACE;
|
||||||
|
ds_state.front.failOp = VK_STENCIL_OP_KEEP;
|
||||||
|
ds_state.front.depthFailOp = VK_STENCIL_OP_KEEP;
|
||||||
|
ds_state.front.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||||
|
ds_state.back = ds_state.front;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ds_state.stencilTestEnable = VK_FALSE;
|
||||||
|
memset(&ds_state.front, 0, sizeof(ds_state.front));
|
||||||
|
memset(&ds_state.back, 0, sizeof(ds_state.back));
|
||||||
|
}
|
||||||
|
|
||||||
ds_state.minDepthBounds = 0.0f;
|
ds_state.minDepthBounds = 0.0f;
|
||||||
ds_state.maxDepthBounds = 1.0f;
|
ds_state.maxDepthBounds = 1.0f;
|
||||||
|
|
||||||
|
@ -822,11 +850,21 @@ static HRESULT vkd3d_meta_create_copy_image_pipeline(struct vkd3d_meta_ops *meta
|
||||||
key->sample_count, key->format, key->layout, &pipeline->vk_render_pass)) < 0)
|
key->sample_count, key->format, key->layout, &pipeline->vk_render_pass)) < 0)
|
||||||
return hresult_from_vk_result(vr);
|
return hresult_from_vk_result(vr);
|
||||||
|
|
||||||
/* Special path when copying stencil -> color. */
|
|
||||||
if (key->format->vk_format == VK_FORMAT_R8_UINT)
|
if (key->format->vk_format == VK_FORMAT_R8_UINT)
|
||||||
|
{
|
||||||
|
/* Special path when copying stencil -> color. */
|
||||||
vk_module = meta_copy_image_ops->vk_fs_uint_module;
|
vk_module = meta_copy_image_ops->vk_fs_uint_module;
|
||||||
|
}
|
||||||
|
else if (key->dst_aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT)
|
||||||
|
{
|
||||||
|
/* FragStencilRef path. */
|
||||||
|
vk_module = meta_copy_image_ops->vk_fs_stencil_module;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
/* Depth or float color path. */
|
||||||
vk_module = meta_copy_image_ops->vk_fs_float_module;
|
vk_module = meta_copy_image_ops->vk_fs_float_module;
|
||||||
|
}
|
||||||
|
|
||||||
if ((vr = vkd3d_meta_create_graphics_pipeline(meta_ops,
|
if ((vr = vkd3d_meta_create_graphics_pipeline(meta_ops,
|
||||||
meta_copy_image_ops->vk_pipeline_layout, pipeline->vk_render_pass,
|
meta_copy_image_ops->vk_pipeline_layout, pipeline->vk_render_pass,
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
#extension GL_EXT_samplerless_texture_functions : enable
|
||||||
|
#extension GL_ARB_shader_stencil_export : enable
|
||||||
|
|
||||||
|
#define MODE_1D 0
|
||||||
|
#define MODE_2D 1
|
||||||
|
#define MODE_MS 2
|
||||||
|
|
||||||
|
layout(constant_id = 0) const uint c_mode = MODE_2D;
|
||||||
|
|
||||||
|
layout(binding = 0) uniform utexture1DArray tex_1d;
|
||||||
|
layout(binding = 0) uniform utexture2DArray tex_2d;
|
||||||
|
layout(binding = 0) uniform utexture2DMSArray tex_ms;
|
||||||
|
|
||||||
|
layout(push_constant)
|
||||||
|
uniform u_info_t {
|
||||||
|
ivec2 offset;
|
||||||
|
} u_info;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
ivec3 coord = ivec3(u_info.offset + ivec2(gl_FragCoord.xy), gl_Layer);
|
||||||
|
uint value;
|
||||||
|
if (c_mode == MODE_1D) value = texelFetch(tex_1d, coord.xz, 0).r;
|
||||||
|
if (c_mode == MODE_2D) value = texelFetch(tex_2d, coord, 0).r;
|
||||||
|
if (c_mode == MODE_MS) value = texelFetch(tex_ms, coord, gl_SampleID).r;
|
||||||
|
gl_FragStencilRefARB = int(value);
|
||||||
|
}
|
|
@ -2481,6 +2481,7 @@ struct vkd3d_copy_image_pipeline_key
|
||||||
VkImageViewType view_type;
|
VkImageViewType view_type;
|
||||||
VkSampleCountFlagBits sample_count;
|
VkSampleCountFlagBits sample_count;
|
||||||
VkImageLayout layout;
|
VkImageLayout layout;
|
||||||
|
VkImageAspectFlags dst_aspect_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vkd3d_copy_image_pipeline
|
struct vkd3d_copy_image_pipeline
|
||||||
|
@ -2497,6 +2498,7 @@ struct vkd3d_copy_image_ops
|
||||||
VkPipelineLayout vk_pipeline_layout;
|
VkPipelineLayout vk_pipeline_layout;
|
||||||
VkShaderModule vk_fs_float_module;
|
VkShaderModule vk_fs_float_module;
|
||||||
VkShaderModule vk_fs_uint_module;
|
VkShaderModule vk_fs_uint_module;
|
||||||
|
VkShaderModule vk_fs_stencil_module;
|
||||||
|
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ enum vkd3d_meta_copy_mode
|
||||||
#include <gs_fullscreen.h>
|
#include <gs_fullscreen.h>
|
||||||
#include <fs_copy_image_float.h>
|
#include <fs_copy_image_float.h>
|
||||||
#include <fs_copy_image_uint.h>
|
#include <fs_copy_image_uint.h>
|
||||||
|
#include <fs_copy_image_stencil.h>
|
||||||
#include <vs_swapchain_fullscreen.h>
|
#include <vs_swapchain_fullscreen.h>
|
||||||
#include <fs_swapchain_fullscreen.h>
|
#include <fs_swapchain_fullscreen.h>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue