HRESULT NineVolume9_UploadSelf( struct NineVolume9 *This ) { struct pipe_context *pipe = This->pipe; struct pipe_resource *res = This->resource; uint8_t *ptr; unsigned i; DBG("This=%p dirty=%i data=%p res=%p\n", This, NineVolume9_IsDirty(This), This->data, res); assert(This->desc.Pool == D3DPOOL_MANAGED); if (!NineVolume9_IsDirty(This)) return D3D_OK; assert(res); for (i = 0; i < Elements(This->dirty_box); ++i) { const struct pipe_box *box = &This->dirty_box[i]; if (box->width == 0) break; ptr = NineVolume9_GetSystemMemPointer(This, box->x, box->y, box->z); pipe->transfer_inline_write(pipe, res, This->level, 0, box, ptr, This->stride, This->layer_stride); } NineVolume9_ClearDirtyRegion(This); return D3D_OK; }
HRESULT NineVolume9_UploadSelf( struct NineVolume9 *This, const struct pipe_box *damaged ) { struct pipe_context *pipe = This->pipe; struct pipe_resource *res = This->resource; struct pipe_box box; uint8_t *ptr; DBG("This=%p damaged=%p data=%p res=%p\n", This, damaged, This->data, res); assert(This->desc.Pool == D3DPOOL_MANAGED); assert(res); if (damaged) { box = *damaged; } else { box.x = 0; box.y = 0; box.z = 0; box.width = This->desc.Width; box.height = This->desc.Height; box.depth = This->desc.Depth; } ptr = NineVolume9_GetSystemMemPointer(This, box.x, box.y, box.z); pipe->texture_subdata(pipe, res, This->level, 0, &box, ptr, This->stride, This->layer_stride); return D3D_OK; }
HRESULT NineVolume9_CopyVolume( struct NineVolume9 *This, struct NineVolume9 *From, unsigned dstx, unsigned dsty, unsigned dstz, struct pipe_box *pSrcBox ) { struct pipe_context *pipe = This->pipe; struct pipe_resource *r_dst = This->resource; struct pipe_resource *r_src = From->resource; struct pipe_transfer *transfer; struct pipe_box src_box; struct pipe_box dst_box; uint8_t *p_dst; const uint8_t *p_src; DBG("This=%p From=%p dstx=%u dsty=%u dstz=%u pSrcBox=%p\n", This, From, dstx, dsty, dstz, pSrcBox); assert(This->desc.Pool != D3DPOOL_MANAGED && From->desc.Pool != D3DPOOL_MANAGED); user_assert(This->desc.Format == From->desc.Format, D3DERR_INVALIDCALL); dst_box.x = dstx; dst_box.y = dsty; dst_box.z = dstz; if (pSrcBox) { /* make sure it doesn't range outside the source volume */ user_assert(pSrcBox->x >= 0 && (pSrcBox->width - pSrcBox->x) <= From->desc.Width && pSrcBox->y >= 0 && (pSrcBox->height - pSrcBox->y) <= From->desc.Height && pSrcBox->z >= 0 && (pSrcBox->depth - pSrcBox->z) <= From->desc.Depth, D3DERR_INVALIDCALL); src_box = *pSrcBox; } else { src_box.x = 0; src_box.y = 0; src_box.z = 0; src_box.width = From->desc.Width; src_box.height = From->desc.Height; src_box.depth = From->desc.Depth; } /* limits */ dst_box.width = This->desc.Width - dst_box.x; dst_box.height = This->desc.Height - dst_box.y; dst_box.depth = This->desc.Depth - dst_box.z; user_assert(src_box.width <= dst_box.width && src_box.height <= dst_box.height && src_box.depth <= dst_box.depth, D3DERR_INVALIDCALL); dst_box.width = src_box.width; dst_box.height = src_box.height; dst_box.depth = src_box.depth; if (r_dst && r_src) { pipe->resource_copy_region(pipe, r_dst, This->level, dst_box.x, dst_box.y, dst_box.z, r_src, From->level, &src_box); } else if (r_dst) { p_src = NineVolume9_GetSystemMemPointer(From, src_box.x, src_box.y, src_box.z); pipe->transfer_inline_write(pipe, r_dst, This->level, 0, /* WRITE|DISCARD are implicit */ &dst_box, p_src, From->stride, From->layer_stride); } else if (r_src) { p_dst = NineVolume9_GetSystemMemPointer(This, 0, 0, 0); p_src = pipe->transfer_map(pipe, r_src, From->level, PIPE_TRANSFER_READ, &src_box, &transfer); if (!p_src) return D3DERR_DRIVERINTERNALERROR; util_copy_box(p_dst, This->info.format, This->stride, This->layer_stride, dst_box.x, dst_box.y, dst_box.z, dst_box.width, dst_box.height, dst_box.depth, p_src, transfer->stride, transfer->layer_stride, src_box.x, src_box.y, src_box.z); pipe->transfer_unmap(pipe, transfer); } else { p_dst = NineVolume9_GetSystemMemPointer(This, 0, 0, 0); p_src = NineVolume9_GetSystemMemPointer(From, 0, 0, 0); util_copy_box(p_dst, This->info.format, This->stride, This->layer_stride, dst_box.x, dst_box.y, dst_box.z, dst_box.width, dst_box.height, dst_box.depth, p_src, From->stride, From->layer_stride, src_box.x, src_box.y, src_box.z); } if (This->desc.Pool == D3DPOOL_DEFAULT) NineVolume9_MarkContainerDirty(This); if (!r_dst && This->resource) NineVolume9_AddDirtyRegion(This, &dst_box); return D3D_OK; }
HRESULT WINAPI NineVolume9_LockBox( struct NineVolume9 *This, D3DLOCKED_BOX *pLockedVolume, const D3DBOX *pBox, DWORD Flags ) { struct pipe_resource *resource = This->resource; struct pipe_box box; unsigned usage; DBG("This=%p(%p) pLockedVolume=%p pBox=%p[%u..%u,%u..%u,%u..%u] Flags=%s\n", This, This->base.container, pLockedVolume, pBox, pBox ? pBox->Left : 0, pBox ? pBox->Right : 0, pBox ? pBox->Top : 0, pBox ? pBox->Bottom : 0, pBox ? pBox->Front : 0, pBox ? pBox->Back : 0, nine_D3DLOCK_to_str(Flags)); user_assert(This->desc.Pool != D3DPOOL_DEFAULT || (This->desc.Usage & D3DUSAGE_DYNAMIC), D3DERR_INVALIDCALL); user_assert(!((Flags & D3DLOCK_DISCARD) && (Flags & D3DLOCK_READONLY)), D3DERR_INVALIDCALL); user_assert(This->lock_count == 0, D3DERR_INVALIDCALL); user_assert(pLockedVolume, E_POINTER); if (pBox && This->desc.Pool == D3DPOOL_DEFAULT && util_format_is_compressed(This->info.format)) { const unsigned w = util_format_get_blockwidth(This->info.format); const unsigned h = util_format_get_blockheight(This->info.format); user_assert(!(pBox->Left % w) && !(pBox->Right % w) && !(pBox->Top % h) && !(pBox->Bottom % h), D3DERR_INVALIDCALL); } if (Flags & D3DLOCK_DISCARD) { usage = PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE; } else { usage = (Flags & D3DLOCK_READONLY) ? PIPE_TRANSFER_READ : PIPE_TRANSFER_READ_WRITE; } if (Flags & D3DLOCK_DONOTWAIT) usage |= PIPE_TRANSFER_DONTBLOCK; if (pBox) { d3dbox_to_pipe_box(&box, pBox); if (u_box_clip_2d(&box, &box, This->desc.Width, This->desc.Height) < 0) { DBG("Locked volume intersection empty.\n"); return D3DERR_INVALIDCALL; } } else { u_box_3d(0, 0, 0, This->desc.Width, This->desc.Height, This->desc.Depth, &box); } if (This->data) { pLockedVolume->RowPitch = This->stride; pLockedVolume->SlicePitch = This->layer_stride; pLockedVolume->pBits = NineVolume9_GetSystemMemPointer(This, box.x, box.y, box.z); } else { pLockedVolume->pBits = This->pipe->transfer_map(This->pipe, resource, This->level, usage, &box, &This->transfer); if (!This->transfer) { if (Flags & D3DLOCK_DONOTWAIT) return D3DERR_WASSTILLDRAWING; return D3DERR_DRIVERINTERNALERROR; } pLockedVolume->RowPitch = This->transfer->stride; pLockedVolume->SlicePitch = This->transfer->layer_stride; } if (!(Flags & (D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_READONLY))) { NineVolume9_MarkContainerDirty(This); if (This->desc.Pool == D3DPOOL_MANAGED) NineVolume9_AddDirtyRegion(This, &box); } ++This->lock_count; return D3D_OK; }
HRESULT NINE_WINAPI NineVolume9_LockBox( struct NineVolume9 *This, D3DLOCKED_BOX *pLockedVolume, const D3DBOX *pBox, DWORD Flags ) { struct pipe_resource *resource = This->resource; struct pipe_box box; unsigned usage; DBG("This=%p(%p) pLockedVolume=%p pBox=%p[%u..%u,%u..%u,%u..%u] Flags=%s\n", This, This->base.container, pLockedVolume, pBox, pBox ? pBox->Left : 0, pBox ? pBox->Right : 0, pBox ? pBox->Top : 0, pBox ? pBox->Bottom : 0, pBox ? pBox->Front : 0, pBox ? pBox->Back : 0, nine_D3DLOCK_to_str(Flags)); /* check if it's already locked */ user_assert(This->lock_count == 0, D3DERR_INVALIDCALL); /* set pBits to NULL after lock_count check */ user_assert(pLockedVolume, E_POINTER); pLockedVolume->pBits = NULL; user_assert(This->desc.Pool != D3DPOOL_DEFAULT || (This->desc.Usage & D3DUSAGE_DYNAMIC), D3DERR_INVALIDCALL); user_assert(!((Flags & D3DLOCK_DISCARD) && (Flags & D3DLOCK_READONLY)), D3DERR_INVALIDCALL); if (pBox && compressed_format (This->desc.Format)) { /* For volume all pools are checked */ const unsigned w = util_format_get_blockwidth(This->info.format); const unsigned h = util_format_get_blockheight(This->info.format); user_assert((pBox->Left == 0 && pBox->Right == This->desc.Width && pBox->Top == 0 && pBox->Bottom == This->desc.Height) || (!(pBox->Left % w) && !(pBox->Right % w) && !(pBox->Top % h) && !(pBox->Bottom % h)), D3DERR_INVALIDCALL); } if (Flags & D3DLOCK_DISCARD) { usage = PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE; } else { usage = (Flags & D3DLOCK_READONLY) ? PIPE_TRANSFER_READ : PIPE_TRANSFER_READ_WRITE; } if (Flags & D3DLOCK_DONOTWAIT) usage |= PIPE_TRANSFER_DONTBLOCK; if (pBox) { user_assert(pBox->Right > pBox->Left, D3DERR_INVALIDCALL); user_assert(pBox->Bottom > pBox->Top, D3DERR_INVALIDCALL); user_assert(pBox->Back > pBox->Front, D3DERR_INVALIDCALL); user_assert(pBox->Right <= This->desc.Width, D3DERR_INVALIDCALL); user_assert(pBox->Bottom <= This->desc.Height, D3DERR_INVALIDCALL); user_assert(pBox->Back <= This->desc.Depth, D3DERR_INVALIDCALL); d3dbox_to_pipe_box(&box, pBox); if (u_box_clip_2d(&box, &box, This->desc.Width, This->desc.Height) < 0) { DBG("Locked volume intersection empty.\n"); return D3DERR_INVALIDCALL; } } else { u_box_3d(0, 0, 0, This->desc.Width, This->desc.Height, This->desc.Depth, &box); } if (This->data_conversion) { /* For now we only have uncompressed formats here */ pLockedVolume->RowPitch = This->stride_conversion; pLockedVolume->SlicePitch = This->layer_stride_conversion; pLockedVolume->pBits = This->data_conversion + box.z * This->layer_stride_conversion + box.y * This->stride_conversion + util_format_get_stride(This->format_conversion, box.x); } else if (This->data) { pLockedVolume->RowPitch = This->stride; pLockedVolume->SlicePitch = This->layer_stride; pLockedVolume->pBits = NineVolume9_GetSystemMemPointer(This, box.x, box.y, box.z); } else { pLockedVolume->pBits = This->pipe->transfer_map(This->pipe, resource, This->level, usage, &box, &This->transfer); if (!This->transfer) { if (Flags & D3DLOCK_DONOTWAIT) return D3DERR_WASSTILLDRAWING; return D3DERR_DRIVERINTERNALERROR; } pLockedVolume->RowPitch = This->transfer->stride; pLockedVolume->SlicePitch = This->transfer->layer_stride; } if (!(Flags & (D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_READONLY))) { NineVolume9_MarkContainerDirty(This); NineVolume9_AddDirtyRegion(This, &box); } ++This->lock_count; return D3D_OK; }