libs/vkd3d: Implement depth/stencil pipeline state attachments.

This commit is contained in:
Henri Verbeet
2016-11-02 21:03:47 +01:00
parent fa4072a892
commit d97df34093
3 changed files with 191 additions and 33 deletions

View File

@ -1373,17 +1373,21 @@ static bool d3d12_command_list_update_current_framebuffer(struct d3d12_command_l
{ {
struct VkFramebufferCreateInfo fb_desc; struct VkFramebufferCreateInfo fb_desc;
VkFramebuffer vk_framebuffer; VkFramebuffer vk_framebuffer;
size_t start_idx = 0;
VkResult vr; VkResult vr;
if (list->current_framebuffer != VK_NULL_HANDLE) if (list->current_framebuffer != VK_NULL_HANDLE)
return true; return true;
if (!list->state->u.graphics.rt_idx)
++start_idx;
fb_desc.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; fb_desc.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
fb_desc.pNext = NULL; fb_desc.pNext = NULL;
fb_desc.flags = 0; fb_desc.flags = 0;
fb_desc.renderPass = list->state->u.graphics.render_pass; fb_desc.renderPass = list->state->u.graphics.render_pass;
fb_desc.attachmentCount = list->state->u.graphics.attachment_count; fb_desc.attachmentCount = list->state->u.graphics.attachment_count;
fb_desc.pAttachments = list->views; fb_desc.pAttachments = &list->views[start_idx];
fb_desc.width = list->fb_width; fb_desc.width = list->fb_width;
fb_desc.height = list->fb_height; fb_desc.height = list->fb_height;
fb_desc.layers = 1; fb_desc.layers = 1;
@ -1491,7 +1495,7 @@ static bool d3d12_command_list_update_current_pipeline(struct d3d12_command_list
/* FIXME: Logic ops are per-target in D3D. */ /* FIXME: Logic ops are per-target in D3D. */
blend_desc.logicOpEnable = VK_FALSE; blend_desc.logicOpEnable = VK_FALSE;
blend_desc.logicOp = VK_LOGIC_OP_COPY; blend_desc.logicOp = VK_LOGIC_OP_COPY;
blend_desc.attachmentCount = state->attachment_count; blend_desc.attachmentCount = state->attachment_count - state->rt_idx;
blend_desc.pAttachments = state->blend_attachments; blend_desc.pAttachments = state->blend_attachments;
blend_desc.blendConstants[0] = D3D12_DEFAULT_BLEND_FACTOR_RED; blend_desc.blendConstants[0] = D3D12_DEFAULT_BLEND_FACTOR_RED;
blend_desc.blendConstants[1] = D3D12_DEFAULT_BLEND_FACTOR_GREEN; blend_desc.blendConstants[1] = D3D12_DEFAULT_BLEND_FACTOR_GREEN;
@ -1509,7 +1513,7 @@ static bool d3d12_command_list_update_current_pipeline(struct d3d12_command_list
pipeline_desc.pViewportState = &vp_desc; pipeline_desc.pViewportState = &vp_desc;
pipeline_desc.pRasterizationState = &state->rs_desc; pipeline_desc.pRasterizationState = &state->rs_desc;
pipeline_desc.pMultisampleState = &state->ms_desc; pipeline_desc.pMultisampleState = &state->ms_desc;
pipeline_desc.pDepthStencilState = NULL; pipeline_desc.pDepthStencilState = &state->ds_desc;
pipeline_desc.pColorBlendState = &blend_desc; pipeline_desc.pColorBlendState = &blend_desc;
pipeline_desc.pDynamicState = &dynamic_desc; pipeline_desc.pDynamicState = &dynamic_desc;
pipeline_desc.layout = state->root_signature->vk_pipeline_layout; pipeline_desc.layout = state->root_signature->vk_pipeline_layout;
@ -2207,14 +2211,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi
iface, render_target_descriptor_count, render_target_descriptors, iface, render_target_descriptor_count, render_target_descriptors,
single_descriptor_handle, depth_stencil_descriptor); single_descriptor_handle, depth_stencil_descriptor);
if (depth_stencil_descriptor) if (render_target_descriptor_count > ARRAY_SIZE(list->views) - 1)
FIXME("Ignoring depth/stencil descriptor %p.\n", depth_stencil_descriptor);
if (render_target_descriptor_count > ARRAY_SIZE(list->views))
{ {
WARN("Descriptor count %u > %zu, ignoring extra descriptors.\n", WARN("Descriptor count %u > %zu, ignoring extra descriptors.\n",
render_target_descriptor_count, ARRAY_SIZE(list->views)); render_target_descriptor_count, ARRAY_SIZE(list->views) - 1);
render_target_descriptor_count = ARRAY_SIZE(list->views); render_target_descriptor_count = ARRAY_SIZE(list->views) - 1;
} }
list->fb_width = 0; list->fb_width = 0;
@ -2225,13 +2226,22 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi
d3d12_command_list_track_resource_usage(list, rtv_desc->resource); d3d12_command_list_track_resource_usage(list, rtv_desc->resource);
list->views[i] = rtv_desc->vk_view; list->views[i + 1] = rtv_desc->vk_view;
if (rtv_desc->width > list->fb_width) if (rtv_desc->width > list->fb_width)
list->fb_width = rtv_desc->width; list->fb_width = rtv_desc->width;
if (rtv_desc->height > list->fb_height) if (rtv_desc->height > list->fb_height)
list->fb_height = rtv_desc->height; list->fb_height = rtv_desc->height;
} }
if (depth_stencil_descriptor)
{
const struct d3d12_dsv_desc *dsv_desc = (const struct d3d12_dsv_desc *)depth_stencil_descriptor->ptr;
d3d12_command_list_track_resource_usage(list, dsv_desc->resource);
list->views[0] = dsv_desc->vk_view;
}
d3d12_command_list_invalidate_current_framebuffer(list); d3d12_command_list_invalidate_current_framebuffer(list);
} }

View File

@ -502,6 +502,104 @@ static void rs_desc_from_d3d12(struct VkPipelineRasterizationStateCreateInfo *vk
FIXME("Ignoring ConservativeRaster %#x.\n", d3d12_desc->ConservativeRaster); FIXME("Ignoring ConservativeRaster %#x.\n", d3d12_desc->ConservativeRaster);
} }
static enum VkStencilOp vk_stencil_op_from_d3d12(D3D12_STENCIL_OP op)
{
switch (op)
{
case D3D12_STENCIL_OP_KEEP:
return VK_STENCIL_OP_KEEP;
case D3D12_STENCIL_OP_ZERO:
return VK_STENCIL_OP_ZERO;
case D3D12_STENCIL_OP_REPLACE:
return VK_STENCIL_OP_REPLACE;
case D3D12_STENCIL_OP_INCR_SAT:
return VK_STENCIL_OP_INCREMENT_AND_CLAMP;
case D3D12_STENCIL_OP_DECR_SAT:
return VK_STENCIL_OP_DECREMENT_AND_CLAMP;
case D3D12_STENCIL_OP_INVERT:
return VK_STENCIL_OP_INVERT;
case D3D12_STENCIL_OP_INCR:
return VK_STENCIL_OP_INCREMENT_AND_WRAP;
case D3D12_STENCIL_OP_DECR:
return VK_STENCIL_OP_DECREMENT_AND_WRAP;
default:
FIXME("Unhandled stencil op %#x.\n", op);
return VK_STENCIL_OP_KEEP;
}
}
static enum VkCompareOp vk_compare_op_from_d3d12(D3D12_COMPARISON_FUNC op)
{
switch (op)
{
case D3D12_COMPARISON_FUNC_NEVER:
return VK_COMPARE_OP_NEVER;
case D3D12_COMPARISON_FUNC_LESS:
return VK_COMPARE_OP_LESS;
case D3D12_COMPARISON_FUNC_EQUAL:
return VK_COMPARE_OP_EQUAL;
case D3D12_COMPARISON_FUNC_LESS_EQUAL:
return VK_COMPARE_OP_LESS_OR_EQUAL;
case D3D12_COMPARISON_FUNC_GREATER:
return VK_COMPARE_OP_GREATER;
case D3D12_COMPARISON_FUNC_NOT_EQUAL:
return VK_COMPARE_OP_NOT_EQUAL;
case D3D12_COMPARISON_FUNC_GREATER_EQUAL:
return VK_COMPARE_OP_GREATER_OR_EQUAL;
case D3D12_COMPARISON_FUNC_ALWAYS:
return VK_COMPARE_OP_ALWAYS;
default:
FIXME("Unhandled compare op %#x.\n", op);
return VK_COMPARE_OP_NEVER;
}
}
static void vk_stencil_op_state_from_d3d12(struct VkStencilOpState *vk_desc,
const D3D12_DEPTH_STENCILOP_DESC *d3d12_desc, uint32_t compare_mask, uint32_t write_mask)
{
vk_desc->failOp = vk_stencil_op_from_d3d12(d3d12_desc->StencilFailOp);
vk_desc->passOp = vk_stencil_op_from_d3d12(d3d12_desc->StencilPassOp);
vk_desc->depthFailOp = vk_stencil_op_from_d3d12(d3d12_desc->StencilDepthFailOp);
vk_desc->compareOp = vk_compare_op_from_d3d12(d3d12_desc->StencilFunc);
vk_desc->compareMask = compare_mask;
vk_desc->writeMask = write_mask;
vk_desc->reference = 0; /* FIXME: From OMSetStencilRef(). */
}
static void ds_desc_from_d3d12(struct VkPipelineDepthStencilStateCreateInfo *vk_desc,
const D3D12_DEPTH_STENCIL_DESC *d3d12_desc)
{
memset(vk_desc, 0, sizeof(*vk_desc));
vk_desc->sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
vk_desc->pNext = NULL;
vk_desc->flags = 0;
if ((vk_desc->depthTestEnable = d3d12_desc->DepthEnable))
{
vk_desc->depthWriteEnable = d3d12_desc->DepthWriteMask & D3D12_DEPTH_WRITE_MASK_ALL;
vk_desc->depthCompareOp = vk_compare_op_from_d3d12(d3d12_desc->DepthFunc);
}
else
{
vk_desc->depthWriteEnable = VK_FALSE;
vk_desc->depthCompareOp = VK_COMPARE_OP_NEVER;
}
vk_desc->depthBoundsTestEnable = VK_FALSE;
if ((vk_desc->stencilTestEnable = d3d12_desc->StencilEnable))
{
vk_stencil_op_state_from_d3d12(&vk_desc->front, &d3d12_desc->FrontFace,
d3d12_desc->StencilReadMask, d3d12_desc->StencilWriteMask);
vk_stencil_op_state_from_d3d12(&vk_desc->back, &d3d12_desc->BackFace,
d3d12_desc->StencilReadMask, d3d12_desc->StencilWriteMask);
}
else
{
memset(&vk_desc->front, 0, sizeof(vk_desc->front));
memset(&vk_desc->back, 0, sizeof(vk_desc->back));
}
vk_desc->minDepthBounds = 0.0f;
vk_desc->maxDepthBounds = 1.0f;
}
static enum VkBlendFactor vk_blend_factor_from_d3d12(D3D12_BLEND blend, bool alpha) static enum VkBlendFactor vk_blend_factor_from_d3d12(D3D12_BLEND blend, bool alpha)
{ {
switch (blend) switch (blend)
@ -610,6 +708,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
struct VkRenderPassCreateInfo pass_desc; struct VkRenderPassCreateInfo pass_desc;
const struct vkd3d_format *format; const struct vkd3d_format *format;
enum VkVertexInputRate input_rate; enum VkVertexInputRate input_rate;
size_t rt_count;
unsigned int i; unsigned int i;
uint32_t mask; uint32_t mask;
VkResult vr; VkResult vr;
@ -708,17 +807,59 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
mask |= 1u << e->InputSlot; mask |= 1u << e->InputSlot;
} }
graphics->attachment_count = desc->NumRenderTargets; rt_count = desc->NumRenderTargets;
if (graphics->attachment_count > ARRAY_SIZE(graphics->attachments)) if (rt_count > ARRAY_SIZE(graphics->attachments) - 1)
{ {
FIXME("NumRenderTargets %zu > %zu, ignoring extra formats.\n", FIXME("NumRenderTargets %zu > %zu, ignoring extra formats.\n",
graphics->attachment_count, ARRAY_SIZE(graphics->attachments)); rt_count, ARRAY_SIZE(graphics->attachments) - 1);
graphics->attachment_count = ARRAY_SIZE(graphics->attachments); rt_count = ARRAY_SIZE(graphics->attachments) - 1;
} }
for (i = 0; i < graphics->attachment_count; ++i) graphics->rt_idx = 0;
if (desc->DepthStencilState.DepthEnable || desc->DepthStencilState.StencilEnable)
{
if (!(format = vkd3d_get_format(desc->DSVFormat)))
{
WARN("Invalid DXGI format %#x.\n", desc->DSVFormat);
hr = E_FAIL;
goto fail;
}
graphics->attachments[0].flags = 0;
graphics->attachments[0].format = format->vk_format;
graphics->attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
if (desc->DepthStencilState.DepthEnable)
{
graphics->attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
graphics->attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
}
else
{
graphics->attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
graphics->attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
}
if (desc->DepthStencilState.StencilEnable)
{
graphics->attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
graphics->attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
}
else
{
graphics->attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
graphics->attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
}
graphics->attachments[0].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
graphics->attachments[0].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
graphics->attachment_references[0].attachment = 0;
graphics->attachment_references[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
++graphics->rt_idx;
}
for (i = 0; i < rt_count; ++i)
{ {
unsigned int blend_idx = desc->BlendState.IndependentBlendEnable ? i : 0; unsigned int blend_idx = desc->BlendState.IndependentBlendEnable ? i : 0;
size_t idx = graphics->rt_idx + i;
if (!(format = vkd3d_get_format(desc->RTVFormats[i]))) if (!(format = vkd3d_get_format(desc->RTVFormats[i])))
{ {
@ -727,30 +868,34 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
goto fail; goto fail;
} }
graphics->attachments[i].flags = 0; graphics->attachments[idx].flags = 0;
graphics->attachments[i].format = format->vk_format; graphics->attachments[idx].format = format->vk_format;
graphics->attachments[i].samples = VK_SAMPLE_COUNT_1_BIT; graphics->attachments[idx].samples = VK_SAMPLE_COUNT_1_BIT;
graphics->attachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; graphics->attachments[idx].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
graphics->attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE; graphics->attachments[idx].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
graphics->attachments[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; graphics->attachments[idx].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
graphics->attachments[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; graphics->attachments[idx].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
graphics->attachments[i].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; graphics->attachments[idx].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
graphics->attachments[i].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; graphics->attachments[idx].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
graphics->attachment_references[i].attachment = i; graphics->attachment_references[idx].attachment = idx;
graphics->attachment_references[i].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; graphics->attachment_references[idx].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
blend_attachment_from_d3d12(&graphics->blend_attachments[i], &desc->BlendState.RenderTarget[blend_idx]); blend_attachment_from_d3d12(&graphics->blend_attachments[i], &desc->BlendState.RenderTarget[blend_idx]);
} }
graphics->attachment_count = graphics->rt_idx + rt_count;
sub_pass_desc.flags = 0; sub_pass_desc.flags = 0;
sub_pass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; sub_pass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
sub_pass_desc.inputAttachmentCount = 0; sub_pass_desc.inputAttachmentCount = 0;
sub_pass_desc.pInputAttachments = NULL; sub_pass_desc.pInputAttachments = NULL;
sub_pass_desc.colorAttachmentCount = graphics->attachment_count; sub_pass_desc.colorAttachmentCount = rt_count;
sub_pass_desc.pColorAttachments = graphics->attachment_references; sub_pass_desc.pColorAttachments = &graphics->attachment_references[graphics->rt_idx];
sub_pass_desc.pResolveAttachments = NULL; sub_pass_desc.pResolveAttachments = NULL;
sub_pass_desc.pDepthStencilAttachment = NULL; if (graphics->rt_idx)
sub_pass_desc.pDepthStencilAttachment = &graphics->attachment_references[0];
else
sub_pass_desc.pDepthStencilAttachment = NULL;
sub_pass_desc.preserveAttachmentCount = 0; sub_pass_desc.preserveAttachmentCount = 0;
sub_pass_desc.pPreserveAttachments = NULL; sub_pass_desc.pPreserveAttachments = NULL;
@ -782,6 +927,8 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
graphics->ms_desc.alphaToCoverageEnable = desc->BlendState.AlphaToCoverageEnable; graphics->ms_desc.alphaToCoverageEnable = desc->BlendState.AlphaToCoverageEnable;
graphics->ms_desc.alphaToOneEnable = VK_FALSE; graphics->ms_desc.alphaToOneEnable = VK_FALSE;
ds_desc_from_d3d12(&graphics->ds_desc, &desc->DepthStencilState);
graphics->root_signature = unsafe_impl_from_ID3D12RootSignature(desc->pRootSignature); graphics->root_signature = unsafe_impl_from_ID3D12RootSignature(desc->pRootSignature);
state->vk_bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS; state->vk_bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS;

View File

@ -231,14 +231,15 @@ struct d3d12_graphics_pipeline_state
enum VkVertexInputRate input_rates[D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; enum VkVertexInputRate input_rates[D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
size_t attribute_count; size_t attribute_count;
struct VkAttachmentDescription attachments[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT]; struct VkAttachmentDescription attachments[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT + 1];
struct VkAttachmentReference attachment_references[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT]; struct VkAttachmentReference attachment_references[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT + 1];
struct VkPipelineColorBlendAttachmentState blend_attachments[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT]; struct VkPipelineColorBlendAttachmentState blend_attachments[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT];
size_t attachment_count; size_t attachment_count, rt_idx;
VkRenderPass render_pass; VkRenderPass render_pass;
struct VkPipelineRasterizationStateCreateInfo rs_desc; struct VkPipelineRasterizationStateCreateInfo rs_desc;
struct VkPipelineMultisampleStateCreateInfo ms_desc; struct VkPipelineMultisampleStateCreateInfo ms_desc;
struct VkPipelineDepthStencilStateCreateInfo ds_desc;
struct d3d12_root_signature *root_signature; struct d3d12_root_signature *root_signature;
}; };
@ -319,7 +320,7 @@ struct d3d12_command_list
uint32_t strides[D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; uint32_t strides[D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
struct VkPipelineInputAssemblyStateCreateInfo ia_desc; struct VkPipelineInputAssemblyStateCreateInfo ia_desc;
VkImageView views[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT]; VkImageView views[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT + 1];
unsigned int fb_width; unsigned int fb_width;
unsigned int fb_height; unsigned int fb_height;