SHOW:
|
|
- or go back to the newest paste.
| 1 | diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c | |
| 2 | index c53021b..5b4ef8e 100644 | |
| 3 | --- a/dlls/wined3d/buffer.c | |
| 4 | +++ b/dlls/wined3d/buffer.c | |
| 5 | @@ -1147,7 +1147,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device | |
| 6 | ||
| 7 | hr = resource_init(&buffer->resource, device, WINED3D_RTYPE_BUFFER, format, | |
| 8 | WINED3D_MULTISAMPLE_NONE, 0, usage, pool, size, 1, 1, size, | |
| 9 | - parent, parent_ops, &buffer_resource_ops); | |
| 10 | + parent, parent_ops, &buffer_resource_ops, 0); | |
| 11 | if (FAILED(hr)) | |
| 12 | {
| |
| 13 | WARN("Failed to initialize resource, hr %#x\n", hr);
| |
| 14 | diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c | |
| 15 | index 177d23e..21b4c0d 100644 | |
| 16 | --- a/dlls/wined3d/resource.c | |
| 17 | +++ b/dlls/wined3d/resource.c | |
| 18 | @@ -82,7 +82,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * | |
| 19 | enum wined3d_multisample_type multisample_type, UINT multisample_quality, | |
| 20 | DWORD usage, enum wined3d_pool pool, UINT width, UINT height, UINT depth, UINT size, | |
| 21 | void *parent, const struct wined3d_parent_ops *parent_ops, | |
| 22 | - const struct wined3d_resource_ops *resource_ops) | |
| 23 | + const struct wined3d_resource_ops *resource_ops, void *have_alloc) | |
| 24 | {
| |
| 25 | const struct wined3d *d3d = device->wined3d; | |
| 26 | ||
| 27 | @@ -120,7 +120,9 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * | |
| 28 | ||
| 29 | if (size) | |
| 30 | {
| |
| 31 | - if (!wined3d_resource_allocate_sysmem(resource)) | |
| 32 | + if (have_alloc) {
| |
| 33 | + resource->heap_memory = have_alloc; | |
| 34 | + } else if (!wined3d_resource_allocate_sysmem(resource)) | |
| 35 | {
| |
| 36 | ERR("Failed to allocate system memory.\n");
| |
| 37 | return E_OUTOFMEMORY; | |
| 38 | diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c | |
| 39 | index 628a4a5..3ab9878 100644 | |
| 40 | --- a/dlls/wined3d/surface.c | |
| 41 | +++ b/dlls/wined3d/surface.c | |
| 42 | @@ -6307,7 +6307,7 @@ cpu: | |
| 43 | } | |
| 44 | ||
| 45 | static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_texture *container, | |
| 46 | - const struct wined3d_resource_desc *desc, DWORD flags) | |
| 47 | + const struct wined3d_resource_desc *desc, DWORD flags, void *have_alloc) | |
| 48 | {
| |
| 49 | struct wined3d_device *device = container->resource.device; | |
| 50 | const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; | |
| 51 | @@ -6365,7 +6365,7 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text | |
| 52 | ||
| 53 | if (FAILED(hr = resource_init(&surface->resource, device, WINED3D_RTYPE_SURFACE, format, | |
| 54 | desc->multisample_type, multisample_quality, desc->usage, desc->pool, desc->width, desc->height, 1, | |
| 55 | - resource_size, NULL, &wined3d_null_parent_ops, &surface_resource_ops))) | |
| 56 | + resource_size, NULL, &wined3d_null_parent_ops, &surface_resource_ops, have_alloc))) | |
| 57 | {
| |
| 58 | WARN("Failed to initialize resource, returning %#x.\n", hr);
| |
| 59 | return hr; | |
| 60 | @@ -6415,7 +6415,7 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text | |
| 61 | } | |
| 62 | ||
| 63 | HRESULT CDECL wined3d_surface_create(struct wined3d_texture *container, | |
| 64 | - const struct wined3d_resource_desc *desc, DWORD flags, struct wined3d_surface **surface) | |
| 65 | + const struct wined3d_resource_desc *desc, DWORD flags, struct wined3d_surface **surface, void *have_alloc) | |
| 66 | {
| |
| 67 | struct wined3d_device_parent *device_parent = container->resource.device->device_parent; | |
| 68 | const struct wined3d_parent_ops *parent_ops; | |
| 69 | @@ -6432,7 +6432,7 @@ HRESULT CDECL wined3d_surface_create(struct wined3d_texture *container, | |
| 70 | if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) | |
| 71 | return E_OUTOFMEMORY; | |
| 72 | ||
| 73 | - if (FAILED(hr = surface_init(object, container, desc, flags))) | |
| 74 | + if (FAILED(hr = surface_init(object, container, desc, flags, have_alloc))) | |
| 75 | {
| |
| 76 | WARN("Failed to initialize surface, returning %#x.\n", hr);
| |
| 77 | HeapFree(GetProcessHeap(), 0, object); | |
| 78 | diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c | |
| 79 | index 897af19..cb03c4c 100644 | |
| 80 | --- a/dlls/wined3d/texture.c | |
| 81 | +++ b/dlls/wined3d/texture.c | |
| 82 | @@ -51,7 +51,7 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc | |
| 83 | ||
| 84 | if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format, | |
| 85 | desc->multisample_type, desc->multisample_quality, desc->usage, desc->pool, | |
| 86 | - desc->width, desc->height, desc->depth, 0, parent, parent_ops, resource_ops))) | |
| 87 | + desc->width, desc->height, desc->depth, 0, parent, parent_ops, resource_ops, 0))) | |
| 88 | {
| |
| 89 | WARN("Failed to initialize resource, returning %#x\n", hr);
| |
| 90 | return hr; | |
| 91 | @@ -879,7 +879,7 @@ static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wi | |
| 92 | UINT idx = j * texture->level_count + i; | |
| 93 | struct wined3d_surface *surface; | |
| 94 | ||
| 95 | - if (FAILED(hr = wined3d_surface_create(texture, &surface_desc, surface_flags, &surface))) | |
| 96 | + if (FAILED(hr = wined3d_surface_create(texture, &surface_desc, surface_flags, &surface, 0))) | |
| 97 | {
| |
| 98 | WARN("Failed to create surface, hr %#x.\n", hr);
| |
| 99 | wined3d_texture_cleanup(texture); | |
| 100 | @@ -897,6 +897,21 @@ static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wi | |
| 101 | return WINED3D_OK; | |
| 102 | } | |
| 103 | ||
| 104 | +void* wined3d_resource_allocate_sysmem_from_size(SIZE_T size) | |
| 105 | +{
| |
| 106 | + void **p; | |
| 107 | + SIZE_T align = RESOURCE_ALIGNMENT - 1 + sizeof(*p); | |
| 108 | + void *mem; | |
| 109 | + | |
| 110 | + if (!(mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + align))) | |
| 111 | + return FALSE; | |
| 112 | + | |
| 113 | + p = (void **)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)) - 1; | |
| 114 | + *p = mem; | |
| 115 | + | |
| 116 | + return ++p; | |
| 117 | +} | |
| 118 | + | |
| 119 | static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, | |
| 120 | UINT levels, DWORD surface_flags, struct wined3d_device *device, void *parent, | |
| 121 | const struct wined3d_parent_ops *parent_ops) | |
| 122 | @@ -1029,25 +1044,42 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 | |
| 123 | /* Generate all the surfaces. */ | |
| 124 | surface_desc = *desc; | |
| 125 | surface_desc.resource_type = WINED3D_RTYPE_SURFACE; | |
| 126 | + | |
| 127 | + SIZE_T resource_size = 0; | |
| 128 | + UINT pw = surface_desc.width; | |
| 129 | + UINT ph = surface_desc.height; | |
| 130 | + const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format); | |
| 131 | + // compute the needed space for all mipmaps | |
| 132 | + for (i = 0; i < texture->level_count; ++i) | |
| 133 | + {
| |
| 134 | + resource_size += wined3d_format_calculate_size(format, device->surface_alignment, pw, ph, 1); | |
| 135 | + // next mipmap | |
| 136 | + pw = max(1, pw >> 1); | |
| 137 | + ph = max(1, ph >> 1); | |
| 138 | + } | |
| 139 | + // alloc | |
| 140 | + void *base_surface_alloc = wined3d_resource_allocate_sysmem_from_size(resource_size); | |
| 141 | + void *last_alloc = base_surface_alloc; | |
| 142 | for (i = 0; i < texture->level_count; ++i) | |
| 143 | {
| |
| 144 | struct wined3d_surface *surface; | |
| 145 | ||
| 146 | - if (FAILED(hr = wined3d_surface_create(texture, &surface_desc, surface_flags, &surface))) | |
| 147 | + if (FAILED(hr = wined3d_surface_create(texture, &surface_desc, surface_flags, &surface, last_alloc))) | |
| 148 | {
| |
| 149 | WARN("Failed to create surface, hr %#x.\n", hr);
| |
| 150 | wined3d_texture_cleanup(texture); | |
| 151 | return hr; | |
| 152 | } | |
| 153 | + last_alloc += wined3d_format_calculate_size(format, device->surface_alignment, surface_desc.width, surface_desc.height, 1); | |
| 154 | ||
| 155 | surface_set_texture_target(surface, texture->target, i); | |
| 156 | texture->sub_resources[i] = &surface->resource; | |
| 157 | + | |
| 158 | TRACE("Created surface level %u @ %p.\n", i, surface);
| |
| 159 | /* Calculate the next mipmap level. */ | |
| 160 | surface_desc.width = max(1, surface_desc.width >> 1); | |
| 161 | surface_desc.height = max(1, surface_desc.height >> 1); | |
| 162 | } | |
| 163 | - | |
| 164 | return WINED3D_OK; | |
| 165 | } | |
| 166 | ||
| 167 | diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c | |
| 168 | index 817fe7e..335c65e 100644 | |
| 169 | --- a/dlls/wined3d/volume.c | |
| 170 | +++ b/dlls/wined3d/volume.c | |
| 171 | @@ -839,7 +839,7 @@ static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_texture | |
| 172 | ||
| 173 | if (FAILED(hr = resource_init(&volume->resource, device, WINED3D_RTYPE_VOLUME, format, | |
| 174 | WINED3D_MULTISAMPLE_NONE, 0, desc->usage, desc->pool, desc->width, desc->height, desc->depth, | |
| 175 | - size, NULL, &wined3d_null_parent_ops, &volume_resource_ops))) | |
| 176 | + size, NULL, &wined3d_null_parent_ops, &volume_resource_ops, 0))) | |
| 177 | {
| |
| 178 | WARN("Failed to initialize resource, returning %#x.\n", hr);
| |
| 179 | return hr; | |
| 180 | diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h | |
| 181 | index 991db87..853a6c3 100644 | |
| 182 | --- a/dlls/wined3d/wined3d_private.h | |
| 183 | +++ b/dlls/wined3d/wined3d_private.h | |
| 184 | @@ -2015,7 +2015,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * | |
| 185 | enum wined3d_multisample_type multisample_type, UINT multisample_quality, | |
| 186 | DWORD usage, enum wined3d_pool pool, UINT width, UINT height, UINT depth, UINT size, | |
| 187 | void *parent, const struct wined3d_parent_ops *parent_ops, | |
| 188 | - const struct wined3d_resource_ops *resource_ops) DECLSPEC_HIDDEN; | |
| 189 | + const struct wined3d_resource_ops *resource_ops, void *have_alloc) DECLSPEC_HIDDEN; | |
| 190 | DWORD resource_set_priority(struct wined3d_resource *resource, DWORD priority) DECLSPEC_HIDDEN; | |
| 191 | void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN; | |
| 192 | BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; | |
| 193 | @@ -2275,7 +2275,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P | |
| 194 | struct wined3d_surface *src_surface, const RECT *src_rect) DECLSPEC_HIDDEN; | |
| 195 | void surface_validate_location(struct wined3d_surface *surface, DWORD location) DECLSPEC_HIDDEN; | |
| 196 | HRESULT CDECL wined3d_surface_create(struct wined3d_texture *container, | |
| 197 | - const struct wined3d_resource_desc *desc, DWORD flags, struct wined3d_surface **surface) DECLSPEC_HIDDEN; | |
| 198 | + const struct wined3d_resource_desc *desc, DWORD flags, struct wined3d_surface **surface, void *last_alloc) DECLSPEC_HIDDEN; | |
| 199 | void surface_prepare_map_memory(struct wined3d_surface *surface) DECLSPEC_HIDDEN; | |
| 200 | ||
| 201 | void get_drawable_size_swapchain(const struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN; |