From f1023815ce09a8ff38492f926bc0a97bf1c504c2 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Mon, 27 Apr 2009 09:37:14 +0200 Subject: [PATCH] wined3d: Add a wined3d pixel shader to struct d3d10_pixel_shader. --- dlls/d3d10core/d3d10core_private.h | 5 +++++ dlls/d3d10core/device.c | 21 +++++++++++++++++++- dlls/d3d10core/shader.c | 31 ++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/dlls/d3d10core/d3d10core_private.h b/dlls/d3d10core/d3d10core_private.h index df9794ff12b..3f782baf1dc 100644 --- a/dlls/d3d10core/d3d10core_private.h +++ b/dlls/d3d10core/d3d10core_private.h @@ -39,6 +39,7 @@ ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 )) #define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C') #define TAG_ISGN MAKE_TAG('I', 'S', 'G', 'N') +#define TAG_SHDR MAKE_TAG('S', 'H', 'D', 'R') /* TRACE helper functions */ const char *debug_d3d10_primitive_topology(D3D10_PRIMITIVE_TOPOLOGY topology); @@ -149,8 +150,12 @@ struct d3d10_pixel_shader { const struct ID3D10PixelShaderVtbl *vtbl; LONG refcount; + + IWineD3DPixelShader *wined3d_shader; }; +HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length, const DWORD **shader_code); + /* Layered device */ enum dxgi_device_layer_id { diff --git a/dlls/d3d10core/device.c b/dlls/d3d10core/device.c index 2b704b35c10..5c91cbd5f40 100644 --- a/dlls/d3d10core/device.c +++ b/dlls/d3d10core/device.c @@ -1023,11 +1023,21 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateGeometryShaderWithStreamOutp static HRESULT STDMETHODCALLTYPE d3d10_device_CreatePixelShader(ID3D10Device *iface, const void *byte_code, SIZE_T byte_code_length, ID3D10PixelShader **shader) { + struct d3d10_device *This = (struct d3d10_device *)iface; struct d3d10_pixel_shader *object; + const DWORD *shader_code; + HRESULT hr; - FIXME("iface %p, byte_code %p, byte_code_length %lu, shader %p stub!\n", + TRACE("iface %p, byte_code %p, byte_code_length %lu, shader %p\n", iface, byte_code, byte_code_length, shader); + hr = shader_extract_from_dxbc(byte_code, byte_code_length, &shader_code); + if (FAILED(hr)) + { + ERR("Failed to extract shader, hr %#x\n", hr); + return hr; + } + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) { @@ -1038,6 +1048,15 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreatePixelShader(ID3D10Device *if object->vtbl = &d3d10_pixel_shader_vtbl; object->refcount = 1; + hr = IWineD3DDevice_CreatePixelShader(This->wined3d_device, + shader_code, &object->wined3d_shader, (IUnknown *)object); + if (FAILED(hr)) + { + ERR("CreatePixelShader failed, hr %#x\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + *shader = (ID3D10PixelShader *)object; return S_OK; diff --git a/dlls/d3d10core/shader.c b/dlls/d3d10core/shader.c index b614779bec1..8b3d01e442c 100644 --- a/dlls/d3d10core/shader.c +++ b/dlls/d3d10core/shader.c @@ -24,6 +24,37 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d10core); +static HRESULT shdr_handler(const char *data, DWORD data_size, DWORD tag, void *ctx) +{ + const DWORD **shader_data = ctx; + char tag_str[5]; + + switch(tag) + { + case TAG_SHDR: + *shader_data = (const DWORD *)data; + return S_OK; + + default: + memcpy(tag_str, &tag, 4); + tag_str[4] = '\0'; + FIXME("Unhandled chunk %s\n", tag_str); + return S_OK; + } +} + +HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length, const DWORD **shader_code) +{ + HRESULT hr; + + hr = parse_dxbc(dxbc, dxbc_length, shdr_handler, shader_code); + if (!*shader_code) hr = E_FAIL; + + if (FAILED(hr)) ERR("Failed to parse shader, hr %#x\n", hr); + + return hr; +} + /* IUnknown methods */ static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_QueryInterface(ID3D10VertexShader *iface,