From: Józef Kucia jkucia@codeweavers.com
A NULL RTV is expected to be used when RTVFormat is DXGI_FORMAT_UNKNOWN.
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- libs/vkd3d/command.c | 26 +++++++++++++----- libs/vkd3d/state.c | 55 +++++++++++++++++++++++++------------- libs/vkd3d/vkd3d_private.h | 1 + 3 files changed, 57 insertions(+), 25 deletions(-)
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index abe4f27ecb24..07de716faa04 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -2331,8 +2331,11 @@ static bool d3d12_command_list_update_current_framebuffer(struct d3d12_command_l { struct d3d12_device *device = list->device; const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + VkImageView views[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT + 1]; + struct d3d12_graphics_pipeline_state *graphics; struct VkFramebufferCreateInfo fb_desc; VkFramebuffer vk_framebuffer; + unsigned int view_count; size_t start_idx = 0; unsigned int i; VkResult vr; @@ -2340,24 +2343,35 @@ static bool d3d12_command_list_update_current_framebuffer(struct d3d12_command_l if (list->current_framebuffer != VK_NULL_HANDLE) return true;
- if (!list->state->u.graphics.rt_idx) + graphics = &list->state->u.graphics; + + if (!graphics->rt_idx) ++start_idx;
- for (i = 0; i < list->state->u.graphics.attachment_count; ++i) + for (i = 0, view_count = 0; i < graphics->attachment_count; ++i) { + if (graphics->null_attachment_mask & (1u << i)) + { + if (list->views[start_idx + i]) + WARN("Expected NULL view for attachment %u.\n", i); + continue; + } + if (!list->views[start_idx + i]) { - FIXME("Invalid attachment %u.\n", i); + FIXME("Invalid view for attachment %u.\n", i); return false; } + + views[view_count++] = list->views[start_idx + i]; }
fb_desc.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; fb_desc.pNext = NULL; fb_desc.flags = 0; - fb_desc.renderPass = list->state->u.graphics.render_pass; - fb_desc.attachmentCount = list->state->u.graphics.attachment_count; - fb_desc.pAttachments = &list->views[start_idx]; + fb_desc.renderPass = graphics->render_pass; + fb_desc.attachmentCount = view_count; + fb_desc.pAttachments = views; d3d12_command_list_get_fb_extent(list, &fb_desc.width, &fb_desc.height, &fb_desc.layers); if ((vr = VK_CALL(vkCreateFramebuffer(device->vk_device, &fb_desc, NULL, &vk_framebuffer))) < 0) { diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 2b7059ccb390..bc59b0187294 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -1049,11 +1049,11 @@ static HRESULT vkd3d_render_pass_cache_create_pass_locked(struct vkd3d_render_pa VkAttachmentDescription attachments[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT + 1]; const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; struct vkd3d_render_pass_entry *entry; + unsigned int index, attachment_index; unsigned int color_attachment_index; VkSubpassDescription sub_pass_desc; VkRenderPassCreateInfo pass_info; bool have_depth_stencil; - unsigned int index; VkResult vr;
if (!vkd3d_array_reserve((void **)&cache->render_passes, &cache->render_passes_size, @@ -1104,28 +1104,37 @@ static HRESULT vkd3d_render_pass_cache_create_pass_locked(struct vkd3d_render_pa attachments[index].initialLayout = depth_layout; attachments[index].finalLayout = depth_layout;
- attachment_references[index].attachment = 0; + attachment_references[index].attachment = index; attachment_references[index].layout = depth_layout;
++index; }
+ attachment_index = index; assert(index == color_attachment_index); for (; index < key->attachment_count; ++index) { + if (!key->vk_formats[index]) + { + attachment_references[index].attachment = VK_ATTACHMENT_UNUSED; + attachment_references[index].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + continue; + }
- attachments[index].flags = 0; - attachments[index].format = key->vk_formats[index]; - attachments[index].samples = key->sample_count; - attachments[index].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachments[index].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[index].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[index].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[index].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attachments[index].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - attachment_references[index].attachment = index; + attachments[attachment_index].flags = 0; + attachments[attachment_index].format = key->vk_formats[index]; + attachments[attachment_index].samples = key->sample_count; + attachments[attachment_index].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + attachments[attachment_index].storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachments[attachment_index].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachments[attachment_index].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachments[attachment_index].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachments[attachment_index].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + attachment_references[index].attachment = attachment_index; attachment_references[index].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + ++attachment_index; }
sub_pass_desc.flags = 0; @@ -1145,7 +1154,7 @@ static HRESULT vkd3d_render_pass_cache_create_pass_locked(struct vkd3d_render_pa pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; pass_info.pNext = NULL; pass_info.flags = 0; - pass_info.attachmentCount = key->attachment_count; + pass_info.attachmentCount = attachment_index; pass_info.pAttachments = attachments; pass_info.subpassCount = 1; pass_info.pSubpasses = &sub_pass_desc; @@ -2140,6 +2149,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s FIXME("DSV format is DXGI_FORMAT_UNKNOWN, disabling depth/stencil tests.\n");
graphics->rt_idx = 0; + graphics->null_attachment_mask = 0; if (desc->DSVFormat != DXGI_FORMAT_UNKNOWN && (desc->DepthStencilState.DepthEnable || desc->DepthStencilState.StencilEnable)) { @@ -2183,7 +2193,18 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s const D3D12_RENDER_TARGET_BLEND_DESC *rt_desc; size_t idx = graphics->rt_idx + i;
- if (!(format = vkd3d_get_format(device, desc->RTVFormats[i], false))) + if (desc->RTVFormats[i] == DXGI_FORMAT_UNKNOWN) + { + graphics->null_attachment_mask |= 1u << idx; + ps_output_swizzle[i] = VKD3D_NO_SWIZZLE; + render_pass_key.vk_formats[idx] = VK_FORMAT_UNDEFINED; + } + else if ((format = vkd3d_get_format(device, desc->RTVFormats[i], false))) + { + ps_output_swizzle[i] = vkd3d_get_rt_format_swizzle(format); + render_pass_key.vk_formats[idx] = format->vk_format; + } + else { WARN("Invalid RTV format %#x.\n", desc->RTVFormats[i]); hr = E_INVALIDARG; @@ -2204,10 +2225,6 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s goto fail; }
- ps_output_swizzle[i] = vkd3d_get_rt_format_swizzle(format); - - render_pass_key.vk_formats[idx] = format->vk_format; - blend_attachment_from_d3d12(&graphics->blend_attachments[i], rt_desc); } graphics->attachment_count = graphics->rt_idx + rt_count; diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 057a0a7c0dea..b5beffaf5d5e 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -675,6 +675,7 @@ struct d3d12_graphics_pipeline_state
VkPipelineColorBlendAttachmentState blend_attachments[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT]; unsigned int attachment_count, rt_idx; + unsigned int null_attachment_mask; VkRenderPass render_pass;
D3D12_INDEX_BUFFER_STRIP_CUT_VALUE index_buffer_strip_cut_value;