libs/vkd3d: Implement d3d12_device_CreateGraphicsPipelineState().

This commit is contained in:
Henri Verbeet 2016-09-28 12:16:19 +02:00
parent e4e1ef5944
commit 5c9ea3ede3
4 changed files with 429 additions and 27 deletions

View File

@ -26,6 +26,7 @@ import "dxgibase.h";
#include "unknown.idl"
const UINT D3D12_APPEND_ALIGNED_ELEMENT = 0xffffffff;
const UINT D3D12_DEFAULT_DEPTH_BIAS = 0;
cpp_quote("#define D3D12_DEFAULT_DEPTH_BIAS_CLAMP (0.0f)")
cpp_quote("#define D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS (0.0f)")
@ -37,6 +38,7 @@ const UINT D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT = 32;
const UINT D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES = 0xffffffff;
const UINT D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT = 8;
const UINT D3D12_TEXTURE_DATA_PITCH_ALIGNMENT = 256;
const UINT D3D12_VS_INPUT_REGISTER_COUNT = 32;
[uuid(8BA5FB08-5195-40E2-AC58-0D989C3A0102), object, local, pointer_default(unique)]
interface ID3D10Blob : IUnknown

View File

@ -580,10 +580,18 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Devic
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12Device *iface,
const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, REFIID riid, void **pipeline_state)
{
FIXME("iface %p, desc %p, riid %s, pipeline_state %p stub!\n",
struct d3d12_device *device = impl_from_ID3D12Device(iface);
struct d3d12_pipeline_state *object;
HRESULT hr;
TRACE("iface %p, desc %p, riid %s, pipeline_state %p.\n",
iface, desc, debugstr_guid(riid), pipeline_state);
return E_NOTIMPL;
if (FAILED(hr = d3d12_pipeline_state_create_graphics(device, desc, &object)))
return hr;
return return_interface((IUnknown *)&object->ID3D12PipelineState_iface,
&IID_ID3D12PipelineState, riid, pipeline_state);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12Device *iface,

View File

@ -1,5 +1,6 @@
/*
* Copyright 2016 Józef Kucia for CodeWeavers
* Copyright 2016 Henri Verbeet for CodeWeavers
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -254,8 +255,20 @@ static ULONG STDMETHODCALLTYPE d3d12_pipeline_state_Release(ID3D12PipelineState
{
struct d3d12_device *device = state->device;
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
unsigned int i;
VK_CALL(vkDestroyPipeline(device->vk_device, state->vk_pipeline, NULL));
if (state->vk_bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS)
{
for (i = 0; i < state->u.graphics.stage_count; ++i)
{
VK_CALL(vkDestroyShaderModule(device->vk_device, state->u.graphics.stages[i].module, NULL));
}
VK_CALL(vkDestroyRenderPass(device->vk_device, state->u.graphics.render_pass, NULL));
}
else if (state->vk_bind_point == VK_PIPELINE_BIND_POINT_COMPUTE)
{
VK_CALL(vkDestroyPipeline(device->vk_device, state->u.compute.vk_pipeline, NULL));
}
vkd3d_free(state);
@ -339,15 +352,42 @@ struct d3d12_pipeline_state *unsafe_impl_from_ID3D12PipelineState(ID3D12Pipeline
return impl_from_ID3D12PipelineState(iface);
}
static HRESULT create_shader_stage(struct d3d12_device *device, struct VkPipelineShaderStageCreateInfo *stage_desc,
enum VkShaderStageFlagBits stage, const D3D12_SHADER_BYTECODE *code)
{
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
struct VkShaderModuleCreateInfo shader_desc;
VkResult vr;
stage_desc->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
stage_desc->pNext = NULL;
stage_desc->flags = 0;
stage_desc->stage = stage;
stage_desc->pName = "main";
stage_desc->pSpecializationInfo = NULL;
shader_desc.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
shader_desc.pNext = NULL;
shader_desc.flags = 0;
shader_desc.codeSize = code->BytecodeLength;
shader_desc.pCode = code->pShaderBytecode;
if ((vr = VK_CALL(vkCreateShaderModule(device->vk_device, &shader_desc, NULL, &stage_desc->module))) < 0)
{
WARN("Failed to create Vulkan shader module, vr %d.\n", vr);
return hresult_from_vk_result(vr);
}
return S_OK;
}
static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *state,
struct d3d12_device *device, const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc)
{
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
struct d3d12_root_signature *root_signature;
VkComputePipelineCreateInfo pipeline_info;
VkShaderModuleCreateInfo shader_info;
VkShaderModule shader;
VkResult vr;
HRESULT hr;
state->ID3D12PipelineState_iface.lpVtbl = &d3d12_pipeline_state_vtbl;
state->refcount = 1;
@ -358,41 +398,25 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
return E_INVALIDARG;
}
shader_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
shader_info.pNext = NULL;
shader_info.flags = 0;
shader_info.codeSize = desc->CS.BytecodeLength;
shader_info.pCode = desc->CS.pShaderBytecode;
if ((vr = VK_CALL(vkCreateShaderModule(device->vk_device, &shader_info, NULL, &shader))))
{
WARN("Failed to create Vulkan shader module, vr %d.\n", vr);
return hresult_from_vk_result(vr);
}
pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
pipeline_info.pNext = NULL;
pipeline_info.flags = 0;
pipeline_info.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
pipeline_info.stage.pNext = NULL;
pipeline_info.stage.flags = 0;
pipeline_info.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
pipeline_info.stage.module = shader;
pipeline_info.stage.pName = "main";
pipeline_info.stage.pSpecializationInfo = NULL;
if (FAILED(hr = create_shader_stage(device, &pipeline_info.stage, VK_SHADER_STAGE_COMPUTE_BIT, &desc->CS)))
return hr;
pipeline_info.layout = root_signature->vk_pipeline_layout;
pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
pipeline_info.basePipelineIndex = -1;
vr = VK_CALL(vkCreateComputePipelines(device->vk_device, VK_NULL_HANDLE,
1, &pipeline_info, NULL, &state->vk_pipeline));
VK_CALL(vkDestroyShaderModule(device->vk_device, shader, NULL));
1, &pipeline_info, NULL, &state->u.compute.vk_pipeline));
VK_CALL(vkDestroyShaderModule(device->vk_device, pipeline_info.stage.module, NULL));
if (vr)
{
WARN("Failed to create Vulkan compute pipeline, vr %d.\n", vr);
return hresult_from_vk_result(vr);
}
state->vk_bind_point = VK_PIPELINE_BIND_POINT_COMPUTE;
state->device = device;
ID3D12Device_AddRef(&device->ID3D12Device_iface);
@ -420,3 +444,337 @@ HRESULT d3d12_pipeline_state_create_compute(struct d3d12_device *device,
return S_OK;
}
static enum VkPolygonMode vk_polygon_mode_from_d3d12(D3D12_FILL_MODE mode)
{
switch (mode)
{
case D3D12_FILL_MODE_WIREFRAME:
return VK_POLYGON_MODE_LINE;
case D3D12_FILL_MODE_SOLID:
return VK_POLYGON_MODE_FILL;
default:
FIXME("Unhandled fill mode %#x.\n", mode);
return VK_POLYGON_MODE_FILL;
}
}
static enum VkCullModeFlagBits vk_cull_mode_from_d3d12(D3D12_CULL_MODE mode)
{
switch (mode)
{
case D3D12_CULL_MODE_NONE:
return VK_CULL_MODE_NONE;
case D3D12_CULL_MODE_FRONT:
return VK_CULL_MODE_FRONT_BIT;
case D3D12_CULL_MODE_BACK:
return VK_CULL_MODE_BACK_BIT;
default:
FIXME("Unhandled cull mode %#x.\n", mode);
return VK_CULL_MODE_NONE;
}
}
static void rs_desc_from_d3d12(struct VkPipelineRasterizationStateCreateInfo *vk_desc,
const D3D12_RASTERIZER_DESC *d3d12_desc)
{
vk_desc->sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
vk_desc->pNext = NULL;
vk_desc->flags = 0;
vk_desc->depthClampEnable = !d3d12_desc->DepthClipEnable;
vk_desc->rasterizerDiscardEnable = VK_FALSE;
vk_desc->polygonMode = vk_polygon_mode_from_d3d12(d3d12_desc->FillMode);
vk_desc->cullMode = vk_cull_mode_from_d3d12(d3d12_desc->CullMode);
vk_desc->frontFace = d3d12_desc->FrontCounterClockwise ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE;
vk_desc->depthBiasEnable = VK_TRUE;
vk_desc->depthBiasConstantFactor = d3d12_desc->DepthBias;
vk_desc->depthBiasClamp = d3d12_desc->DepthBiasClamp;
vk_desc->depthBiasSlopeFactor = d3d12_desc->SlopeScaledDepthBias;
vk_desc->lineWidth = 1.0f;
if (d3d12_desc->MultisampleEnable)
FIXME("Ignoring MultisampleEnable %#x.\n", d3d12_desc->MultisampleEnable);
if (d3d12_desc->AntialiasedLineEnable)
FIXME("Ignoring AntialiasedLineEnable %#x.\n", d3d12_desc->AntialiasedLineEnable);
if (d3d12_desc->ForcedSampleCount)
FIXME("Ignoring ForcedSampleCount %#x.\n", d3d12_desc->ForcedSampleCount);
if (d3d12_desc->ConservativeRaster)
FIXME("Ignoring ConservativeRaster %#x.\n", d3d12_desc->ConservativeRaster);
}
static enum VkBlendFactor vk_blend_factor_from_d3d12(D3D12_BLEND blend, bool alpha)
{
switch (blend)
{
case D3D12_BLEND_ZERO:
return VK_BLEND_FACTOR_ZERO;
case D3D12_BLEND_ONE:
return VK_BLEND_FACTOR_ONE;
case D3D12_BLEND_SRC_COLOR:
return VK_BLEND_FACTOR_SRC_COLOR;
case D3D12_BLEND_INV_SRC_COLOR:
return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
case D3D12_BLEND_SRC_ALPHA:
return VK_BLEND_FACTOR_SRC_ALPHA;
case D3D12_BLEND_INV_SRC_ALPHA:
return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
case D3D12_BLEND_DEST_ALPHA:
return VK_BLEND_FACTOR_DST_ALPHA;
case D3D12_BLEND_INV_DEST_ALPHA:
return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
case D3D12_BLEND_DEST_COLOR:
return VK_BLEND_FACTOR_DST_COLOR;
case D3D12_BLEND_INV_DEST_COLOR:
return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
case D3D12_BLEND_SRC_ALPHA_SAT:
return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
case D3D12_BLEND_BLEND_FACTOR:
if (alpha)
return VK_BLEND_FACTOR_CONSTANT_ALPHA;
return VK_BLEND_FACTOR_CONSTANT_COLOR;
case D3D12_BLEND_INV_BLEND_FACTOR:
if (alpha)
return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
case D3D12_BLEND_SRC1_COLOR:
return VK_BLEND_FACTOR_SRC1_COLOR;
case D3D12_BLEND_INV_SRC1_COLOR:
return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;
case D3D12_BLEND_SRC1_ALPHA:
return VK_BLEND_FACTOR_SRC1_ALPHA;
case D3D12_BLEND_INV_SRC1_ALPHA:
return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
default:
FIXME("Unhandled blend %#x.\n", blend);
return VK_BLEND_FACTOR_ZERO;
}
}
static enum VkBlendOp vk_blend_op_from_d3d12(D3D12_BLEND_OP op)
{
switch (op)
{
case D3D12_BLEND_OP_ADD:
return VK_BLEND_OP_ADD;
case D3D12_BLEND_OP_SUBTRACT:
return VK_BLEND_OP_SUBTRACT;
case D3D12_BLEND_OP_REV_SUBTRACT:
return VK_BLEND_OP_REVERSE_SUBTRACT;
case D3D12_BLEND_OP_MIN:
return VK_BLEND_OP_MIN;
case D3D12_BLEND_OP_MAX:
return VK_BLEND_OP_MAX;
default:
FIXME("Unhandled blend op %#x.\n", op);
return VK_BLEND_OP_ADD;
}
}
static void blend_attachment_from_d3d12(struct VkPipelineColorBlendAttachmentState *vk_desc,
const D3D12_RENDER_TARGET_BLEND_DESC *d3d12_desc)
{
vk_desc->blendEnable = d3d12_desc->BlendEnable;
vk_desc->srcColorBlendFactor = vk_blend_factor_from_d3d12(d3d12_desc->SrcBlend, false);
vk_desc->dstColorBlendFactor = vk_blend_factor_from_d3d12(d3d12_desc->DestBlend, false);
vk_desc->colorBlendOp = vk_blend_op_from_d3d12(d3d12_desc->BlendOp);
vk_desc->srcAlphaBlendFactor = vk_blend_factor_from_d3d12(d3d12_desc->SrcBlendAlpha, true);
vk_desc->dstAlphaBlendFactor = vk_blend_factor_from_d3d12(d3d12_desc->DestBlendAlpha, true);
vk_desc->alphaBlendOp = vk_blend_op_from_d3d12(d3d12_desc->BlendOpAlpha);;
vk_desc->colorWriteMask = 0;
if (d3d12_desc->RenderTargetWriteMask & D3D12_COLOR_WRITE_ENABLE_RED)
vk_desc->colorWriteMask |= VK_COLOR_COMPONENT_R_BIT;
if (d3d12_desc->RenderTargetWriteMask & D3D12_COLOR_WRITE_ENABLE_GREEN)
vk_desc->colorWriteMask |= VK_COLOR_COMPONENT_G_BIT;
if (d3d12_desc->RenderTargetWriteMask & D3D12_COLOR_WRITE_ENABLE_BLUE)
vk_desc->colorWriteMask |= VK_COLOR_COMPONENT_B_BIT;
if (d3d12_desc->RenderTargetWriteMask & D3D12_COLOR_WRITE_ENABLE_ALPHA)
vk_desc->colorWriteMask |= VK_COLOR_COMPONENT_A_BIT;
if (d3d12_desc->LogicOpEnable)
FIXME("Ignoring LogicOpEnable %#x.\n", d3d12_desc->LogicOpEnable);
}
static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *state,
struct d3d12_device *device, const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc)
{
struct d3d12_graphics_pipeline_state *graphics = &state->u.graphics;
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
struct VkSubpassDescription sub_pass_desc;
struct VkRenderPassCreateInfo pass_desc;
const struct vkd3d_format *format;
unsigned int i;
VkResult vr;
HRESULT hr;
static const struct
{
enum VkShaderStageFlagBits stage;
ptrdiff_t offset;
}
shader_stages[] =
{
{VK_SHADER_STAGE_VERTEX_BIT, offsetof(D3D12_GRAPHICS_PIPELINE_STATE_DESC, VS)},
{VK_SHADER_STAGE_FRAGMENT_BIT, offsetof(D3D12_GRAPHICS_PIPELINE_STATE_DESC, PS)},
{VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, offsetof(D3D12_GRAPHICS_PIPELINE_STATE_DESC, DS)},
{VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, offsetof(D3D12_GRAPHICS_PIPELINE_STATE_DESC, HS)},
{VK_SHADER_STAGE_GEOMETRY_BIT, offsetof(D3D12_GRAPHICS_PIPELINE_STATE_DESC, GS)},
};
state->ID3D12PipelineState_iface.lpVtbl = &d3d12_pipeline_state_vtbl;
state->refcount = 1;
for (i = 0, graphics->stage_count = 0; i < ARRAY_SIZE(shader_stages); ++i)
{
const D3D12_SHADER_BYTECODE *b = (const void *)((uintptr_t)desc + shader_stages[i].offset);
if (!b->pShaderBytecode)
continue;
if (FAILED(hr = create_shader_stage(device, &graphics->stages[graphics->stage_count],
shader_stages[i].stage, b)))
goto fail;
++graphics->stage_count;
}
graphics->attribute_count = desc->InputLayout.NumElements;
if (graphics->attribute_count > ARRAY_SIZE(graphics->attributes))
{
FIXME("InputLayout.NumElements %zu > %zu, ignoring extra elements.\n",
graphics->attribute_count, ARRAY_SIZE(graphics->attributes));
graphics->attribute_count = ARRAY_SIZE(graphics->attributes);
}
for (i = 0; i < graphics->attribute_count; ++i)
{
const D3D12_INPUT_ELEMENT_DESC *e = &desc->InputLayout.pInputElementDescs[i];
if (!(format = vkd3d_get_format(e->Format)))
{
WARN("Invalid DXGI format %#x.\n", e->Format);
hr = E_FAIL;
goto fail;
}
graphics->attributes[i].location = i;
graphics->attributes[i].binding = e->InputSlot;
graphics->attributes[i].format = format->vk_format;
if (e->AlignedByteOffset == D3D12_APPEND_ALIGNED_ELEMENT)
FIXME("D3D12_APPEND_ALIGNED_ELEMENT not implemented.\n");
graphics->attributes[i].offset = e->AlignedByteOffset;
if (e->InputSlotClass != D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA)
FIXME("Ignoring input slot class %#x on input element %u.\n", e->InputSlotClass, i);
}
graphics->attachment_count = desc->NumRenderTargets;
if (graphics->attachment_count > ARRAY_SIZE(graphics->attachments))
{
FIXME("NumRenderTargets %zu > %zu, ignoring extra formats.\n",
graphics->attachment_count, ARRAY_SIZE(graphics->attachments));
graphics->attachment_count = ARRAY_SIZE(graphics->attachments);
}
for (i = 0; i < graphics->attachment_count; ++i)
{
unsigned int blend_idx = desc->BlendState.IndependentBlendEnable ? i : 0;
if (!(format = vkd3d_get_format(desc->RTVFormats[i])))
{
WARN("Invalid DXGI format %#x.\n", desc->RTVFormats[i]);
hr = E_FAIL;
goto fail;
}
graphics->attachments[i].flags = 0;
graphics->attachments[i].format = format->vk_format;
graphics->attachments[i].samples = VK_SAMPLE_COUNT_1_BIT;
graphics->attachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
graphics->attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
graphics->attachments[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
graphics->attachments[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
graphics->attachments[i].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
graphics->attachments[i].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
graphics->attachment_references[i].attachment = i;
graphics->attachment_references[i].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
blend_attachment_from_d3d12(&graphics->blend_attachments[i], &desc->BlendState.RenderTarget[blend_idx]);
}
sub_pass_desc.flags = 0;
sub_pass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
sub_pass_desc.inputAttachmentCount = 0;
sub_pass_desc.pInputAttachments = NULL;
sub_pass_desc.colorAttachmentCount = graphics->attachment_count;
sub_pass_desc.pColorAttachments = graphics->attachment_references;
sub_pass_desc.pResolveAttachments = NULL;
sub_pass_desc.pDepthStencilAttachment = NULL;
sub_pass_desc.preserveAttachmentCount = 0;
sub_pass_desc.pPreserveAttachments = NULL;
pass_desc.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
pass_desc.pNext = NULL;
pass_desc.flags = 0;
pass_desc.attachmentCount = graphics->attachment_count;
pass_desc.pAttachments = graphics->attachments;
pass_desc.subpassCount = 1;
pass_desc.pSubpasses = &sub_pass_desc;
pass_desc.dependencyCount = 0;
pass_desc.pDependencies = NULL;
if ((vr = VK_CALL(vkCreateRenderPass(device->vk_device, &pass_desc, NULL, &graphics->render_pass))) < 0)
{
WARN("Failed to create Vulkan render pass, vr %d.\n", vr);
hr = hresult_from_vk_result(vr);
goto fail;
}
rs_desc_from_d3d12(&graphics->rs_desc, &desc->RasterizerState);
graphics->ms_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
graphics->ms_desc.pNext = NULL;
graphics->ms_desc.flags = 0;
graphics->ms_desc.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
graphics->ms_desc.sampleShadingEnable = VK_FALSE;
graphics->ms_desc.minSampleShading = 0.0f;
graphics->ms_desc.pSampleMask = NULL;
graphics->ms_desc.alphaToCoverageEnable = desc->BlendState.AlphaToCoverageEnable;
graphics->ms_desc.alphaToOneEnable = VK_FALSE;
graphics->root_signature = unsafe_impl_from_ID3D12RootSignature(desc->pRootSignature);
state->vk_bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS;
state->device = device;
ID3D12Device_AddRef(&device->ID3D12Device_iface);
return S_OK;
fail:
for (i = 0; i < graphics->stage_count; ++i)
{
VK_CALL(vkDestroyShaderModule(device->vk_device, state->u.graphics.stages[i].module, NULL));
}
return hr;
}
HRESULT d3d12_pipeline_state_create_graphics(struct d3d12_device *device,
const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, struct d3d12_pipeline_state **state)
{
struct d3d12_pipeline_state *object;
HRESULT hr;
if (!(object = vkd3d_malloc(sizeof(*object))))
return E_OUTOFMEMORY;
if (FAILED(hr = d3d12_pipeline_state_init_graphics(object, device, desc)))
{
vkd3d_free(object);
return hr;
}
TRACE("Created graphics pipeline state %p.\n", object);
*state = object;
return S_OK;
}

View File

@ -37,6 +37,8 @@
#define VKD3D_DESCRIPTOR_MAGIC_FREE 0x00000000u
#define VKD3D_DESCRIPTOR_MAGIC_RTV 0x00565452u
#define VKD3D_MAX_SHADER_STAGES 5u
struct d3d12_command_list;
struct d3d12_device;
@ -178,19 +180,51 @@ struct d3d12_root_signature
HRESULT d3d12_root_signature_create(struct d3d12_device *device,
const D3D12_ROOT_SIGNATURE_DESC *desc, struct d3d12_root_signature **root_signature) DECLSPEC_HIDDEN;
struct d3d12_graphics_pipeline_state
{
struct VkPipelineShaderStageCreateInfo stages[VKD3D_MAX_SHADER_STAGES];
size_t stage_count;
struct VkVertexInputAttributeDescription attributes[D3D12_VS_INPUT_REGISTER_COUNT];
size_t attribute_count;
struct VkAttachmentDescription attachments[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT];
struct VkAttachmentReference attachment_references[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT];
struct VkPipelineColorBlendAttachmentState blend_attachments[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT];
size_t attachment_count;
VkRenderPass render_pass;
struct VkPipelineRasterizationStateCreateInfo rs_desc;
struct VkPipelineMultisampleStateCreateInfo ms_desc;
struct d3d12_root_signature *root_signature;
};
struct d3d12_compute_pipeline_state
{
VkPipeline vk_pipeline;
};
/* ID3D12PipelineState */
struct d3d12_pipeline_state
{
ID3D12PipelineState ID3D12PipelineState_iface;
LONG refcount;
VkPipeline vk_pipeline;
union
{
struct d3d12_graphics_pipeline_state graphics;
struct d3d12_compute_pipeline_state compute;
} u;
VkPipelineBindPoint vk_bind_point;
struct d3d12_device *device;
};
HRESULT d3d12_pipeline_state_create_compute(struct d3d12_device *device,
const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc, struct d3d12_pipeline_state **state) DECLSPEC_HIDDEN;
HRESULT d3d12_pipeline_state_create_graphics(struct d3d12_device *device,
const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, struct d3d12_pipeline_state **state) DECLSPEC_HIDDEN;
struct d3d12_pipeline_state *unsafe_impl_from_ID3D12PipelineState(ID3D12PipelineState *iface) DECLSPEC_HIDDEN;
/* ID3D12CommandAllocator */