ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

volume.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2002-2005 Jason Edmeades
00003  * Copyright 2002-2005 Raphael Junqueira
00004  * Copyright 2005 Oliver Stieber
00005  * Copyright 2009-2011 Henri Verbeet for CodeWeavers
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  */
00021 
00022 #include "config.h"
00023 #include "wined3d_private.h"
00024 
00025 WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
00026 
00027 /* Context activation is done by the caller. */
00028 static void volume_bind_and_dirtify(const struct wined3d_volume *volume, struct wined3d_context *context)
00029 {
00030     struct wined3d_texture *container = volume->container;
00031     DWORD active_sampler;
00032 
00033     /* We don't need a specific texture unit, but after binding the texture the current unit is dirty.
00034      * Read the unit back instead of switching to 0, this avoids messing around with the state manager's
00035      * gl states. The current texture unit should always be a valid one.
00036      *
00037      * To be more specific, this is tricky because we can implicitly be called
00038      * from sampler() in state.c. This means we can't touch anything other than
00039      * whatever happens to be the currently active texture, or we would risk
00040      * marking already applied sampler states dirty again. */
00041     active_sampler = volume->resource.device->rev_tex_unit_map[context->active_texture];
00042 
00043     if (active_sampler != WINED3D_UNMAPPED_STAGE)
00044         device_invalidate_state(volume->resource.device, STATE_SAMPLER(active_sampler));
00045 
00046     container->texture_ops->texture_bind(container, context, FALSE);
00047 }
00048 
00049 void volume_add_dirty_box(struct wined3d_volume *volume, const struct wined3d_box *dirty_box)
00050 {
00051     volume->dirty = TRUE;
00052     if (dirty_box)
00053     {
00054         volume->lockedBox.left = min(volume->lockedBox.left, dirty_box->left);
00055         volume->lockedBox.top = min(volume->lockedBox.top, dirty_box->top);
00056         volume->lockedBox.front = min(volume->lockedBox.front, dirty_box->front);
00057         volume->lockedBox.right = max(volume->lockedBox.right, dirty_box->right);
00058         volume->lockedBox.bottom = max(volume->lockedBox.bottom, dirty_box->bottom);
00059         volume->lockedBox.back = max(volume->lockedBox.back, dirty_box->back);
00060     }
00061     else
00062     {
00063         volume->lockedBox.left = 0;
00064         volume->lockedBox.top = 0;
00065         volume->lockedBox.front = 0;
00066         volume->lockedBox.right = volume->resource.width;
00067         volume->lockedBox.bottom = volume->resource.height;
00068         volume->lockedBox.back = volume->resource.depth;
00069     }
00070 }
00071 
00072 void volume_set_container(struct wined3d_volume *volume, struct wined3d_texture *container)
00073 {
00074     TRACE("volume %p, container %p.\n", volume, container);
00075 
00076     volume->container = container;
00077 }
00078 
00079 /* Context activation is done by the caller. */
00080 void volume_load(const struct wined3d_volume *volume, struct wined3d_context *context, UINT level, BOOL srgb_mode)
00081 {
00082     const struct wined3d_gl_info *gl_info = context->gl_info;
00083     const struct wined3d_format *format = volume->resource.format;
00084 
00085     TRACE("volume %p, context %p, level %u, srgb %#x, format %s (%#x).\n",
00086             volume, context, level, srgb_mode, debug_d3dformat(format->id), format->id);
00087 
00088     volume_bind_and_dirtify(volume, context);
00089 
00090     ENTER_GL();
00091     GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, level, format->glInternal,
00092             volume->resource.width, volume->resource.height, volume->resource.depth,
00093             0, format->glFormat, format->glType, volume->resource.allocatedMemory));
00094     checkGLcall("glTexImage3D");
00095     LEAVE_GL();
00096 
00097     /* When adding code releasing volume->resource.allocatedMemory to save
00098      * data keep in mind that GL_UNPACK_CLIENT_STORAGE_APPLE is enabled by
00099      * default if supported(GL_APPLE_client_storage). Thus do not release
00100      * volume->resource.allocatedMemory if GL_APPLE_client_storage is
00101      * supported. */
00102 }
00103 
00104 /* Do not call while under the GL lock. */
00105 static void volume_unload(struct wined3d_resource *resource)
00106 {
00107     TRACE("texture %p.\n", resource);
00108 
00109     /* The whole content is shadowed on This->resource.allocatedMemory, and
00110      * the texture name is managed by the VolumeTexture container. */
00111 
00112     resource_unload(resource);
00113 }
00114 
00115 ULONG CDECL wined3d_volume_incref(struct wined3d_volume *volume)
00116 {
00117     ULONG refcount;
00118 
00119     if (volume->container)
00120     {
00121         TRACE("Forwarding to container %p.\n", volume->container);
00122         return wined3d_texture_incref(volume->container);
00123     }
00124 
00125     refcount = InterlockedIncrement(&volume->resource.ref);
00126 
00127     TRACE("%p increasing refcount to %u.\n", volume, refcount);
00128 
00129     return refcount;
00130 }
00131 
00132 /* Do not call while under the GL lock. */
00133 ULONG CDECL wined3d_volume_decref(struct wined3d_volume *volume)
00134 {
00135     ULONG refcount;
00136 
00137     if (volume->container)
00138     {
00139         TRACE("Forwarding to container %p.\n", volume->container);
00140         return wined3d_texture_decref(volume->container);
00141     }
00142 
00143     refcount = InterlockedDecrement(&volume->resource.ref);
00144 
00145     TRACE("%p decreasing refcount to %u.\n", volume, refcount);
00146 
00147     if (!refcount)
00148     {
00149         resource_cleanup(&volume->resource);
00150         volume->resource.parent_ops->wined3d_object_destroyed(volume->resource.parent);
00151         HeapFree(GetProcessHeap(), 0, volume);
00152     }
00153 
00154     return refcount;
00155 }
00156 
00157 void * CDECL wined3d_volume_get_parent(const struct wined3d_volume *volume)
00158 {
00159     TRACE("volume %p.\n", volume);
00160 
00161     return volume->resource.parent;
00162 }
00163 
00164 DWORD CDECL wined3d_volume_set_priority(struct wined3d_volume *volume, DWORD priority)
00165 {
00166     return resource_set_priority(&volume->resource, priority);
00167 }
00168 
00169 DWORD CDECL wined3d_volume_get_priority(const struct wined3d_volume *volume)
00170 {
00171     return resource_get_priority(&volume->resource);
00172 }
00173 
00174 /* Do not call while under the GL lock. */
00175 void CDECL wined3d_volume_preload(struct wined3d_volume *volume)
00176 {
00177     FIXME("volume %p stub!\n", volume);
00178 }
00179 
00180 struct wined3d_resource * CDECL wined3d_volume_get_resource(struct wined3d_volume *volume)
00181 {
00182     TRACE("volume %p.\n", volume);
00183 
00184     return &volume->resource;
00185 }
00186 
00187 HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume,
00188         struct wined3d_mapped_box *mapped_box, const struct wined3d_box *box, DWORD flags)
00189 {
00190     TRACE("volume %p, mapped_box %p, box %p, flags %#x.\n",
00191             volume, mapped_box, box, flags);
00192 
00193     if (!volume->resource.allocatedMemory)
00194         volume->resource.allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->resource.size);
00195 
00196     TRACE("allocatedMemory %p.\n", volume->resource.allocatedMemory);
00197 
00198     mapped_box->row_pitch = volume->resource.format->byte_count * volume->resource.width; /* Bytes / row */
00199     mapped_box->slice_pitch = volume->resource.format->byte_count
00200             * volume->resource.width * volume->resource.height; /* Bytes / slice */
00201     if (!box)
00202     {
00203         TRACE("No box supplied - all is ok\n");
00204         mapped_box->data = volume->resource.allocatedMemory;
00205         volume->lockedBox.left   = 0;
00206         volume->lockedBox.top    = 0;
00207         volume->lockedBox.front  = 0;
00208         volume->lockedBox.right  = volume->resource.width;
00209         volume->lockedBox.bottom = volume->resource.height;
00210         volume->lockedBox.back   = volume->resource.depth;
00211     }
00212     else
00213     {
00214         TRACE("Lock Box (%p) = l %u, t %u, r %u, b %u, fr %u, ba %u\n",
00215                 box, box->left, box->top, box->right, box->bottom, box->front, box->back);
00216         mapped_box->data = volume->resource.allocatedMemory
00217                 + (mapped_box->slice_pitch * box->front)     /* FIXME: is front < back or vica versa? */
00218                 + (mapped_box->row_pitch * box->top)
00219                 + (box->left * volume->resource.format->byte_count);
00220         volume->lockedBox.left   = box->left;
00221         volume->lockedBox.top    = box->top;
00222         volume->lockedBox.front  = box->front;
00223         volume->lockedBox.right  = box->right;
00224         volume->lockedBox.bottom = box->bottom;
00225         volume->lockedBox.back   = box->back;
00226     }
00227 
00228     if (!(flags & (WINED3DLOCK_NO_DIRTY_UPDATE | WINED3DLOCK_READONLY)))
00229     {
00230         volume_add_dirty_box(volume, &volume->lockedBox);
00231         wined3d_texture_set_dirty(volume->container, TRUE);
00232     }
00233 
00234     volume->locked = TRUE;
00235 
00236     TRACE("Returning memory %p, row pitch %d, slice pitch %d.\n",
00237             mapped_box->data, mapped_box->row_pitch, mapped_box->slice_pitch);
00238 
00239     return WINED3D_OK;
00240 }
00241 
00242 struct wined3d_volume * CDECL wined3d_volume_from_resource(struct wined3d_resource *resource)
00243 {
00244     return volume_from_resource(resource);
00245 }
00246 
00247 HRESULT CDECL wined3d_volume_unmap(struct wined3d_volume *volume)
00248 {
00249     TRACE("volume %p.\n", volume);
00250 
00251     if (!volume->locked)
00252     {
00253         WARN("Trying to unlock unlocked volume %p.\n", volume);
00254         return WINED3DERR_INVALIDCALL;
00255     }
00256 
00257     volume->locked = FALSE;
00258     memset(&volume->lockedBox, 0, sizeof(volume->lockedBox));
00259 
00260     return WINED3D_OK;
00261 }
00262 
00263 static const struct wined3d_resource_ops volume_resource_ops =
00264 {
00265     volume_unload,
00266 };
00267 
00268 static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_device *device, UINT width,
00269         UINT height, UINT depth, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool,
00270         void *parent, const struct wined3d_parent_ops *parent_ops)
00271 {
00272     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
00273     const struct wined3d_format *format = wined3d_get_format(gl_info, format_id);
00274     HRESULT hr;
00275 
00276     if (!gl_info->supported[EXT_TEXTURE3D])
00277     {
00278         WARN("Volume cannot be created - no volume texture support.\n");
00279         return WINED3DERR_INVALIDCALL;
00280     }
00281 
00282     hr = resource_init(&volume->resource, device, WINED3D_RTYPE_VOLUME, format,
00283             WINED3D_MULTISAMPLE_NONE, 0, usage, pool, width, height, depth,
00284             width * height * depth * format->byte_count, parent, parent_ops,
00285             &volume_resource_ops);
00286     if (FAILED(hr))
00287     {
00288         WARN("Failed to initialize resource, returning %#x.\n", hr);
00289         return hr;
00290     }
00291 
00292     volume->lockable = TRUE;
00293     volume->locked = FALSE;
00294     memset(&volume->lockedBox, 0, sizeof(volume->lockedBox));
00295     volume->dirty = TRUE;
00296 
00297     volume_add_dirty_box(volume, NULL);
00298 
00299     return WINED3D_OK;
00300 }
00301 
00302 HRESULT CDECL wined3d_volume_create(struct wined3d_device *device, UINT width, UINT height,
00303         UINT depth, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool, void *parent,
00304         const struct wined3d_parent_ops *parent_ops, struct wined3d_volume **volume)
00305 {
00306     struct wined3d_volume *object;
00307     HRESULT hr;
00308 
00309     TRACE("device %p, width %u, height %u, depth %u, usage %#x, format %s, pool %s\n",
00310             device, width, height, depth, usage, debug_d3dformat(format_id), debug_d3dpool(pool));
00311     TRACE("parent %p, parent_ops %p, volume %p.\n", parent, parent_ops, volume);
00312 
00313     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
00314     if (!object)
00315     {
00316         ERR("Out of memory\n");
00317         *volume = NULL;
00318         return WINED3DERR_OUTOFVIDEOMEMORY;
00319     }
00320 
00321     hr = volume_init(object, device, width, height, depth, usage, format_id, pool, parent, parent_ops);
00322     if (FAILED(hr))
00323     {
00324         WARN("Failed to initialize volume, returning %#x.\n", hr);
00325         HeapFree(GetProcessHeap(), 0, object);
00326         return hr;
00327     }
00328 
00329     TRACE("Created volume %p.\n", object);
00330     *volume = object;
00331 
00332     return WINED3D_OK;
00333 }

Generated on Mon May 28 2012 04:19:04 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.