static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader, struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length) { struct wined3d_shader_signature output_signature; struct wined3d_shader_signature input_signature; struct d3d_shader_info shader_info; struct wined3d_shader_desc desc; HRESULT hr; shader->ID3D11GeometryShader_iface.lpVtbl = &d3d11_geometry_shader_vtbl; shader->ID3D10GeometryShader_iface.lpVtbl = &d3d10_geometry_shader_vtbl; shader->refcount = 1; wined3d_mutex_lock(); wined3d_private_store_init(&shader->private_store); shader_info.input_signature = &input_signature; shader_info.output_signature = &output_signature; if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &shader_info))) { ERR("Failed to extract shader, hr %#x.\n", hr); wined3d_private_store_cleanup(&shader->private_store); wined3d_mutex_unlock(); return hr; } desc.byte_code = shader_info.shader_code; desc.input_signature = &input_signature; desc.output_signature = &output_signature; desc.max_version = 4; hr = wined3d_shader_create_gs(device->wined3d_device, &desc, shader, &d3d_geometry_shader_wined3d_parent_ops, &shader->wined3d_shader); shader_free_signature(&input_signature); shader_free_signature(&output_signature); if (FAILED(hr)) { WARN("Failed to create wined3d geometry shader, hr %#x.\n", hr); wined3d_private_store_cleanup(&shader->private_store); wined3d_mutex_unlock(); return E_INVALIDARG; } wined3d_mutex_unlock(); shader->device = &device->ID3D11Device_iface; ID3D11Device_AddRef(shader->device); return S_OK; }
HRESULT d3d10_pixel_shader_init(struct d3d10_pixel_shader *shader, struct d3d10_device *device, const void *byte_code, SIZE_T byte_code_length) { struct d3d10_shader_info shader_info; HRESULT hr; shader->ID3D10PixelShader_iface.lpVtbl = &d3d10_pixel_shader_vtbl; shader->refcount = 1; shader_info.output_signature = &shader->output_signature; hr = shader_extract_from_dxbc(byte_code, byte_code_length, &shader_info); if (FAILED(hr)) { ERR("Failed to extract shader, hr %#x.\n", hr); return hr; } hr = wined3d_shader_create_ps(device->wined3d_device, shader_info.shader_code, &shader->output_signature, shader, &d3d10_pixel_shader_wined3d_parent_ops, &shader->wined3d_shader, 4); if (FAILED(hr)) { WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr); shader_free_signature(&shader->output_signature); hr = E_INVALIDARG; return hr; } shader->device = &device->ID3D10Device1_iface; ID3D10Device1_AddRef(shader->device); return S_OK; }
HRESULT d3d10_geometry_shader_init(struct d3d10_geometry_shader *shader, struct d3d10_device *device, const void *byte_code, SIZE_T byte_code_length) { struct d3d10_shader_info shader_info; HRESULT hr; shader->ID3D10GeometryShader_iface.lpVtbl = &d3d10_geometry_shader_vtbl; shader->refcount = 1; shader_info.output_signature = &shader->output_signature; hr = shader_extract_from_dxbc(byte_code, byte_code_length, &shader_info); if (FAILED(hr)) { ERR("Failed to extract shader, hr %#x.\n", hr); return hr; } hr = wined3d_shader_create_gs(device->wined3d_device, shader_info.shader_code, &shader->output_signature, shader, &d3d10_geometry_shader_wined3d_parent_ops, &shader->wined3d_shader); if (FAILED(hr)) { WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr); shader_free_signature(&shader->output_signature); return hr; } return S_OK; }
HRESULT d3d10_pixel_shader_init(struct d3d10_pixel_shader *shader, struct d3d10_device *device, const void *byte_code, SIZE_T byte_code_length) { struct d3d10_shader_info shader_info; HRESULT hr; shader->vtbl = &d3d10_pixel_shader_vtbl; shader->refcount = 1; shader_info.output_signature = &shader->output_signature; hr = shader_extract_from_dxbc(byte_code, byte_code_length, &shader_info); if (FAILED(hr)) { ERR("Failed to extract shader, hr %#x.\n", hr); return hr; } hr = IWineD3DDevice_CreatePixelShader(device->wined3d_device, shader_info.shader_code, &shader->output_signature, shader, &d3d10_pixel_shader_wined3d_parent_ops, &shader->wined3d_shader); if (FAILED(hr)) { WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr); shader_free_signature(&shader->output_signature); return hr; } return S_OK; }
static HRESULT d3d10_input_layout_to_wined3d_declaration(const D3D10_INPUT_ELEMENT_DESC *element_descs, UINT element_count, const void *shader_byte_code, SIZE_T shader_byte_code_length, WINED3DVERTEXELEMENT **wined3d_elements, UINT *wined3d_element_count) { struct wined3d_shader_signature is; HRESULT hr; UINT i; hr = parse_dxbc(shader_byte_code, shader_byte_code_length, isgn_handler, &is); if (FAILED(hr)) { ERR("Failed to parse input signature.\n"); return E_FAIL; } *wined3d_elements = HeapAlloc(GetProcessHeap(), 0, element_count * sizeof(**wined3d_elements)); if (!*wined3d_elements) { ERR("Failed to allocate wined3d vertex element array memory.\n"); HeapFree(GetProcessHeap(), 0, is.elements); return E_OUTOFMEMORY; } *wined3d_element_count = 0; for (i = 0; i < element_count; ++i) { UINT j; for (j = 0; j < is.element_count; ++j) { if (!strcmp(element_descs[i].SemanticName, is.elements[j].semantic_name) && element_descs[i].SemanticIndex == is.elements[j].semantic_idx) { WINED3DVERTEXELEMENT *e = &(*wined3d_elements)[(*wined3d_element_count)++]; const D3D10_INPUT_ELEMENT_DESC *f = &element_descs[i]; e->format = wined3dformat_from_dxgi_format(f->Format); e->input_slot = f->InputSlot; e->offset = f->AlignedByteOffset; e->output_slot = is.elements[j].register_idx; e->method = WINED3DDECLMETHOD_DEFAULT; e->usage = 0; e->usage_idx = 0; if (f->AlignedByteOffset == D3D10_APPEND_ALIGNED_ELEMENT) FIXME("D3D10_APPEND_ALIGNED_ELEMENT not supported\n"); if (f->InputSlotClass != D3D10_INPUT_PER_VERTEX_DATA) FIXME("Ignoring input slot class (%#x)\n", f->InputSlotClass); if (f->InstanceDataStepRate) FIXME("Ignoring instace data step rate (%#x)\n", f->InstanceDataStepRate); break; } } } shader_free_signature(&is); return S_OK; }
static HRESULT d3d11_input_layout_to_wined3d_declaration(const D3D11_INPUT_ELEMENT_DESC *element_descs, UINT element_count, const void *shader_byte_code, SIZE_T shader_byte_code_length, struct wined3d_vertex_element **wined3d_elements) { struct wined3d_shader_signature is; unsigned int i; HRESULT hr; if (FAILED(hr = parse_dxbc(shader_byte_code, shader_byte_code_length, isgn_handler, &is))) { ERR("Failed to parse input signature.\n"); return E_FAIL; } if (!(*wined3d_elements = d3d11_calloc(element_count, sizeof(**wined3d_elements)))) { ERR("Failed to allocate wined3d vertex element array memory.\n"); HeapFree(GetProcessHeap(), 0, is.elements); return E_OUTOFMEMORY; } for (i = 0; i < element_count; ++i) { struct wined3d_vertex_element *e = &(*wined3d_elements)[i]; const D3D11_INPUT_ELEMENT_DESC *f = &element_descs[i]; unsigned int j; e->format = wined3dformat_from_dxgi_format(f->Format); e->input_slot = f->InputSlot; e->offset = f->AlignedByteOffset; e->output_slot = WINED3D_OUTPUT_SLOT_UNUSED; e->input_slot_class = f->InputSlotClass; e->instance_data_step_rate = f->InstanceDataStepRate; e->method = WINED3D_DECL_METHOD_DEFAULT; e->usage = 0; e->usage_idx = 0; for (j = 0; j < is.element_count; ++j) { if (!strcasecmp(element_descs[i].SemanticName, is.elements[j].semantic_name) && element_descs[i].SemanticIndex == is.elements[j].semantic_idx) { e->output_slot = is.elements[j].register_idx; break; } } if (e->output_slot == WINED3D_OUTPUT_SLOT_UNUSED) WARN("Unused input element %u.\n", i); } shader_free_signature(&is); return S_OK; }
static HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length, struct d3d_shader_info *shader_info) { HRESULT hr; shader_info->shader_code = NULL; memset(shader_info->input_signature, 0, sizeof(*shader_info->input_signature)); memset(shader_info->output_signature, 0, sizeof(*shader_info->output_signature)); hr = parse_dxbc(dxbc, dxbc_length, shdr_handler, shader_info); if (!shader_info->shader_code) hr = E_INVALIDARG; if (FAILED(hr)) { ERR("Failed to parse shader, hr %#x\n", hr); shader_free_signature(shader_info->input_signature); shader_free_signature(shader_info->output_signature); } return hr; }
static void STDMETHODCALLTYPE d3d10_pixel_shader_wined3d_object_destroyed(void *parent) { struct d3d10_pixel_shader *shader = parent; shader_free_signature(&shader->output_signature); HeapFree(GetProcessHeap(), 0, shader); }