direct3d: Implement missing blend operations. This is only for Direct3D 9; Direct3D 11 already had this implemented. Fixes #5375.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
diff --git a/include/SDL_blendmode.h b/include/SDL_blendmode.h
index b6d140d..08c9f9d 100644
--- a/include/SDL_blendmode.h
+++ b/include/SDL_blendmode.h
@@ -67,9 +67,8 @@ typedef enum
SDL_BLENDOPERATION_ADD = 0x1, /**< dst + src: supported by all renderers */
SDL_BLENDOPERATION_SUBTRACT = 0x2, /**< dst - src : supported by D3D9, D3D11, OpenGL, OpenGLES */
SDL_BLENDOPERATION_REV_SUBTRACT = 0x3, /**< src - dst : supported by D3D9, D3D11, OpenGL, OpenGLES */
- SDL_BLENDOPERATION_MINIMUM = 0x4, /**< min(dst, src) : supported by D3D11 */
- SDL_BLENDOPERATION_MAXIMUM = 0x5 /**< max(dst, src) : supported by D3D11 */
-
+ SDL_BLENDOPERATION_MINIMUM = 0x4, /**< min(dst, src) : supported by D3D9, D3D11 */
+ SDL_BLENDOPERATION_MAXIMUM = 0x5 /**< max(dst, src) : supported by D3D9, D3D11 */
} SDL_BlendOperation;
/**
@@ -87,7 +86,6 @@ typedef enum
SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR = 0x8, /**< 1-dstR, 1-dstG, 1-dstB, 1-dstA */
SDL_BLENDFACTOR_DST_ALPHA = 0x9, /**< dstA, dstA, dstA, dstA */
SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA = 0xA /**< 1-dstA, 1-dstA, 1-dstA, 1-dstA */
-
} SDL_BlendFactor;
/**
@@ -135,10 +133,10 @@ typedef enum
* SDL 2.0.6. All renderers support the four blend modes listed in the
* SDL_BlendMode enumeration.
*
- * - **direct3d**: Supports `SDL_BLENDOPERATION_ADD` with all factors.
- * - **direct3d11**: Supports all operations with all factors. However, some
+ * - **direct3d**: Supports all operations with all factors. However, some
* factors produce unexpected results with `SDL_BLENDOPERATION_MINIMUM` and
* `SDL_BLENDOPERATION_MAXIMUM`.
+ * - **direct3d11**: Same as Direct3D 9.
* - **opengl**: Supports the `SDL_BLENDOPERATION_ADD` operation with all
* factors. OpenGL versions 1.1, 1.2, and 1.3 do not work correctly with SDL
* 2.0.6.
diff --git a/src/render/direct3d/SDL_render_d3d.c b/src/render/direct3d/SDL_render_d3d.c
index b267fb2..477f4e9 100644
--- a/src/render/direct3d/SDL_render_d3d.c
+++ b/src/render/direct3d/SDL_render_d3d.c
@@ -347,7 +347,8 @@ D3D_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
}
}
-static D3DBLEND GetBlendFunc(SDL_BlendFactor factor)
+static D3DBLEND
+GetBlendFunc(SDL_BlendFactor factor)
{
switch (factor) {
case SDL_BLENDFACTOR_ZERO:
@@ -370,9 +371,28 @@ static D3DBLEND GetBlendFunc(SDL_BlendFactor factor)
return D3DBLEND_DESTALPHA;
case SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA:
return D3DBLEND_INVDESTALPHA;
- default:
- return (D3DBLEND)0;
+ default: break;
}
+ return (D3DBLEND) 0;
+}
+
+static D3DBLENDOP
+GetBlendEquation(SDL_BlendOperation operation)
+{
+ switch (operation) {
+ case SDL_BLENDOPERATION_ADD:
+ return D3DBLENDOP_ADD;
+ case SDL_BLENDOPERATION_SUBTRACT:
+ return D3DBLENDOP_SUBTRACT;
+ case SDL_BLENDOPERATION_REV_SUBTRACT:
+ return D3DBLENDOP_REVSUBTRACT;
+ case SDL_BLENDOPERATION_MINIMUM:
+ return D3DBLENDOP_MIN;
+ case SDL_BLENDOPERATION_MAXIMUM:
+ return D3DBLENDOP_MAX;
+ default: break;
+ }
+ return (D3DBLENDOP) 0;
}
static SDL_bool
@@ -387,14 +407,16 @@ D3D_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
SDL_BlendOperation alphaOperation = SDL_GetBlendModeAlphaOperation(blendMode);
if (!GetBlendFunc(srcColorFactor) || !GetBlendFunc(srcAlphaFactor) ||
- !GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor)) {
+ !GetBlendEquation(colorOperation) ||
+ !GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor) ||
+ !GetBlendEquation(alphaOperation)) {
return SDL_FALSE;
}
- if ((srcColorFactor != srcAlphaFactor || dstColorFactor != dstAlphaFactor) && !data->enableSeparateAlphaBlend) {
- return SDL_FALSE;
- }
- if (colorOperation != SDL_BLENDOPERATION_ADD || alphaOperation != SDL_BLENDOPERATION_ADD) {
- return SDL_FALSE;
+
+ if (!data->enableSeparateAlphaBlend) {
+ if ((srcColorFactor != srcAlphaFactor) || (dstColorFactor != dstAlphaFactor) || (colorOperation != alphaOperation)) {
+ return SDL_FALSE;
+ }
}
return SDL_TRUE;
}
@@ -1040,11 +1062,15 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blend)));
IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
GetBlendFunc(SDL_GetBlendModeDstColorFactor(blend)));
+ IDirect3DDevice9_SetRenderState(data->device, D3DRS_BLENDOP,
+ GetBlendEquation(SDL_GetBlendModeColorOperation(blend)));
if (data->enableSeparateAlphaBlend) {
IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLENDALPHA,
GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blend)));
IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLENDALPHA,
GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blend)));
+ IDirect3DDevice9_SetRenderState(data->device, D3DRS_BLENDOPALPHA,
+ GetBlendEquation(SDL_GetBlendModeAlphaOperation(blend)));
}
}