public static unsafe PhysicsShapeHandle CreateConcaveHullShape(IEnumerable <Vector3> vertices, IEnumerable <int> indices, CollisionShapeOptionsDesc shapeOptions, string acdFilePath)
 {
     return(LosgapSystem.InvokeOnMaster(() => {
         AlignedAllocation <CollisionShapeOptionsDesc> shapeOptionsAligned = new AlignedAllocation <CollisionShapeOptionsDesc>(16L, (uint)sizeof(CollisionShapeOptionsDesc));
         *((CollisionShapeOptionsDesc *)shapeOptionsAligned.AlignedPointer) = shapeOptions;
         Vector3 *verticesLocal = stackalloc Vector3[vertices.Count()];
         int *indicesLocal = stackalloc int[indices.Count()];
         int numVertices = 0;
         int numIndices = 0;
         foreach (Vector3 vertex in vertices)
         {
             verticesLocal[numVertices++] = vertex;
         }
         foreach (int index in indices)
         {
             indicesLocal[numIndices++] = index;
         }
         PhysicsShapeHandle result;
         InteropUtils.CallNative(
             NativeMethods.PhysicsManager_CreateConcaveHullShape,
             (IntPtr)verticesLocal,
             numVertices,
             (IntPtr)indicesLocal,
             numIndices,
             shapeOptionsAligned.AlignedPointer,
             acdFilePath,
             (IntPtr)(&result)
             ).ThrowOnFailure();
         shapeOptionsAligned.Dispose();
         return result;
     }));
 }
        public unsafe void TestDepthStencilTargetWithWindow()
        {
            Window depthStencilWindow = new Window("Test window");

            RenderTargetViewHandle outRTV;
            DepthStencilViewHandle outDSV;

            depthStencilWindow.GetWindowRTVAndDSV(out outRTV, out outDSV);

            RenderCommand testCommand = RenderCommand.ClearDepthStencil(depthStencilWindow);

            Assert.AreEqual(RenderCommandInstruction.ClearDepthStencil, testCommand.Instruction);
            Assert.AreEqual(
                outDSV,
                UnsafeUtils.Reinterpret <IntPtr, DepthStencilViewHandle>(new IntPtr(UnsafeUtils.Reinterpret <RenderCommandArgument, long>(testCommand.Arg1, sizeof(long))), sizeof(DepthStencilViewHandle))
                );

            depthStencilWindow.Close();

            LosgapSystem.InvokeOnMaster(() => { });             // Wait for the window to be closed

            testCommand = RenderCommand.ClearDepthStencil(depthStencilWindow);
            Assert.AreEqual(RenderCommandInstruction.NoOperation, testCommand.Instruction);

#if !DEVELOPMENT && !RELEASE
            try {
                RenderCommand.ClearDepthStencil(null as Window);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
#endif
        }
        public unsafe void TestSetRenderTargetsWithWindow()
        {
            Window renderTargetWindow = new Window("Test window");

            RenderTargetViewHandle outRTV;
            DepthStencilViewHandle outDSV;

            renderTargetWindow.GetWindowRTVAndDSV(out outRTV, out outDSV);

            RenderCommand testCommand = RenderCommand.SetRenderTargets(renderTargetWindow);

            Assert.AreEqual(RenderCommandInstruction.SetRenderTargets, testCommand.Instruction);
            Assert.AreEqual(
                outRTV,
                ((RenderTargetViewHandle *)new IntPtr(UnsafeUtils.Reinterpret <RenderCommandArgument, long>(testCommand.Arg1, sizeof(long))))[0]
                );
            Assert.AreEqual((RenderCommandArgument)(IntPtr)(ResourceViewHandle)outDSV, testCommand.Arg2);
            Assert.AreEqual((RenderCommandArgument)1U, testCommand.Arg3);

            renderTargetWindow.Close();

            LosgapSystem.InvokeOnMaster(() => { });             // Wait for the window to be closed

            testCommand = RenderCommand.SetRenderTargets(renderTargetWindow);
            Assert.AreEqual(RenderCommandInstruction.NoOperation, testCommand.Instruction);

#if !DEVELOPMENT && !RELEASE
            try {
                RenderCommand.SetRenderTargets(null as Window);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
#endif
        }
        public void TestWrite()
        {
            LosgapSystem.InvokeOnMaster(() => {
                // Define variables and constants
                IBuffer res = BufferFactory.NewBuffer <int>()
                              .WithUsage(ResourceUsage.Write)
                              .WithLength(100)
                              .Create();

                IBuffer copyDest = (res as Buffer <int>).Clone()
                                   .WithUsage(ResourceUsage.StagingRead)
                                   .WithPermittedBindings(GPUBindings.None)
                                   .Create();

                // Set up context


                // Execute
                Assert.IsTrue(res.CanWrite);
                res.Write(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, 10U);
                res.CopyTo(copyDest);

                // Assert outcome
                byte[] readData = copyDest.Read();
                for (int i = 10; i < 20; ++i)
                {
                    Assert.AreEqual(i - 9, readData[i]);
                }

                res.Dispose();
                copyDest.Dispose();
            });
        }
 internal unsafe static PhysicsBodyHandle CreateRigidBody(PhysicsShapeHandle shapeHandle, float mass, bool alwaysActive, bool forceIntransigence, bool collideOnlyAgainstWorld, bool collideAgainstDynamicsOnly, IntPtr translationPtr, IntPtr rotationPtr, IntPtr shapeOffsetPtr)
 {
     Assure.GreaterThanOrEqualTo(mass, 0f);
     if (collideOnlyAgainstWorld && collideAgainstDynamicsOnly)
     {
         throw new ArgumentException("Can't collide against world and only dynamics simultaneously.");
     }
     return(LosgapSystem.InvokeOnMaster(() => {
         PhysicsBodyHandle result;
         InteropUtils.CallNative(
             NativeMethods.PhysicsManager_CreateRigidBody,
             translationPtr,
             rotationPtr,
             shapeOffsetPtr,
             shapeHandle,
             mass,
             (InteropBool)alwaysActive,
             (InteropBool)forceIntransigence,
             (InteropBool)collideOnlyAgainstWorld,
             (InteropBool)collideAgainstDynamicsOnly,
             (IntPtr)(&result)
             ).ThrowOnFailure();
         return result;
     }));
 }
Beispiel #6
0
        public void TestGenerateMips()
        {
            LosgapSystem.InvokeOnMaster(() => {
                // Define variables and constants
                const uint WIDTH_TX  = 256U;
                const uint HEIGHT_TX = 128U;
                const uint ARR_LEN   = 4U;
                Texture2DArray <TexelFormat.RGBA8UNorm> sourceTex = TextureFactory.NewTexture2D <TexelFormat.RGBA8UNorm>()
                                                                    .WithWidth(WIDTH_TX)
                                                                    .WithHeight(HEIGHT_TX)
                                                                    .WithMipAllocation(true)
                                                                    .WithMipGenerationTarget(true)
                                                                    .WithPermittedBindings(GPUBindings.ReadableShaderResource | GPUBindings.RenderTarget)
                                                                    .WithUsage(ResourceUsage.Write)
                                                                    .CreateArray(ARR_LEN);

                Texture2DArray <TexelFormat.RGBA8UNorm> copyDestTex = sourceTex.Clone()
                                                                      .WithUsage(ResourceUsage.StagingRead)
                                                                      .WithPermittedBindings(GPUBindings.None)
                                                                      .WithMipGenerationTarget(false)
                                                                      .CreateArray(ARR_LEN);

                // Set up context
                for (uint u = 0U; u < ARR_LEN; u++)
                {
                    sourceTex[u].Write(
                        // ReSharper disable PossibleLossOfFraction No one cares
                        Enumerable.Range(0, (int)TextureUtils.GetSizeTexels(false, WIDTH_TX, HEIGHT_TX))
                        .Select(i => new TexelFormat.RGBA8UNorm {
                        R = 0f, G = 0.33f, B = 0.67f, A = 1f
                    }).ToArray(),
                        // ReSharper restore PossibleLossOfFraction
                        new SubresourceBox(0U, WIDTH_TX, 0U, HEIGHT_TX),
                        0U
                        );
                }

                // Execute
                sourceTex.GenerateMips();
                sourceTex.CopyTo(copyDestTex);

                // Assert outcome
                for (uint u = 0U; u < ARR_LEN; u++)
                {
                    for (uint i = 1U; i < TextureUtils.GetNumMips(WIDTH_TX, HEIGHT_TX); ++i)
                    {
                        IEnumerable <TexelFormat.RGBA8UNorm> outData = copyDestTex[u].Read(i);
                        // ReSharper disable CompareOfFloatsByEqualityOperator Exact equality is fine here
                        Assert.IsTrue(outData.Any(texel => texel.R != 0f || texel.G != 0f || texel.B != 0f || texel.A != 0f));
                        // ReSharper restore CompareOfFloatsByEqualityOperator
                    }
                }

                sourceTex.Dispose();
                copyDestTex.Dispose();
            });
        }
Beispiel #7
0
        public void TestWrite()
        {
            LosgapSystem.InvokeOnMaster(() => {
                // Define variables and constants
                const uint WIDTH_TX  = 100U;
                const uint HEIGHT_TX = 100U;

                const uint WRITE_OFFSET_U = 30U;
                const uint WRITE_OFFSET_V = 30U;

                SubresourceBox writeTarget = new SubresourceBox(
                    WRITE_OFFSET_U, WIDTH_TX,
                    WRITE_OFFSET_V, HEIGHT_TX
                    );

                Texture2D <TexelFormat.RGBA8Int> srcTex = TextureFactory.NewTexture2D <TexelFormat.RGBA8Int>()
                                                          .WithUsage(ResourceUsage.Write)
                                                          .WithMultisampling(true)
                                                          .WithWidth(WIDTH_TX)
                                                          .WithHeight(HEIGHT_TX);

                // Set up context


                // Execute
                srcTex.Write(
                    Enumerable.Range(0, (int)writeTarget.Volume)
                    .Select(i => new TexelFormat.RGBA8Int {
                    R = (sbyte)i, G = (sbyte)(i * 2), B = (sbyte)(i * 3), A = (sbyte)(i * 4)
                })
                    .ToArray(),
                    writeTarget
                    );

                Texture2D <TexelFormat.RGBA8Int> dstTex = srcTex.Clone()
                                                          .WithUsage(ResourceUsage.StagingRead)
                                                          .WithPermittedBindings(GPUBindings.None);

                srcTex.CopyTo(dstTex);

                // Assert outcome
                TexelArray2D <TexelFormat.RGBA8Int> copiedData = dstTex.Read(0U);
                for (uint v = WRITE_OFFSET_V, value = 0U; v < HEIGHT_TX; ++v)
                {
                    for (uint u = WRITE_OFFSET_U; u < WIDTH_TX; ++u, ++value)
                    {
                        Assert.AreEqual((sbyte)value, copiedData[(int)u, (int)v].R);
                        Assert.AreEqual((sbyte)(value * 2U), copiedData[(int)u, (int)v].G);
                        Assert.AreEqual((sbyte)(value * 3U), copiedData[(int)u, (int)v].B);
                        Assert.AreEqual((sbyte)(value * 4U), copiedData[(int)u, (int)v].A);
                    }
                }

                srcTex.Dispose();
                dstTex.Dispose();
            });
        }
Beispiel #8
0
        public void TestCopyTo()
        {
            LosgapSystem.InvokeOnMaster(() => {
                // Define variables and constants
                const uint WIDTH_TX = 512U;

                const uint NUM_TEXELS_TO_COPY  = 25U;
                const uint FIRST_TEXEL_TO_COPY = 25U;
                const uint SRC_MIP_INDEX       = 1U;
                const uint DST_MIP_INDEX       = 3U;
                const uint DST_WRITE_OFFSET    = 15U;
                const uint DATA_VALUE_START_R  = 512U + FIRST_TEXEL_TO_COPY;

                Texture1D <TexelFormat.RGBA32Int> srcTex = TextureFactory.NewTexture1D <TexelFormat.RGBA32Int>()
                                                           .WithDynamicDetail(false)
                                                           .WithInitialData(
                    Enumerable.Range(0, (int)TextureUtils.GetSizeTexels(true, WIDTH_TX))
                    .Select(i => new TexelFormat.RGBA32Int {
                    R = i, G = i * 2, B = i * 3, A = i * 4
                })
                    .ToArray()
                    )
                                                           .WithMipAllocation(true)
                                                           .WithMipGenerationTarget(false)
                                                           .WithPermittedBindings(GPUBindings.ReadableShaderResource)
                                                           .WithUsage(ResourceUsage.Immutable)
                                                           .WithWidth(WIDTH_TX);

                // Set up context


                // Execute
                Texture1D <TexelFormat.RGBA32Int> dstTex = srcTex.Clone()
                                                           .WithUsage(ResourceUsage.StagingRead)
                                                           .WithPermittedBindings(GPUBindings.None);
                srcTex.CopyTo(
                    dstTex,
                    new SubresourceBox(FIRST_TEXEL_TO_COPY, FIRST_TEXEL_TO_COPY + NUM_TEXELS_TO_COPY),
                    SRC_MIP_INDEX,
                    DST_MIP_INDEX,
                    DST_WRITE_OFFSET
                    );

                // Assert outcome
                TexelArray1D <TexelFormat.RGBA32Int> copiedData = dstTex.Read(DST_MIP_INDEX);
                for (int i = 0; i < NUM_TEXELS_TO_COPY; ++i)
                {
                    Assert.AreEqual(DATA_VALUE_START_R + i, copiedData[i + (int)DST_WRITE_OFFSET].R);
                    Assert.AreEqual((DATA_VALUE_START_R + i) * 2, copiedData[i + (int)DST_WRITE_OFFSET].G);
                    Assert.AreEqual((DATA_VALUE_START_R + i) * 3, copiedData[i + (int)DST_WRITE_OFFSET].B);
                    Assert.AreEqual((DATA_VALUE_START_R + i) * 4, copiedData[i + (int)DST_WRITE_OFFSET].A);
                }

                srcTex.Dispose();
                dstTex.Dispose();
            });
        }
Beispiel #9
0
        public void TestCopyTo()
        {
            LosgapSystem.InvokeOnMaster(() => {
                // Define variables and constants
                const uint MIP0_WIDTH   = 512U;
                const uint ARRAY_LENGTH = 10U;
                Texture1DArray <TexelFormat.RGBA32UInt> srcArray = TextureFactory.NewTexture1D <TexelFormat.RGBA32UInt>()
                                                                   .WithDynamicDetail(false)
                                                                   .WithInitialData(
                    Enumerable.Repeat(
                        Enumerable.Range(0, (int)TextureUtils.GetSizeTexels(true, MIP0_WIDTH))
                        .Select(i => (uint)i)
                        .Select(i => new TexelFormat.RGBA32UInt {
                    R = i, G = i * 2, B = i * 3, A = i * 4
                }),
                        (int)ARRAY_LENGTH
                        )
                    .Flatten()
                    .ToArray()
                    )
                                                                   .WithMipAllocation(true)
                                                                   .WithMipGenerationTarget(false)
                                                                   .WithPermittedBindings(GPUBindings.ReadableShaderResource)
                                                                   .WithUsage(ResourceUsage.Immutable)
                                                                   .WithMipAllocation(true)
                                                                   .WithUsage(ResourceUsage.Write)
                                                                   .WithWidth(MIP0_WIDTH)
                                                                   .CreateArray(ARRAY_LENGTH);

                // Set up context
                Texture1DArray <TexelFormat.RGBA32UInt> dstArray = srcArray.Clone()
                                                                   .WithUsage(ResourceUsage.StagingRead)
                                                                   .WithPermittedBindings(GPUBindings.None)
                                                                   .CreateArray(srcArray.ArrayLength);

                srcArray.CopyTo(dstArray);

                var data = dstArray[4].ReadAll();

                // Execute
                for (int i = 0, curMipIndex = 0; i < data.Length; ++curMipIndex)
                {
                    for (int j = 0; j < dstArray.MipWidth((uint)curMipIndex); ++j, ++i)
                    {
                        Assert.AreEqual((uint)i, data[i].R);
                        Assert.AreEqual((uint)i * 2, data[i].G);
                        Assert.AreEqual((uint)i * 3, data[i].B);
                        Assert.AreEqual((uint)i * 4, data[i].A);
                    }
                }

                // Assert outcome
                srcArray.Dispose();
                dstArray.Dispose();
            });
        }
 byte[] IBuffer.Read()
 {
     return(LosgapSystem.InvokeOnMaster(() => {
         byte[] result = new byte[Size];
         Mutate_MapRead(
             data => UnsafeUtils.CopyGenericArray <byte>(data, result, sizeof(byte)),
             ResourceMapping.Read
             );
         return result;
     }));
 }
Beispiel #11
0
        /// <summary>
        /// Performs a <see cref="ResourceUsage.StagingRead"/> on this texture, copying all the data from every mip level and
        /// concatenating it in to a single <typeparamref name="TTexel"/> array.
        /// </summary>
        /// <returns>An array of all texels in this resource, ordered by ascending mip level.</returns>
        /// <exception cref="ResourceOperationUnavailableException">Thrown if <see cref="BaseResource.CanRead"/> is
        /// <c>false</c>.</exception>
        public override TTexel[] ReadAll()
        {
            ThrowIfCannotRead();
            return(LosgapSystem.InvokeOnMaster(() => {
                TTexel[] result = new TTexel[SizeTexels];

                lock (InstanceMutationLock) {
                    if (IsDisposed)
                    {
                        Logger.Warn("Attempted read manipulation on disposed resource of type: " + GetType().Name);
                        return result;
                    }
                    GCHandle pinnedResult = GCHandle.Alloc(result, GCHandleType.Pinned);
                    try {
                        int offsetBytes = 0;
                        for (uint i = 0; i < NumMips; ++i)
                        {
                            IntPtr outDataPtr;
                            uint outRowStrideBytes, outSliceStrideBytes;
                            InteropUtils.CallNative(
                                NativeMethods.ResourceFactory_MapSubresource,
                                RenderingModule.DeviceContext,
                                ResourceHandle,
                                GetSubresourceIndex(i),
                                ResourceMapping.Read,
                                (IntPtr)(&outDataPtr),
                                (IntPtr)(&outRowStrideBytes),
                                (IntPtr)(&outSliceStrideBytes)
                                ).ThrowOnFailure();

                            try {
                                uint numBytes = MipWidth(i) * TexelSizeBytes;
                                UnsafeUtils.MemCopy(outDataPtr, pinnedResult.AddrOfPinnedObject() + offsetBytes, numBytes);
                                offsetBytes += (int)numBytes;
                            }
                            finally {
                                InteropUtils.CallNative(
                                    NativeMethods.ResourceFactory_UnmapSubresource,
                                    RenderingModule.DeviceContext,
                                    ResourceHandle,
                                    GetSubresourceIndex(i)
                                    ).ThrowOnFailure();
                            }
                        }
                    }
                    finally {
                        pinnedResult.Free();
                    }
                }

                return result;
            }));
        }
Beispiel #12
0
        public void TestDiscardWrite()
        {
            LosgapSystem.InvokeOnMaster(() => {
                // Define variables and constants
                const uint WIDTH_TX  = 400U;
                const uint HEIGHT_TX = 200U;

                const uint WRITE_OFFSET_U = 190U;
                const uint WRITE_OFFSET_V = 10U;
                const int NUM_TX_TO_WRITE = 13555;

                Texture2D <TexelFormat.RGB32UInt> srcTex = TextureFactory.NewTexture2D <TexelFormat.RGB32UInt>()
                                                           .WithPermittedBindings(GPUBindings.ReadableShaderResource)
                                                           .WithUsage(ResourceUsage.DiscardWrite)
                                                           .WithWidth(WIDTH_TX)
                                                           .WithHeight(HEIGHT_TX);

                // Set up context


                // Execute
                srcTex.DiscardWrite(
                    Enumerable.Range(0, NUM_TX_TO_WRITE)
                    .Select(i => new TexelFormat.RGB32UInt {
                    R = (uint)i, G = (uint)i * 2, B = (uint)i * 3
                })
                    .ToArray(),
                    0U,
                    WRITE_OFFSET_U,
                    WRITE_OFFSET_V
                    );

                Texture2D <TexelFormat.RGB32UInt> dstTex = srcTex.Clone()
                                                           .WithUsage(ResourceUsage.StagingRead)
                                                           .WithPermittedBindings(GPUBindings.None);


                srcTex.CopyTo(dstTex);

                // Assert outcome
                TexelFormat.RGB32UInt[] copiedData = dstTex.Read(0U).Data;
                int offset = (int)(WRITE_OFFSET_V * WIDTH_TX + WRITE_OFFSET_U);
                for (int i = 0; i < NUM_TX_TO_WRITE; ++i)
                {
                    Assert.AreEqual((uint)i, copiedData[i + offset].R);
                    Assert.AreEqual((uint)i * 2U, copiedData[i + offset].G);
                    Assert.AreEqual((uint)i * 3U, copiedData[i + offset].B);
                }

                srcTex.Dispose();
                dstTex.Dispose();
            });
        }
Beispiel #13
0
        public void TestWrite()
        {
            LosgapSystem.InvokeOnMaster(() => {
                // Define variables and constants
                const uint WIDTH_TX = 512U;

                const uint TARGET_MIP_INDEX = 1U;
                const uint WRITE_OFFSET     = 30U;
                const int NUM_TX_TO_WRITE   = 198;

                Texture1D <TexelFormat.RGBA32Int> srcTex = TextureFactory.NewTexture1D <TexelFormat.RGBA32Int>()
                                                           .WithPermittedBindings(GPUBindings.ReadableShaderResource)
                                                           .WithMipAllocation(true)
                                                           .WithDynamicDetail(true)
                                                           .WithUsage(ResourceUsage.Write)
                                                           .WithWidth(WIDTH_TX);

                // Set up context


                // Execute
                srcTex.Write(
                    Enumerable.Range(0, NUM_TX_TO_WRITE)
                    .Select(i => new TexelFormat.RGBA32Int {
                    R = i, G = i * 2, B = i * 3, A = i * 4
                })
                    .ToArray(),
                    TARGET_MIP_INDEX,
                    WRITE_OFFSET
                    );

                Texture1D <TexelFormat.RGBA32Int> dstTex = srcTex.Clone()
                                                           .WithDynamicDetail(false)
                                                           .WithUsage(ResourceUsage.StagingRead)
                                                           .WithPermittedBindings(GPUBindings.None);

                srcTex.CopyTo(dstTex);

                // Assert outcome
                TexelArray1D <TexelFormat.RGBA32Int> copiedData = dstTex.Read(TARGET_MIP_INDEX);
                for (int i = 0; i < NUM_TX_TO_WRITE; ++i)
                {
                    Assert.AreEqual(i, copiedData[i + (int)WRITE_OFFSET].R);
                    Assert.AreEqual(i * 2, copiedData[i + (int)WRITE_OFFSET].G);
                    Assert.AreEqual(i * 3, copiedData[i + (int)WRITE_OFFSET].B);
                    Assert.AreEqual(i * 4, copiedData[i + (int)WRITE_OFFSET].A);
                }

                srcTex.Dispose();
                dstTex.Dispose();
            });
        }
        /// <summary>
        /// Performs a <see cref="ResourceUsage.StagingReadWrite"/> on this texture, allowing an in-place modification of the data
        /// through a read/write operation. This can be faster than an individual read and write operation in certain use cases.
        /// </summary>
        /// <param name="readWriteAction">An action that takes the supplied <see cref="RawResourceDataView3D{T}"/> and uses it to
        /// manipulate the data in-place. The supplied resource view is only valid for the duration of the invocation of this
        /// <see cref="Action"/>.</param>
        /// <param name="mipIndex">The mip index to read/write.</param>
        /// <exception cref="ResourceOperationUnavailableException">Thrown if <see cref="BaseResource.CanReadWrite"/> is
        /// <c>false</c>.</exception>
        public void ReadWrite(Action <RawResourceDataView3D <TTexel> > readWriteAction, uint mipIndex)
        {
            Assure.LessThan(
                mipIndex, NumMips,
                "Can not read from mip level " + mipIndex + ": Only " + NumMips + " present in texture."
                );

            ThrowIfCannotReadWrite();

            LosgapSystem.InvokeOnMaster(() => {
                lock (InstanceMutationLock) {
                    if (IsDisposed)
                    {
                        Logger.Warn("Attempted read-write manipulation on disposed resource of type: " + GetType().Name);
                        return;
                    }
                    IntPtr outDataPtr;
                    uint outRowStrideBytes, outSliceStrideBytes;
                    InteropUtils.CallNative(
                        NativeMethods.ResourceFactory_MapSubresource,
                        RenderingModule.DeviceContext,
                        ResourceHandle,
                        GetSubresourceIndex(mipIndex),
                        ResourceMapping.ReadWrite,
                        (IntPtr)(&outDataPtr),
                        (IntPtr)(&outRowStrideBytes),
                        (IntPtr)(&outSliceStrideBytes)
                        ).ThrowOnFailure();

                    try {
                        readWriteAction(new RawResourceDataView3D <TTexel>(
                                            outDataPtr,
                                            TexelSizeBytes,
                                            MipWidth(mipIndex),
                                            MipHeight(mipIndex),
                                            MipDepth(mipIndex),
                                            outRowStrideBytes,
                                            outSliceStrideBytes
                                            ));
                    }
                    finally {
                        InteropUtils.CallNative(
                            NativeMethods.ResourceFactory_UnmapSubresource,
                            RenderingModule.DeviceContext,
                            ResourceHandle,
                            GetSubresourceIndex(mipIndex)
                            ).ThrowOnFailure();
                    }
                }
            });
        }
 void IBuffer.ReadWrite(Action <byte[]> readWriteAction)
 {
     LosgapSystem.InvokeOnMaster(() =>
                                 Mutate_MapRead(
                                     dataAsPtr => {
         byte[] dataAsArray = new byte[Size];
         UnsafeUtils.CopyGenericArray <byte>(dataAsPtr, dataAsArray, sizeof(byte));
         readWriteAction(dataAsArray);
         UnsafeUtils.CopyGenericArray <byte>(dataAsArray, dataAsPtr, sizeof(byte));
     },
                                     ResourceMapping.ReadWrite
                                     )
                                 );
 }
        public override unsafe void Flush()
        {
            IntPtr commandListHandleMem = RenderCommandTempMemPool.GetLocalPool().Reserve((uint)IntPtr.Size);

            QueueCommand(new RenderCommand(RenderCommandInstruction.FinishCommandList, (IntPtr)(&commandListHandleMem)));

            uint offset = 0U;
            bool success;

            for (int i = 0; i < DeferredActions.Count; i++)
            {
                KeyValuePair <uint, Action> curAction = DeferredActions[i];
                char *failReason = stackalloc char[InteropUtils.MAX_INTEROP_FAIL_REASON_STRING_LENGTH + 1];
                success = NativeMethods.RenderPassManager_FlushInstructions(
                    (IntPtr)failReason,
                    RenderingModule.DeviceContext,
                    RenderCommandList.AlignedPointer + (int)offset * sizeof(RenderCommand),
                    curAction.Key - offset
                    );
                if (!success)
                {
                    throw new NativeOperationFailedException(Marshal.PtrToStringUni((IntPtr)failReason));
                }
                offset = curAction.Key;
                curAction.Value();
            }

            char *failReason2 = stackalloc char[InteropUtils.MAX_INTEROP_FAIL_REASON_STRING_LENGTH + 1];

            success = NativeMethods.RenderPassManager_FlushInstructions(
                (IntPtr)failReason2,
                RenderingModule.DeviceContext,
                RenderCommandList.AlignedPointer + (int)offset * sizeof(RenderCommand),
                CurListIndex - offset
                );
            if (!success)
            {
                throw new NativeOperationFailedException(Marshal.PtrToStringUni((IntPtr)failReason2));
            }

            lastCommandListHandle = commandListHandleMem;

            LosgapSystem.InvokeOnMaster(invokeOnMasterAction);

            CurListIndex = 0U;
            DeferredActions.Clear();

            RenderCommandTempMemPool.GetLocalPool().FreeAll();
        }
Beispiel #17
0
        /// <summary>
        /// Performs a <see cref="ResourceUsage.StagingRead"/> on this texture,
        /// returning a view of the texel data at the given <paramref name="mipIndex"/>.
        /// </summary>
        /// <param name="mipIndex">The mip index to read data from. Must be less than <see cref="ITexture.NumMips"/>.</param>
        /// <returns>A <see cref="TexelArray1D{TTexel}"/> of the data.</returns>
        /// <exception cref="ResourceOperationUnavailableException">Thrown if <see cref="BaseResource.CanRead"/> is
        /// <c>false</c>.</exception>
        public TexelArray1D <TTexel> Read(uint mipIndex)
        {
            Assure.LessThan(
                mipIndex, NumMips,
                "Can not read from mip level " + mipIndex + ": Only " + NumMips + " present in texture."
                );

            ThrowIfCannotRead();

            TTexel[] data = LosgapSystem.InvokeOnMaster(() => {
                TTexel[] result = new TTexel[MipWidth(mipIndex)];

                lock (InstanceMutationLock) {
                    if (IsDisposed)
                    {
                        Logger.Warn("Attempted read manipulation on disposed resource of type: " + GetType().Name);
                        return(result);
                    }
                    IntPtr outDataPtr;
                    uint outRowStrideBytes, outSliceStrideBytes;
                    InteropUtils.CallNative(
                        NativeMethods.ResourceFactory_MapSubresource,
                        RenderingModule.DeviceContext,
                        ResourceHandle,
                        GetSubresourceIndex(mipIndex),
                        ResourceMapping.Read,
                        (IntPtr)(&outDataPtr),
                        (IntPtr)(&outRowStrideBytes),
                        (IntPtr)(&outSliceStrideBytes)
                        ).ThrowOnFailure();

                    try {
                        UnsafeUtils.CopyGenericArray <TTexel>(outDataPtr, result, TexelSizeBytes);
                        return(result);
                    }
                    finally {
                        InteropUtils.CallNative(
                            NativeMethods.ResourceFactory_UnmapSubresource,
                            RenderingModule.DeviceContext,
                            ResourceHandle,
                            GetSubresourceIndex(mipIndex)
                            ).ThrowOnFailure();
                    }
                }
            });

            return(new TexelArray1D <TTexel>(data));
        }
 internal unsafe static Vector3 GetBodyAngularVelocity(PhysicsBodyHandle body)
 {
     return(LosgapSystem.InvokeOnMaster(() => {
         AlignedAllocation <Vector4> vec4Aligned = new AlignedAllocation <Vector4>(16L, (uint)sizeof(Vector4));
         InteropUtils.CallNative(NativeMethods.PhysicsManager_GetBodyAngularVelocity,
                                 body,
                                 vec4Aligned.AlignedPointer
                                 ).ThrowOnFailure();
         try {
             return (Vector3)(*((Vector4 *)vec4Aligned.AlignedPointer));
         }
         finally {
             vec4Aligned.Dispose();
         }
     }));
 }
 public static unsafe PhysicsShapeHandle CreateSimpleSphereShape(float radius, CollisionShapeOptionsDesc shapeOptions)
 {
     return(LosgapSystem.InvokeOnMaster(() => {
         AlignedAllocation <CollisionShapeOptionsDesc> shapeOptionsAligned = new AlignedAllocation <CollisionShapeOptionsDesc>(16L, (uint)sizeof(CollisionShapeOptionsDesc));
         *((CollisionShapeOptionsDesc *)shapeOptionsAligned.AlignedPointer) = shapeOptions;
         PhysicsShapeHandle result;
         InteropUtils.CallNative(
             NativeMethods.PhysicsManager_CreateSimpleSphereShape,
             radius,
             shapeOptionsAligned.AlignedPointer,
             (IntPtr)(&result)
             ).ThrowOnFailure();
         shapeOptionsAligned.Dispose();
         return result;
     }));
 }
Beispiel #20
0
 /// <summary>
 /// In fullscreen mode, this function sets the resolution of the display. In windowed mode,
 /// this function sets the size of the client area of the window.
 /// </summary>
 /// <param name="widthPx">The width, in pixels, of the new resolution.</param>
 /// <param name="heightPx">The height, in pixels, of the new resolution.</param>
 /// <seealso cref="SetResolution(Ophidian.Losgap.Rendering.NativeOutputResolution)"/>
 public void SetResolution(uint widthPx, uint heightPx)
 {
     LosgapSystem.InvokeOnMaster(() => {
         lock (WindowMutationLock) {
             if (IsClosed)
             {
                 return;
             }
             InteropUtils.CallNative(
                 NativeMethods.WindowFactory_SetResolution,
                 WindowHandle,
                 widthPx,
                 heightPx
                 ).ThrowOnFailure();
         }
     });
 }
 public static unsafe PhysicsShapeHandle CreateBoxShape(float width, float height, float depth, CollisionShapeOptionsDesc shapeOptions)
 {
     return(LosgapSystem.InvokeOnMaster(() => {
         AlignedAllocation <CollisionShapeOptionsDesc> shapeOptionsAligned = new AlignedAllocation <CollisionShapeOptionsDesc>(16L, (uint)sizeof(CollisionShapeOptionsDesc));
         *((CollisionShapeOptionsDesc *)shapeOptionsAligned.AlignedPointer) = shapeOptions;
         AlignedAllocation <Vector4> boxExtents = new AlignedAllocation <Vector4>(16L, (uint)sizeof(Vector4));
         *((Vector4 *)boxExtents.AlignedPointer) = new Vector4(width * 0.5f, height * 0.5f, depth * 0.5f, 0f);
         PhysicsShapeHandle result;
         InteropUtils.CallNative(
             NativeMethods.PhysicsManager_CreateBoxShape,
             boxExtents.AlignedPointer,
             shapeOptionsAligned.AlignedPointer,
             (IntPtr)(&result)
             ).ThrowOnFailure();
         shapeOptionsAligned.Dispose();
         boxExtents.Dispose();
         return result;
     }));
 }
Beispiel #22
0
        public void TestCopyTo()
        {
            LosgapSystem.InvokeOnMaster(() => {
                // Define variables and constants
                const uint WIDTH_TX = 512U;
                Texture1D <TexelFormat.RGBA32Int> srcTex = TextureFactory.NewTexture1D <TexelFormat.RGBA32Int>()
                                                           .WithDynamicDetail(false)
                                                           .WithInitialData(
                    Enumerable.Range(0, (int)TextureUtils.GetSizeTexels(true, WIDTH_TX))
                    .Select(i => new TexelFormat.RGBA32Int {
                    R = i, G = i * 2, B = i * 3, A = i * 4
                })
                    .ToArray()
                    )
                                                           .WithMipAllocation(true)
                                                           .WithMipGenerationTarget(false)
                                                           .WithPermittedBindings(GPUBindings.ReadableShaderResource)
                                                           .WithUsage(ResourceUsage.Immutable)
                                                           .WithWidth(WIDTH_TX);

                // Set up context


                // Execute
                Texture1D <TexelFormat.RGBA32Int> dstTex = srcTex.Clone()
                                                           .WithUsage(ResourceUsage.StagingRead)
                                                           .WithPermittedBindings(GPUBindings.None);
                srcTex.CopyTo(dstTex);

                // Assert outcome
                TexelFormat.RGBA32Int[] copiedData = dstTex.ReadAll();
                for (int i = 0; i < copiedData.Length; ++i)
                {
                    Assert.AreEqual(i, copiedData[i].R);
                    Assert.AreEqual(i * 2, copiedData[i].G);
                    Assert.AreEqual(i * 3, copiedData[i].B);
                    Assert.AreEqual(i * 4, copiedData[i].A);
                }

                srcTex.Dispose();
                dstTex.Dispose();
            });
        }
 public static unsafe PhysicsShapeHandle CreateConeShape(float radius, float height, CollisionShapeOptionsDesc shapeOptions, out Vector3 translationOffset)
 {
     //translationOffset = Vector3.DOWN * (height * 0.5f);
     translationOffset = Vector3.ZERO;
     return(LosgapSystem.InvokeOnMaster(() => {
         AlignedAllocation <CollisionShapeOptionsDesc> shapeOptionsAligned = new AlignedAllocation <CollisionShapeOptionsDesc>(16L, (uint)sizeof(CollisionShapeOptionsDesc));
         *((CollisionShapeOptionsDesc *)shapeOptionsAligned.AlignedPointer) = shapeOptions;
         PhysicsShapeHandle result;
         InteropUtils.CallNative(
             NativeMethods.PhysicsManager_CreateConeShape,
             radius,
             height,
             shapeOptionsAligned.AlignedPointer,
             (IntPtr)(&result)
             ).ThrowOnFailure();
         shapeOptionsAligned.Dispose();
         return result;
     }));
 }
Beispiel #24
0
        public void TestDiscardWrite()
        {
            LosgapSystem.InvokeOnMaster(() => {
                // Define variables and constants
                Buffer <decimal> testBuffer = BufferFactory.NewBuffer <decimal>()
                                              .WithUsage(ResourceUsage.DiscardWrite)
                                              .WithLength(300);
                Buffer <decimal> copyDestBuffer = testBuffer.Clone()
                                                  .WithUsage(ResourceUsage.StagingRead)
                                                  .WithPermittedBindings(GPUBindings.None);

                // Set up context


                // Execute
                testBuffer.DiscardWrite(Enumerable.Range(0, 300).Select(i => (decimal)i).ToArray(), 0);
                testBuffer.DiscardWrite(Enumerable.Range(0, 200).Select(i => (decimal)i).ToArray(), 100);
                testBuffer.DiscardWrite(new ArraySlice <decimal>(Enumerable.Range(0, 200).Select(i => (decimal)i).ToArray(), 50, 50), 24);

#if !DEVELOPMENT && !RELEASE
                try {
                    testBuffer.DiscardWrite(new ArraySlice <decimal>(Enumerable.Range(0, 200).Select(i => (decimal)i).ToArray(), 50), 250);
                    Assert.Fail();
                }
                catch (AssuranceFailedException) { }
#endif

                testBuffer.CopyTo(copyDestBuffer);
                decimal[] testData = copyDestBuffer.Read();
                for (int i = 24; i < 24 + 50; ++i)
                {
                    Assert.AreEqual((decimal)(50 + (i - 24)), testData[i]);
                }

                // Assert outcome
                Assert.IsTrue(testBuffer.CanDiscardWrite);
                Assert.IsFalse(copyDestBuffer.CanDiscardWrite);

                testBuffer.Dispose();
                copyDestBuffer.Dispose();
            });
        }
Beispiel #25
0
 public void SetPhysicsShape(
     PhysicsShapeHandle shapeHandle,
     Vector3 physicsShapeOffset,
     float mass,
     bool forceIntransigence             = false,
     bool disablePerformanceDeactivation = false,
     bool collideOnlyWithWorld           = false,
     bool collideWithOnlyDynamics        = false,
     float restitution     = PhysicsManager.DEFAULT_RESTITUTION,
     float linearDamping   = PhysicsManager.DEFAULT_LINEAR_DAMPING,
     float angularDamping  = PhysicsManager.DEFAULT_ANGULAR_DAMPING,
     float friction        = PhysicsManager.DEFAULT_FRICTION,
     float rollingFriction = PhysicsManager.DEFAULT_ROLLING_FRICTION)
 {
     LosgapSystem.InvokeOnMaster(() => {                     // Anti-deadlock measures x.x
         lock (InstanceMutationLock) {
             if (physicsBody != PhysicsBodyHandle.NULL)
             {
                 physicsBody.Dispose();
             }
             if (this.physicsShapeOffset == null)
             {
                 this.physicsShapeOffset = new AlignedAllocation <Vector4>(TRANSFORM_ALIGNMENT, (uint)sizeof(Vector4));
             }
             this.physicsShapeOffset.Value.Write(physicsShapeOffset);
             physicsBody = PhysicsManager.CreateRigidBody(
                 shapeHandle,
                 mass,
                 disablePerformanceDeactivation,
                 forceIntransigence,
                 collideOnlyWithWorld,
                 collideWithOnlyDynamics,
                 transform.AlignedPointer + 32,
                 transform.AlignedPointer + 16,
                 this.physicsShapeOffset.Value.AlignedPointer
                 );
         }
     });
     SetPhysicsProperties(restitution, linearDamping, angularDamping, friction, rollingFriction);
 }
 internal unsafe static FixedConstraintHandle CreateFixedConstraint(
     PhysicsBodyHandle parentBody, PhysicsBodyHandle childBody,
     Vector3 parentInitialTranslation, Quaternion parentInitialRotation,
     Vector3 childInitialTranslation, Quaternion childInitialRotation)
 {
     return(LosgapSystem.InvokeOnMaster(() => {
         Vector3 parentInitTransLocal = parentInitialTranslation;
         Quaternion parentInitRotLocal = parentInitialRotation;
         Vector3 childInitTransLocal = childInitialTranslation;
         Quaternion childInitRotLocal = childInitialRotation;
         FixedConstraintHandle result;
         InteropUtils.CallNative(NativeMethods.PhysicsManager_CreateFixedConstraint,
                                 parentBody,
                                 childBody,
                                 (IntPtr)(&parentInitTransLocal),
                                 (IntPtr)(&parentInitRotLocal),
                                 (IntPtr)(&childInitTransLocal),
                                 (IntPtr)(&childInitRotLocal),
                                 (IntPtr)(&result)
                                 );
         return result;
     }));
 }
 public static unsafe PhysicsShapeHandle CreateCompoundCurveShape(IEnumerable <Vector3> vertices, CollisionShapeOptionsDesc shapeOptions)
 {
     return(LosgapSystem.InvokeOnMaster(() => {
         AlignedAllocation <CollisionShapeOptionsDesc> shapeOptionsAligned = new AlignedAllocation <CollisionShapeOptionsDesc>(16L, (uint)sizeof(CollisionShapeOptionsDesc));
         *((CollisionShapeOptionsDesc *)shapeOptionsAligned.AlignedPointer) = shapeOptions;
         Vector3 *verticesLocal = stackalloc Vector3[vertices.Count()];
         int numVertices = 0;
         foreach (Vector3 vertex in vertices)
         {
             verticesLocal[numVertices++] = vertex;
         }
         PhysicsShapeHandle result;
         InteropUtils.CallNative(
             NativeMethods.PhysicsManager_CreateCompoundCurveShape,
             (IntPtr)verticesLocal,
             (uint)numVertices / 8U,
             shapeOptionsAligned.AlignedPointer,
             (IntPtr)(&result)
             ).ThrowOnFailure();
         shapeOptionsAligned.Dispose();
         return result;
     }));
 }
        internal static unsafe PhysicsBodyHandle RayTestNearest(Vector3 startPoint, Vector3 endPoint, out Vector3 hitPoint)
        {
            AlignedAllocation <Vector4> hitPointAligned = new AlignedAllocation <Vector4>(16L, (uint)sizeof(Vector4));
            Vector4 *hitPoint4Ptr = (Vector4 *)hitPointAligned.AlignedPointer;
            var      result       = LosgapSystem.InvokeOnMaster(() => {
                AlignedAllocation <Vector4> startPointAligned  = new AlignedAllocation <Vector4>(16L, (uint)sizeof(Vector4));
                *((Vector4 *)startPointAligned.AlignedPointer) = startPoint;
                AlignedAllocation <Vector4> endPointAligned    = new AlignedAllocation <Vector4>(16L, (uint)sizeof(Vector4));
                *((Vector4 *)endPointAligned.AlignedPointer)   = endPoint;
                Vector4 *hitPoint4PtrLocal = hitPoint4Ptr;
                PhysicsBodyHandle outPBH;
                InteropUtils.CallNative(NativeMethods.PhysicsManager_RayTestNearest,
                                        startPointAligned.AlignedPointer,
                                        endPointAligned.AlignedPointer,
                                        (IntPtr)(&outPBH),
                                        (IntPtr)(hitPoint4PtrLocal)
                                        ).ThrowOnFailure();
                startPointAligned.Dispose();
                endPointAligned.Dispose();
                return(outPBH);
            });

            try {
                if (result != PhysicsBodyHandle.NULL)
                {
                    hitPoint = (Vector3)(*((Vector4 *)hitPointAligned.AlignedPointer));
                }
                else
                {
                    hitPoint = Vector3.ZERO;
                }
                return(result);
            }
            finally {
                hitPointAligned.Dispose();
            }
        }
Beispiel #29
0
        public void TestCopyTo()
        {
            LosgapSystem.InvokeOnMaster(() => {
                // Define variables and constants
                const uint WIDTH_TX  = 256U;
                const uint HEIGHT_TX = 32U;
                const uint DEPTH_TX  = 32U;

                const uint NUM_TEXELS_TO_COPY_PER_ROW = 25U;
                const uint FIRST_TEXEL_TO_COPY_IN_ROW = 25U;
                const uint NUM_ROWS_TO_COPY_PER_SLICE = 5U;
                const uint FIRST_ROW_TO_COPY_IN_SLICE = 1U;
                const uint NUM_SLICES_TO_COPY         = 10U;
                const uint FIRST_SLICE_TO_COPY        = 4U;
                const uint SRC_MIP_INDEX      = 1U;
                const uint DST_MIP_INDEX      = 1U;
                const uint DST_WRITE_OFFSET_X = 15U;
                const uint DST_WRITE_OFFSET_Y = 2U;
                const uint DST_WRITE_OFFSET_Z = 0U;

                const float DATA_VALUE_ADDITION_W = (float)(HEIGHT_TX >> 1) * (float)(WIDTH_TX >> 1);
                const float DATA_VALUE_ADDITION_V = (float)(WIDTH_TX >> 1);
                const float DATA_VALUE_START_R    =
                    WIDTH_TX * HEIGHT_TX * DEPTH_TX
                    + FIRST_TEXEL_TO_COPY_IN_ROW
                    + DATA_VALUE_ADDITION_V * FIRST_ROW_TO_COPY_IN_SLICE
                    + DATA_VALUE_ADDITION_W * FIRST_SLICE_TO_COPY;

                TexelFormat.RGBA32Float[] initialData = Enumerable.Range(0, (int)TextureUtils.GetSizeTexels(true, WIDTH_TX, HEIGHT_TX, DEPTH_TX))
                                                        .Select(i => new TexelFormat.RGBA32Float {
                    R = (float)i, G = (float)i * 2f, B = (float)i * 4f, A = (float)i * 8f
                })
                                                        .ToArray();

                Texture3D <TexelFormat.RGBA32Float> srcTex = TextureFactory.NewTexture3D <TexelFormat.RGBA32Float>()
                                                             .WithDynamicDetail(false)
                                                             .WithInitialData(initialData)
                                                             .WithMipAllocation(true)
                                                             .WithMipGenerationTarget(false)
                                                             .WithPermittedBindings(GPUBindings.ReadableShaderResource)
                                                             .WithUsage(ResourceUsage.Immutable)
                                                             .WithWidth(WIDTH_TX)
                                                             .WithHeight(HEIGHT_TX)
                                                             .WithDepth(DEPTH_TX);

                // Set up context

                // Execute
                Texture3D <TexelFormat.RGBA32Float> dstTex = srcTex.Clone()
                                                             .WithUsage(ResourceUsage.StagingRead)
                                                             .WithPermittedBindings(GPUBindings.None);
                SubresourceBox targetBox = new SubresourceBox(
                    FIRST_TEXEL_TO_COPY_IN_ROW, FIRST_TEXEL_TO_COPY_IN_ROW + NUM_TEXELS_TO_COPY_PER_ROW,
                    FIRST_ROW_TO_COPY_IN_SLICE, FIRST_ROW_TO_COPY_IN_SLICE + NUM_ROWS_TO_COPY_PER_SLICE,
                    FIRST_SLICE_TO_COPY, FIRST_SLICE_TO_COPY + NUM_SLICES_TO_COPY
                    );
                srcTex.CopyTo(
                    dstTex,
                    targetBox,
                    SRC_MIP_INDEX,
                    DST_MIP_INDEX,
                    DST_WRITE_OFFSET_X,
                    DST_WRITE_OFFSET_Y,
                    DST_WRITE_OFFSET_Z
                    );

                // Assert outcome
                TexelArray3D <TexelFormat.RGBA32Float> copiedData = dstTex.Read(DST_MIP_INDEX);
                for (int w = 0; w < NUM_SLICES_TO_COPY; ++w)
                {
                    for (int v = 0; v < NUM_ROWS_TO_COPY_PER_SLICE; ++v)
                    {
                        for (int u = 0; u < NUM_TEXELS_TO_COPY_PER_ROW; ++u)
                        {
                            var thisTexel = copiedData[u + (int)DST_WRITE_OFFSET_X, v + (int)DST_WRITE_OFFSET_Y, w + (int)DST_WRITE_OFFSET_Z];
                            Assert.AreEqual((float)(DATA_VALUE_START_R + u + v * DATA_VALUE_ADDITION_V + w * DATA_VALUE_ADDITION_W), thisTexel.R);
                            Assert.AreEqual((float)(DATA_VALUE_START_R + u + v * DATA_VALUE_ADDITION_V + w * DATA_VALUE_ADDITION_W) * 2f, thisTexel.G);
                            Assert.AreEqual((float)(DATA_VALUE_START_R + u + v * DATA_VALUE_ADDITION_V + w * DATA_VALUE_ADDITION_W) * 4f, thisTexel.B);
                            Assert.AreEqual((float)(DATA_VALUE_START_R + u + v * DATA_VALUE_ADDITION_V + w * DATA_VALUE_ADDITION_W) * 8f, thisTexel.A);
                        }
                    }
                }

                srcTex.Dispose();
                dstTex.Dispose();
            });
        }
 /// <summary>
 /// Assists in performing a <see cref="ResourceUsage.StagingReadWrite"/> on this buffer by mapping it to CPU memory
 /// and providing a pointer to the data.
 /// </summary>
 /// <param name="mappedDataPtrAction">An action that usually will modify (read/write) the data at the given pointer.
 /// The supplied <see cref="IntPtr"/> is only valid for as long as the supplied
 /// <see cref="Action"/> is running.</param>
 protected void MapReadWrite(Action <IntPtr> mappedDataPtrAction)
 {
     ThrowIfCannotReadWrite();
     LosgapSystem.InvokeOnMaster(() => Mutate_MapRead(mappedDataPtrAction, ResourceMapping.ReadWrite));
 }