diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec index d22ab5fbb3d..792408194d2 100644 --- a/dlls/d3dx9_36/d3dx9_36.spec +++ b/dlls/d3dx9_36/d3dx9_36.spec @@ -129,7 +129,7 @@ @ stub D3DXFillVolumeTexture @ stub D3DXFillVolumeTextureTX @ stub D3DXFilterTexture -@ stub D3DXFindShaderComment +@ stdcall D3DXFindShaderComment(ptr long ptr ptr) @ stub D3DXFloat16To32Array @ stub D3DXFloat32To16Array @ stub D3DXFrameAppendChild diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c index 1106594bec5..22c297e86b9 100644 --- a/dlls/d3dx9_36/shader.c +++ b/dlls/d3dx9_36/shader.c @@ -135,6 +135,39 @@ LPCSTR WINAPI D3DXGetVertexShaderProfile(LPDIRECT3DDEVICE9 device) return NULL; } +HRESULT WINAPI D3DXFindShaderComment(CONST DWORD* byte_code, DWORD fourcc, LPCVOID* data, UINT* size) +{ + CONST DWORD *ptr = byte_code; + + TRACE("(%p, %x, %p, %p)", byte_code, fourcc, data, size); + + if (!byte_code) + return D3DERR_INVALIDCALL; + + while (*++ptr != D3DSIO_END) + { + /* Check if it is a comment */ + if ((*ptr & D3DSI_OPCODE_MASK) == D3DSIO_COMMENT) + { + DWORD comment_size = (*ptr & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT; + + /* Check if this is the comment we are looking for */ + if (*(ptr + 1) == fourcc) + { + if (size) + *size = (comment_size - 1) * sizeof(DWORD); + if (data) + *data = ptr + 2; + TRACE("Returning comment data at %p with size %d\n", *data, *size); + return D3D_OK; + } + ptr += comment_size; + } + } + + return S_FALSE; +} + HRESULT WINAPI D3DXAssembleShader(LPCSTR data, UINT data_len, CONST D3DXMACRO* defines, diff --git a/dlls/d3dx9_36/tests/shader.c b/dlls/d3dx9_36/tests/shader.c index b13fed16c01..03c77c2c6e4 100644 --- a/dlls/d3dx9_36/tests/shader.c +++ b/dlls/d3dx9_36/tests/shader.c @@ -37,6 +37,16 @@ static const DWORD simple_ps[] = { 0x00000005, 0x800f0000, 0xb0e40000, 0x80e40000, /* mul r0, t0, r0 */ 0x0000ffff}; /* END */ +#define FCC_TEXT MAKEFOURCC('T','E','X','T') +#define FCC_CTAB MAKEFOURCC('C','T','A','B') + +static const DWORD shader_with_ctab[] = { + 0xfffe0300, /* vs_3_0 */ + 0x0002fffe, FCC_TEXT, 0x00000000, /* TEXT comment */ + 0x0006fffe, FCC_CTAB, 0x0000001c, 0x00000000, 0xfffe0300, 0x00000000, /* CTAB comment */ + 0x00000000, + 0x0004fffe, FCC_TEXT, 0x00000000, 0x00000000, 0x00000000, /* TEXT comment */ + 0x0000ffff}; /* END */ static void test_get_shader_size(void) { @@ -70,8 +80,36 @@ static void test_get_shader_version(void) ok(shader_version == 0, "Got shader version 0x%08x, expected 0\n", shader_version); } +static void test_find_shader_comment(void) +{ + HRESULT hr; + LPCVOID data; + UINT size; + + hr = D3DXFindShaderComment(NULL, MAKEFOURCC('C','T','A','B'), &data, &size); + ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL); + + hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('C','T','A','B'), NULL, &size); + ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr); + + hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('C','T','A','B'), &data, NULL); + ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr); + + hr = D3DXFindShaderComment(shader_with_ctab, 0, &data, &size); + ok(hr == S_FALSE, "Got result %x, expected 1 (S_FALSE)\n", hr); + + hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('X','X','X','X'), &data, &size); + ok(hr == S_FALSE, "Got result %x, expected 1 (S_FALSE)\n", hr); + + hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('C','T','A','B'), &data, &size); + ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr); + ok(data == (LPCVOID)(shader_with_ctab + 6), "Got result %p, expected %p\n", data, shader_with_ctab + 6); + ok(size == 20, "Got result %d, expected 20\n", size); +} + START_TEST(shader) { test_get_shader_size(); test_get_shader_version(); + test_find_shader_comment(); } diff --git a/include/d3dx9shader.h b/include/d3dx9shader.h index a0df2a8896c..6d11b3d198b 100644 --- a/include/d3dx9shader.h +++ b/include/d3dx9shader.h @@ -248,6 +248,7 @@ LPCSTR WINAPI D3DXGetPixelShaderProfile(LPDIRECT3DDEVICE9 device); UINT WINAPI D3DXGetShaderSize(const DWORD *byte_code); DWORD WINAPI D3DXGetShaderVersion(const DWORD *byte_code); LPCSTR WINAPI D3DXGetVertexShaderProfile(LPDIRECT3DDEVICE9 device); +HRESULT WINAPI D3DXFindShaderComment(CONST DWORD* byte_code, DWORD fourcc, LPCVOID* data, UINT* size); HRESULT WINAPI D3DXAssembleShaderFromFileA(LPCSTR filename, CONST D3DXMACRO* defines,