On Sat, May 14, 2022 at 2:38 AM James McDonnell topgamer7@gmail.com wrote:
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.
There is, however, the fact that ID3D11BlendState1 lets you query the description in the form of a D3D11_BLEND_DESC1.
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;
In theory, you are correct. In practice, it doesn't matter. The docs (https://docs.microsoft.com/en-us/windows/win32/api/d3d11_1/ns-d3d11_1-d3d11_...) have this to say:
When you set the LogicOpEnable member of the first element of the RenderTarget array (RenderTarget[0]) to TRUE, you must also set the BlendEnable member of RenderTarget[0] to FALSE, and the IndependentBlendEnable member of this D3D11_BLEND_DESC1 to FALSE. This reflects the limitation in hardware that you can't mix logic operations with blending across multiple render targets, and that when you use a logic operation, you must apply the same logic operation to all render targets.
In other words, the logic op has to be the same for all eight RTs, just like in OpenGL (cf. glLogicOp(3G)) and Vulkan. The D3D11 spec (https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec...) agrees.
Why did MS do this when no hardware actually supports per-RT logic ops? I don't know; maybe they were anticipating such hardware appearing someday.