diff --git a/dlls/d3d10/d3d10.spec b/dlls/d3d10/d3d10.spec index 1a09f4a056e..49733deefa3 100644 --- a/dlls/d3d10/d3d10.spec +++ b/dlls/d3d10/d3d10.spec @@ -21,7 +21,7 @@ @ stub D3D10RegisterLayers @ stdcall D3D10StateBlockMaskDifference(ptr ptr ptr) @ stdcall D3D10StateBlockMaskDisableAll(ptr) -@ stub D3D10StateBlockMaskDisableCapture +@ stdcall D3D10StateBlockMaskDisableCapture(ptr long long long) @ stub D3D10StateBlockMaskEnableAll @ stub D3D10StateBlockMaskEnableCapture @ stub D3D10StateBlockMaskGetSetting diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h index df525ca0696..f44afe04f02 100644 --- a/dlls/d3d10/d3d10_private.h +++ b/dlls/d3d10/d3d10_private.h @@ -41,6 +41,7 @@ const char *debug_d3d10_driver_type(D3D10_DRIVER_TYPE driver_type) DECLSPEC_HIDDEN; const char *debug_d3d10_shader_variable_class(D3D10_SHADER_VARIABLE_CLASS c) DECLSPEC_HIDDEN; const char *debug_d3d10_shader_variable_type(D3D10_SHADER_VARIABLE_TYPE t) DECLSPEC_HIDDEN; +const char *debug_d3d10_device_state_types(D3D10_DEVICE_STATE_TYPES t) DECLSPEC_HIDDEN; void *d3d10_rb_alloc(size_t size) DECLSPEC_HIDDEN; void *d3d10_rb_realloc(void *ptr, size_t size) DECLSPEC_HIDDEN; diff --git a/dlls/d3d10/stateblock.c b/dlls/d3d10/stateblock.c index 76a27f92b61..bf3d64c5f0a 100644 --- a/dlls/d3d10/stateblock.c +++ b/dlls/d3d10/stateblock.c @@ -144,6 +144,37 @@ HRESULT WINAPI D3D10CreateStateBlock(ID3D10Device *device, return S_OK; } +static HRESULT stateblock_mask_clear_bits(BYTE *field, UINT field_size, UINT start_bit, UINT count) +{ + UINT end_bit = start_bit + count; + BYTE start_mask = 0x7f >> (~start_bit & 7); + BYTE end_mask = 0xff << (end_bit & 7); + UINT start_idx = start_bit >> 3; + UINT end_idx = end_bit >> 3; + + if (start_bit >= field_size || field_size - start_bit < count) + return E_INVALIDARG; + + if (start_idx == end_idx) + { + field[start_idx] &= start_mask | end_mask; + return S_OK; + } + + if (start_bit & 7) + { + field[start_idx] &= start_mask; + ++start_idx; + } + + memset(&field[start_idx], 0, end_idx - start_idx); + + if (end_bit & 7) + field[end_idx] &= end_mask; + + return S_OK; +} + HRESULT WINAPI D3D10StateBlockMaskDifference(D3D10_STATE_BLOCK_MASK *mask_x, D3D10_STATE_BLOCK_MASK *mask_y, D3D10_STATE_BLOCK_MASK *result) { @@ -178,3 +209,78 @@ HRESULT WINAPI D3D10StateBlockMaskDisableAll(D3D10_STATE_BLOCK_MASK *mask) return S_OK; } + +HRESULT WINAPI D3D10StateBlockMaskDisableCapture(D3D10_STATE_BLOCK_MASK *mask, + D3D10_DEVICE_STATE_TYPES state_type, UINT start_idx, UINT count) +{ + TRACE("mask %p state_type %s, start_idx %u, count %u.\n", + mask, debug_d3d10_device_state_types(state_type), start_idx, count); + + if (!mask) + return E_INVALIDARG; + + switch (state_type) + { + case D3D10_DST_SO_BUFFERS: + return stateblock_mask_clear_bits(&mask->SOBuffers, 1, start_idx, count); + case D3D10_DST_OM_RENDER_TARGETS: + return stateblock_mask_clear_bits(&mask->OMRenderTargets, 1, start_idx, count); + case D3D10_DST_DEPTH_STENCIL_STATE: + return stateblock_mask_clear_bits(&mask->OMDepthStencilState, 1, start_idx, count); + case D3D10_DST_BLEND_STATE: + return stateblock_mask_clear_bits(&mask->OMBlendState, 1, start_idx, count); + case D3D10_DST_VS: + return stateblock_mask_clear_bits(&mask->VS, 1, start_idx, count); + case D3D10_DST_VS_SAMPLERS: + return stateblock_mask_clear_bits(mask->VSSamplers, + D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT, start_idx, count); + case D3D10_DST_VS_SHADER_RESOURCES: + return stateblock_mask_clear_bits(mask->VSShaderResources, + D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, start_idx, count); + case D3D10_DST_VS_CONSTANT_BUFFERS: + return stateblock_mask_clear_bits(mask->VSConstantBuffers, + D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, start_idx, count); + case D3D10_DST_GS: + return stateblock_mask_clear_bits(&mask->GS, 1, start_idx, count); + case D3D10_DST_GS_SAMPLERS: + return stateblock_mask_clear_bits(mask->GSSamplers, + D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT, start_idx, count); + case D3D10_DST_GS_SHADER_RESOURCES: + return stateblock_mask_clear_bits(mask->GSShaderResources, + D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, start_idx, count); + case D3D10_DST_GS_CONSTANT_BUFFERS: + return stateblock_mask_clear_bits(mask->GSConstantBuffers, + D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, start_idx, count); + case D3D10_DST_PS: + return stateblock_mask_clear_bits(&mask->PS, 1, start_idx, count); + case D3D10_DST_PS_SAMPLERS: + return stateblock_mask_clear_bits(mask->PSSamplers, + D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT, start_idx, count); + case D3D10_DST_PS_SHADER_RESOURCES: + return stateblock_mask_clear_bits(mask->PSShaderResources, + D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, start_idx, count); + case D3D10_DST_PS_CONSTANT_BUFFERS: + return stateblock_mask_clear_bits(mask->PSConstantBuffers, + D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, start_idx, count); + case D3D10_DST_IA_VERTEX_BUFFERS: + return stateblock_mask_clear_bits(mask->IAVertexBuffers, + D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, start_idx, count); + case D3D10_DST_IA_INDEX_BUFFER: + return stateblock_mask_clear_bits(&mask->IAIndexBuffer, 1, start_idx, count); + case D3D10_DST_IA_INPUT_LAYOUT: + return stateblock_mask_clear_bits(&mask->IAInputLayout, 1, start_idx, count); + case D3D10_DST_IA_PRIMITIVE_TOPOLOGY: + return stateblock_mask_clear_bits(&mask->IAPrimitiveTopology, 1, start_idx, count); + case D3D10_DST_RS_VIEWPORTS: + return stateblock_mask_clear_bits(&mask->RSViewports, 1, start_idx, count); + case D3D10_DST_RS_SCISSOR_RECTS: + return stateblock_mask_clear_bits(&mask->RSScissorRects, 1, start_idx, count); + case D3D10_DST_RS_RASTERIZER_STATE: + return stateblock_mask_clear_bits(&mask->RSRasterizerState, 1, start_idx, count); + case D3D10_DST_PREDICATION: + return stateblock_mask_clear_bits(&mask->Predication, 1, start_idx, count); + default: + FIXME("Unhandled state_type %#x.\n", state_type); + return E_INVALIDARG; + } +} diff --git a/dlls/d3d10/tests/device.c b/dlls/d3d10/tests/device.c index 21970027875..c29f65ba980 100644 --- a/dlls/d3d10/tests/device.c +++ b/dlls/d3d10/tests/device.c @@ -66,8 +66,34 @@ static void test_device_interfaces(ID3D10Device *device) static void test_stateblock_mask(void) { + static const struct + { + UINT start_idx; + UINT count; + BYTE expected[5]; + } + capture_test[] = + { + { 8, 4, {0xff, 0xf0, 0xff, 0xff, 0xff}}, + { 9, 4, {0xff, 0xe1, 0xff, 0xff, 0xff}}, + {10, 4, {0xff, 0xc3, 0xff, 0xff, 0xff}}, + {11, 4, {0xff, 0x87, 0xff, 0xff, 0xff}}, + {12, 4, {0xff, 0x0f, 0xff, 0xff, 0xff}}, + {13, 4, {0xff, 0x1f, 0xfe, 0xff, 0xff}}, + {14, 4, {0xff, 0x3f, 0xfc, 0xff, 0xff}}, + {15, 4, {0xff, 0x7f, 0xf8, 0xff, 0xff}}, + { 8, 12, {0xff, 0x00, 0xf0, 0xff, 0xff}}, + { 9, 12, {0xff, 0x01, 0xe0, 0xff, 0xff}}, + {10, 12, {0xff, 0x03, 0xc0, 0xff, 0xff}}, + {11, 12, {0xff, 0x07, 0x80, 0xff, 0xff}}, + {12, 12, {0xff, 0x0f, 0x00, 0xff, 0xff}}, + {13, 12, {0xff, 0x1f, 0x00, 0xfe, 0xff}}, + {14, 12, {0xff, 0x3f, 0x00, 0xfc, 0xff}}, + {15, 12, {0xff, 0x7f, 0x00, 0xf8, 0xff}}, + }; D3D10_STATE_BLOCK_MASK mask_x, mask_y, result; HRESULT hr; + UINT i; memset(&mask_x, 0, sizeof(mask_x)); memset(&mask_y, 0, sizeof(mask_y)); @@ -96,6 +122,30 @@ static void test_stateblock_mask(void) ok(!result.Predication, "Got unexpected result.Predication %#x.\n", result.Predication); hr = D3D10StateBlockMaskDisableAll(NULL); ok(hr == E_INVALIDARG, "Got unexpect hr %#x.\n", hr); + + result.VS = 0xff; + hr = D3D10StateBlockMaskDisableCapture(&result, D3D10_DST_VS, 0, 1); + ok(SUCCEEDED(hr), "D3D10StateBlockMaskDisableCapture failed, hr %#x.\n", hr); + ok(result.VS == 0xfe, "Got unexpected result.VS %#x.\n", result.VS); + hr = D3D10StateBlockMaskDisableCapture(&result, D3D10_DST_VS, 0, 4); + ok(hr == E_INVALIDARG, "Got unexpect hr %#x.\n", hr); + hr = D3D10StateBlockMaskDisableCapture(&result, D3D10_DST_VS, 1, 1); + ok(hr == E_INVALIDARG, "Got unexpect hr %#x.\n", hr); + hr = D3D10StateBlockMaskDisableCapture(NULL, D3D10_DST_VS, 0, 1); + ok(hr == E_INVALIDARG, "Got unexpect hr %#x.\n", hr); + for (i = 0; i < sizeof(capture_test) / sizeof(*capture_test); ++i) + { + memset(&result, 0xff, sizeof(result)); + hr = D3D10StateBlockMaskDisableCapture(&result, D3D10_DST_VS_SHADER_RESOURCES, + capture_test[i].start_idx, capture_test[i].count); + ok(SUCCEEDED(hr), "D3D10StateBlockMaskDisableCapture failed, hr %#x.\n", hr); + + ok(!memcmp(result.VSShaderResources, capture_test[i].expected, 5), + "Got unexpect result.VSShaderResources[0..4] {%#x, %#x, %#x, %#x, %#x} for test %u.\n", + result.VSShaderResources[0], result.VSShaderResources[1], + result.VSShaderResources[2], result.VSShaderResources[3], + result.VSShaderResources[4], i); + } } START_TEST(device) diff --git a/dlls/d3d10/utils.c b/dlls/d3d10/utils.c index a3f761ec7e8..6806e5e6d26 100644 --- a/dlls/d3d10/utils.c +++ b/dlls/d3d10/utils.c @@ -95,6 +95,40 @@ const char *debug_d3d10_shader_variable_type(D3D10_SHADER_VARIABLE_TYPE t) } } +const char *debug_d3d10_device_state_types(D3D10_DEVICE_STATE_TYPES t) +{ + switch (t) + { + WINE_D3D10_TO_STR(D3D10_DST_SO_BUFFERS); + WINE_D3D10_TO_STR(D3D10_DST_OM_RENDER_TARGETS); + WINE_D3D10_TO_STR(D3D10_DST_DEPTH_STENCIL_STATE); + WINE_D3D10_TO_STR(D3D10_DST_BLEND_STATE); + WINE_D3D10_TO_STR(D3D10_DST_VS); + WINE_D3D10_TO_STR(D3D10_DST_VS_SAMPLERS); + WINE_D3D10_TO_STR(D3D10_DST_VS_SHADER_RESOURCES); + WINE_D3D10_TO_STR(D3D10_DST_VS_CONSTANT_BUFFERS); + WINE_D3D10_TO_STR(D3D10_DST_GS); + WINE_D3D10_TO_STR(D3D10_DST_GS_SAMPLERS); + WINE_D3D10_TO_STR(D3D10_DST_GS_SHADER_RESOURCES); + WINE_D3D10_TO_STR(D3D10_DST_GS_CONSTANT_BUFFERS); + WINE_D3D10_TO_STR(D3D10_DST_PS); + WINE_D3D10_TO_STR(D3D10_DST_PS_SAMPLERS); + WINE_D3D10_TO_STR(D3D10_DST_PS_SHADER_RESOURCES); + WINE_D3D10_TO_STR(D3D10_DST_PS_CONSTANT_BUFFERS); + WINE_D3D10_TO_STR(D3D10_DST_IA_VERTEX_BUFFERS); + WINE_D3D10_TO_STR(D3D10_DST_IA_INDEX_BUFFER); + WINE_D3D10_TO_STR(D3D10_DST_IA_INPUT_LAYOUT); + WINE_D3D10_TO_STR(D3D10_DST_IA_PRIMITIVE_TOPOLOGY); + WINE_D3D10_TO_STR(D3D10_DST_RS_VIEWPORTS); + WINE_D3D10_TO_STR(D3D10_DST_RS_SCISSOR_RECTS); + WINE_D3D10_TO_STR(D3D10_DST_RS_RASTERIZER_STATE); + WINE_D3D10_TO_STR(D3D10_DST_PREDICATION); + default: + FIXME("Unrecognized D3D10_DEVICE_STATE_TYPES %#x.\n", t); + return "unrecognized"; + } +} + #undef WINE_D3D10_TO_STR void *d3d10_rb_alloc(size_t size) diff --git a/include/d3d10effect.h b/include/d3d10effect.h index e293d3bd650..b195dff647b 100644 --- a/include/d3d10effect.h +++ b/include/d3d10effect.h @@ -30,6 +30,34 @@ #define D3D10_BYTES_FROM_BITS(x) (((x) + 7) >> 3) #endif +typedef enum _D3D10_DEVICE_STATE_TYPES +{ + D3D10_DST_SO_BUFFERS = 1, + D3D10_DST_OM_RENDER_TARGETS, + D3D10_DST_DEPTH_STENCIL_STATE, + D3D10_DST_BLEND_STATE, + D3D10_DST_VS, + D3D10_DST_VS_SAMPLERS, + D3D10_DST_VS_SHADER_RESOURCES, + D3D10_DST_VS_CONSTANT_BUFFERS, + D3D10_DST_GS, + D3D10_DST_GS_SAMPLERS, + D3D10_DST_GS_SHADER_RESOURCES, + D3D10_DST_GS_CONSTANT_BUFFERS, + D3D10_DST_PS, + D3D10_DST_PS_SAMPLERS, + D3D10_DST_PS_SHADER_RESOURCES, + D3D10_DST_PS_CONSTANT_BUFFERS, + D3D10_DST_IA_VERTEX_BUFFERS, + D3D10_DST_IA_INDEX_BUFFER, + D3D10_DST_IA_INPUT_LAYOUT, + D3D10_DST_IA_PRIMITIVE_TOPOLOGY, + D3D10_DST_RS_VIEWPORTS, + D3D10_DST_RS_SCISSOR_RECTS, + D3D10_DST_RS_RASTERIZER_STATE, + D3D10_DST_PREDICATION, +} D3D10_DEVICE_STATE_TYPES; + typedef struct _D3D10_EFFECT_TYPE_DESC { LPCSTR TypeName; @@ -807,6 +835,8 @@ HRESULT WINAPI D3D10CreateStateBlock(ID3D10Device *device, HRESULT WINAPI D3D10StateBlockMaskDifference(D3D10_STATE_BLOCK_MASK *mask_x, D3D10_STATE_BLOCK_MASK *mask_y, D3D10_STATE_BLOCK_MASK *result); HRESULT WINAPI D3D10StateBlockMaskDisableAll(D3D10_STATE_BLOCK_MASK *mask); +HRESULT WINAPI D3D10StateBlockMaskDisableCapture(D3D10_STATE_BLOCK_MASK *mask, + D3D10_DEVICE_STATE_TYPES state_type, UINT start_idx, UINT count); #ifdef __cplusplus }