[PATCH] d3d11: Implement CreateBlendState1 and GetDesc1.

James McDonnell topgamer7 at gmail.com
Sat May 14 02:38:11 CDT 2022


On 2022-05-13 08:55, Henri Verbeet wrote:
> On Thu, 12 May 2022 at 02:04, James McDonnell <topgamer7 at gmail.com> wrote:
>>   static HRESULT STDMETHODCALLTYPE d3d11_device_CreateBlendState1(ID3D11Device2 *iface,
>> -        const D3D11_BLEND_DESC1 *desc, ID3D11BlendState1 **state)
>> +        const D3D11_BLEND_DESC1 *desc, ID3D11BlendState1 **blend_state)
>>   {
>> -    FIXME("iface %p, desc %p, state %p stub!\n", iface, desc, state);
>> +    struct d3d_device *device = impl_from_ID3D11Device2(iface);
>> +    struct d3d_blend_state *object;
>> +    HRESULT hr;
>> +    unsigned i, j;
>> +    D3D11_BLEND_DESC simple_desc;
>>
>> -    return E_NOTIMPL;
>> +    TRACE("iface %p, desc %p, blend_state %p.\n", iface, desc, blend_state);
>> +    FIXME("Logical operations are not implemented.\n");
>> +
>> +    memset(&simple_desc, 0, sizeof(simple_desc));
>> +    simple_desc.AlphaToCoverageEnable = desc->AlphaToCoverageEnable;
>> +    simple_desc.IndependentBlendEnable = desc->IndependentBlendEnable;
>> +    for (i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i)
>> +    {
>> +        j = desc->IndependentBlendEnable ? i : 0;
>> +        simple_desc.RenderTarget[i].BlendEnable = desc->RenderTarget[j].BlendEnable;
>> +        simple_desc.RenderTarget[i].SrcBlend = desc->RenderTarget[j].SrcBlend;
>> +        simple_desc.RenderTarget[i].DestBlend = desc->RenderTarget[j].DestBlend;
>> +        simple_desc.RenderTarget[i].BlendOp = desc->RenderTarget[j].BlendOp;
>> +        simple_desc.RenderTarget[i].SrcBlendAlpha = desc->RenderTarget[j].SrcBlendAlpha;
>> +        simple_desc.RenderTarget[i].DestBlendAlpha = desc->RenderTarget[j].DestBlendAlpha;
>> +        simple_desc.RenderTarget[i].BlendOpAlpha = desc->RenderTarget[j].BlendOpAlpha;
>> +        simple_desc.RenderTarget[i].RenderTargetWriteMask = desc->RenderTarget[j].RenderTargetWriteMask;
>> +    }
>> +
>> +    if (FAILED(hr = d3d_blend_state_create(device, &simple_desc, &object)))
>> +        return hr;
>> +
>> +    *blend_state = (ID3D11BlendState1*)&object->ID3D11BlendState1_iface;
>> +
>> +    return S_OK;
>>   }
> I think at the very least, this patch should modify
> d3d_blend_state_create() to take a D3D11_BLEND_DESC1 structure instead
> of a D3D11_BLEND_DESC structure, and store it in the d3d_blend_state
> structure, so that d3d11_blend_state_GetDesc1() can be properly
> implemented. Ideally there would then also be a follow-up patch to
> handle the new fields in wined3d for both the OpenGL and Vulkan
> backends.

I figured this would be a good introductory step to at least partially 
support software such as Affinity Photo which uses the CreateBlendState1 
instead of it purely being a stub and non-functional.

I agree with you that it makes sense to store and use the DESC1 version 
of the blend state. Which is why I included the fixme warning about the 
LogicOp. However I have spent a  limited amount of time trying to 
understand OpenGL/Vulkan.

I would think that the step to update blend state to DESC1 should be 
done at the same time as the update for opengl and vulkan. Because 
without doing that work you can't actually test the differences that 
DESC1 puts in place anyway.

 From what I could tell, the vulkan struct doesn't neatly line up with 
the d3d struct however:

typedef struct VkPipelineColorBlendAttachmentState
{
     VkBool32 blendEnable;
     VkBlendFactor srcColorBlendFactor;
     VkBlendFactor dstColorBlendFactor;
     VkBlendOp colorBlendOp;
     VkBlendFactor srcAlphaBlendFactor;
     VkBlendFactor dstAlphaBlendFactor;
     VkBlendOp alphaBlendOp;
     VkColorComponentFlags colorWriteMask;
} VkPipelineColorBlendAttachmentState;

typedef struct VkPipelineColorBlendStateCreateInfo
{
     VkStructureType sType;
     const void *pNext;
     VkPipelineColorBlendStateCreateFlags flags;
     VkBool32 logicOpEnable;
     VkLogicOp logicOp;
     uint32_t attachmentCount;
     const VkPipelineColorBlendAttachmentState *pAttachments;
     float blendConstants[4];
} VkPipelineColorBlendStateCreateInfo;

---

typedef struct D3D11_RENDER_TARGET_BLEND_DESC1
{
     BOOL           BlendEnable;
     BOOL           LogicOpEnable;
     D3D11_BLEND    SrcBlend;
     D3D11_BLEND    DestBlend;
     D3D11_BLEND_OP BlendOp;
     D3D11_BLEND    SrcBlendAlpha;
     D3D11_BLEND    DestBlendAlpha;
     D3D11_BLEND_OP BlendOpAlpha;
     D3D11_LOGIC_OP LogicOp;
     UINT8          RenderTargetWriteMask;
} D3D11_RENDER_TARGET_BLEND_DESC1;

typedef struct D3D11_BLEND_DESC1
{
     BOOL                            AlphaToCoverageEnable;
     BOOL                            IndependentBlendEnable;
     D3D11_RENDER_TARGET_BLEND_DESC1 
RenderTarget[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
} D3D11_BLEND_DESC1;




More information about the wine-devel mailing list