From: Conor McCarthy cmccarthy@codeweavers.com
Based on vkd3d-proton patches by Philip Rebohle and Hans-Kristian Arntzen. --- include/vkd3d_d3d12.idl | 70 +++++++ libs/vkd3d/device.c | 37 +++- libs/vkd3d/state.c | 394 +++++++++++++++++++++++++++++++------ libs/vkd3d/vkd3d_private.h | 40 +++- 4 files changed, 480 insertions(+), 61 deletions(-)
diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl index 06287f5a..992bdcac 100644 --- a/include/vkd3d_d3d12.idl +++ b/include/vkd3d_d3d12.idl @@ -38,6 +38,7 @@ cpp_quote("#define D3D12_DEFAULT_BLEND_FACTOR_BLUE (1.0f)") cpp_quote("#define D3D12_DEFAULT_BLEND_FACTOR_GREEN (1.0f)") cpp_quote("#define D3D12_DEFAULT_BLEND_FACTOR_RED (1.0f)") const UINT D3D12_DEFAULT_DEPTH_BIAS = 0; +const UINT D3D12_DEFAULT_SAMPLE_MASK = 0xffffffff; cpp_quote("#define D3D12_DEFAULT_DEPTH_BIAS_CLAMP (0.0f)") cpp_quote("#define D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS (0.0f)") const UINT D3D12_DEFAULT_STENCIL_READ_MASK = 0xff; @@ -1430,6 +1431,19 @@ typedef struct D3D12_DEPTH_STENCIL_DESC D3D12_DEPTH_STENCILOP_DESC BackFace; } D3D12_DEPTH_STENCIL_DESC;
+typedef struct D3D12_DEPTH_STENCIL_DESC1 +{ + BOOL DepthEnable; + D3D12_DEPTH_WRITE_MASK DepthWriteMask; + D3D12_COMPARISON_FUNC DepthFunc; + BOOL StencilEnable; + UINT8 StencilReadMask; + UINT8 StencilWriteMask; + D3D12_DEPTH_STENCILOP_DESC FrontFace; + D3D12_DEPTH_STENCILOP_DESC BackFace; + BOOL DepthBoundsTestEnable; +} D3D12_DEPTH_STENCIL_DESC1; + typedef enum D3D12_BLEND { D3D12_BLEND_ZERO = 1, @@ -1606,6 +1620,62 @@ typedef enum D3D12_PRIMITIVE_TOPOLOGY_TYPE D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH = 4, } D3D12_PRIMITIVE_TOPOLOGY_TYPE;
+typedef struct D3D12_RT_FORMAT_ARRAY +{ + DXGI_FORMAT RTFormats[8]; + UINT NumRenderTargets; +} D3D12_RT_FORMAT_ARRAY; + +typedef enum D3D12_VIEW_INSTANCING_FLAGS +{ + D3D12_VIEW_INSTANCING_FLAG_NONE = 0, + D3D12_VIEW_INSTANCING_FLAG_ENABLE_VIEW_INSTANCE_MASKING = 0x1, +} D3D12_VIEW_INSTANCING_FLAGS; +cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_VIEW_INSTANCING_FLAGS);") + +typedef struct D3D12_VIEW_INSTANCE_LOCATION +{ + UINT ViewportArrayIndex; + UINT RenderTargetArrayIndex; +} D3D12_VIEW_INSTANCE_LOCATION; + +typedef struct D3D12_VIEW_INSTANCING_DESC +{ + UINT ViewInstanceCount; + const D3D12_VIEW_INSTANCE_LOCATION *pViewInstanceLocations; + D3D12_VIEW_INSTANCING_FLAGS Flags; +} D3D12_VIEW_INSTANCING_DESC; + +typedef enum D3D12_PIPELINE_STATE_SUBOBJECT_TYPE +{ + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE = 0, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VS = 1, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PS = 2, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DS = 3, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_HS = 4, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_GS = 5, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CS = 6, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_STREAM_OUTPUT = 7, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_BLEND = 8, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_MASK = 9, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER = 10, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL = 11, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_INPUT_LAYOUT = 12, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_IB_STRIP_CUT_VALUE = 13, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY = 14, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS = 15, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT = 16, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_DESC = 17, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_NODE_MASK = 18, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CACHED_PSO = 19, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS = 20, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1 = 21, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VIEW_INSTANCING = 22, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_AS = 24, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MS = 25, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MAX_VALID = 26, +} D3D12_PIPELINE_STATE_SUBOBJECT_TYPE; + typedef struct D3D12_CACHED_PIPELINE_STATE { const void *pCachedBlob; diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 8f0d09bd..222555d4 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -2464,6 +2464,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(d3d12_device_iface
if (IsEqualGUID(riid, &IID_ID3D12Device) || IsEqualGUID(riid, &IID_ID3D12Device1) + || IsEqualGUID(riid, &IID_ID3D12Device2) || IsEqualGUID(riid, &IID_ID3D12Object) || IsEqualGUID(riid, &IID_IUnknown)) { @@ -2611,13 +2612,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(d3d12_ const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, REFIID riid, void **pipeline_state) { struct d3d12_device *device = impl_from_ID3D12Device(iface); + struct d3d12_pipeline_state_desc pipeline_desc; 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);
- if (FAILED(hr = d3d12_pipeline_state_create_graphics(device, desc, &object))) + if (FAILED(hr = pipeline_state_desc_from_d3d12_graphics_desc(&pipeline_desc, desc))) + return hr; + + if (FAILED(hr = d3d12_pipeline_state_create_graphics(device, &pipeline_desc, &object))) return hr;
return return_interface(&object->ID3D12PipelineState_iface, @@ -2628,13 +2633,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(d3d12_d const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc, REFIID riid, void **pipeline_state) { struct d3d12_device *device = impl_from_ID3D12Device(iface); + struct d3d12_pipeline_state_desc pipeline_desc; 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);
- if (FAILED(hr = d3d12_pipeline_state_create_compute(device, desc, &object))) + if (FAILED(hr = pipeline_state_desc_from_d3d12_compute_desc(&pipeline_desc, desc))) + return hr; + + if (FAILED(hr = d3d12_pipeline_state_create_compute(device, &pipeline_desc, &object))) return hr;
return return_interface(&object->ID3D12PipelineState_iface, @@ -3937,7 +3946,27 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(d3d12_device_ return S_OK; }
-static const struct ID3D12Device1Vtbl d3d12_device_vtbl = +static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineState(d3d12_device_iface *iface, + const D3D12_PIPELINE_STATE_STREAM_DESC *desc, REFIID riid, void **pipeline_state) +{ + struct d3d12_device *device = impl_from_ID3D12Device(iface); + struct d3d12_pipeline_state_desc pipeline_desc; + struct d3d12_pipeline_state *object; + VkPipelineBindPoint bind_point; + HRESULT hr; + + TRACE("iface %p, desc %p, riid %s, pipeline_state %p.\n", iface, desc, debugstr_guid(riid), pipeline_state); + + if (FAILED(hr = pipeline_state_desc_from_d3d12_stream_desc(&pipeline_desc, desc, &bind_point))) + return hr; + + if (FAILED(hr = d3d12_pipeline_state_create(device, bind_point, &pipeline_desc, &object))) + return hr; + + return return_interface(&object->ID3D12PipelineState_iface, &IID_ID3D12PipelineState, riid, pipeline_state); +} + +static const struct ID3D12Device2Vtbl d3d12_device_vtbl = { /* IUnknown methods */ d3d12_device_QueryInterface, @@ -3990,6 +4019,8 @@ static const struct ID3D12Device1Vtbl d3d12_device_vtbl = d3d12_device_CreatePipelineLibrary, d3d12_device_SetEventOnMultipleFenceCompletion, d3d12_device_SetResidencyPriority, + /* ID3D12Device2 methods */ + d3d12_device_CreatePipelineState, };
struct d3d12_device *unsafe_impl_from_ID3D12Device(d3d12_device_iface *iface) diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 2d813824..a7392035 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -1736,6 +1736,247 @@ void vkd3d_render_pass_cache_cleanup(struct vkd3d_render_pass_cache *cache, cache->render_passes = NULL; }
+static void d3d12_promote_depth_stencil_desc(D3D12_DEPTH_STENCIL_DESC1 *dst, const D3D12_DEPTH_STENCIL_DESC *src) +{ + dst->DepthEnable = src->DepthEnable; + dst->DepthWriteMask = src->DepthWriteMask; + dst->DepthFunc = src->DepthFunc; + dst->StencilEnable = src->StencilEnable; + dst->StencilReadMask = src->StencilReadMask; + dst->StencilWriteMask = src->StencilWriteMask; + dst->FrontFace = src->FrontFace; + dst->BackFace = src->BackFace; + dst->DepthBoundsTestEnable = FALSE; +} + +static void d3d12_init_pipeline_state_desc(struct d3d12_pipeline_state_desc *desc) +{ + D3D12_DEPTH_STENCIL_DESC1 *ds_state = &desc->depth_stencil_state; + D3D12_RASTERIZER_DESC *rs_state = &desc->rasterizer_state; + D3D12_BLEND_DESC *blend_state = &desc->blend_state; + DXGI_SAMPLE_DESC *sample_desc = &desc->sample_desc; + + memset(desc, 0, sizeof(*desc)); + ds_state->DepthEnable = TRUE; + ds_state->DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + ds_state->DepthFunc = D3D12_COMPARISON_FUNC_LESS; + ds_state->StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK; + ds_state->StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK; + ds_state->FrontFace.StencilFunc = ds_state->BackFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS; + ds_state->FrontFace.StencilDepthFailOp = ds_state->BackFace.StencilDepthFailOp = D3D12_STENCIL_OP_KEEP; + ds_state->FrontFace.StencilPassOp = ds_state->BackFace.StencilPassOp = D3D12_STENCIL_OP_KEEP; + ds_state->FrontFace.StencilFailOp = ds_state->BackFace.StencilFailOp = D3D12_STENCIL_OP_KEEP; + + rs_state->FillMode = D3D12_FILL_MODE_SOLID; + rs_state->CullMode = D3D12_CULL_MODE_BACK; + rs_state->DepthClipEnable = TRUE; + rs_state->ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; + + blend_state->RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + + sample_desc->Count = 1; + sample_desc->Quality = 0; + + desc->sample_mask = D3D12_DEFAULT_SAMPLE_MASK; +} + +HRESULT pipeline_state_desc_from_d3d12_graphics_desc(struct d3d12_pipeline_state_desc *desc, + const D3D12_GRAPHICS_PIPELINE_STATE_DESC *d3d12_desc) +{ + memset(desc, 0, sizeof(*desc)); + desc->root_signature = d3d12_desc->pRootSignature; + desc->vs = d3d12_desc->VS; + desc->ps = d3d12_desc->PS; + desc->ds = d3d12_desc->DS; + desc->hs = d3d12_desc->HS; + desc->gs = d3d12_desc->GS; + desc->stream_output = d3d12_desc->StreamOutput; + desc->blend_state = d3d12_desc->BlendState; + desc->sample_mask = d3d12_desc->SampleMask; + desc->rasterizer_state = d3d12_desc->RasterizerState; + d3d12_promote_depth_stencil_desc(&desc->depth_stencil_state, &d3d12_desc->DepthStencilState); + desc->input_layout = d3d12_desc->InputLayout; + desc->strip_cut_value = d3d12_desc->IBStripCutValue; + desc->primitive_topology_type = d3d12_desc->PrimitiveTopologyType; + desc->rtv_formats.NumRenderTargets = d3d12_desc->NumRenderTargets; + memcpy(desc->rtv_formats.RTFormats, d3d12_desc->RTVFormats, sizeof(desc->rtv_formats.RTFormats)); + desc->dsv_format = d3d12_desc->DSVFormat; + desc->sample_desc = d3d12_desc->SampleDesc; + desc->node_mask = d3d12_desc->NodeMask; + desc->cached_pso = d3d12_desc->CachedPSO; + desc->flags = d3d12_desc->Flags; + return S_OK; +} + +HRESULT pipeline_state_desc_from_d3d12_compute_desc(struct d3d12_pipeline_state_desc *desc, + const D3D12_COMPUTE_PIPELINE_STATE_DESC *d3d12_desc) +{ + memset(desc, 0, sizeof(*desc)); + desc->root_signature = d3d12_desc->pRootSignature; + desc->cs = d3d12_desc->CS; + desc->node_mask = d3d12_desc->NodeMask; + desc->cached_pso = d3d12_desc->CachedPSO; + desc->flags = d3d12_desc->Flags; + return S_OK; +} + +#define VKD3D_HANDLE_SUBOBJECT_EXPLICIT(type_enum, type_name, assignment) \ + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ ## type_enum: \ + {\ + const struct\ + {\ + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE type; \ + type_name data; \ + } *subobject = (void *)stream_ptr; \ + if (stream_ptr + sizeof(*subobject) > stream_end) \ + { \ + WARN("Invalid pipeline state stream.\n"); \ + return E_INVALIDARG; \ + } \ + stream_ptr += align(sizeof(*subobject), sizeof(void*)); \ + assignment; \ + break;\ + } + +#define VKD3D_HANDLE_SUBOBJECT(type_enum, type, left_side) \ + VKD3D_HANDLE_SUBOBJECT_EXPLICIT(type_enum, type, left_side = subobject->data) + +static VkShaderStageFlags pipeline_state_desc_get_shader_stages(const struct d3d12_pipeline_state_desc *desc) +{ + VkShaderStageFlags result = 0; + + if (desc->vs.BytecodeLength && desc->vs.pShaderBytecode) + result |= VK_SHADER_STAGE_VERTEX_BIT; + if (desc->hs.BytecodeLength && desc->hs.pShaderBytecode) + result |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; + if (desc->ds.BytecodeLength && desc->ds.pShaderBytecode) + result |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; + if (desc->gs.BytecodeLength && desc->gs.pShaderBytecode) + result |= VK_SHADER_STAGE_GEOMETRY_BIT; + if (desc->ps.BytecodeLength && desc->ps.pShaderBytecode) + result |= VK_SHADER_STAGE_FRAGMENT_BIT; + if (desc->cs.BytecodeLength && desc->cs.pShaderBytecode) + result |= VK_SHADER_STAGE_COMPUTE_BIT; + + /* If we use rasterizer discard, force fragment shader to not exist. + * See VUID-VkGraphicsPipelineCreateInfo-pStages-06894. */ + if (desc->stream_output.NumEntries && + desc->stream_output.RasterizedStream == D3D12_SO_NO_RASTERIZED_STREAM) + { + result &= ~VK_SHADER_STAGE_FRAGMENT_BIT; + } + + return result; +} + +HRESULT pipeline_state_desc_from_d3d12_stream_desc(struct d3d12_pipeline_state_desc *desc, + const D3D12_PIPELINE_STATE_STREAM_DESC *d3d12_desc, VkPipelineBindPoint *vk_bind_point) +{ + VkShaderStageFlags defined_stages, disallowed_stages; + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE subobject_type; + const char *stream_ptr, *stream_end; + uint64_t defined_subobjects = 0; + uint64_t subobject_bit; + + /* Initialize defaults for undefined subobjects */ + d3d12_init_pipeline_state_desc(desc); + + /* Structs are packed, but padded so that their size + * is always a multiple of the size of a pointer. */ + stream_ptr = d3d12_desc->pPipelineStateSubobjectStream; + stream_end = stream_ptr + d3d12_desc->SizeInBytes; + + while (stream_ptr < stream_end) + { + if (stream_ptr + sizeof(subobject_type) > stream_end) + { + WARN("Invalid pipeline state stream.\n"); + return E_INVALIDARG; + } + + subobject_type = *(const D3D12_PIPELINE_STATE_SUBOBJECT_TYPE *)stream_ptr; + subobject_bit = 1ull << subobject_type; + + if (defined_subobjects & subobject_bit) + { + WARN("Duplicate pipeline subobject type %u.\n", subobject_type); + return E_INVALIDARG; + } + + defined_subobjects |= subobject_bit; + + switch (subobject_type) + { + VKD3D_HANDLE_SUBOBJECT(ROOT_SIGNATURE, ID3D12RootSignature*, desc->root_signature); + VKD3D_HANDLE_SUBOBJECT(VS, D3D12_SHADER_BYTECODE, desc->vs); + VKD3D_HANDLE_SUBOBJECT(PS, D3D12_SHADER_BYTECODE, desc->ps); + VKD3D_HANDLE_SUBOBJECT(DS, D3D12_SHADER_BYTECODE, desc->ds); + VKD3D_HANDLE_SUBOBJECT(HS, D3D12_SHADER_BYTECODE, desc->hs); + VKD3D_HANDLE_SUBOBJECT(GS, D3D12_SHADER_BYTECODE, desc->gs); + VKD3D_HANDLE_SUBOBJECT(CS, D3D12_SHADER_BYTECODE, desc->cs); + VKD3D_HANDLE_SUBOBJECT(STREAM_OUTPUT, D3D12_STREAM_OUTPUT_DESC, desc->stream_output); + VKD3D_HANDLE_SUBOBJECT(BLEND, D3D12_BLEND_DESC, desc->blend_state); + VKD3D_HANDLE_SUBOBJECT(SAMPLE_MASK, UINT, desc->sample_mask); + VKD3D_HANDLE_SUBOBJECT(RASTERIZER, D3D12_RASTERIZER_DESC, desc->rasterizer_state); + VKD3D_HANDLE_SUBOBJECT_EXPLICIT(DEPTH_STENCIL, D3D12_DEPTH_STENCIL_DESC, + d3d12_promote_depth_stencil_desc(&desc->depth_stencil_state, &subobject->data)); + VKD3D_HANDLE_SUBOBJECT(INPUT_LAYOUT, D3D12_INPUT_LAYOUT_DESC, desc->input_layout); + VKD3D_HANDLE_SUBOBJECT(IB_STRIP_CUT_VALUE, D3D12_INDEX_BUFFER_STRIP_CUT_VALUE, desc->strip_cut_value); + VKD3D_HANDLE_SUBOBJECT(PRIMITIVE_TOPOLOGY, D3D12_PRIMITIVE_TOPOLOGY_TYPE, desc->primitive_topology_type); + VKD3D_HANDLE_SUBOBJECT(RENDER_TARGET_FORMATS, D3D12_RT_FORMAT_ARRAY, desc->rtv_formats); + VKD3D_HANDLE_SUBOBJECT(DEPTH_STENCIL_FORMAT, DXGI_FORMAT, desc->dsv_format); + VKD3D_HANDLE_SUBOBJECT(SAMPLE_DESC, DXGI_SAMPLE_DESC, desc->sample_desc); + VKD3D_HANDLE_SUBOBJECT(NODE_MASK, UINT, desc->node_mask); + VKD3D_HANDLE_SUBOBJECT(CACHED_PSO, D3D12_CACHED_PIPELINE_STATE, desc->cached_pso); + VKD3D_HANDLE_SUBOBJECT(FLAGS, D3D12_PIPELINE_STATE_FLAGS, desc->flags); + VKD3D_HANDLE_SUBOBJECT(DEPTH_STENCIL1, D3D12_DEPTH_STENCIL_DESC1, desc->depth_stencil_state); + VKD3D_HANDLE_SUBOBJECT(VIEW_INSTANCING, D3D12_VIEW_INSTANCING_DESC, desc->view_instancing_desc); + + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_AS: + FIXME("Amplification shaders are not supported yet.\n"); + return E_INVALIDARG; + + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MS: + FIXME("Mesh shaders are not supported yet.\n"); + return E_INVALIDARG; + + default: + FIXME("Unhandled pipeline subobject type %u.\n", subobject_type); + return E_INVALIDARG; + } + } + + /* Deduce pipeline type from specified shaders */ + defined_stages = pipeline_state_desc_get_shader_stages(desc); + + if (defined_stages & VK_SHADER_STAGE_VERTEX_BIT) + { + disallowed_stages = VK_SHADER_STAGE_COMPUTE_BIT; + *vk_bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS; + } + else if (defined_stages & VK_SHADER_STAGE_COMPUTE_BIT) + { + disallowed_stages = VK_SHADER_STAGE_VERTEX_BIT; + *vk_bind_point = VK_PIPELINE_BIND_POINT_COMPUTE; + } + else + { + WARN("Cannot deduce pipeline type from shader stages 0x%#x.\n", defined_stages); + return E_INVALIDARG; + } + + if (defined_stages & disallowed_stages) + { + WARN("Invalid combination of shader stages 0x%#x.\n", defined_stages); + return E_INVALIDARG; + } + + return S_OK; +} + +#undef VKD3D_HANDLE_SUBOBJECT +#undef VKD3D_HANDLE_SUBOBJECT_EXPLICIT + struct vkd3d_pipeline_key { D3D12_PRIMITIVE_TOPOLOGY topology; @@ -2193,7 +2434,7 @@ static HRESULT d3d12_pipeline_state_find_and_init_uav_counters(struct d3d12_pipe }
static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *state, - struct d3d12_device *device, const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc) + struct d3d12_device *device, const struct d3d12_pipeline_state_desc *desc) { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; struct vkd3d_shader_interface_info shader_interface; @@ -2208,14 +2449,14 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
memset(&state->uav_counters, 0, sizeof(state->uav_counters));
- if (!(root_signature = unsafe_impl_from_ID3D12RootSignature(desc->pRootSignature))) + if (!(root_signature = unsafe_impl_from_ID3D12RootSignature(desc->root_signature))) { WARN("Root signature is NULL.\n"); return E_INVALIDARG; }
if (FAILED(hr = d3d12_pipeline_state_find_and_init_uav_counters(state, device, root_signature, - &desc->CS, VK_SHADER_STAGE_COMPUTE_BIT))) + &desc->cs, VK_SHADER_STAGE_COMPUTE_BIT))) return hr;
memset(&target_info, 0, sizeof(target_info)); @@ -2256,7 +2497,7 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
vk_pipeline_layout = state->uav_counters.vk_pipeline_layout ? state->uav_counters.vk_pipeline_layout : root_signature->vk_pipeline_layout; - if (FAILED(hr = vkd3d_create_compute_pipeline(device, &desc->CS, &shader_interface, + if (FAILED(hr = vkd3d_create_compute_pipeline(device, &desc->cs, &shader_interface, vk_pipeline_layout, &state->u.compute.vk_pipeline))) { WARN("Failed to create Vulkan compute pipeline, hr %#x.\n", hr); @@ -2278,7 +2519,7 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st }
HRESULT d3d12_pipeline_state_create_compute(struct d3d12_device *device, - const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc, struct d3d12_pipeline_state **state) + const struct d3d12_pipeline_state_desc *desc, struct d3d12_pipeline_state **state) { struct d3d12_pipeline_state *object; HRESULT hr; @@ -2457,7 +2698,7 @@ static void vk_stencil_op_state_from_d3d12(struct VkStencilOpState *vk_desc, }
static void ds_desc_from_d3d12(struct VkPipelineDepthStencilStateCreateInfo *vk_desc, - const D3D12_DEPTH_STENCIL_DESC *d3d12_desc) + const D3D12_DEPTH_STENCIL_DESC1 *d3d12_desc) { memset(vk_desc, 0, sizeof(*vk_desc)); vk_desc->sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; @@ -2738,12 +2979,12 @@ static VkLogicOp vk_logic_op_from_d3d12(D3D12_LOGIC_OP op) }
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_device *device, const struct d3d12_pipeline_state_desc *desc) { unsigned int ps_output_swizzle[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT]; struct d3d12_graphics_pipeline_state *graphics = &state->u.graphics; const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; - const D3D12_STREAM_OUTPUT_DESC *so_desc = &desc->StreamOutput; + const D3D12_STREAM_OUTPUT_DESC *so_desc = &desc->stream_output; VkVertexInputBindingDivisorDescriptionEXT *binding_divisor; const struct vkd3d_vulkan_info *vk_info = &device->vk_info; uint32_t instance_divisors[D3D12_VS_INPUT_REGISTER_COUNT]; @@ -2787,11 +3028,11 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s } shader_stages[] = { - {VK_SHADER_STAGE_VERTEX_BIT, offsetof(D3D12_GRAPHICS_PIPELINE_STATE_DESC, VS)}, - {VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, offsetof(D3D12_GRAPHICS_PIPELINE_STATE_DESC, HS)}, - {VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, offsetof(D3D12_GRAPHICS_PIPELINE_STATE_DESC, DS)}, - {VK_SHADER_STAGE_GEOMETRY_BIT, offsetof(D3D12_GRAPHICS_PIPELINE_STATE_DESC, GS)}, - {VK_SHADER_STAGE_FRAGMENT_BIT, offsetof(D3D12_GRAPHICS_PIPELINE_STATE_DESC, PS)}, + {VK_SHADER_STAGE_VERTEX_BIT, offsetof(struct d3d12_pipeline_state_desc, vs)}, + {VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, offsetof(struct d3d12_pipeline_state_desc, hs)}, + {VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, offsetof(struct d3d12_pipeline_state_desc, ds)}, + {VK_SHADER_STAGE_GEOMETRY_BIT, offsetof(struct d3d12_pipeline_state_desc, gs)}, + {VK_SHADER_STAGE_FRAGMENT_BIT, offsetof(struct d3d12_pipeline_state_desc, ps)}, };
state->ID3D12PipelineState_iface.lpVtbl = &d3d12_pipeline_state_vtbl; @@ -2802,26 +3043,26 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
memset(&input_signature, 0, sizeof(input_signature));
- for (i = desc->NumRenderTargets; i < ARRAY_SIZE(desc->RTVFormats); ++i) + for (i = desc->rtv_formats.NumRenderTargets; i < ARRAY_SIZE(desc->rtv_formats.RTFormats); ++i) { - if (desc->RTVFormats[i] != DXGI_FORMAT_UNKNOWN) + if (desc->rtv_formats.RTFormats[i] != DXGI_FORMAT_UNKNOWN) { WARN("Format must be set to DXGI_FORMAT_UNKNOWN for inactive render targets.\n"); return E_INVALIDARG; } }
- if (!(root_signature = unsafe_impl_from_ID3D12RootSignature(desc->pRootSignature))) + if (!(root_signature = unsafe_impl_from_ID3D12RootSignature(desc->root_signature))) { WARN("Root signature is NULL.\n"); return E_INVALIDARG; }
- sample_count = vk_samples_from_dxgi_sample_desc(&desc->SampleDesc); - if (desc->SampleDesc.Count != 1 && desc->SampleDesc.Quality) - WARN("Ignoring sample quality %u.\n", desc->SampleDesc.Quality); + sample_count = vk_samples_from_dxgi_sample_desc(&desc->sample_desc); + if (desc->sample_desc.Count != 1 && desc->sample_desc.Quality) + WARN("Ignoring sample quality %u.\n", desc->sample_desc.Quality);
- rt_count = desc->NumRenderTargets; + rt_count = desc->rtv_formats.NumRenderTargets; if (rt_count > ARRAY_SIZE(graphics->blend_attachments)) { FIXME("NumRenderTargets %zu > %zu, ignoring extra formats.\n", @@ -2829,40 +3070,40 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s rt_count = ARRAY_SIZE(graphics->blend_attachments); }
- graphics->om_logic_op_enable = desc->BlendState.RenderTarget[0].LogicOpEnable + graphics->om_logic_op_enable = desc->blend_state.RenderTarget[0].LogicOpEnable && device->feature_options.OutputMergerLogicOp; graphics->om_logic_op = graphics->om_logic_op_enable - ? vk_logic_op_from_d3d12(desc->BlendState.RenderTarget[0].LogicOp) + ? vk_logic_op_from_d3d12(desc->blend_state.RenderTarget[0].LogicOp) : VK_LOGIC_OP_COPY; - if (desc->BlendState.RenderTarget[0].LogicOpEnable && !graphics->om_logic_op_enable) + if (desc->blend_state.RenderTarget[0].LogicOpEnable && !graphics->om_logic_op_enable) WARN("The device does not support output merger logic ops. Ignoring logic op %#x.\n", - desc->BlendState.RenderTarget[0].LogicOp); + desc->blend_state.RenderTarget[0].LogicOp);
graphics->null_attachment_mask = 0; for (i = 0; i < rt_count; ++i) { const D3D12_RENDER_TARGET_BLEND_DESC *rt_desc;
- if (desc->RTVFormats[i] == DXGI_FORMAT_UNKNOWN) + if (desc->rtv_formats.RTFormats[i] == DXGI_FORMAT_UNKNOWN) { graphics->null_attachment_mask |= 1u << i; ps_output_swizzle[i] = VKD3D_SHADER_NO_SWIZZLE; graphics->rtv_formats[i] = VK_FORMAT_UNDEFINED; } - else if ((format = vkd3d_get_format(device, desc->RTVFormats[i], false))) + else if ((format = vkd3d_get_format(device, desc->rtv_formats.RTFormats[i], false))) { ps_output_swizzle[i] = vkd3d_get_rt_format_swizzle(format); graphics->rtv_formats[i] = format->vk_format; } else { - WARN("Invalid RTV format %#x.\n", desc->RTVFormats[i]); + WARN("Invalid RTV format %#x.\n", desc->rtv_formats.RTFormats[i]); hr = E_INVALIDARG; goto fail; }
- rt_desc = &desc->BlendState.RenderTarget[desc->BlendState.IndependentBlendEnable ? i : 0]; - if (desc->BlendState.IndependentBlendEnable && rt_desc->LogicOpEnable) + rt_desc = &desc->blend_state.RenderTarget[desc->blend_state.IndependentBlendEnable ? i : 0]; + if (desc->blend_state.IndependentBlendEnable && rt_desc->LogicOpEnable) { WARN("IndependentBlendEnable must be FALSE when logic operations are enabled.\n"); hr = E_INVALIDARG; @@ -2881,8 +3122,8 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s graphics->rtv_formats[i] = VK_FORMAT_UNDEFINED; graphics->rt_count = rt_count;
- ds_desc_from_d3d12(&graphics->ds_desc, &desc->DepthStencilState); - if (desc->DSVFormat == DXGI_FORMAT_UNKNOWN + ds_desc_from_d3d12(&graphics->ds_desc, &desc->depth_stencil_state); + if (desc->dsv_format == DXGI_FORMAT_UNKNOWN && graphics->ds_desc.depthTestEnable && !graphics->ds_desc.depthWriteEnable && graphics->ds_desc.depthCompareOp == VK_COMPARE_OP_ALWAYS && !graphics->ds_desc.stencilTestEnable) { @@ -2893,13 +3134,13 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s graphics->dsv_format = VK_FORMAT_UNDEFINED; if (graphics->ds_desc.depthTestEnable || graphics->ds_desc.stencilTestEnable) { - if (desc->DSVFormat == DXGI_FORMAT_UNKNOWN) + if (desc->dsv_format == DXGI_FORMAT_UNKNOWN) { WARN("DSV format is DXGI_FORMAT_UNKNOWN.\n"); graphics->dsv_format = VK_FORMAT_UNDEFINED; graphics->null_attachment_mask |= dsv_attachment_mask(graphics); } - else if ((format = vkd3d_get_format(device, desc->DSVFormat, true))) + else if ((format = vkd3d_get_format(device, desc->dsv_format, true))) { if (!(format->vk_aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) FIXME("Format %#x is not depth/stencil format.\n", format->dxgi_format); @@ -2908,12 +3149,12 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s } else { - WARN("Invalid DSV format %#x.\n", desc->DSVFormat); + WARN("Invalid DSV format %#x.\n", desc->dsv_format); hr = E_INVALIDARG; goto fail; }
- if (!desc->PS.pShaderBytecode) + if (!desc->ps.pShaderBytecode) { if (FAILED(hr = create_shader_stage(device, &graphics->stages[graphics->stage_count], VK_SHADER_STAGE_FRAGMENT_BIT, &default_ps, NULL))) @@ -2936,7 +3177,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s ps_target_info.extension_count = vk_info->shader_extension_count; ps_target_info.parameters = ps_shader_parameters; ps_target_info.parameter_count = ARRAY_SIZE(ps_shader_parameters); - ps_target_info.dual_source_blending = is_dual_source_blending(&desc->BlendState.RenderTarget[0]); + ps_target_info.dual_source_blending = is_dual_source_blending(&desc->blend_state.RenderTarget[0]); ps_target_info.output_swizzles = ps_output_swizzle; ps_target_info.output_swizzle_count = rt_count;
@@ -2946,11 +3187,11 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s hr = E_INVALIDARG; goto fail; } - if (ps_target_info.dual_source_blending && desc->BlendState.IndependentBlendEnable) + if (ps_target_info.dual_source_blending && desc->blend_state.IndependentBlendEnable) { - for (i = 1; i < ARRAY_SIZE(desc->BlendState.RenderTarget); ++i) + for (i = 1; i < ARRAY_SIZE(desc->blend_state.RenderTarget); ++i) { - if (desc->BlendState.RenderTarget[i].BlendEnable) + if (desc->blend_state.RenderTarget[i].BlendEnable) { WARN("Blend enable cannot be set for render target %u when dual source blending is used.\n", i); hr = E_INVALIDARG; @@ -2992,9 +3233,9 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s xfb_info.buffer_strides = so_desc->pBufferStrides; xfb_info.buffer_stride_count = so_desc->NumStrides;
- if (desc->GS.pShaderBytecode) + if (desc->gs.pShaderBytecode) xfb_stage = VK_SHADER_STAGE_GEOMETRY_BIT; - else if (desc->DS.pShaderBytecode) + else if (desc->ds.pShaderBytecode) xfb_stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; else xfb_stage = VK_SHADER_STAGE_VERTEX_BIT; @@ -3046,7 +3287,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: - if (desc->PrimitiveTopologyType != D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH) + if (desc->primitive_topology_type != D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH) { WARN("D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH must be used with tessellation shaders.\n"); hr = E_INVALIDARG; @@ -3088,7 +3329,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s ++graphics->stage_count; }
- graphics->attribute_count = desc->InputLayout.NumElements; + graphics->attribute_count = desc->input_layout.NumElements; if (graphics->attribute_count > ARRAY_SIZE(graphics->attributes)) { FIXME("InputLayout.NumElements %zu > %zu, ignoring extra elements.\n", @@ -3104,13 +3345,13 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s goto fail; }
- if (FAILED(hr = compute_input_layout_offsets(device, &desc->InputLayout, aligned_offsets))) + if (FAILED(hr = compute_input_layout_offsets(device, &desc->input_layout, aligned_offsets))) goto fail;
graphics->instance_divisor_count = 0; for (i = 0, j = 0, mask = 0; i < graphics->attribute_count; ++i) { - const D3D12_INPUT_ELEMENT_DESC *e = &desc->InputLayout.pInputElementDescs[i]; + const D3D12_INPUT_ELEMENT_DESC *e = &desc->input_layout.pInputElementDescs[i]; const struct vkd3d_shader_signature_element *signature_element;
/* TODO: DXGI_FORMAT_UNKNOWN will succeed here, which may not match @@ -3194,30 +3435,30 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s graphics->attribute_count = j; vkd3d_shader_free_shader_signature(&input_signature);
- switch (desc->IBStripCutValue) + switch (desc->strip_cut_value) { case D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED: case D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF: case D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF: - graphics->index_buffer_strip_cut_value = desc->IBStripCutValue; + graphics->index_buffer_strip_cut_value = desc->strip_cut_value; break; default: - WARN("Invalid index buffer strip cut value %#x.\n", desc->IBStripCutValue); + WARN("Invalid index buffer strip cut value %#x.\n", desc->strip_cut_value); hr = E_INVALIDARG; goto fail; }
is_dsv_format_unknown = graphics->null_attachment_mask & dsv_attachment_mask(graphics);
- rs_desc_from_d3d12(&graphics->rs_desc, &desc->RasterizerState); + rs_desc_from_d3d12(&graphics->rs_desc, &desc->rasterizer_state); have_attachment = graphics->rt_count || graphics->dsv_format || is_dsv_format_unknown; - if ((!have_attachment && !(desc->PS.pShaderBytecode && desc->PS.BytecodeLength)) + if ((!have_attachment && !(desc->ps.pShaderBytecode && desc->ps.BytecodeLength)) || (graphics->xfb_enabled && so_desc->RasterizedStream == D3D12_SO_NO_RASTERIZED_STREAM)) graphics->rs_desc.rasterizerDiscardEnable = VK_TRUE;
rs_stream_info_from_d3d12(&graphics->rs_stream_info, &graphics->rs_desc, so_desc, vk_info); if (vk_info->EXT_depth_clip_enable) - rs_depth_clip_info_from_d3d12(&graphics->rs_depth_clip_info, &graphics->rs_desc, &desc->RasterizerState); + rs_depth_clip_info_from_d3d12(&graphics->rs_depth_clip_info, &graphics->rs_desc, &desc->rasterizer_state);
graphics->ms_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; graphics->ms_desc.pNext = NULL; @@ -3226,16 +3467,23 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s graphics->ms_desc.sampleShadingEnable = VK_FALSE; graphics->ms_desc.minSampleShading = 0.0f; graphics->ms_desc.pSampleMask = NULL; - if (desc->SampleMask != ~0u) + if (desc->sample_mask != ~0u) { assert(DIV_ROUND_UP(sample_count, 32) <= ARRAY_SIZE(graphics->sample_mask)); - graphics->sample_mask[0] = desc->SampleMask; + graphics->sample_mask[0] = desc->sample_mask; graphics->sample_mask[1] = 0xffffffffu; graphics->ms_desc.pSampleMask = graphics->sample_mask; } - graphics->ms_desc.alphaToCoverageEnable = desc->BlendState.AlphaToCoverageEnable; + graphics->ms_desc.alphaToCoverageEnable = desc->blend_state.AlphaToCoverageEnable; graphics->ms_desc.alphaToOneEnable = VK_FALSE;
+ if (desc->view_instancing_desc.ViewInstanceCount) + { + FIXME("View instancing is not supported yet.\n"); + hr = E_INVALIDARG; + goto fail; + } + /* We defer creating the render pass for pipelines wth DSVFormat equal to * DXGI_FORMAT_UNKNOWN. We take the actual DSV format from the bound DSV. */ if (is_dsv_format_unknown) @@ -3269,7 +3517,7 @@ fail: }
HRESULT d3d12_pipeline_state_create_graphics(struct d3d12_device *device, - const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, struct d3d12_pipeline_state **state) + const struct d3d12_pipeline_state_desc *desc, struct d3d12_pipeline_state **state) { struct d3d12_pipeline_state *object; HRESULT hr; @@ -3290,6 +3538,42 @@ HRESULT d3d12_pipeline_state_create_graphics(struct d3d12_device *device, return S_OK; }
+HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindPoint bind_point, + const struct d3d12_pipeline_state_desc *desc, struct d3d12_pipeline_state **state) +{ + struct d3d12_pipeline_state *object; + HRESULT hr; + + if (!(object = vkd3d_calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + switch (bind_point) + { + case VK_PIPELINE_BIND_POINT_COMPUTE: + hr = d3d12_pipeline_state_init_compute(object, device, desc); + break; + + case VK_PIPELINE_BIND_POINT_GRAPHICS: + hr = d3d12_pipeline_state_init_graphics(object, device, desc); + break; + + default: + WARN("Invalid bind point %u.", bind_point); + hr = E_INVALIDARG; + } + + if (FAILED(hr)) + { + vkd3d_free(object); + return hr; + } + + TRACE("Created pipeline state %p.\n", object); + + *state = object; + return S_OK; +} + static enum VkPrimitiveTopology vk_topology_from_d3d12_topology(D3D12_PRIMITIVE_TOPOLOGY topology) { switch (topology) diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 9ef3a6c6..2e5ac747 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -1264,10 +1264,44 @@ static inline bool d3d12_pipeline_state_has_unknown_dsv_format(struct d3d12_pipe return false; }
+struct d3d12_pipeline_state_desc +{ + ID3D12RootSignature *root_signature; + D3D12_SHADER_BYTECODE vs; + D3D12_SHADER_BYTECODE ps; + D3D12_SHADER_BYTECODE ds; + D3D12_SHADER_BYTECODE hs; + D3D12_SHADER_BYTECODE gs; + D3D12_SHADER_BYTECODE cs; + D3D12_STREAM_OUTPUT_DESC stream_output; + D3D12_BLEND_DESC blend_state; + unsigned int sample_mask; + D3D12_RASTERIZER_DESC rasterizer_state; + D3D12_DEPTH_STENCIL_DESC1 depth_stencil_state; + D3D12_INPUT_LAYOUT_DESC input_layout; + D3D12_INDEX_BUFFER_STRIP_CUT_VALUE strip_cut_value; + D3D12_PRIMITIVE_TOPOLOGY_TYPE primitive_topology_type; + D3D12_RT_FORMAT_ARRAY rtv_formats; + DXGI_FORMAT dsv_format; + DXGI_SAMPLE_DESC sample_desc; + D3D12_VIEW_INSTANCING_DESC view_instancing_desc; + unsigned int node_mask; + D3D12_CACHED_PIPELINE_STATE cached_pso; + D3D12_PIPELINE_STATE_FLAGS flags; +}; + +HRESULT pipeline_state_desc_from_d3d12_graphics_desc(struct d3d12_pipeline_state_desc *desc, + const D3D12_GRAPHICS_PIPELINE_STATE_DESC *d3d12_desc); +HRESULT pipeline_state_desc_from_d3d12_compute_desc(struct d3d12_pipeline_state_desc *desc, + const D3D12_COMPUTE_PIPELINE_STATE_DESC *d3d12_desc); +HRESULT pipeline_state_desc_from_d3d12_stream_desc(struct d3d12_pipeline_state_desc *desc, + const D3D12_PIPELINE_STATE_STREAM_DESC *d3d12_desc, VkPipelineBindPoint *vk_bind_point); HRESULT d3d12_pipeline_state_create_compute(struct d3d12_device *device, - const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc, struct d3d12_pipeline_state **state); + const struct d3d12_pipeline_state_desc *desc, struct d3d12_pipeline_state **state); HRESULT d3d12_pipeline_state_create_graphics(struct d3d12_device *device, - const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, struct d3d12_pipeline_state **state); + const struct d3d12_pipeline_state_desc *desc, struct d3d12_pipeline_state **state); +HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindPoint bind_point, + const struct d3d12_pipeline_state_desc *desc, struct d3d12_pipeline_state **state); VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_state *state, D3D12_PRIMITIVE_TOPOLOGY topology, const uint32_t *strides, VkFormat dsv_format, VkRenderPass *vk_render_pass); struct d3d12_pipeline_state *unsafe_impl_from_ID3D12PipelineState(ID3D12PipelineState *iface); @@ -1653,7 +1687,7 @@ struct vkd3d_desc_object_cache
#define VKD3D_DESCRIPTOR_POOL_COUNT 6
-typedef ID3D12Device1 d3d12_device_iface; +typedef ID3D12Device2 d3d12_device_iface;
/* ID3D12Device */ struct d3d12_device