diff --git a/dlls/d3d10core/d3d10core_private.h b/dlls/d3d10core/d3d10core_private.h index 29f565379c2..b7779007cd3 100644 --- a/dlls/d3d10core/d3d10core_private.h +++ b/dlls/d3d10core/d3d10core_private.h @@ -90,7 +90,7 @@ struct d3d10_texture2d }; HRESULT d3d10_texture2d_init(struct d3d10_texture2d *texture, struct d3d10_device *device, - const D3D10_TEXTURE2D_DESC *desc) DECLSPEC_HIDDEN; + const D3D10_TEXTURE2D_DESC *desc, const D3D10_SUBRESOURCE_DATA *initial_data) DECLSPEC_HIDDEN; struct d3d10_texture2d *unsafe_impl_from_ID3D10Texture2D(ID3D10Texture2D *iface) DECLSPEC_HIDDEN; /* ID3D10Texture3D */ @@ -105,7 +105,7 @@ struct d3d10_texture3d }; HRESULT d3d10_texture3d_init(struct d3d10_texture3d *texture, struct d3d10_device *device, - const D3D10_TEXTURE3D_DESC *desc) DECLSPEC_HIDDEN; + const D3D10_TEXTURE3D_DESC *desc, const D3D10_SUBRESOURCE_DATA *data) DECLSPEC_HIDDEN; /* ID3D10Buffer */ struct d3d10_buffer diff --git a/dlls/d3d10core/device.c b/dlls/d3d10core/device.c index 44a80858419..ccac3f293a0 100644 --- a/dlls/d3d10core/device.c +++ b/dlls/d3d10core/device.c @@ -1414,7 +1414,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateTexture2D(ID3D10Device1 *ifa const D3D10_TEXTURE2D_DESC *desc, const D3D10_SUBRESOURCE_DATA *data, ID3D10Texture2D **texture) { - struct d3d10_device *This = impl_from_ID3D10Device(iface); + struct d3d10_device *device = impl_from_ID3D10Device(iface); struct d3d10_texture2d *object; HRESULT hr; @@ -1424,8 +1424,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateTexture2D(ID3D10Device1 *ifa if (!object) return E_OUTOFMEMORY; - hr = d3d10_texture2d_init(object, This, desc); - if (FAILED(hr)) + if (FAILED(hr = d3d10_texture2d_init(object, device, desc, data))) { WARN("Failed to initialize texture, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); @@ -1453,8 +1452,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateTexture3D(ID3D10Device1 *ifa if (!object) return E_OUTOFMEMORY; - hr = d3d10_texture3d_init(object, device, desc); - if (FAILED(hr)) + if (FAILED(hr = d3d10_texture3d_init(object, device, desc, data))) { WARN("Failed to initialize texture, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); diff --git a/dlls/d3d10core/texture.c b/dlls/d3d10core/texture.c index d9354ee7df5..330dea95a36 100644 --- a/dlls/d3d10core/texture.c +++ b/dlls/d3d10core/texture.c @@ -248,7 +248,7 @@ static const struct wined3d_parent_ops d3d10_texture2d_wined3d_parent_ops = }; HRESULT d3d10_texture2d_init(struct d3d10_texture2d *texture, struct d3d10_device *device, - const D3D10_TEXTURE2D_DESC *desc) + const D3D10_TEXTURE2D_DESC *desc, const D3D10_SUBRESOURCE_DATA *data) { struct wined3d_resource_desc wined3d_desc; unsigned int levels; @@ -303,8 +303,9 @@ HRESULT d3d10_texture2d_init(struct d3d10_texture2d *texture, struct d3d10_devic levels = desc->MipLevels ? desc->MipLevels : wined3d_log2i(max(desc->Width, desc->Height)) + 1; - if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc, levels, - 0, texture, &d3d10_texture2d_wined3d_parent_ops, &texture->wined3d_texture))) + if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc, + levels, 0, (struct wined3d_sub_resource_data *)data, texture, + &d3d10_texture2d_wined3d_parent_ops, &texture->wined3d_texture))) { WARN("Failed to create wined3d texture, hr %#x.\n", hr); if (texture->dxgi_surface) @@ -517,7 +518,7 @@ static const struct wined3d_parent_ops d3d10_texture3d_wined3d_parent_ops = }; HRESULT d3d10_texture3d_init(struct d3d10_texture3d *texture, struct d3d10_device *device, - const D3D10_TEXTURE3D_DESC *desc) + const D3D10_TEXTURE3D_DESC *desc, const D3D10_SUBRESOURCE_DATA *data) { struct wined3d_resource_desc wined3d_desc; unsigned int levels; @@ -540,8 +541,9 @@ HRESULT d3d10_texture3d_init(struct d3d10_texture3d *texture, struct d3d10_devic levels = desc->MipLevels ? desc->MipLevels : wined3d_log2i(max(max(desc->Width, desc->Height), desc->Depth)) + 1; - if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc, levels, - 0, texture, &d3d10_texture3d_wined3d_parent_ops, &texture->wined3d_texture))) + if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc, + levels, 0, (struct wined3d_sub_resource_data *)data, texture, + &d3d10_texture3d_wined3d_parent_ops, &texture->wined3d_texture))) { WARN("Failed to create wined3d texture, hr %#x.\n", hr); return hr; diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index 659cae603de..6a4802d54ac 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -941,7 +941,7 @@ static HRESULT d3d8_device_create_surface(struct d3d8_device *device, UINT width wined3d_mutex_lock(); if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &desc, - 1, flags, NULL, &d3d8_null_wined3d_parent_ops, &texture))) + 1, flags, NULL, NULL, &d3d8_null_wined3d_parent_ops, &texture))) { wined3d_mutex_unlock(); WARN("Failed to create texture, hr %#x.\n", hr); @@ -3012,7 +3012,7 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic texture_desc = *desc; texture_desc.resource_type = WINED3D_RTYPE_TEXTURE; if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &texture_desc, 1, - WINED3D_SURFACE_MAPPABLE, &device->IDirect3DDevice8_iface, &d3d8_null_wined3d_parent_ops, &texture))) + WINED3D_SURFACE_MAPPABLE, NULL, &device->IDirect3DDevice8_iface, &d3d8_null_wined3d_parent_ops, &texture))) { WARN("Failed to create texture, hr %#x.\n", hr); return hr; diff --git a/dlls/d3d8/texture.c b/dlls/d3d8/texture.c index 24c0b283c5d..269ce4e500b 100644 --- a/dlls/d3d8/texture.c +++ b/dlls/d3d8/texture.c @@ -1177,7 +1177,7 @@ HRESULT texture_init(struct d3d8_texture *texture, struct d3d8_device *device, wined3d_mutex_lock(); hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags, - texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture); + NULL, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) { @@ -1222,7 +1222,7 @@ HRESULT cubetexture_init(struct d3d8_texture *texture, struct d3d8_device *devic wined3d_mutex_lock(); hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags, - texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture); + NULL, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) { @@ -1263,7 +1263,7 @@ HRESULT volumetexture_init(struct d3d8_texture *texture, struct d3d8_device *dev wined3d_mutex_lock(); hr = wined3d_texture_create(device->wined3d_device, &desc, levels, 0, - texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture); + NULL, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) { diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index e2e3504848b..a80b30accdb 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -1041,7 +1041,7 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width wined3d_mutex_lock(); if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &desc, - 1, flags, NULL, &d3d9_null_wined3d_parent_ops, &texture))) + 1, flags, NULL, NULL, &d3d9_null_wined3d_parent_ops, &texture))) { wined3d_mutex_unlock(); WARN("Failed to create texture, hr %#x.\n", hr); @@ -3547,7 +3547,7 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic texture_desc = *desc; texture_desc.resource_type = WINED3D_RTYPE_TEXTURE; if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &texture_desc, 1, - WINED3D_SURFACE_MAPPABLE, container_parent, &d3d9_null_wined3d_parent_ops, &texture))) + WINED3D_SURFACE_MAPPABLE, NULL, container_parent, &d3d9_null_wined3d_parent_ops, &texture))) { WARN("Failed to create texture, hr %#x.\n", hr); return hr; diff --git a/dlls/d3d9/texture.c b/dlls/d3d9/texture.c index c35ccdd72b5..c1a02778939 100644 --- a/dlls/d3d9/texture.c +++ b/dlls/d3d9/texture.c @@ -1306,7 +1306,7 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device, wined3d_mutex_lock(); hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags, - texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture); + NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) { @@ -1356,7 +1356,7 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic wined3d_mutex_lock(); hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags, - texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture); + NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) { @@ -1402,7 +1402,7 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev wined3d_mutex_lock(); hr = wined3d_texture_create(device->wined3d_device, &desc, levels, 0, - texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture); + NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) { diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index f0ebc52b031..fcbc3bfdca6 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -4786,7 +4786,7 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic texture_desc = *desc; texture_desc.resource_type = WINED3D_RTYPE_TEXTURE; if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &texture_desc, 1, - WINED3D_SURFACE_MAPPABLE, ddraw, &ddraw_frontbuffer_parent_ops, &texture))) + WINED3D_SURFACE_MAPPABLE, NULL, ddraw, &ddraw_frontbuffer_parent_ops, &texture))) { WARN("Failed to create texture, hr %#x.\n", hr); return hr; diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index a4184b8aac6..a387d1271cf 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -5992,7 +5992,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ * Commandos: Behind Enemy Lines is another. We set * WINED3D_SURFACE_PIN_SYSMEM because of this. */ if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &wined3d_desc, levels, - WINED3D_SURFACE_PIN_SYSMEM, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture))) + WINED3D_SURFACE_PIN_SYSMEM, NULL, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture))) { WARN("Failed to create wined3d texture, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, texture); @@ -6104,7 +6104,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ desc->dwBackBufferCount = 0; if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &wined3d_desc, 1, - WINED3D_SURFACE_PIN_SYSMEM, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture))) + WINED3D_SURFACE_PIN_SYSMEM, NULL, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture))) { HeapFree(GetProcessHeap(), 0, texture); hr = hr_ddraw_from_wined3d(hr); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 89ec00a8ed9..d26d3f9b13d 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -591,7 +591,7 @@ static void device_load_logo(struct wined3d_device *device, const char *filename desc.depth = 1; desc.size = 0; if (FAILED(hr = wined3d_texture_create(device, &desc, 1, WINED3D_SURFACE_MAPPABLE, - NULL, &wined3d_null_parent_ops, &device->logo_texture))) + NULL, NULL, &wined3d_null_parent_ops, &device->logo_texture))) { ERR("Wine logo requested, but failed to create texture, hr %#x.\n", hr); goto out; @@ -3455,9 +3455,9 @@ void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device static HRESULT device_update_volume(struct wined3d_device *device, struct wined3d_volume *src_volume, struct wined3d_volume *dst_volume) { + struct wined3d_const_bo_address data; struct wined3d_map_desc src; HRESULT hr; - struct wined3d_bo_address data; struct wined3d_context *context; TRACE("device %p, src_volume %p, dst_volume %p.\n", @@ -4016,7 +4016,7 @@ static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined desc.size = 0; if (FAILED(wined3d_texture_create(device, &desc, 1, WINED3D_SURFACE_MAPPABLE, - NULL, &wined3d_null_parent_ops, &texture))) + NULL, NULL, &wined3d_null_parent_ops, &texture))) { ERR("Failed to create cursor texture.\n"); wined3d_surface_unmap(cursor_image); diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 092cbe680c5..fb27c8a9e5d 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -1469,9 +1469,9 @@ static void surface_download_data(struct wined3d_surface *surface, const struct /* This call just uploads data, the caller is responsible for binding the * correct texture. */ /* Context activation is done by the caller. */ -static void surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, +void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point, - BOOL srgb, const struct wined3d_bo_address *data) + BOOL srgb, const struct wined3d_const_bo_address *data) { UINT update_w = src_rect->right - src_rect->left; UINT update_h = src_rect->bottom - src_rect->top; @@ -1700,7 +1700,8 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P surface_get_memory(src_surface, &data, src_surface->locations); src_pitch = wined3d_surface_get_pitch(src_surface); - surface_upload_data(dst_surface, gl_info, src_format, src_rect, src_pitch, dst_point, FALSE, &data); + wined3d_surface_upload_data(dst_surface, gl_info, src_format, src_rect, + src_pitch, dst_point, FALSE, wined3d_const_bo_address(&data)); context_invalidate_active_texture(context); @@ -2468,7 +2469,7 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_surface *so desc.usage = 0; desc.pool = WINED3D_POOL_SCRATCH; if (FAILED(wined3d_texture_create(source->resource.device, &desc, 1, - WINED3D_SURFACE_MAPPABLE | WINED3D_SURFACE_DISCARD, NULL, &wined3d_null_parent_ops, &ret))) + WINED3D_SURFACE_MAPPABLE | WINED3D_SURFACE_DISCARD, NULL, NULL, &wined3d_null_parent_ops, &ret))) { ERR("Failed to create a destination surface for conversion.\n"); return NULL; @@ -4254,7 +4255,8 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, data.addr = mem; } - surface_upload_data(surface, gl_info, &format, &src_rect, src_pitch, &dst_point, srgb, &data); + wined3d_surface_upload_data(surface, gl_info, &format, &src_rect, + src_pitch, &dst_point, srgb, wined3d_const_bo_address(&data)); context_release(context); diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index dfcf02d9183..d33bad10e03 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -816,6 +816,29 @@ HRESULT CDECL wined3d_texture_add_dirty_region(struct wined3d_texture *texture, return WINED3D_OK; } +static void wined3d_texture_upload_data(struct wined3d_texture *texture, const struct wined3d_sub_resource_data *data) +{ + unsigned int sub_count = texture->level_count * texture->layer_count; + struct wined3d_context *context; + unsigned int i; + + context = context_acquire(texture->resource.device, NULL); + + wined3d_texture_prepare_texture(texture, context, FALSE); + wined3d_texture_bind(texture, context, FALSE); + + for (i = 0; i < sub_count; ++i) + { + struct wined3d_resource *sub_resource = texture->sub_resources[i]; + + texture->texture_ops->texture_sub_resource_upload_data(sub_resource, context, &data[i]); + texture->texture_ops->texture_sub_resource_validate_location(sub_resource, WINED3D_LOCATION_TEXTURE_RGB); + texture->texture_ops->texture_sub_resource_invalidate_location(sub_resource, ~WINED3D_LOCATION_TEXTURE_RGB); + } + + context_release(context); +} + static void texture2d_sub_resource_load(struct wined3d_resource *sub_resource, struct wined3d_context *context, BOOL srgb) { @@ -846,6 +869,33 @@ static void texture2d_sub_resource_invalidate_location(struct wined3d_resource * surface_invalidate_location(surface, location); } +static void texture2d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location) +{ + struct wined3d_surface *surface = surface_from_resource(sub_resource); + + surface_validate_location(surface, location); +} + +static void texture2d_sub_resource_upload_data(struct wined3d_resource *sub_resource, + const struct wined3d_context *context, const struct wined3d_sub_resource_data *data) +{ + struct wined3d_surface *surface = surface_from_resource(sub_resource); + static const POINT dst_point = {0, 0}; + struct wined3d_const_bo_address addr; + RECT src_rect; + + src_rect.left = 0; + src_rect.top = 0; + src_rect.right = surface->resource.width; + src_rect.bottom = surface->resource.height; + + addr.buffer_object = 0; + addr.addr = data->data; + + wined3d_surface_upload_data(surface, context->gl_info, surface->container->resource.format, + &src_rect, data->row_pitch, &dst_point, FALSE, &addr); +} + /* Context activation is done by the caller. */ static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) { @@ -951,6 +1001,8 @@ static const struct wined3d_texture_ops texture2d_ops = texture2d_sub_resource_add_dirty_region, texture2d_sub_resource_cleanup, texture2d_sub_resource_invalidate_location, + texture2d_sub_resource_validate_location, + texture2d_sub_resource_upload_data, texture2d_prepare_texture, }; @@ -1274,6 +1326,30 @@ static void texture3d_sub_resource_invalidate_location(struct wined3d_resource * wined3d_volume_invalidate_location(volume, location); } +static void texture3d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location) +{ + struct wined3d_volume *volume = volume_from_resource(sub_resource); + + wined3d_volume_validate_location(volume, location); +} + +static void texture3d_sub_resource_upload_data(struct wined3d_resource *sub_resource, + const struct wined3d_context *context, const struct wined3d_sub_resource_data *data) +{ + struct wined3d_volume *volume = volume_from_resource(sub_resource); + struct wined3d_const_bo_address addr; + unsigned int row_pitch, slice_pitch; + + wined3d_volume_get_pitch(volume, &row_pitch, &slice_pitch); + if (row_pitch != data->row_pitch || slice_pitch != data->slice_pitch) + FIXME("Ignoring row/slice pitch (%u/%u).\n", data->row_pitch, data->slice_pitch); + + addr.buffer_object = 0; + addr.addr = data->data; + + wined3d_volume_upload_data(volume, context, &addr); +} + static void texture3d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) { unsigned int sub_count = texture->level_count * texture->layer_count; @@ -1318,6 +1394,8 @@ static const struct wined3d_texture_ops texture3d_ops = texture3d_sub_resource_add_dirty_region, texture3d_sub_resource_cleanup, texture3d_sub_resource_invalidate_location, + texture3d_sub_resource_validate_location, + texture3d_sub_resource_upload_data, texture3d_prepare_texture, }; @@ -1426,14 +1504,14 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct } HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc, - UINT level_count, DWORD surface_flags, void *parent, const struct wined3d_parent_ops *parent_ops, - struct wined3d_texture **texture) + UINT level_count, DWORD surface_flags, const struct wined3d_sub_resource_data *data, void *parent, + const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture) { struct wined3d_texture *object; HRESULT hr; - TRACE("device %p, desc %p, level_count %u, surface_flags %#x, parent %p, parent_ops %p, texture %p.\n", - device, desc, level_count, surface_flags, parent, parent_ops, texture); + TRACE("device %p, desc %p, level_count %u, surface_flags %#x, data %p, parent %p, parent_ops %p, texture %p.\n", + device, desc, level_count, surface_flags, data, parent, parent_ops, texture); if (!level_count) { @@ -1471,6 +1549,11 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct return hr; } + /* FIXME: We'd like to avoid ever allocating system memory for the texture + * in this case. */ + if (data) + wined3d_texture_upload_data(object, data); + TRACE("Created texture %p.\n", object); *texture = object; diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c index 58d73216769..b5ab862c054 100644 --- a/dlls/wined3d/volume.c +++ b/dlls/wined3d/volume.c @@ -40,8 +40,7 @@ BOOL volume_prepare_system_memory(struct wined3d_volume *volume) return TRUE; } -static void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch, - UINT *slice_pitch) +void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch, UINT *slice_pitch) { const struct wined3d_format *format = volume->resource.format; @@ -67,14 +66,15 @@ static void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT * /* Context activation is done by the caller. */ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context, - const struct wined3d_bo_address *data) + const struct wined3d_const_bo_address *data) { const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_format *format = volume->resource.format; UINT width = volume->resource.width; UINT height = volume->resource.height; UINT depth = volume->resource.depth; - BYTE *mem = data->addr; + const void *mem = data->addr; + void *converted_mem = NULL; TRACE("volume %p, context %p, level %u, format %s (%#x).\n", volume, context, volume->texture_level, debug_d3dformat(format->id), @@ -97,9 +97,10 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine wined3d_volume_get_pitch(volume, &src_row_pitch, &src_slice_pitch); - mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch * depth); - format->convert(data->addr, mem, src_row_pitch, src_slice_pitch, + converted_mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch * depth); + format->convert(data->addr, converted_mem, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch, width, height, depth); + mem = converted_mem; } if (data->buffer_object) @@ -119,11 +120,10 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine checkGLcall("glBindBufferARB"); } - if (mem != data->addr) - HeapFree(GetProcessHeap(), 0, mem); + HeapFree(GetProcessHeap(), 0, converted_mem); } -static void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location) +void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location) { TRACE("Volume %p, setting %s.\n", volume, wined3d_debug_location(location)); volume->locations |= location; @@ -217,7 +217,7 @@ static void wined3d_volume_srgb_transfer(struct wined3d_volume *volume, wined3d_texture_bind_and_dirtify(volume->container, context, !dest_is_srgb); wined3d_volume_download_data(volume, context, &data); wined3d_texture_bind_and_dirtify(volume->container, context, dest_is_srgb); - wined3d_volume_upload_data(volume, context, &data); + wined3d_volume_upload_data(volume, context, wined3d_const_bo_address(&data)); HeapFree(GetProcessHeap(), 0, data.addr); } @@ -274,12 +274,12 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, } else if (volume->locations & WINED3D_LOCATION_SYSMEM) { - struct wined3d_bo_address data = {0, volume->resource.heap_memory}; + struct wined3d_const_bo_address data = {0, volume->resource.heap_memory}; wined3d_volume_upload_data(volume, context, &data); } else if (volume->locations & WINED3D_LOCATION_BUFFER) { - struct wined3d_bo_address data = {volume->pbo, NULL}; + struct wined3d_const_bo_address data = {volume->pbo, NULL}; wined3d_volume_upload_data(volume, context, &data); } else if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 7935a5dc5a4..047946bf58a 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -948,6 +948,17 @@ struct wined3d_bo_address BYTE *addr; }; +struct wined3d_const_bo_address +{ + GLuint buffer_object; + const BYTE *addr; +}; + +static inline struct wined3d_const_bo_address *wined3d_const_bo_address(struct wined3d_bo_address *data) +{ + return (struct wined3d_const_bo_address *)data; +} + struct wined3d_stream_info_element { const struct wined3d_format *format; @@ -2146,6 +2157,9 @@ struct wined3d_texture_ops const struct wined3d_box *dirty_region); void (*texture_sub_resource_cleanup)(struct wined3d_resource *sub_resource); void (*texture_sub_resource_invalidate_location)(struct wined3d_resource *sub_resource, DWORD location); + void (*texture_sub_resource_validate_location)(struct wined3d_resource *sub_resource, DWORD location); + void (*texture_sub_resource_upload_data)(struct wined3d_resource *sub_resource, + const struct wined3d_context *context, const struct wined3d_sub_resource_data *data); void (*texture_prepare_texture)(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb); }; @@ -2250,11 +2264,13 @@ BOOL volume_prepare_system_memory(struct wined3d_volume *volume) DECLSPEC_HIDDEN HRESULT wined3d_volume_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, unsigned int level, struct wined3d_volume **volume) DECLSPEC_HIDDEN; void wined3d_volume_destroy(struct wined3d_volume *volume) DECLSPEC_HIDDEN; +void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch, UINT *slice_pitch) DECLSPEC_HIDDEN; void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, BOOL srgb_mode) DECLSPEC_HIDDEN; void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN; +void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN; void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context, - const struct wined3d_bo_address *data) DECLSPEC_HIDDEN; + const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN; struct wined3d_surface_dib { @@ -2372,6 +2388,9 @@ HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct w struct wined3d_surface **surface) DECLSPEC_HIDDEN; void wined3d_surface_destroy(struct wined3d_surface *surface) DECLSPEC_HIDDEN; void surface_prepare_map_memory(struct wined3d_surface *surface) DECLSPEC_HIDDEN; +void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, + const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point, + BOOL srgb, const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN; void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 0cf26e1dcb2..6e063887a94 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -1721,6 +1721,13 @@ struct wined3d_map_desc void *data; }; +struct wined3d_sub_resource_data +{ + const void *data; + unsigned int row_pitch; + unsigned int slice_pitch; +}; + struct wined3d_box { UINT left; @@ -2516,8 +2523,8 @@ void __cdecl wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, H HRESULT __cdecl wined3d_texture_add_dirty_region(struct wined3d_texture *texture, UINT layer, const struct wined3d_box *dirty_region); HRESULT __cdecl wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc, - UINT level_count, DWORD surface_flags, void *parent, const struct wined3d_parent_ops *parent_ops, - struct wined3d_texture **texture); + UINT level_count, DWORD surface_flags, const struct wined3d_sub_resource_data *data, void *parent, + const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture); ULONG __cdecl wined3d_texture_decref(struct wined3d_texture *texture); void __cdecl wined3d_texture_generate_mipmaps(struct wined3d_texture *texture); enum wined3d_texture_filter_type __cdecl wined3d_texture_get_autogen_filter_type(const struct wined3d_texture *texture);