1 /* 2 * Copyright 2009, 2011 Henri Verbeet for CodeWeavers 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 * 18 */ 19 20 #include "wined3d_private.h" 21 22 WINE_DEFAULT_DEBUG_CHANNEL(d3d); 23 24 ULONG CDECL wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view *view) 25 { 26 ULONG refcount = InterlockedIncrement(&view->refcount); 27 28 TRACE("%p increasing refcount to %u.\n", view, refcount); 29 30 return refcount; 31 } 32 33 #if defined(STAGING_CSMT) 34 void wined3d_rendertarget_view_destroy(struct wined3d_rendertarget_view *view) 35 { 36 HeapFree(GetProcessHeap(), 0, view); 37 } 38 39 #endif /* STAGING_CSMT */ 40 ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *view) 41 { 42 ULONG refcount = InterlockedDecrement(&view->refcount); 43 44 TRACE("%p decreasing refcount to %u.\n", view, refcount); 45 46 if (!refcount) 47 { 48 #if defined(STAGING_CSMT) 49 struct wined3d_device *device = view->resource->device; 50 51 /* Call wined3d_object_destroyed() before releasing the resource, 52 * since releasing the resource may end up destroying the parent. */ 53 view->parent_ops->wined3d_object_destroyed(view->parent); 54 wined3d_resource_decref(view->resource); 55 wined3d_cs_emit_view_destroy(device->cs, view); 56 #else /* STAGING_CSMT */ 57 /* Call wined3d_object_destroyed() before releasing the resource, 58 * since releasing the resource may end up destroying the parent. */ 59 view->parent_ops->wined3d_object_destroyed(view->parent); 60 wined3d_resource_decref(view->resource); 61 HeapFree(GetProcessHeap(), 0, view); 62 #endif /* STAGING_CSMT */ 63 } 64 65 return refcount; 66 } 67 68 void * CDECL wined3d_rendertarget_view_get_parent(const struct wined3d_rendertarget_view *view) 69 { 70 TRACE("view %p.\n", view); 71 72 return view->parent; 73 } 74 75 void * CDECL wined3d_rendertarget_view_get_sub_resource_parent(const struct wined3d_rendertarget_view *view) 76 { 77 struct wined3d_resource *sub_resource; 78 79 TRACE("view %p.\n", view); 80 81 if (view->resource->type == WINED3D_RTYPE_BUFFER) 82 return wined3d_buffer_get_parent(buffer_from_resource(view->resource)); 83 84 if (!(sub_resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(view->resource), 85 view->sub_resource_idx))) 86 return NULL; 87 88 return wined3d_resource_get_parent(sub_resource); 89 } 90 91 void CDECL wined3d_rendertarget_view_set_parent(struct wined3d_rendertarget_view *view, void *parent) 92 { 93 TRACE("view %p, parent %p.\n", view, parent); 94 95 view->parent = parent; 96 } 97 98 struct wined3d_resource * CDECL wined3d_rendertarget_view_get_resource(const struct wined3d_rendertarget_view *view) 99 { 100 TRACE("view %p.\n", view); 101 102 return view->resource; 103 } 104 105 static void wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *view, 106 const struct wined3d_rendertarget_view_desc *desc, struct wined3d_resource *resource, 107 void *parent, const struct wined3d_parent_ops *parent_ops) 108 { 109 const struct wined3d_gl_info *gl_info = &resource->device->adapter->gl_info; 110 111 view->refcount = 1; 112 view->resource = resource; 113 wined3d_resource_incref(resource); 114 view->parent = parent; 115 view->parent_ops = parent_ops; 116 117 view->format = wined3d_get_format(gl_info, desc->format_id); 118 view->format_flags = view->format->flags[resource->gl_type]; 119 if (resource->type == WINED3D_RTYPE_BUFFER) 120 { 121 view->sub_resource_idx = 0; 122 view->buffer_offset = desc->u.buffer.start_idx; 123 view->width = desc->u.buffer.count; 124 view->height = 1; 125 view->depth = 1; 126 } 127 else 128 { 129 struct wined3d_texture *texture = wined3d_texture_from_resource(resource); 130 struct wined3d_resource *sub_resource; 131 132 view->sub_resource_idx = desc->u.texture.layer_idx * texture->level_count + desc->u.texture.level_idx; 133 sub_resource = wined3d_texture_get_sub_resource(texture, view->sub_resource_idx); 134 135 view->buffer_offset = 0; 136 view->width = sub_resource->width; 137 view->height = sub_resource->height; 138 view->depth = desc->u.texture.layer_count; 139 } 140 } 141 142 HRESULT CDECL wined3d_rendertarget_view_create(const struct wined3d_rendertarget_view_desc *desc, 143 struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, 144 struct wined3d_rendertarget_view **view) 145 { 146 struct wined3d_rendertarget_view *object; 147 148 TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n", 149 desc, resource, parent, parent_ops, view); 150 151 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) 152 return E_OUTOFMEMORY; 153 154 wined3d_rendertarget_view_init(object, desc, resource, parent, parent_ops); 155 156 TRACE("Created render target view %p.\n", object); 157 *view = object; 158 159 return WINED3D_OK; 160 } 161 162 HRESULT CDECL wined3d_rendertarget_view_create_from_sub_resource(struct wined3d_texture *texture, 163 unsigned int sub_resource_idx, void *parent, const struct wined3d_parent_ops *parent_ops, 164 struct wined3d_rendertarget_view **view) 165 { 166 struct wined3d_rendertarget_view_desc desc; 167 168 TRACE("texture %p, sub_resource_idx %u, parent %p, parent_ops %p, view %p.\n", 169 texture, sub_resource_idx, parent, parent_ops, view); 170 171 desc.format_id = texture->resource.format->id; 172 desc.u.texture.level_idx = sub_resource_idx % texture->level_count; 173 desc.u.texture.layer_idx = sub_resource_idx / texture->level_count; 174 desc.u.texture.layer_count = 1; 175 176 return wined3d_rendertarget_view_create(&desc, &texture->resource, parent, parent_ops, view); 177 } 178 179 ULONG CDECL wined3d_shader_resource_view_incref(struct wined3d_shader_resource_view *view) 180 { 181 ULONG refcount = InterlockedIncrement(&view->refcount); 182 183 TRACE("%p increasing refcount to %u.\n", view, refcount); 184 185 return refcount; 186 } 187 188 ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_view *view) 189 { 190 ULONG refcount = InterlockedDecrement(&view->refcount); 191 192 TRACE("%p decreasing refcount to %u.\n", view, refcount); 193 194 if (!refcount) 195 { 196 /* Call wined3d_object_destroyed() before releasing the resource, 197 * since releasing the resource may end up destroying the parent. */ 198 view->parent_ops->wined3d_object_destroyed(view->parent); 199 wined3d_resource_decref(view->resource); 200 HeapFree(GetProcessHeap(), 0, view); 201 } 202 203 return refcount; 204 } 205 206 void * CDECL wined3d_shader_resource_view_get_parent(const struct wined3d_shader_resource_view *view) 207 { 208 TRACE("view %p.\n", view); 209 210 return view->parent; 211 } 212 213 HRESULT CDECL wined3d_shader_resource_view_create(struct wined3d_resource *resource, void *parent, 214 const struct wined3d_parent_ops *parent_ops, struct wined3d_shader_resource_view **view) 215 { 216 struct wined3d_shader_resource_view *object; 217 218 TRACE("resource %p, parent %p, parent_ops %p, view %p.\n", resource, parent, parent_ops, view); 219 220 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) 221 return E_OUTOFMEMORY; 222 223 object->refcount = 1; 224 object->resource = resource; 225 wined3d_resource_incref(resource); 226 object->parent = parent; 227 object->parent_ops = parent_ops; 228 229 TRACE("Created shader resource view %p.\n", object); 230 *view = object; 231 232 return WINED3D_OK; 233 } 234