[PATCH 2/3] wined3d: Allow initial texture contents to be specified with wined3d_texture_create().
Henri Verbeet
hverbeet at codeweavers.com
Mon Jan 5 06:24:58 CST 2015
---
dlls/d3d10core/d3d10core_private.h | 4 +-
dlls/d3d10core/device.c | 8 ++--
dlls/d3d10core/texture.c | 14 +++---
dlls/d3d8/device.c | 4 +-
dlls/d3d8/texture.c | 6 +--
dlls/d3d9/device.c | 4 +-
dlls/d3d9/texture.c | 6 +--
dlls/ddraw/ddraw.c | 2 +-
dlls/ddraw/surface.c | 4 +-
dlls/wined3d/device.c | 6 +--
dlls/wined3d/surface.c | 12 +++--
dlls/wined3d/texture.c | 91 ++++++++++++++++++++++++++++++++++--
dlls/wined3d/volume.c | 24 +++++-----
dlls/wined3d/wined3d_private.h | 21 ++++++++-
include/wine/wined3d.h | 11 ++++-
15 files changed, 164 insertions(+), 53 deletions(-)
diff --git a/dlls/d3d10core/d3d10core_private.h b/dlls/d3d10core/d3d10core_private.h
index 29f5653..b777900 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 44a8085..ccac3f2 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 d9354ee..330dea9 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 659cae6..6a4802d 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 24c0b28..269ce4e 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 e2e3504..a80b30a 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 c35ccdd..c1a0277 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 f0ebc52..fcbc3bf 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 a4184b8..a387d12 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 89ec00a..d26d3f9 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 092cbe6..fb27c8a 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 dfcf02d..d33bad1 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 58d7321..b5ab862 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 7935a5d..047946b 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 0cf26e1..6e06388 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);
--
1.7.10.4
More information about the wine-patches
mailing list