From: Chip Davis cdavis5x@gmail.com
Signed-off-by: Chip Davis cdavis5x@gmail.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v3: fix the clear color...
dlls/d3d11/tests/d3d11.c | 166 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 6c0ae089f78..99f304e5b68 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -34034,6 +34034,171 @@ static void test_user_defined_annotation(void) release_test_context(&test_context); }
+static void test_logic_op(void) +{ + D3D11_FEATURE_DATA_D3D11_OPTIONS options; + struct d3d11_test_context test_context; + D3D11_TEXTURE2D_DESC texture_desc; + ID3D11RenderTargetView *rtvs[8]; + ID3D11BlendState1 *blend_state; + ID3D11DeviceContext *context; + struct resource_readback rb; + ID3D11Texture2D *rts[8]; + ID3D11Device1 *device1; + ID3D11PixelShader *ps; + ID3D11Device *device; + unsigned int i, j; + DWORD color; + HRESULT hr; + + static const DWORD ps_code[] = + { +#if 0 + void main(float4 position : SV_Position, + out uint4 t0 : SV_Target0, out uint4 t1 : SV_Target1, + out uint4 t2 : SV_Target2, out uint4 t3 : SV_Target3, + out uint4 t4 : SV_Target4, out uint4 t5 : SV_Target5, + out uint4 t6 : SV_Target6, out uint4 t7 : SV_Target7) + { + t0 = t1 = t2 = t3 = t4 = t5 = t6 = t7 = uint4(0x00, 0x00, 0xff, 0xff); + } +#endif + 0x43425844, 0x4ed0bba7, 0x9f7d54c4, 0xba1e3dce, 0xc29634f8, 0x00000001, 0x000002b0, 0x00000003, + 0x0000002c, 0x00000060, 0x0000013c, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, + 0x4e47534f, 0x000000d4, 0x00000008, 0x00000008, 0x000000c8, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x0000000f, 0x000000c8, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x0000000f, + 0x000000c8, 0x00000002, 0x00000000, 0x00000001, 0x00000002, 0x0000000f, 0x000000c8, 0x00000003, + 0x00000000, 0x00000001, 0x00000003, 0x0000000f, 0x000000c8, 0x00000004, 0x00000000, 0x00000001, + 0x00000004, 0x0000000f, 0x000000c8, 0x00000005, 0x00000000, 0x00000001, 0x00000005, 0x0000000f, + 0x000000c8, 0x00000006, 0x00000000, 0x00000001, 0x00000006, 0x0000000f, 0x000000c8, 0x00000007, + 0x00000000, 0x00000001, 0x00000007, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, + 0x0000016c, 0x00000040, 0x0000005b, 0x03000065, 0x001020f2, 0x00000000, 0x03000065, 0x001020f2, + 0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x03000065, 0x001020f2, 0x00000003, 0x03000065, + 0x001020f2, 0x00000004, 0x03000065, 0x001020f2, 0x00000005, 0x03000065, 0x001020f2, 0x00000006, + 0x03000065, 0x001020f2, 0x00000007, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x00000000, + 0x00000000, 0x000000ff, 0x000000ff, 0x08000036, 0x001020f2, 0x00000001, 0x00004002, 0x00000000, + 0x00000000, 0x000000ff, 0x000000ff, 0x08000036, 0x001020f2, 0x00000002, 0x00004002, 0x00000000, + 0x00000000, 0x000000ff, 0x000000ff, 0x08000036, 0x001020f2, 0x00000003, 0x00004002, 0x00000000, + 0x00000000, 0x000000ff, 0x000000ff, 0x08000036, 0x001020f2, 0x00000004, 0x00004002, 0x00000000, + 0x00000000, 0x000000ff, 0x000000ff, 0x08000036, 0x001020f2, 0x00000005, 0x00004002, 0x00000000, + 0x00000000, 0x000000ff, 0x000000ff, 0x08000036, 0x001020f2, 0x00000006, 0x00004002, 0x00000000, + 0x00000000, 0x000000ff, 0x000000ff, 0x08000036, 0x001020f2, 0x00000007, 0x00004002, 0x00000000, + 0x00000000, 0x000000ff, 0x000000ff, 0x0100003e + }; + + D3D11_BLEND_DESC1 blend_desc = + { + .IndependentBlendEnable = TRUE, + .RenderTarget = + { + {FALSE, TRUE, D3D11_BLEND_ONE, D3D11_BLEND_ZERO, D3D11_BLEND_OP_ADD, + D3D11_BLEND_ONE, D3D11_BLEND_ZERO, D3D11_BLEND_OP_ADD, D3D11_LOGIC_OP_CLEAR, + D3D11_COLOR_WRITE_ENABLE_ALL}, + {FALSE, TRUE, D3D11_BLEND_ONE, D3D11_BLEND_ZERO, D3D11_BLEND_OP_ADD, + D3D11_BLEND_ZERO, D3D11_BLEND_ONE, D3D11_BLEND_OP_ADD, D3D11_LOGIC_OP_CLEAR, + D3D11_COLOR_WRITE_ENABLE_ALL}, + }, + }; + + static const struct + { + D3D11_LOGIC_OP op; + DWORD color; + } + tests[] = + { + {D3D11_LOGIC_OP_CLEAR, 0x00000000}, + {D3D11_LOGIC_OP_NOR, 0x000000ff}, + {D3D11_LOGIC_OP_AND_INVERTED, 0x0000ff00}, + {D3D11_LOGIC_OP_COPY_INVERTED, 0x0000ffff}, + {D3D11_LOGIC_OP_AND_REVERSE, 0x00ff0000}, + {D3D11_LOGIC_OP_INVERT, 0x00ff00ff}, + {D3D11_LOGIC_OP_XOR, 0x00ffff00}, + {D3D11_LOGIC_OP_NAND, 0x00ffffff}, + {D3D11_LOGIC_OP_AND, 0xff000000}, + {D3D11_LOGIC_OP_EQUIV, 0xff0000ff}, + {D3D11_LOGIC_OP_NOOP, 0xff00ff00}, + {D3D11_LOGIC_OP_OR_INVERTED, 0xff00ffff}, + {D3D11_LOGIC_OP_COPY, 0xffff0000}, + {D3D11_LOGIC_OP_OR_REVERSE, 0xffff00ff}, + {D3D11_LOGIC_OP_OR, 0xffffff00}, + {D3D11_LOGIC_OP_SET, 0xffffffff}, + }; + static const float clear_color[] = {0.0f, 255.0f, 0.0f, 255.0f}; + + if (!init_test_context(&test_context, NULL)) + return; + device = test_context.device; + context = test_context.immediate_context; + + if (FAILED(hr = ID3D11Device_CheckFeatureSupport(device, D3D11_FEATURE_D3D11_OPTIONS, &options, sizeof(options))) + || !options.OutputMergerLogicOp) + { + skip("Logic op is not supported.\n"); + release_test_context(&test_context); + return; + } + + hr = ID3D11Device_QueryInterface(device, &IID_ID3D11Device1, (void **)&device1); + ok(hr == S_OK, "Failed to get ID3D11Device1 interface, hr %#lx.\n", hr); + + hr = ID3D11Device_CreatePixelShader(device, ps_code, sizeof(ps_code), NULL, &ps); + ok(hr == S_OK, "Failed to create pixel shader, hr %#lx.\n", hr); + ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0); + + hr = ID3D11Device1_CreateBlendState1(device1, &blend_desc, &blend_state); + ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr); + + blend_desc.IndependentBlendEnable = FALSE; + hr = ID3D11Device1_CreateBlendState1(device1, &blend_desc, &blend_state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ID3D11BlendState1_Release(blend_state); + + ID3D11Texture2D_GetDesc(test_context.backbuffer, &texture_desc); + texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UINT; + for (i = 0; i < 8; ++i) + { + hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, &rts[i]); + ok(hr == S_OK, "Failed to create texture %u, hr %#lx.\n", i, hr); + + hr = ID3D11Device_CreateRenderTargetView(device, (ID3D11Resource *)rts[i], NULL, &rtvs[i]); + ok(hr == S_OK, "Failed to create rendertarget view %u, hr %#lx.\n", i, hr); + } + + ID3D11DeviceContext_OMSetRenderTargets(context, 8, rtvs, NULL); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + blend_desc.RenderTarget[0].LogicOp = tests[i].op; + hr = ID3D11Device1_CreateBlendState1(device1, &blend_desc, &blend_state); + ok(hr == S_OK, "Failed to create blend state, hr %#lx.\n", hr); + ID3D11DeviceContext_OMSetBlendState(context, (ID3D11BlendState *)blend_state, NULL, D3D11_DEFAULT_SAMPLE_MASK); + ID3D11BlendState1_Release(blend_state); + + for (j = 0; j < 8; ++j) + ID3D11DeviceContext_ClearRenderTargetView(context, rtvs[j], clear_color); + draw_quad(&test_context); + + for (j = 0; j < 8; ++j) + { + get_texture_readback(rts[j], 0, &rb); + color = get_readback_color(&rb, 320, 240, 0); + ok(compare_color(color, tests[i].color, 1), "%u: Got unexpected color 0x%08lx.\n", i, color); + release_resource_readback(&rb); + } + } + + for (i = 0; i < 8; i++) + { + ID3D11Texture2D_Release(rts[i]); + ID3D11RenderTargetView_Release(rtvs[i]); + } + ID3D11PixelShader_Release(ps); + ID3D11Device1_Release(device1); + release_test_context(&test_context); +} + START_TEST(d3d11) { unsigned int argc, i; @@ -34214,6 +34379,7 @@ START_TEST(d3d11) queue_test(test_constant_buffer_offset); queue_test(test_dynamic_map_synchronization); queue_test(test_user_defined_annotation); + queue_test(test_logic_op);
run_queued_tests();
From: Chip Davis cdavis5x@gmail.com
Signed-off-by: Chip Davis cdavis5x@gmail.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v3: Add a FIXME for translation of the logic op to wined3d.
dlls/d3d11/d3d11_private.h | 12 ++--- dlls/d3d11/device.c | 65 ++++++++++++++++-------- dlls/d3d11/state.c | 100 +++++++++++++++++++++++++------------ 3 files changed, 118 insertions(+), 59 deletions(-)
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index efe26551258..29a01dd91ad 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -408,26 +408,26 @@ struct d3d11_class_linkage HRESULT d3d11_class_linkage_create(struct d3d_device *device, struct d3d11_class_linkage **class_linkage) DECLSPEC_HIDDEN;
-/* ID3D11BlendState, ID3D10BlendState1 */ +/* ID3D11BlendState1, ID3D10BlendState1 */ struct d3d_blend_state { - ID3D11BlendState ID3D11BlendState_iface; + ID3D11BlendState1 ID3D11BlendState1_iface; ID3D10BlendState1 ID3D10BlendState1_iface; LONG refcount;
struct wined3d_private_store private_store; struct wined3d_blend_state *wined3d_state; - D3D11_BLEND_DESC desc; + D3D11_BLEND_DESC1 desc; struct wine_rb_entry entry; ID3D11Device2 *device; };
-static inline struct d3d_blend_state *impl_from_ID3D11BlendState(ID3D11BlendState *iface) +static inline struct d3d_blend_state *impl_from_ID3D11BlendState1(ID3D11BlendState1 *iface) { - return CONTAINING_RECORD(iface, struct d3d_blend_state, ID3D11BlendState_iface); + return CONTAINING_RECORD(iface, struct d3d_blend_state, ID3D11BlendState1_iface); }
-HRESULT d3d_blend_state_create(struct d3d_device *device, const D3D11_BLEND_DESC *desc, +HRESULT d3d_blend_state_create(struct d3d_device *device, const D3D11_BLEND_DESC1 *desc, struct d3d_blend_state **state) DECLSPEC_HIDDEN; struct d3d_blend_state *unsafe_impl_from_ID3D11BlendState(ID3D11BlendState *iface) DECLSPEC_HIDDEN; struct d3d_blend_state *unsafe_impl_from_ID3D10BlendState(ID3D10BlendState *iface) DECLSPEC_HIDDEN; diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index ecf45e9ce33..263613911f8 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -2204,7 +2204,7 @@ static void STDMETHODCALLTYPE d3d11_device_context_OMGetBlendState(ID3D11DeviceC if (wined3d_state) { blend_state_impl = wined3d_blend_state_get_parent(wined3d_state); - ID3D11BlendState_AddRef(*blend_state = &blend_state_impl->ID3D11BlendState_iface); + ID3D11BlendState_AddRef(*blend_state = (ID3D11BlendState *)&blend_state_impl->ID3D11BlendState1_iface); } else *blend_state = NULL; @@ -3632,23 +3632,53 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CreateClassLinkage(ID3D11Device2 * return S_OK; }
-static HRESULT STDMETHODCALLTYPE d3d11_device_CreateBlendState(ID3D11Device2 *iface, - const D3D11_BLEND_DESC *desc, ID3D11BlendState **blend_state) +static HRESULT STDMETHODCALLTYPE d3d11_device_CreateBlendState1(ID3D11Device2 *iface, + const D3D11_BLEND_DESC1 *desc, ID3D11BlendState1 **state) { struct d3d_device *device = impl_from_ID3D11Device2(iface); struct d3d_blend_state *object; HRESULT hr;
- TRACE("iface %p, desc %p, blend_state %p.\n", iface, desc, blend_state); + TRACE("iface %p, desc %p, state %p.\n", iface, desc, state);
if (FAILED(hr = d3d_blend_state_create(device, desc, &object))) return hr;
- *blend_state = &object->ID3D11BlendState_iface; + *state = &object->ID3D11BlendState1_iface;
return S_OK; }
+static HRESULT STDMETHODCALLTYPE d3d11_device_CreateBlendState(ID3D11Device2 *iface, + const D3D11_BLEND_DESC *desc, ID3D11BlendState **blend_state) +{ + D3D11_BLEND_DESC1 d3d11_1_desc; + unsigned int i; + + TRACE("iface %p, desc %p, blend_state %p.\n", iface, desc, blend_state); + + if (!desc) + return E_INVALIDARG; + + d3d11_1_desc.AlphaToCoverageEnable = desc->AlphaToCoverageEnable; + d3d11_1_desc.IndependentBlendEnable = desc->IndependentBlendEnable; + for (i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + { + d3d11_1_desc.RenderTarget[i].BlendEnable = desc->RenderTarget[i].BlendEnable; + d3d11_1_desc.RenderTarget[i].LogicOpEnable = FALSE; + d3d11_1_desc.RenderTarget[i].SrcBlend = desc->RenderTarget[i].SrcBlend; + d3d11_1_desc.RenderTarget[i].DestBlend = desc->RenderTarget[i].DestBlend; + d3d11_1_desc.RenderTarget[i].BlendOp = desc->RenderTarget[i].BlendOp; + d3d11_1_desc.RenderTarget[i].SrcBlendAlpha = desc->RenderTarget[i].SrcBlendAlpha; + d3d11_1_desc.RenderTarget[i].DestBlendAlpha = desc->RenderTarget[i].DestBlendAlpha; + d3d11_1_desc.RenderTarget[i].BlendOpAlpha = desc->RenderTarget[i].BlendOpAlpha; + d3d11_1_desc.RenderTarget[i].LogicOp = D3D11_LOGIC_OP_COPY; + d3d11_1_desc.RenderTarget[i].RenderTargetWriteMask = desc->RenderTarget[i].RenderTargetWriteMask; + } + + return d3d11_device_CreateBlendState1(iface, &d3d11_1_desc, (ID3D11BlendState1 **)blend_state); +} + static HRESULT STDMETHODCALLTYPE d3d11_device_CreateDepthStencilState(ID3D11Device2 *iface, const D3D11_DEPTH_STENCIL_DESC *desc, ID3D11DepthStencilState **depth_stencil_state) { @@ -4281,14 +4311,6 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CreateDeferredContext1(ID3D11Devic return S_OK; }
-static HRESULT STDMETHODCALLTYPE d3d11_device_CreateBlendState1(ID3D11Device2 *iface, - const D3D11_BLEND_DESC1 *desc, ID3D11BlendState1 **state) -{ - FIXME("iface %p, desc %p, state %p stub!\n", iface, desc, state); - - return E_NOTIMPL; -} - static HRESULT STDMETHODCALLTYPE d3d11_device_CreateRasterizerState1(ID3D11Device2 *iface, const D3D11_RASTERIZER_DESC1 *desc, ID3D11RasterizerState1 **state) { @@ -4993,7 +5015,8 @@ static void STDMETHODCALLTYPE d3d10_device_OMSetBlendState(ID3D10Device1 *iface,
blend_state_object = unsafe_impl_from_ID3D10BlendState(blend_state); d3d11_device_context_OMSetBlendState(&device->immediate_context.ID3D11DeviceContext1_iface, - blend_state_object ? &blend_state_object->ID3D11BlendState_iface : NULL, blend_factor, sample_mask); + blend_state_object ? (ID3D11BlendState *)&blend_state_object->ID3D11BlendState1_iface : NULL, + blend_factor, sample_mask); }
static void STDMETHODCALLTYPE d3d10_device_OMSetDepthStencilState(ID3D10Device1 *iface, @@ -5670,7 +5693,8 @@ static void STDMETHODCALLTYPE d3d10_device_OMGetBlendState(ID3D10Device1 *iface, { if (d3d11_blend_state) { - *blend_state = (ID3D10BlendState *)&impl_from_ID3D11BlendState(d3d11_blend_state)->ID3D10BlendState1_iface; + *blend_state = (ID3D10BlendState *)&impl_from_ID3D11BlendState1( + (ID3D11BlendState1 *)d3d11_blend_state)->ID3D10BlendState1_iface; ID3D10BlendState_AddRef(*blend_state); } else @@ -6267,16 +6291,15 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateBlendState1(ID3D10Device1 *i const D3D10_BLEND_DESC1 *desc, ID3D10BlendState1 **blend_state) { struct d3d_device *device = impl_from_ID3D10Device(iface); - struct d3d_blend_state *object; + ID3D11BlendState *object; HRESULT hr;
TRACE("iface %p, desc %p, blend_state %p.\n", iface, desc, blend_state);
- if (FAILED(hr = d3d_blend_state_create(device, (const D3D11_BLEND_DESC *)desc, &object))) + if (FAILED(hr = d3d11_device_CreateBlendState(&device->ID3D11Device2_iface, (const D3D11_BLEND_DESC *)desc, &object))) return hr;
- *blend_state = &object->ID3D10BlendState1_iface; - + *blend_state = &impl_from_ID3D11BlendState1((ID3D11BlendState1 *)object)->ID3D10BlendState1_iface; return S_OK; }
@@ -6867,8 +6890,8 @@ static int d3d_sampler_state_compare(const void *key, const struct wine_rb_entry
static int d3d_blend_state_compare(const void *key, const struct wine_rb_entry *entry) { - const D3D11_BLEND_DESC *ka = key; - const D3D11_BLEND_DESC *kb = &WINE_RB_ENTRY_VALUE(entry, const struct d3d_blend_state, entry)->desc; + const D3D11_BLEND_DESC1 *ka = key; + const D3D11_BLEND_DESC1 *kb = &WINE_RB_ENTRY_VALUE(entry, const struct d3d_blend_state, entry)->desc;
return memcmp(ka, kb, sizeof(*ka)); } diff --git a/dlls/d3d11/state.c b/dlls/d3d11/state.c index f67017ff1ef..94b6d712945 100644 --- a/dlls/d3d11/state.c +++ b/dlls/d3d11/state.c @@ -21,20 +21,21 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d11);
-/* ID3D11BlendState methods */ +/* ID3D11BlendState1 methods */
-static HRESULT STDMETHODCALLTYPE d3d11_blend_state_QueryInterface(ID3D11BlendState *iface, +static HRESULT STDMETHODCALLTYPE d3d11_blend_state_QueryInterface(ID3D11BlendState1 *iface, REFIID riid, void **object) { - struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface); + struct d3d_blend_state *state = impl_from_ID3D11BlendState1(iface);
TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
if (IsEqualGUID(riid, &IID_ID3D11BlendState) + || IsEqualGUID(riid, &IID_ID3D11BlendState1) || IsEqualGUID(riid, &IID_ID3D11DeviceChild) || IsEqualGUID(riid, &IID_IUnknown)) { - ID3D11BlendState_AddRef(iface); + ID3D11BlendState1_AddRef(iface); *object = iface; return S_OK; } @@ -54,9 +55,9 @@ static HRESULT STDMETHODCALLTYPE d3d11_blend_state_QueryInterface(ID3D11BlendSta return E_NOINTERFACE; }
-static ULONG STDMETHODCALLTYPE d3d11_blend_state_AddRef(ID3D11BlendState *iface) +static ULONG STDMETHODCALLTYPE d3d11_blend_state_AddRef(ID3D11BlendState1 *iface) { - struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface); + struct d3d_blend_state *state = impl_from_ID3D11BlendState1(iface); ULONG refcount = InterlockedIncrement(&state->refcount);
TRACE("%p increasing refcount to %lu.\n", state, refcount); @@ -70,9 +71,9 @@ static ULONG STDMETHODCALLTYPE d3d11_blend_state_AddRef(ID3D11BlendState *iface) return refcount; }
-static ULONG STDMETHODCALLTYPE d3d11_blend_state_Release(ID3D11BlendState *iface) +static ULONG STDMETHODCALLTYPE d3d11_blend_state_Release(ID3D11BlendState1 *iface) { - struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface); + struct d3d_blend_state *state = impl_from_ID3D11BlendState1(iface); ULONG refcount = InterlockedDecrement(&state->refcount);
TRACE("%p decreasing refcount to %lu.\n", state, refcount); @@ -87,10 +88,10 @@ static ULONG STDMETHODCALLTYPE d3d11_blend_state_Release(ID3D11BlendState *iface return refcount; }
-static void STDMETHODCALLTYPE d3d11_blend_state_GetDevice(ID3D11BlendState *iface, +static void STDMETHODCALLTYPE d3d11_blend_state_GetDevice(ID3D11BlendState1 *iface, ID3D11Device **device) { - struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface); + struct d3d_blend_state *state = impl_from_ID3D11BlendState1(iface);
TRACE("iface %p, device %p.\n", iface, device);
@@ -98,46 +99,69 @@ static void STDMETHODCALLTYPE d3d11_blend_state_GetDevice(ID3D11BlendState *ifac ID3D11Device_AddRef(*device); }
-static HRESULT STDMETHODCALLTYPE d3d11_blend_state_GetPrivateData(ID3D11BlendState *iface, +static HRESULT STDMETHODCALLTYPE d3d11_blend_state_GetPrivateData(ID3D11BlendState1 *iface, REFGUID guid, UINT *data_size, void *data) { - struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface); + struct d3d_blend_state *state = impl_from_ID3D11BlendState1(iface);
TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
return d3d_get_private_data(&state->private_store, guid, data_size, data); }
-static HRESULT STDMETHODCALLTYPE d3d11_blend_state_SetPrivateData(ID3D11BlendState *iface, +static HRESULT STDMETHODCALLTYPE d3d11_blend_state_SetPrivateData(ID3D11BlendState1 *iface, REFGUID guid, UINT data_size, const void *data) { - struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface); + struct d3d_blend_state *state = impl_from_ID3D11BlendState1(iface);
TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
return d3d_set_private_data(&state->private_store, guid, data_size, data); }
-static HRESULT STDMETHODCALLTYPE d3d11_blend_state_SetPrivateDataInterface(ID3D11BlendState *iface, +static HRESULT STDMETHODCALLTYPE d3d11_blend_state_SetPrivateDataInterface(ID3D11BlendState1 *iface, REFGUID guid, const IUnknown *data) { - struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface); + struct d3d_blend_state *state = impl_from_ID3D11BlendState1(iface);
TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
return d3d_set_private_data_interface(&state->private_store, guid, data); }
-static void STDMETHODCALLTYPE d3d11_blend_state_GetDesc(ID3D11BlendState *iface, D3D11_BLEND_DESC *desc) +static void STDMETHODCALLTYPE d3d11_blend_state_GetDesc(ID3D11BlendState1 *iface, D3D11_BLEND_DESC *desc) { - struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface); + struct d3d_blend_state *state = impl_from_ID3D11BlendState1(iface); + const D3D11_BLEND_DESC1 *d3d11_desc = &state->desc; + unsigned int i; + + TRACE("iface %p, desc %p.\n", iface, desc); + + desc->AlphaToCoverageEnable = d3d11_desc->AlphaToCoverageEnable; + desc->IndependentBlendEnable = d3d11_desc->IndependentBlendEnable; + for (i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + { + desc->RenderTarget[i].BlendEnable = d3d11_desc->RenderTarget[i].BlendEnable; + desc->RenderTarget[i].SrcBlend = d3d11_desc->RenderTarget[i].SrcBlend; + desc->RenderTarget[i].DestBlend = d3d11_desc->RenderTarget[i].DestBlend; + desc->RenderTarget[i].BlendOp = d3d11_desc->RenderTarget[i].BlendOp; + desc->RenderTarget[i].SrcBlendAlpha = d3d11_desc->RenderTarget[i].SrcBlendAlpha; + desc->RenderTarget[i].DestBlendAlpha = d3d11_desc->RenderTarget[i].DestBlendAlpha; + desc->RenderTarget[i].BlendOpAlpha = d3d11_desc->RenderTarget[i].BlendOpAlpha; + desc->RenderTarget[i].RenderTargetWriteMask = d3d11_desc->RenderTarget[i].RenderTargetWriteMask; + } +} + +static void STDMETHODCALLTYPE d3d11_blend_state_GetDesc1(ID3D11BlendState1 *iface, D3D11_BLEND_DESC1 *desc) +{ + struct d3d_blend_state *state = impl_from_ID3D11BlendState1(iface);
TRACE("iface %p, desc %p.\n", iface, desc);
*desc = state->desc; }
-static const struct ID3D11BlendStateVtbl d3d11_blend_state_vtbl = +static const struct ID3D11BlendState1Vtbl d3d11_blend_state_vtbl = { /* IUnknown methods */ d3d11_blend_state_QueryInterface, @@ -150,6 +174,8 @@ static const struct ID3D11BlendStateVtbl d3d11_blend_state_vtbl = d3d11_blend_state_SetPrivateDataInterface, /* ID3D11BlendState methods */ d3d11_blend_state_GetDesc, + /* ID3D11BlendState1 methods */ + d3d11_blend_state_GetDesc1, };
/* ID3D10BlendState methods */ @@ -168,7 +194,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_blend_state_QueryInterface(ID3D10BlendSta
TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
- return d3d11_blend_state_QueryInterface(&state->ID3D11BlendState_iface, riid, object); + return d3d11_blend_state_QueryInterface(&state->ID3D11BlendState1_iface, riid, object); }
static ULONG STDMETHODCALLTYPE d3d10_blend_state_AddRef(ID3D10BlendState1 *iface) @@ -177,7 +203,7 @@ static ULONG STDMETHODCALLTYPE d3d10_blend_state_AddRef(ID3D10BlendState1 *iface
TRACE("iface %p.\n", iface);
- return d3d11_blend_state_AddRef(&state->ID3D11BlendState_iface); + return d3d11_blend_state_AddRef(&state->ID3D11BlendState1_iface); }
static ULONG STDMETHODCALLTYPE d3d10_blend_state_Release(ID3D10BlendState1 *iface) @@ -186,7 +212,7 @@ static ULONG STDMETHODCALLTYPE d3d10_blend_state_Release(ID3D10BlendState1 *ifac
TRACE("iface %p.\n", iface);
- return d3d11_blend_state_Release(&state->ID3D11BlendState_iface); + return d3d11_blend_state_Release(&state->ID3D11BlendState1_iface); }
/* ID3D10DeviceChild methods */ @@ -247,7 +273,7 @@ static D3D10_BLEND_OP d3d10_blend_op_from_d3d11(D3D11_BLEND_OP op) static void STDMETHODCALLTYPE d3d10_blend_state_GetDesc(ID3D10BlendState1 *iface, D3D10_BLEND_DESC *desc) { struct d3d_blend_state *state = impl_from_ID3D10BlendState(iface); - const D3D11_BLEND_DESC *d3d11_desc = &state->desc; + const D3D11_BLEND_DESC1 *d3d11_desc = &state->desc; unsigned int i;
TRACE("iface %p, desc %p.\n", iface, desc); @@ -272,7 +298,7 @@ static void STDMETHODCALLTYPE d3d10_blend_state_GetDesc1(ID3D10BlendState1 *ifac
TRACE("iface %p, desc %p.\n", iface, desc);
- memcpy(desc, &state->desc, sizeof(*desc)); + d3d11_blend_state_GetDesc(&state->ID3D11BlendState1_iface, (D3D11_BLEND_DESC *)desc); }
static const struct ID3D10BlendState1Vtbl d3d10_blend_state_vtbl = @@ -317,21 +343,21 @@ static enum wined3d_blend_op wined3d_blend_op_from_d3d11(D3D11_BLEND_OP op) return (enum wined3d_blend_op)op; }
-HRESULT d3d_blend_state_create(struct d3d_device *device, const D3D11_BLEND_DESC *desc, +HRESULT d3d_blend_state_create(struct d3d_device *device, const D3D11_BLEND_DESC1 *desc, struct d3d_blend_state **state) { struct wined3d_blend_state_desc wined3d_desc; struct d3d_blend_state *object; struct wine_rb_entry *entry; - D3D11_BLEND_DESC tmp_desc; + D3D11_BLEND_DESC1 tmp_desc; unsigned int i, j; HRESULT hr;
if (!desc) return E_INVALIDARG;
- /* D3D11_RENDER_TARGET_BLEND_DESC has a hole, which is a problem because we use - * D3D11_BLEND_DESC as a key in the rbtree. */ + /* D3D11_RENDER_TARGET_BLEND_DESC1 has a hole, which is a problem because we use + * D3D11_BLEND_DESC1 as a key in the rbtree. */ memset(&tmp_desc, 0, sizeof(tmp_desc)); tmp_desc.AlphaToCoverageEnable = desc->AlphaToCoverageEnable; tmp_desc.IndependentBlendEnable = desc->IndependentBlendEnable; @@ -357,6 +383,13 @@ HRESULT d3d_blend_state_create(struct d3d_device *device, const D3D11_BLEND_DESC tmp_desc.RenderTarget[i].DestBlendAlpha = D3D11_BLEND_ZERO; tmp_desc.RenderTarget[i].BlendOpAlpha = D3D11_BLEND_OP_ADD; } + + tmp_desc.RenderTarget[i].LogicOpEnable = desc->RenderTarget[j].LogicOpEnable; + if (tmp_desc.RenderTarget[i].LogicOpEnable) + tmp_desc.RenderTarget[i].LogicOp = desc->RenderTarget[j].LogicOp; + else + tmp_desc.RenderTarget[i].LogicOp = D3D11_LOGIC_OP_NOOP; + tmp_desc.RenderTarget[i].RenderTargetWriteMask = desc->RenderTarget[j].RenderTargetWriteMask; }
@@ -366,7 +399,7 @@ HRESULT d3d_blend_state_create(struct d3d_device *device, const D3D11_BLEND_DESC object = WINE_RB_ENTRY_VALUE(entry, struct d3d_blend_state, entry);
TRACE("Returning existing blend state %p.\n", object); - ID3D11BlendState_AddRef(&object->ID3D11BlendState_iface); + ID3D11BlendState1_AddRef(&object->ID3D11BlendState1_iface); *state = object; wined3d_mutex_unlock();
@@ -379,7 +412,7 @@ HRESULT d3d_blend_state_create(struct d3d_device *device, const D3D11_BLEND_DESC return E_OUTOFMEMORY; }
- object->ID3D11BlendState_iface.lpVtbl = &d3d11_blend_state_vtbl; + object->ID3D11BlendState1_iface.lpVtbl = &d3d11_blend_state_vtbl; object->ID3D10BlendState1_iface.lpVtbl = &d3d10_blend_state_vtbl; object->refcount = 1; wined3d_private_store_init(&object->private_store); @@ -408,6 +441,9 @@ HRESULT d3d_blend_state_create(struct d3d_device *device, const D3D11_BLEND_DESC wined3d_desc.rt[i].writemask = desc->RenderTarget[i].RenderTargetWriteMask; }
+ if (desc->RenderTarget[0].LogicOpEnable && desc->RenderTarget[0].LogicOp != D3D11_LOGIC_OP_NOOP) + FIXME("Ignoring logic op %#x.\n", desc->RenderTarget[0].LogicOp); + /* We cannot fail after creating a wined3d_blend_state object. It * would lead to double free. */ if (FAILED(hr = wined3d_blend_state_create(device->wined3d_device, &wined3d_desc, @@ -434,9 +470,9 @@ struct d3d_blend_state *unsafe_impl_from_ID3D11BlendState(ID3D11BlendState *ifac { if (!iface) return NULL; - assert(iface->lpVtbl == &d3d11_blend_state_vtbl); + assert(iface->lpVtbl == (ID3D11BlendStateVtbl *)&d3d11_blend_state_vtbl);
- return impl_from_ID3D11BlendState(iface); + return impl_from_ID3D11BlendState1((ID3D11BlendState1 *)iface); }
struct d3d_blend_state *unsafe_impl_from_ID3D10BlendState(ID3D10BlendState *iface)
From: Stefan Dösinger stefan@codeweavers.com
Signed-off-by: Stefan Dösinger stefan@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/device.c | 4 +-- dlls/wined3d/resource.c | 16 +++++----- dlls/wined3d/utils.c | 58 ++++++++++++++++++++++++---------- dlls/wined3d/wined3d_private.h | 4 +-- 4 files changed, 53 insertions(+), 29 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 8937c7fc0fc..d39634c49fc 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3689,7 +3689,7 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO diffuse_colour = material_diffuse; } wined3d_color_clamp(&diffuse_colour, &diffuse_colour, 0.0f, 1.0f); - *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_colour_format, &diffuse_colour); + wined3d_format_convert_from_float(output_colour_format, &diffuse_colour, dest_ptr); dest_ptr += sizeof(DWORD); }
@@ -3713,7 +3713,7 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO } update_fog_factor(&specular_colour.a, &ls); wined3d_color_clamp(&specular_colour, &specular_colour, 0.0f, 1.0f); - *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_colour_format, &specular_colour); + wined3d_format_convert_from_float(output_colour_format, &specular_colour, dest_ptr); dest_ptr += sizeof(DWORD); }
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c index 7587a6455a4..073bc5b5834 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -621,7 +621,7 @@ void wined3d_resource_memory_colour_fill(struct wined3d_resource *resource, const struct wined3d_format *format = resource->format; unsigned int w, h, d, x, y, z, bpp; uint8_t *dst, *dst2; - uint32_t c; + uint32_t c[4];
w = box->right - box->left; h = box->bottom - box->top; @@ -632,7 +632,7 @@ void wined3d_resource_memory_colour_fill(struct wined3d_resource *resource, + ((box->top / format->block_height) * map->row_pitch) + ((box->left / format->block_width) * format->block_byte_count);
- c = wined3d_format_convert_from_float(format, colour); + wined3d_format_convert_from_float(format, colour, c); bpp = format->byte_count;
switch (bpp) @@ -640,14 +640,14 @@ void wined3d_resource_memory_colour_fill(struct wined3d_resource *resource, case 1: for (x = 0; x < w; ++x) { - dst[x] = c; + dst[x] = c[0]; } break;
case 2: for (x = 0; x < w; ++x) { - ((uint16_t *)dst)[x] = c; + ((uint16_t *)dst)[x] = c[0]; } break;
@@ -656,16 +656,16 @@ void wined3d_resource_memory_colour_fill(struct wined3d_resource *resource, dst2 = dst; for (x = 0; x < w; ++x, dst2 += 3) { - dst2[0] = (c ) & 0xff; - dst2[1] = (c >> 8) & 0xff; - dst2[2] = (c >> 16) & 0xff; + dst2[0] = (c[0] ) & 0xff; + dst2[1] = (c[0] >> 8) & 0xff; + dst2[2] = (c[0] >> 16) & 0xff; } break; } case 4: for (x = 0; x < w; ++x) { - ((uint32_t *)dst)[x] = c; + ((uint32_t *)dst)[x] = c[0]; } break;
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 401d815a365..6fe792c015f 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -6000,8 +6000,14 @@ uint32_t wined3d_format_pack(const struct wined3d_format *format, const struct w
/* Note: It's the caller's responsibility to ensure values can be expressed * in the requested format. UNORM formats for example can only express values - * in the range 0.0f -> 1.0f. */ -DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, const struct wined3d_color *color) + * in the range 0.0f -> 1.0f. + * + * The code below assumes that no component crosses the 32 bit boundary (like + * e.g. a hypothetical, and totally braindead, B30G30R4 format would). + * This function writes at least sizeof(uint32_t) bytes, or format->byte_count, + * whichever is larger. */ +void wined3d_format_convert_from_float(const struct wined3d_format *format, + const struct wined3d_color *color, void *ret) { static const struct { @@ -6044,10 +6050,11 @@ DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, con }; enum wined3d_format_id format_id = format->id; struct wined3d_color colour_srgb; + struct wined3d_uvec4 idx, shift; unsigned int i; - DWORD ret;
TRACE("Converting colour %s to format %s.\n", debug_color(color), debug_d3dformat(format_id)); + memset(ret, 0, max(sizeof(uint32_t), format->byte_count));
for (i = 0; i < ARRAY_SIZE(format_srgb_info); ++i) { @@ -6062,37 +6069,54 @@ DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, con
for (i = 0; i < ARRAY_SIZE(float_conv); ++i) { + uint32_t *ret_i = ret; + if (format_id != float_conv[i].format_id) continue;
- ret = ((DWORD)((color->r * float_conv[i].mul.x) + 0.5f)) << float_conv[i].shift.x; - ret |= ((DWORD)((color->g * float_conv[i].mul.y) + 0.5f)) << float_conv[i].shift.y; - ret |= ((DWORD)((color->b * float_conv[i].mul.z) + 0.5f)) << float_conv[i].shift.z; - ret |= ((DWORD)((color->a * float_conv[i].mul.w) + 0.5f)) << float_conv[i].shift.w; + idx.x = float_conv[i].shift.x / 32; + idx.y = float_conv[i].shift.y / 32; + idx.z = float_conv[i].shift.z / 32; + idx.w = float_conv[i].shift.w / 32; + shift.x = float_conv[i].shift.x % 32; + shift.y = float_conv[i].shift.y % 32; + shift.z = float_conv[i].shift.z % 32; + shift.w = float_conv[i].shift.w % 32;
- TRACE("Returning 0x%08x.\n", ret); + ret_i[idx.x] = ((uint32_t)((color->r * float_conv[i].mul.x) + 0.5f)) << shift.x; + ret_i[idx.y] |= ((uint32_t)((color->g * float_conv[i].mul.y) + 0.5f)) << shift.y; + ret_i[idx.z] |= ((uint32_t)((color->b * float_conv[i].mul.z) + 0.5f)) << shift.z; + ret_i[idx.w] |= ((uint32_t)((color->a * float_conv[i].mul.w) + 0.5f)) << shift.w;
- return ret; + return; }
for (i = 0; i < ARRAY_SIZE(double_conv); ++i) { + uint32_t *ret_i; + if (format_id != double_conv[i].format_id) continue;
- ret = ((DWORD)((color->r * double_conv[i].mul.x) + 0.5)) << double_conv[i].shift.x; - ret |= ((DWORD)((color->g * double_conv[i].mul.y) + 0.5)) << double_conv[i].shift.y; - ret |= ((DWORD)((color->b * double_conv[i].mul.z) + 0.5)) << double_conv[i].shift.z; - ret |= ((DWORD)((color->a * double_conv[i].mul.w) + 0.5)) << double_conv[i].shift.w; + idx.x = double_conv[i].shift.x / 32; + idx.y = double_conv[i].shift.y / 32; + idx.z = double_conv[i].shift.z / 32; + idx.w = double_conv[i].shift.w / 32; + shift.x = double_conv[i].shift.x % 32; + shift.y = double_conv[i].shift.y % 32; + shift.z = double_conv[i].shift.z % 32; + shift.w = double_conv[i].shift.w % 32;
- TRACE("Returning 0x%08x.\n", ret); + ret_i = ret; + ret_i[idx.x] = ((uint32_t)((color->r * double_conv[i].mul.x) + 0.5)) << shift.x; + ret_i[idx.y] |= ((uint32_t)((color->g * double_conv[i].mul.y) + 0.5)) << shift.y; + ret_i[idx.z] |= ((uint32_t)((color->b * double_conv[i].mul.z) + 0.5)) << shift.z; + ret_i[idx.w] |= ((uint32_t)((color->a * double_conv[i].mul.w) + 0.5)) << shift.w;
- return ret; + return; }
FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format_id)); - - return 0; }
static float color_to_float(DWORD color, DWORD size, DWORD offset) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index ba1dc2169b0..37cec7dd2c3 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -6150,8 +6150,8 @@ void wined3d_format_calculate_pitch(const struct wined3d_format *format, unsigne unsigned int width, unsigned int height, unsigned int *row_pitch, unsigned int *slice_pitch) DECLSPEC_HIDDEN; UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height, UINT depth) DECLSPEC_HIDDEN; -DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, - const struct wined3d_color *color) DECLSPEC_HIDDEN; +void wined3d_format_convert_from_float(const struct wined3d_format *format, + const struct wined3d_color *color, void *ret) DECLSPEC_HIDDEN; void wined3d_format_copy_data(const struct wined3d_format *format, const uint8_t *src, unsigned int src_row_pitch, unsigned int src_slice_pitch, uint8_t *dst, unsigned int dst_row_pitch, unsigned int dst_slice_pitch, unsigned int w, unsigned int h, unsigned int d) DECLSPEC_HIDDEN;
From: Stefan Dösinger stefan@codeweavers.com
Signed-off-by: Stefan Dösinger stefan@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/resource.c | 7 +++++++ dlls/wined3d/utils.c | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+)
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c index 073bc5b5834..7fefd516908 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -669,6 +669,13 @@ void wined3d_resource_memory_colour_fill(struct wined3d_resource *resource, } break;
+ case 8: + case 12: + case 16: + for (x = 0; x < w; ++x) + memcpy(((uint8_t *)map->data) + x * bpp, c, bpp); + break; + default: FIXME("Not implemented for bpp %u.\n", bpp); return; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 6fe792c015f..6d785c461d4 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -6116,6 +6116,27 @@ void wined3d_format_convert_from_float(const struct wined3d_format *format, return; }
+ /* 32 bit float formats. We don't handle D32_FLOAT and D32_FLOAT_S8X24_UINT for now. */ + if ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT) && format->red_size == 32) + { + float *ret_f = ret; + + switch (format->byte_count) + { + case 16: ret_f[3] = color->a; + case 12: ret_f[2] = color->b; + case 8: ret_f[1] = color->g; + case 4: ret_f[0] = color->r; + break; + + default: + ERR("Unexpected byte count %u, format %s.\n", format->byte_count, debug_d3dformat(format_id)); + break; + } + + return; + } + FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format_id)); }
From: Stefan Dösinger stefan@codeweavers.com
Signed-off-by: Stefan Dösinger stefan@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/surface.c | 63 ---------------------------- dlls/wined3d/utils.c | 25 ++++++++++++ dlls/wined3d/wined3d_private.h | 75 ++++++++++++++++++++++++++++++---- 3 files changed, 93 insertions(+), 70 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 0d4809ea55b..29bdef9844f 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -39,69 +39,6 @@ static void get_color_masks(const struct wined3d_format *format, uint32_t *masks masks[2] = wined3d_mask_from_size(format->blue_size) << format->blue_offset; }
-/* See also float_16_to_32() in wined3d_private.h */ -static inline unsigned short float_32_to_16(const float *in) -{ - int exp = 0; - float tmp = fabsf(*in); - unsigned int mantissa; - unsigned short ret; - - /* Deal with special numbers */ - if (*in == 0.0f) - return 0x0000; - if (isnan(*in)) - return 0x7c01; - if (isinf(*in)) - return (*in < 0.0f ? 0xfc00 : 0x7c00); - - if (tmp < (float)(1u << 10)) - { - do - { - tmp = tmp * 2.0f; - exp--; - } while (tmp < (float)(1u << 10)); - } - else if (tmp >= (float)(1u << 11)) - { - do - { - tmp /= 2.0f; - exp++; - } while (tmp >= (float)(1u << 11)); - } - - mantissa = (unsigned int)tmp; - if (tmp - mantissa >= 0.5f) - ++mantissa; /* Round to nearest, away from zero. */ - - exp += 10; /* Normalize the mantissa. */ - exp += 15; /* Exponent is encoded with excess 15. */ - - if (exp > 30) /* too big */ - { - ret = 0x7c00; /* INF */ - } - else if (exp <= 0) - { - /* exp == 0: Non-normalized mantissa. Returns 0x0000 (=0.0) for too small numbers. */ - while (exp <= 0) - { - mantissa = mantissa >> 1; - ++exp; - } - ret = mantissa & 0x3ff; - } - else - { - ret = (exp << 10) | (mantissa & 0x3ff); - } - - ret |= ((*in < 0.0f ? 1 : 0) << 15); /* Add the sign */ - return ret; -} - static void convert_r32_float_r16_float(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) { diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 6d785c461d4..892020e2aa9 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -6137,6 +6137,31 @@ void wined3d_format_convert_from_float(const struct wined3d_format *format, return; }
+ if ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT) && format->red_size == 16) + { + uint16_t *ret_s = ret; + + switch (format->byte_count) + { + case 8: + ret_s[3] = float_32_to_16(&color->a); + ret_s[2] = float_32_to_16(&color->b); + /* fall through */ + case 4: + ret_s[1] = float_32_to_16(&color->g); + /* fall through */ + case 2: + ret_s[0] = float_32_to_16(&color->r); + break; + + default: + ERR("Unexpected byte count %u, format %s.\n", format->byte_count, debug_d3dformat(format_id)); + break; + } + + return; + } + FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format_id)); }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 37cec7dd2c3..1d8bb40cec4 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -354,13 +354,12 @@ static inline GLenum wined3d_gl_min_mip_filter(enum wined3d_texture_filter_type return minMipLookup[min_filter].mip[mip_filter]; }
-/* float_16_to_32() and float_32_to_16() (see implementation in - * surface_base.c) convert 16 bit floats in the FLOAT16 data type - * to standard C floats and vice versa. They do not depend on the encoding - * of the C float, so they are platform independent, but slow. On x86 and - * other IEEE 754 compliant platforms the conversion can be accelerated by - * bit shifting the exponent and mantissa. There are also some SSE-based - * assembly routines out there. +/* float_16_to_32() and float_32_to_16() convert 16 bit floats in the + * FLOAT16 data type to standard C floats and vice versa. They do not + * depend on the encoding of the C float, so they are platform independent, + * but slow. On x86 and other IEEE 754 compliant platforms the conversion + * can be accelerated by bit shifting the exponent and mantissa. There are + * also some SSE-based assembly routines out there. * * See GL_NV_half_float for a reference of the FLOAT16 / GL_HALF format */ @@ -404,6 +403,68 @@ static inline float float_24_to_32(DWORD in) } }
+static inline unsigned short float_32_to_16(const float *in) +{ + int exp = 0; + float tmp = fabsf(*in); + unsigned int mantissa; + unsigned short ret; + + /* Deal with special numbers */ + if (*in == 0.0f) + return 0x0000; + if (isnan(*in)) + return 0x7c01; + if (isinf(*in)) + return (*in < 0.0f ? 0xfc00 : 0x7c00); + + if (tmp < (float)(1u << 10)) + { + do + { + tmp = tmp * 2.0f; + exp--; + } while (tmp < (float)(1u << 10)); + } + else if (tmp >= (float)(1u << 11)) + { + do + { + tmp /= 2.0f; + exp++; + } while (tmp >= (float)(1u << 11)); + } + + mantissa = (unsigned int)tmp; + if (tmp - mantissa >= 0.5f) + ++mantissa; /* Round to nearest, away from zero. */ + + exp += 10; /* Normalize the mantissa. */ + exp += 15; /* Exponent is encoded with excess 15. */ + + if (exp > 30) /* too big */ + { + ret = 0x7c00; /* INF */ + } + else if (exp <= 0) + { + /* exp == 0: Non-normalized mantissa. Returns 0x0000 (=0.0) for too small numbers. */ + while (exp <= 0) + { + mantissa = mantissa >> 1; + ++exp; + } + ret = mantissa & 0x3ff; + } + else + { + ret = (exp << 10) | (mantissa & 0x3ff); + } + + ret |= ((*in < 0.0f ? 1 : 0) << 15); /* Add the sign */ + return ret; +} + static inline unsigned int wined3d_popcount(unsigned int x) { #if defined(__MINGW32__)
From: Stefan Dösinger stefan@codeweavers.com
Signed-off-by: Stefan Dösinger stefan@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/utils.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 892020e2aa9..59a4fd29e51 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -346,6 +346,16 @@ static const struct wined3d_format_base_flags format_base_flags[] = {WINED3DFMT_R32_UINT, WINED3DFMT_FLAG_CAST_TO_BLOCK | WINED3DFMT_FLAG_INDEX_BUFFER}, {WINED3DFMT_R32_SINT, WINED3DFMT_FLAG_CAST_TO_BLOCK}, {WINED3DFMT_R16_UINT, WINED3DFMT_FLAG_INDEX_BUFFER}, + {WINED3DFMT_A8_UNORM, WINED3DFMT_FLAG_NORMALISED}, + {WINED3DFMT_B10G10R10A2_UNORM, WINED3DFMT_FLAG_NORMALISED}, + {WINED3DFMT_B2G3R3_UNORM, WINED3DFMT_FLAG_NORMALISED}, + {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_NORMALISED}, + {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_NORMALISED}, + {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_NORMALISED}, + {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_NORMALISED}, + {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_NORMALISED}, + {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_NORMALISED}, + {WINED3DFMT_R10G10B10A2_UNORM, WINED3DFMT_FLAG_NORMALISED}, };
static void rgb888_from_rgb565(WORD rgb565, BYTE *r, BYTE *g, BYTE *b)
From: Stefan Dösinger stefan@codeweavers.com
Signed-off-by: Stefan Dösinger stefan@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/utils.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-)
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 59a4fd29e51..088a904ffeb 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -6027,21 +6027,6 @@ void wined3d_format_convert_from_float(const struct wined3d_format *format, } float_conv[] = { - {WINED3DFMT_B8G8R8A8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, {16, 8, 0, 24}}, - {WINED3DFMT_B8G8R8X8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, {16, 8, 0, 24}}, - {WINED3DFMT_B8G8R8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, {16, 8, 0, 24}}, - {WINED3DFMT_B5G6R5_UNORM, { 31.0f, 63.0f, 31.0f, 0.0f}, {11, 5, 0, 0}}, - {WINED3DFMT_B5G5R5A1_UNORM, { 31.0f, 31.0f, 31.0f, 1.0f}, {10, 5, 0, 15}}, - {WINED3DFMT_B5G5R5X1_UNORM, { 31.0f, 31.0f, 31.0f, 1.0f}, {10, 5, 0, 15}}, - {WINED3DFMT_R8_UNORM, { 255.0f, 0.0f, 0.0f, 0.0f}, { 0, 0, 0, 0}}, - {WINED3DFMT_A8_UNORM, { 0.0f, 0.0f, 0.0f, 255.0f}, { 0, 0, 0, 0}}, - {WINED3DFMT_B4G4R4A4_UNORM, { 15.0f, 15.0f, 15.0f, 15.0f}, { 8, 4, 0, 12}}, - {WINED3DFMT_B4G4R4X4_UNORM, { 15.0f, 15.0f, 15.0f, 15.0f}, { 8, 4, 0, 12}}, - {WINED3DFMT_B2G3R3_UNORM, { 7.0f, 7.0f, 3.0f, 0.0f}, { 5, 2, 0, 0}}, - {WINED3DFMT_R8G8B8A8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, { 0, 8, 16, 24}}, - {WINED3DFMT_R8G8B8X8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, { 0, 8, 16, 24}}, - {WINED3DFMT_B10G10R10A2_UNORM, { 1023.0f, 1023.0f, 1023.0f, 3.0f}, {20, 10, 0, 30}}, - {WINED3DFMT_R10G10B10A2_UNORM, { 1023.0f, 1023.0f, 1023.0f, 3.0f}, { 0, 10, 20, 30}}, {WINED3DFMT_P8_UINT, { 0.0f, 0.0f, 0.0f, 255.0f}, { 0, 0, 0, 0}}, {WINED3DFMT_S1_UINT_D15_UNORM, { 32767.0f, 0.0f, 0.0f, 0.0f}, { 0, 0, 0, 0}}, {WINED3DFMT_D16_UNORM, { 65535.0f, 0.0f, 0.0f, 0.0f}, { 0, 0, 0, 0}}, @@ -6126,6 +6111,27 @@ void wined3d_format_convert_from_float(const struct wined3d_format *format, return; }
+ if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_NORMALISED) + { + uint32_t *ret_i = ret; + + idx.x = format->red_offset / 32; + idx.y = format->green_offset / 32; + idx.z = format->blue_offset / 32; + idx.w = format->alpha_offset / 32; + shift.x = format->red_offset % 32; + shift.y = format->green_offset % 32; + shift.z = format->blue_offset % 32; + shift.w = format->alpha_offset % 32; + + ret_i[idx.x] = ((uint32_t)((color->r * wined3d_mask_from_size(format->red_size)) + 0.5f)) << shift.x; + ret_i[idx.y] |= ((uint32_t)((color->g * wined3d_mask_from_size(format->green_size)) + 0.5f)) << shift.y; + ret_i[idx.z] |= ((uint32_t)((color->b * wined3d_mask_from_size(format->blue_size)) + 0.5f)) << shift.z; + ret_i[idx.w] |= ((uint32_t)((color->a * wined3d_mask_from_size(format->alpha_size)) + 0.5f)) << shift.w; + + return; + } + /* 32 bit float formats. We don't handle D32_FLOAT and D32_FLOAT_S8X24_UINT for now. */ if ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT) && format->red_size == 32) {