private static CpuDescriptorHandle GetNativeShaderResourceViewImpl(GraphicsResource resource) { return(resource.NativeShaderResourceView); }
public void CopyRegion(GraphicsResource source, int sourceSubresource, ResourceRegion?sourecRegion, GraphicsResource destination, int destinationSubResource, int dstX = 0, int dstY = 0, int dstZ = 0) { if (source == null) { throw new ArgumentNullException("source"); } if (destination == null) { throw new ArgumentNullException("destination"); } var nullableSharpDxRegion = new SharpDX.Direct3D11.ResourceRegion?(); if (sourecRegion.HasValue) { var value = sourecRegion.Value; nullableSharpDxRegion = new SharpDX.Direct3D11.ResourceRegion(value.Left, value.Top, value.Front, value.Right, value.Bottom, value.Back); } NativeDeviceContext.CopySubresourceRegion(source.NativeResource, sourceSubresource, nullableSharpDxRegion, destination.NativeResource, destinationSubResource, dstX, dstY, dstZ); }
// TODO GRAPHICS REFACTOR what should we do with this? /// <summary> /// Maps a subresource. /// </summary> /// <param name="resource">The resource.</param> /// <param name="subResourceIndex">Index of the sub resource.</param> /// <param name="mapMode">The map mode.</param> /// <param name="doNotWait">if set to <c>true</c> this method will return immediately if the resource is still being used by the GPU for writing. Default is false</param> /// <param name="offsetInBytes">The offset information in bytes.</param> /// <param name="lengthInBytes">The length information in bytes.</param> /// <returns>Pointer to the sub resource to map.</returns> public MappedResource MapSubresource(GraphicsResource resource, int subResourceIndex, MapMode mapMode, bool doNotWait = false, int offsetInBytes = 0, int lengthInBytes = 0) { if (resource == null) { throw new ArgumentNullException("resource"); } var rowPitch = 0; var depthStride = 0; var usage = GraphicsResourceUsage.Default; var texture = resource as Texture; if (texture != null) { usage = texture.Usage; if (lengthInBytes == 0) { lengthInBytes = texture.ComputeSubresourceSize(subResourceIndex); } rowPitch = texture.ComputeRowPitch(subResourceIndex % texture.MipLevels); depthStride = texture.ComputeSlicePitch(subResourceIndex % texture.MipLevels); if (texture.Usage == GraphicsResourceUsage.Staging) { // Internally it's a buffer, so adapt resource index and offset offsetInBytes = texture.ComputeBufferOffset(subResourceIndex, 0); subResourceIndex = 0; } } else { var buffer = resource as Buffer; if (buffer != null) { usage = buffer.Usage; if (lengthInBytes == 0) { lengthInBytes = buffer.SizeInBytes; } } } // TODO D3D12 WriteDiscard should just reallocate new buffer, and WriteNoOverwrite shouldn't use that path (for now we defer to upload buffer) if (mapMode == MapMode.WriteDiscard || mapMode == MapMode.WriteNoOverwrite) { SharpDX.Direct3D12.Resource uploadResource; int uploadOffset; var uploadMemory = GraphicsDevice.AllocateUploadBuffer(lengthInBytes, out uploadResource, out uploadOffset); return(new MappedResource(resource, subResourceIndex, new DataBox(uploadMemory, rowPitch, depthStride), offsetInBytes, lengthInBytes) { UploadResource = uploadResource, UploadOffset = uploadOffset, }); } else if (mapMode == MapMode.Read || mapMode == MapMode.ReadWrite || mapMode == MapMode.Write) { // Is non-staging ever possible? if (usage != GraphicsResourceUsage.Staging) { throw new InvalidOperationException(); } if (mapMode != MapMode.WriteNoOverwrite) { // Need to wait? if (!GraphicsDevice.IsFenceCompleteInternal(resource.StagingFenceValue)) { if (doNotWait) { return(new MappedResource(resource, subResourceIndex, new DataBox(IntPtr.Zero, 0, 0))); } // Need to flush (part of current command list) if (resource.StagingFenceValue == GraphicsDevice.NextFenceValue) { FlushInternal(false); } GraphicsDevice.WaitForFenceInternal(resource.StagingFenceValue); } } var mappedMemory = resource.NativeResource.Map(subResourceIndex) + offsetInBytes; return(new MappedResource(resource, subResourceIndex, new DataBox(mappedMemory, rowPitch, depthStride), offsetInBytes, lengthInBytes)); } else { throw new NotImplementedException(); } }
/// <summary> /// Sets a shader resource view descriptor. /// </summary> /// <param name="slot">The slot.</param> /// <param name="shaderResourceView">The shader resource view.</param> public void SetShaderResourceView(int slot, GraphicsResource shaderResourceView) { HeapObjects[DescriptorStartOffset + slot].Value = shaderResourceView; }
public void CopyRegion(GraphicsResource source, int sourceSubresource, ResourceRegion?sourecRegion, GraphicsResource destination, int destinationSubResource, int dstX = 0, int dstY = 0, int dstZ = 0) { throw new NotImplementedException(); }
/// <summary> /// Sets a shader resource view descriptor. /// </summary> /// <param name="slot">The slot.</param> /// <param name="shaderResourceView">The shader resource view.</param> public void SetShaderResourceView(int slot, GraphicsResource shaderResourceView) { Device.NativeDevice.CopyDescriptorsSimple(1, SrvStart + BindingOffsets[slot], shaderResourceView.NativeShaderResourceView, DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView); }
public void Copy(GraphicsResource source, GraphicsResource destination) { if (source == null) throw new ArgumentNullException("source"); if (destination == null) throw new ArgumentNullException("destination"); NativeDeviceContext.CopyResource(source.NativeResource, destination.NativeResource); }
/// <summary> /// Copy a region of a <see cref="GraphicsResource"/> into another. /// </summary> /// <param name="source">The source from which to copy the data</param> /// <param name="regionSource">The region of the source <see cref="GraphicsResource"/> to copy.</param> /// <param name="destination">The destination into which to copy the data</param> /// <remarks>This might alter some states such as currently bound texture.</remarks> public void CopyRegion(GraphicsResource source, int sourceSubresource, ResourceRegion? regionSource, GraphicsResource destination, int destinationSubResource, int dstX = 0, int dstY = 0, int dstZ = 0) { #if DEBUG GraphicsDevice.EnsureContextActive(); #endif var sourceTexture = source as Texture; var destTexture = destination as Texture; if (sourceTexture == null || destTexture == null) { throw Internal.Refactor.NewNotImplementedException("Copy is only implemented for Texture objects."); } // Get parent texture if (sourceTexture.ParentTexture != null) sourceTexture = sourceTexture.ParentTexture; if (destTexture.ParentTexture != null) destTexture = sourceTexture.ParentTexture; var sourceWidth = Texture.CalculateMipSize(sourceTexture.Description.Width, sourceSubresource % sourceTexture.MipLevels); var sourceHeight = Texture.CalculateMipSize(sourceTexture.Description.Height, sourceSubresource % sourceTexture.MipLevels); var sourceDepth = Texture.CalculateMipSize(sourceTexture.Description.Depth, sourceSubresource % sourceTexture.MipLevels); var sourceRegion = regionSource.HasValue ? regionSource.Value : new ResourceRegion(0, 0, 0, sourceWidth, sourceHeight, sourceDepth); var sourceRectangle = new Rectangle(sourceRegion.Left, sourceRegion.Top, sourceRegion.Right - sourceRegion.Left, sourceRegion.Bottom - sourceRegion.Top); if (sourceRectangle.Width == 0 || sourceRectangle.Height == 0) return; if (destTexture.Description.Usage == GraphicsResourceUsage.Staging) { if (sourceTexture.Description.Usage == GraphicsResourceUsage.Staging) { // Staging => Staging if (sourceRegion.Left != 0 || sourceRegion.Top != 0 || sourceRegion.Front != 0 || sourceRegion.Right != sourceWidth || sourceRegion.Bottom != sourceHeight || sourceRegion.Back != sourceDepth) { throw new NotSupportedException("ReadPixels from staging texture to staging texture only support full copy of subresource"); } #if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES if (GraphicsDevice.IsOpenGLES2) { Utilities.CopyMemory(destTexture.StagingData + destTexture.ComputeBufferOffset(destinationSubResource, 0), sourceTexture.StagingData + sourceTexture.ComputeBufferOffset(sourceSubresource, 0), destTexture.ComputeSubresourceSize(destinationSubResource)); } else #endif { GL.BindBuffer(BufferTarget.CopyReadBuffer, sourceTexture.PixelBufferObjectId); GL.BindBuffer(BufferTarget.CopyWriteBuffer, destTexture.PixelBufferObjectId); GL.CopyBufferSubData(BufferTarget.CopyReadBuffer, BufferTarget.CopyWriteBuffer, (IntPtr)sourceTexture.ComputeBufferOffset(sourceSubresource, 0), (IntPtr)destTexture.ComputeBufferOffset(destinationSubResource, 0), (IntPtr)destTexture.ComputeSubresourceSize(destinationSubResource)); } } else { // GPU => Staging if (dstX != 0 || dstY != 0 || dstZ != 0) throw new NotSupportedException("ReadPixels from staging texture using non-zero destination is not supported"); GL.Viewport(0, 0, sourceWidth, sourceHeight); var isDepthBuffer = Texture.InternalIsDepthStencilFormat(sourceTexture.Format); GL.BindFramebuffer(FramebufferTarget.Framebuffer, isDepthBuffer ? GraphicsDevice.CopyDepthSourceFBO : GraphicsDevice.CopyColorSourceFBO); var attachmentType = FramebufferAttachment.ColorAttachment0; for (int depthSlice = sourceRegion.Front; depthSlice < sourceRegion.Back; ++depthSlice) { attachmentType = GraphicsDevice.UpdateFBO(FramebufferTarget.Framebuffer, new GraphicsDevice.FBOTexture(sourceTexture, sourceSubresource / sourceTexture.MipLevels + depthSlice, sourceSubresource % sourceTexture.MipLevels)); #if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES if (GraphicsDevice.IsOpenGLES2) { var format = destTexture.TextureFormat; var type = destTexture.TextureType; var srcFormat = sourceTexture.Description.Format; var destFormat = destTexture.Description.Format; if (srcFormat == destFormat && destFormat.SizeInBytes() == 4) // in this case we just want to copy the data we don't care about format conversion. { // RGBA/Unsigned-byte is always a working combination whatever is the internal format (sRGB, etc...) format = PixelFormatGl.Rgba; type = PixelType.UnsignedByte; } GL.ReadPixels(sourceRectangle.Left, sourceRectangle.Top, sourceRectangle.Width, sourceRectangle.Height, format, type, destTexture.StagingData + destTexture.ComputeBufferOffset(destinationSubResource, depthSlice)); } else #endif { GL.BindBuffer(BufferTarget.PixelPackBuffer, destTexture.PixelBufferObjectId); GL.ReadPixels(sourceRectangle.Left, sourceRectangle.Top, sourceRectangle.Width, sourceRectangle.Height, destTexture.TextureFormat, destTexture.TextureType, (IntPtr)destTexture.ComputeBufferOffset(destinationSubResource, depthSlice)); GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); destTexture.PixelBufferFrame = GraphicsDevice.FrameCounter; } } // Unbind attachment GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, attachmentType, TextureTarget2d.Texture2D, 0, 0); // Restore FBO and viewport GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFBO); GL.Viewport((int)viewports[0].X, (int)viewports[0].Y, (int)viewports[0].Width, (int)viewports[0].Height); } return; } // GPU => GPU { var isDepthBuffer = Texture.InternalIsDepthStencilFormat(sourceTexture.Format); // Use our temporary mutable FBO GL.BindFramebuffer(FramebufferTarget.Framebuffer, isDepthBuffer ? GraphicsDevice.CopyDepthSourceFBO : GraphicsDevice.CopyColorSourceFBO); var attachmentType = FramebufferAttachment.ColorAttachment0; if (activeTexture != 0) { activeTexture = 0; GL.ActiveTexture(TextureUnit.Texture0); } GL.Viewport(0, 0, sourceWidth, sourceHeight); GL.BindTexture(destTexture.TextureTarget, destTexture.TextureId); for (int depthSlice = sourceRegion.Front; depthSlice < sourceRegion.Back; ++depthSlice) { // Note: In practice, either it's a 2D texture array and its arrayslice can be non zero, or it's a 3D texture and it's depthslice can be non-zero, but not both at the same time attachmentType = GraphicsDevice.UpdateFBO(FramebufferTarget.Framebuffer, new GraphicsDevice.FBOTexture(sourceTexture, sourceSubresource / sourceTexture.MipLevels + depthSlice, sourceSubresource % sourceTexture.MipLevels)); var arraySlice = destinationSubResource / destTexture.MipLevels; var mipLevel = destinationSubResource % destTexture.MipLevels; switch (destTexture.TextureTarget) { #if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES case TextureTarget.Texture1D: GL.CopyTexSubImage1D(TextureTarget2d.Texture1D, mipLevel, dstX, sourceRectangle.Left, sourceRectangle.Top, sourceRectangle.Width); break; #endif case TextureTarget.Texture2D: GL.CopyTexSubImage2D(TextureTarget2d.Texture2D, mipLevel, dstX, dstY, sourceRectangle.Left, sourceRectangle.Top, sourceRectangle.Width, sourceRectangle.Height); break; case TextureTarget.Texture2DArray: GL.CopyTexSubImage3D(TextureTarget3d.Texture2DArray, mipLevel, dstX, dstY, arraySlice, sourceRectangle.Left, sourceRectangle.Top, sourceRectangle.Width, sourceRectangle.Height); break; case TextureTarget.Texture3D: GL.CopyTexSubImage3D(TextureTarget3d.Texture3D, mipLevel, dstX, dstY, depthSlice, sourceRectangle.Left, sourceRectangle.Top, sourceRectangle.Width, sourceRectangle.Height); break; case TextureTarget.TextureCubeMap: GL.CopyTexSubImage2D(Texture.GetTextureTargetForDataSet2D(destTexture.TextureTarget, arraySlice), mipLevel, dstX, dstY, sourceRectangle.Left, sourceRectangle.Top, sourceRectangle.Width, sourceRectangle.Height); break; default: throw new NotSupportedException("Invalid texture target: " + destTexture.TextureTarget); } } // Unbind texture and force it to be set again next draw call GL.BindTexture(destTexture.TextureTarget, 0); boundShaderResourceViews[0] = null; // Unbind attachment GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, attachmentType, TextureTarget2d.Texture2D, 0, 0); // Restore FBO and viewport GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFBO); GL.Viewport((int)viewports[0].X, (int)viewports[0].Y, (int)viewports[0].Width, (int)viewports[0].Height); } }
/// <summary> /// Copy a <see cref="GraphicsResource"/> into another. /// </summary> /// <param name="source">The source from which to copy the data</param> /// <param name="destination">The destination into which to copy the data</param> /// <remarks>This might alter some states such as currently bound texture.</remarks> public void Copy(GraphicsResource source, GraphicsResource destination) { // Count subresources var subresourceCount = 1; var sourceTexture = source as Texture; if (sourceTexture != null) { subresourceCount = sourceTexture.ArraySize * sourceTexture.MipLevels; } // Copy each subresource for (int i = 0; i < subresourceCount; ++i) { CopyRegion(source, i, null, destination, i); } }
internal void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox) { #if DEBUG GraphicsDevice.EnsureContextActive(); #endif var buffer = resource as Buffer; if (buffer != null) { #if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES if (buffer.StagingData != IntPtr.Zero) { // Specific case for constant buffers SiliconStudio.Core.Utilities.CopyMemory(buffer.StagingData, databox.DataPointer, buffer.Description.SizeInBytes); return; } #endif //UnbindVertexArrayObject(); if (!GraphicsDevice.HasTextureBuffers && buffer.BufferId == 0) { if (activeTexture != 0) { activeTexture = 0; GL.ActiveTexture(TextureUnit.Texture0); } // On platforms where it's not supported, we use a texture instead of a buffer GL.BindTexture(buffer.TextureTarget, buffer.TextureId); boundShaderResourceViews[0] = null; // bound active texture 0 has changed buffer.UpdateTextureSubresource(databox.DataPointer, 0, 0, buffer.ElementCount); } else { GL.BindBuffer(buffer.BufferTarget, buffer.BufferId); GL.BufferData(buffer.BufferTarget, buffer.Description.SizeInBytes, databox.DataPointer, buffer.BufferUsageHint); } } else { var texture = resource as Texture; if (texture != null) { if (activeTexture != 0) { activeTexture = 0; GL.ActiveTexture(TextureUnit.Texture0); } // TODO: Handle pitchs // TODO: handle other texture formats GL.BindTexture(texture.TextureTarget, texture.TextureId); boundShaderResourceViews[0] = null; // bound active texture 0 has changed var desc = texture.Description; var mipLevel = subResourceIndex % texture.MipLevels; var arraySlice = subResourceIndex / texture.MipLevels; switch (texture.TextureTarget) { #if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES case TextureTarget.Texture1D: GL.TexSubImage1D(TextureTarget.Texture1D, mipLevel, 0, desc.Width, texture.TextureFormat, texture.TextureType, databox.DataPointer); break; #endif case TextureTarget.Texture2D: GL.TexSubImage2D(TextureTarget2d.Texture2D, mipLevel, 0, 0, desc.Width, desc.Height, texture.TextureFormat, texture.TextureType, databox.DataPointer); break; case TextureTarget.Texture2DArray: GL.TexSubImage3D(TextureTarget3d.Texture2DArray, mipLevel, 0, 0, arraySlice, desc.Width, desc.Height, 1, texture.TextureFormat, texture.TextureType, databox.DataPointer); break; case TextureTarget.Texture3D: GL.TexSubImage3D(TextureTarget3d.Texture3D, mipLevel, 0, 0, 0, desc.Width, desc.Height, desc.Depth, texture.TextureFormat, texture.TextureType, databox.DataPointer); break; case TextureTarget.TextureCubeMap: GL.TexSubImage2D(Texture.GetTextureTargetForDataSet2D(texture.TextureTarget, arraySlice), mipLevel, 0, 0, desc.Width, desc.Height, texture.TextureFormat, texture.TextureType, databox.DataPointer); break; default: Internal.Refactor.ThrowNotImplementedException("UpdateSubresource not implemented for texture target " + texture.TextureTarget); break; } } else // neither texture nor buffer { Internal.Refactor.ThrowNotImplementedException("UpdateSubresource not implemented for type " + resource.GetType()); } } }
internal void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox, ResourceRegion region) { #if DEBUG GraphicsDevice.EnsureContextActive(); #endif var texture = resource as Texture; if (texture != null) { var width = region.Right - region.Left; var height = region.Bottom - region.Top; // determine the opengl read Unpack Alignment var packAlignment = 0; if ((databox.RowPitch & 1) != 0) { if (databox.RowPitch == width) packAlignment = 1; } else if ((databox.RowPitch & 2) != 0) { var diff = databox.RowPitch - width; if (diff >= 0 && diff < 2) packAlignment = 2; } else if ((databox.RowPitch & 4) != 0) { var diff = databox.RowPitch - width; if (diff >= 0 && diff < 4) packAlignment = 4; } else if ((databox.RowPitch & 8) != 0) { var diff = databox.RowPitch - width; if (diff >= 0 && diff < 8) packAlignment = 8; } else if (databox.RowPitch == width) { packAlignment = 4; } if (packAlignment == 0) Internal.Refactor.ThrowNotImplementedException("The data box RowPitch is not compatible with the region width. This requires additional copy to be implemented."); // change the Unpack Alignment int previousPackAlignment; GL.GetInteger(GetPName.UnpackAlignment, out previousPackAlignment); GL.PixelStore(PixelStoreParameter.UnpackAlignment, packAlignment); if (activeTexture != 0) { activeTexture = 0; GL.ActiveTexture(TextureUnit.Texture0); } // Update the texture region GL.BindTexture(texture.TextureTarget, texture.TextureId); GL.TexSubImage2D((TextureTarget2d)texture.TextureTarget, subResourceIndex, region.Left, region.Top, width, height, texture.TextureFormat, texture.TextureType, databox.DataPointer); boundShaderResourceViews[0] = null; // bound active texture 0 has changed // reset the Unpack Alignment GL.PixelStore(PixelStoreParameter.UnpackAlignment, previousPackAlignment); } else { var buffer = resource as Buffer; if (buffer != null) { if (!GraphicsDevice.HasTextureBuffers && buffer.BufferId == 0) { if (activeTexture != 0) { activeTexture = 0; GL.ActiveTexture(TextureUnit.Texture0); } // On platforms where it's not supported, we use a texture instead of a buffer GL.BindTexture(buffer.TextureTarget, buffer.TextureId); boundShaderResourceViews[0] = null; // bound active texture 0 has changed buffer.UpdateTextureSubresource(databox.DataPointer, 0, region.Left, region.Right - region.Left); } else { GL.BindBuffer(buffer.BufferTarget, buffer.BufferId); if (region.Left == 0 && region.Right == buffer.SizeInBytes) GL.BufferData(buffer.BufferTarget, (IntPtr)region.Right, databox.DataPointer, buffer.BufferUsageHint); else GL.BufferSubData(buffer.BufferTarget, (IntPtr)region.Left, (IntPtr)(region.Right - region.Left), databox.DataPointer); GL.BindBuffer(buffer.BufferTarget, 0); } } } }
/// <summary> /// Sets an unordered access view to the shader pipeline. /// </summary> /// <param name="stage">The stage.</param> /// <param name="slot">The slot.</param> /// <param name="unorderedAccessView">The unordered access view.</param> /// <exception cref="System.ArgumentException">Invalid stage.;stage</exception> internal void SetUnorderedAccessView(ShaderStage stage, int slot, GraphicsResource unorderedAccessView) { #if DEBUG GraphicsDevice.EnsureContextActive(); #endif if (stage != ShaderStage.Compute) throw new ArgumentException("Invalid stage.", nameof(stage)); Internal.Refactor.ThrowNotImplementedException(); }
/// <summary> /// Gets the DX11 native resource handle /// </summary> /// <param name="resource">The Xenko GraphicsResourceBase</param> /// <returns></returns> public static Resource GetNativeResource(GraphicsResource resource) { return(resource.NativeResource); }
public static object GetNativeShaderResourceView(GraphicsResource resource) { return(GetNativeShaderResourceViewImpl(resource)); }
/// <summary> /// Copies a graphics resource to a destination resource. /// </summary> /// <param name="source">The source resource.</param> /// <param name="destination">The destination resource.</param> public void Copy(GraphicsResource source, GraphicsResource destination) { throw new NotImplementedException(); }
public MappedResource MapSubresource(GraphicsResource resource, int subResourceIndex, MapMode mapMode, bool doNotWait = false, int offsetInBytes = 0, int lengthInBytes = 0) { #if DEBUG GraphicsDevice.EnsureContextActive(); #endif // This resource has just been recycled by the GraphicsResourceAllocator, we force a rename to avoid GPU=>GPU sync point if (resource.DiscardNextMap && mapMode == MapMode.WriteNoOverwrite) mapMode = MapMode.WriteDiscard; var buffer = resource as Buffer; if (buffer != null) { if (lengthInBytes == 0) lengthInBytes = buffer.Description.SizeInBytes; if (buffer.StagingData != IntPtr.Zero) { // Specific case for constant buffers return new MappedResource(resource, subResourceIndex, new DataBox { DataPointer = buffer.StagingData + offsetInBytes, SlicePitch = 0, RowPitch = 0 }, offsetInBytes, lengthInBytes); } #if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES // OpenGL ES 2 needs Staging Data if (GraphicsDevice.IsOpenGLES2) { Internal.Refactor.ThrowNotImplementedException(); } #endif IntPtr mapResult = IntPtr.Zero; //UnbindVertexArrayObject(); GL.BindBuffer(buffer.BufferTarget, buffer.BufferId); #if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES //if (mapMode != MapMode.WriteDiscard && mapMode != MapMode.WriteNoOverwrite) // mapResult = GL.MapBuffer(buffer.bufferTarget, mapMode.ToOpenGL()); //else #endif { // Orphan the buffer (let driver knows we don't need it anymore) if (mapMode == MapMode.WriteDiscard) { doNotWait = true; GL.BufferData(buffer.BufferTarget, (IntPtr)buffer.Description.SizeInBytes, IntPtr.Zero, buffer.BufferUsageHint); } var unsynchronized = doNotWait && mapMode != MapMode.Read && mapMode != MapMode.ReadWrite; mapResult = GL.MapBufferRange(buffer.BufferTarget, (IntPtr)offsetInBytes, (IntPtr)lengthInBytes, mapMode.ToOpenGLMask() | (unsynchronized ? BufferAccessMask.MapUnsynchronizedBit : 0)); } return new MappedResource(resource, subResourceIndex, new DataBox { DataPointer = mapResult, SlicePitch = 0, RowPitch = 0 }); } var texture = resource as Texture; if (texture != null) { if (lengthInBytes == 0) lengthInBytes = texture.ComputeSubresourceSize(subResourceIndex); if (mapMode == MapMode.Read) { if (texture.Description.Usage != GraphicsResourceUsage.Staging) throw new NotSupportedException("Only staging textures can be mapped."); var mipLevel = subResourceIndex % texture.MipLevels; #if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES if (GraphicsDevice.IsOpenGLES2 || texture.StagingData != IntPtr.Zero) { return new MappedResource(resource, subResourceIndex, new DataBox { DataPointer = texture.StagingData + offsetInBytes + texture.ComputeBufferOffset(subResourceIndex, 0), SlicePitch = texture.ComputeSlicePitch(mipLevel), RowPitch = texture.ComputeRowPitch(mipLevel) }, offsetInBytes, lengthInBytes); } else #endif { if (doNotWait) { // Wait at least 2 frames after last operation if (GraphicsDevice.FrameCounter < texture.PixelBufferFrame + ReadbackFrameDelay) { return new MappedResource(resource, subResourceIndex, new DataBox(), offsetInBytes, lengthInBytes); } } return MapTexture(texture, true, BufferTarget.PixelPackBuffer, texture.PixelBufferObjectId, subResourceIndex, mapMode, offsetInBytes, lengthInBytes); } } else if (mapMode == MapMode.WriteDiscard) { #if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES if (GraphicsDevice.IsOpenGLES2) { Internal.Refactor.ThrowNotImplementedException(); } #endif if (texture.Description.Usage != GraphicsResourceUsage.Dynamic) throw new NotSupportedException("Only dynamic texture can be mapped."); // Create a temporary unpack pixel buffer // TODO: Pool/allocator? (it's an upload buffer basically) var pixelBufferObjectId = texture.GeneratePixelBufferObject(BufferTarget.PixelUnpackBuffer, PixelStoreParameter.UnpackAlignment, BufferUsageHint.DynamicCopy, texture.ComputeSubresourceSize(subResourceIndex)); return MapTexture(texture, false, BufferTarget.PixelUnpackBuffer, pixelBufferObjectId, subResourceIndex, mapMode, offsetInBytes, lengthInBytes); } } throw Internal.Refactor.NewNotImplementedException("MapSubresource not implemented for type " + resource.GetType()); }
/// <summary> /// Sets an unordered access view to the shader pipeline. /// </summary> /// <param name="stage">The stage.</param> /// <param name="slot">The slot.</param> /// <param name="unorderedAccessView">The unordered access view.</param> /// <exception cref="System.ArgumentException">Invalid stage.;stage</exception> public void SetUnorderedAccessView(ShaderStage stage, int slot, GraphicsResource unorderedAccessView) { throw new NotImplementedException(); }
public void ResourceBarrierTransition(GraphicsResource resource, GraphicsResourceState newState) { NullHelper.ToImplement(); }
/// <summary> /// Sets an unordered access view to the shader pipeline. /// </summary> /// <param name="stage">The stage.</param> /// <param name="slot">The slot.</param> /// <param name="unorderedAccessView">The unordered access view.</param> /// <exception cref="System.ArgumentException">Invalid stage.;stage</exception> internal void SetUnorderedAccessView(ShaderStage stage, int slot, GraphicsResource unorderedAccessView) { if (stage != ShaderStage.Compute) throw new ArgumentException("Invalid stage.", "stage"); NativeDeviceContext.ComputeShader.SetUnorderedAccessView(slot, unorderedAccessView != null ? unorderedAccessView.NativeUnorderedAccessView : null); }
public void Copy(GraphicsResource source, GraphicsResource destination) { }
internal unsafe void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox, ResourceRegion region) { if (resource == null) throw new ArgumentNullException("resource"); NativeDeviceContext.UpdateSubresource(*(SharpDX.DataBox*)Interop.Cast(ref databox), resource.NativeResource, subResourceIndex, *(SharpDX.Direct3D11.ResourceRegion*)Interop.Cast(ref region)); }
public void CopyRegion(GraphicsResource source, int sourceSubresource, ResourceRegion?sourecRegion, GraphicsResource destination, int destinationSubResource, int dstX = 0, int dstY = 0, int dstZ = 0) { NullHelper.ToImplement(); }
internal void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox, ResourceRegion region) { NullHelper.ToImplement(); }
/// <summary> /// Sets a shader resource view to the shader pipeline. /// </summary> /// <param name="stage">The shader stage.</param> /// <param name="slot">The binding slot.</param> /// <param name="shaderResourceView">The shader resource view.</param> internal void SetShaderResourceView(ShaderStage stage, int slot, GraphicsResource shaderResourceView) { shaderStages[(int)stage - 1].SetShaderResource(slot, shaderResourceView != null ? shaderResourceView.NativeShaderResourceView : null); }
/// <summary> /// Maps a subresource. /// </summary> /// <param name="resource">The resource.</param> /// <param name="subResourceIndex">Index of the sub resource.</param> /// <param name="mapMode">The map mode.</param> /// <param name="doNotWait">if set to <c>true</c> this method will return immediately if the resource is still being used by the GPU for writing. Default is false</param> /// <param name="offsetInBytes">The offset information in bytes.</param> /// <param name="lengthInBytes">The length information in bytes.</param> /// <returns>Pointer to the sub resource to map.</returns> public MappedResource MapSubresource(GraphicsResource resource, int subResourceIndex, MapMode mapMode, bool doNotWait = false, int offsetInBytes = 0, int lengthInBytes = 0) { NullHelper.ToImplement(); return(default(MappedResource)); }
public void CopyRegion(GraphicsResource source, int sourceSubresource, ResourceRegion?sourceRegion, GraphicsResource destination, int destinationSubResource, int dstX = 0, int dstY = 0, int dstZ = 0) { if (source is Texture && destination is Texture) { if (((Texture)source).Usage == GraphicsResourceUsage.Staging || ((Texture)destination).Usage == GraphicsResourceUsage.Staging) { throw new NotImplementedException("Copy region of staging resources is not supported yet"); } NativeCommandList.CopyTextureRegion( new TextureCopyLocation(destination.NativeResource, sourceSubresource), dstX, dstY, dstZ, new TextureCopyLocation(source.NativeResource, sourceSubresource), sourceRegion.HasValue ? (SharpDX.Direct3D12.ResourceRegion?) new SharpDX.Direct3D12.ResourceRegion { Left = sourceRegion.Value.Left, Top = sourceRegion.Value.Top, Front = sourceRegion.Value.Front, Right = sourceRegion.Value.Right, Bottom = sourceRegion.Value.Bottom, Back = sourceRegion.Value.Back } : null); } else if (source is Buffer && destination is Buffer) { NativeCommandList.CopyBufferRegion(destination.NativeResource, dstX, source.NativeResource, sourceRegion?.Left ?? 0, sourceRegion.HasValue ? sourceRegion.Value.Right - sourceRegion.Value.Left : ((Buffer)source).SizeInBytes); } }
/// <summary> /// Gets the DX11 native resource handle /// </summary> /// <param name="resource">The Xenko GraphicsResourceBase</param> /// <returns></returns> private static Resource GetNativeResourceImpl(GraphicsResource resource) { return(resource.NativeResource); }
/// <summary> /// Gets the DX11 native resource handle /// </summary> /// <param name="resource">The Xenko GraphicsResourceBase</param> /// <returns></returns> public static object GetNativeResource(GraphicsResource resource) { return(GetNativeResourceImpl(resource)); }
public void UnmapSubresource(GraphicsResource resource, int subResourceIndex) { throw new NotImplementedException(); }
// TODO GRAPHICS REFACTOR what should we do with this? /// <summary> /// Maps a subresource. /// </summary> /// <param name="resource">The resource.</param> /// <param name="subResourceIndex">Index of the sub resource.</param> /// <param name="mapMode">The map mode.</param> /// <param name="doNotWait">if set to <c>true</c> this method will return immediately if the resource is still being used by the GPU for writing. Default is false</param> /// <param name="offsetInBytes">The offset information in bytes.</param> /// <param name="lengthInBytes">The length information in bytes.</param> /// <returns>Pointer to the sub resource to map.</returns> public MappedResource MapSubresource(GraphicsResource resource, int subResourceIndex, MapMode mapMode, bool doNotWait = false, int offsetInBytes = 0, int lengthInBytes = 0) { if (resource == null) { throw new ArgumentNullException("resource"); } var rowPitch = 0; var depthStride = 0; var usage = GraphicsResourceUsage.Default; var texture = resource as Texture; if (texture != null) { usage = texture.Usage; if (lengthInBytes == 0) { lengthInBytes = texture.ComputeSubresourceSize(subResourceIndex); } rowPitch = texture.ComputeRowPitch(subResourceIndex % texture.MipLevels); depthStride = texture.ComputeSlicePitch(subResourceIndex % texture.MipLevels); if (texture.Usage == GraphicsResourceUsage.Staging) { // Internally it's a buffer, so adapt resource index and offset offsetInBytes = texture.ComputeBufferOffset(subResourceIndex, 0); subResourceIndex = 0; } } else { var buffer = resource as Buffer; if (buffer != null) { usage = buffer.Usage; if (lengthInBytes == 0) { lengthInBytes = buffer.SizeInBytes; } } } if (mapMode == MapMode.Read || mapMode == MapMode.ReadWrite || mapMode == MapMode.Write) { // Is non-staging ever possible for Read/Write? if (usage != GraphicsResourceUsage.Staging) { throw new InvalidOperationException(); } } if (mapMode == MapMode.WriteDiscard) { throw new InvalidOperationException("Can't use WriteDiscard on Graphics API that don't support renaming"); } if (mapMode != MapMode.WriteNoOverwrite) { // Need to wait? if (!resource.StagingFenceValue.HasValue || !GraphicsDevice.IsFenceCompleteInternal(resource.StagingFenceValue.Value)) { if (doNotWait) { return(new MappedResource(resource, subResourceIndex, new DataBox(IntPtr.Zero, 0, 0))); } // Need to flush? (i.e. part of) if (resource.StagingBuilder == this) { FlushInternal(false); } if (!resource.StagingFenceValue.HasValue) { throw new InvalidOperationException("CommandList updating the staging resource has not been submitted"); } GraphicsDevice.WaitForFenceInternal(resource.StagingFenceValue.Value); } } var mappedMemory = resource.NativeResource.Map(subResourceIndex) + offsetInBytes; return(new MappedResource(resource, subResourceIndex, new DataBox(mappedMemory, rowPitch, depthStride), offsetInBytes, lengthInBytes)); }
/// <summary> /// Sets a shader resource view to the shader pipeline. /// </summary> /// <param name="stage">The shader stage.</param> /// <param name="slot">The binding slot.</param> /// <param name="shaderResourceView">The shader resource view.</param> public void SetShaderResourceView(ShaderStage stage, int slot, GraphicsResource shaderResourceView) { throw new NotImplementedException(); }
internal void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox, ResourceRegion region) { throw new NotImplementedException(); }
/// <summary> /// Sets an unordered access view descriptor. /// </summary> /// <param name="slot">The slot.</param> /// <param name="unorderedAccessView">The unordered access view.</param> public void SetUnorderedAccessView(int slot, GraphicsResource unorderedAccessView) { // TODO D3D12 throw new NotImplementedException(); }
public DataBox MapSubresource(GraphicsResource resource, int subResourceIndex, MapMode mapMode) { throw new NotImplementedException(); }
public void ResourceBarrierTransition(GraphicsResource resource, GraphicsResourceState newState) { // Nothing to do }
public void CopyRegion(GraphicsResource source, int sourceSubresource, ResourceRegion? sourecRegion, GraphicsResource destination, int destinationSubResource, int dstX = 0, int dstY = 0, int dstZ = 0) { if (source == null) throw new ArgumentNullException("source"); if (destination == null) throw new ArgumentNullException("destination"); var nullableSharpDxRegion = new SharpDX.Direct3D11.ResourceRegion?(); if (sourecRegion.HasValue) { var value = sourecRegion.Value; nullableSharpDxRegion = new SharpDX.Direct3D11.ResourceRegion(value.Left, value.Top, value.Front, value.Right, value.Bottom, value.Back); } NativeDeviceContext.CopySubresourceRegion(source.NativeResource, sourceSubresource, nullableSharpDxRegion, destination.NativeResource, destinationSubResource, dstX, dstY, dstZ); }
// TODO GRAPHICS REFACTOR what should we do with this? /// <summary> /// Maps a subresource. /// </summary> /// <param name="resource">The resource.</param> /// <param name="subResourceIndex">Index of the sub resource.</param> /// <param name="mapMode">The map mode.</param> /// <param name="doNotWait">if set to <c>true</c> this method will return immediately if the resource is still being used by the GPU for writing. Default is false</param> /// <param name="offsetInBytes">The offset information in bytes.</param> /// <param name="lengthInBytes">The length information in bytes.</param> /// <returns>Pointer to the sub resource to map.</returns> public unsafe MappedResource MapSubresource(GraphicsResource resource, int subResourceIndex, MapMode mapMode, bool doNotWait = false, int offsetInBytes = 0, int lengthInBytes = 0) { if (resource == null) throw new ArgumentNullException("resource"); SharpDX.DataBox dataBox = NativeDeviceContext.MapSubresource(resource.NativeResource, subResourceIndex, (SharpDX.Direct3D11.MapMode)mapMode, doNotWait ? SharpDX.Direct3D11.MapFlags.DoNotWait : SharpDX.Direct3D11.MapFlags.None); var databox = *(DataBox*)Interop.Cast(ref dataBox); if (!dataBox.IsEmpty) { databox.DataPointer = (IntPtr)((byte*)databox.DataPointer + offsetInBytes); } return new MappedResource(resource, subResourceIndex, databox); }
/// <summary> /// Sets an unordered access view descriptor. /// </summary> /// <param name="slot">The slot.</param> /// <param name="unorderedAccessView">The unordered access view.</param> public void SetUnorderedAccessView(int slot, GraphicsResource unorderedAccessView) { HeapObjects[DescriptorStartOffset + slot].Value = unorderedAccessView; }
public void ResourceBarrierTransition(GraphicsResource resource, GraphicsResourceState newState) { // Find parent resource if (resource.ParentResource != null) resource = resource.ParentResource; var currentState = resource.NativeResourceState; if (currentState != (ResourceStates)newState) { resource.NativeResourceState = (ResourceStates)newState; NativeCommandList.ResourceBarrierTransition(resource.NativeResource, currentState, (ResourceStates)newState); } }
public void Copy(GraphicsResource source, GraphicsResource destination) { var sourceTexture = source as Texture; var destinationTexture = destination as Texture; if (sourceTexture != null && destinationTexture != null) { var sourceParent = sourceTexture.ParentTexture ?? sourceTexture; var destinationParent = destinationTexture.ParentTexture ?? destinationTexture; if (sourceParent.NativeResourceState != ResourceStates.CopySource) NativeCommandList.ResourceBarrierTransition(sourceTexture.NativeResource, sourceParent.NativeResourceState, ResourceStates.CopySource); if (destinationParent.NativeResourceState != ResourceStates.CopyDestination) NativeCommandList.ResourceBarrierTransition(destinationTexture.NativeResource, destinationParent.NativeResourceState, ResourceStates.CopyDestination); if (destinationTexture.Usage == GraphicsResourceUsage.Staging) { int copyOffset = 0; for (int arraySlice = 0; arraySlice < sourceParent.ArraySize; ++arraySlice) { for (int mipLevel = 0; mipLevel < sourceParent.MipLevels; ++mipLevel) { NativeCommandList.CopyTextureRegion(new TextureCopyLocation(destinationTexture.NativeResource, new PlacedSubResourceFootprint { Footprint = { Width = Texture.CalculateMipSize(destinationTexture.Width, mipLevel), Height = Texture.CalculateMipSize(destinationTexture.Height, mipLevel), Depth = Texture.CalculateMipSize(destinationTexture.Depth, mipLevel), Format = (SharpDX.DXGI.Format)destinationTexture.Format, RowPitch = destinationTexture.ComputeRowPitch(mipLevel), }, Offset = copyOffset, }), 0, 0, 0, new TextureCopyLocation(sourceTexture.NativeResource, arraySlice * sourceParent.MipLevels + mipLevel), null); copyOffset += destinationTexture.ComputeSubresourceSize(mipLevel); } } // Set a value that will destinationParent.StagingFenceValue = GraphicsDevice.NextFenceValue; } else { NativeCommandList.CopyResource(destinationTexture.NativeResource, sourceTexture.NativeResource); } if (sourceParent.NativeResourceState != ResourceStates.CopySource) NativeCommandList.ResourceBarrierTransition(sourceTexture.NativeResource, ResourceStates.CopySource, sourceParent.NativeResourceState); if (destinationParent.NativeResourceState != ResourceStates.CopyDestination) NativeCommandList.ResourceBarrierTransition(destinationTexture.NativeResource, ResourceStates.CopyDestination, destinationParent.NativeResourceState); } else { throw new NotImplementedException(); } }
internal void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox) { throw new NotImplementedException(); }
public void CopyRegion(GraphicsResource source, int sourceSubresource, ResourceRegion? sourceRegion, GraphicsResource destination, int destinationSubResource, int dstX = 0, int dstY = 0, int dstZ = 0) { if (source is Texture && destination is Texture) { if (((Texture)source).Usage == GraphicsResourceUsage.Staging || ((Texture)destination).Usage == GraphicsResourceUsage.Staging) { throw new NotImplementedException("Copy region of staging resources is not supported yet"); } NativeCommandList.CopyTextureRegion( new TextureCopyLocation(destination.NativeResource, sourceSubresource), dstX, dstY, dstZ, new TextureCopyLocation(source.NativeResource, sourceSubresource), sourceRegion.HasValue ? (SharpDX.Direct3D12.ResourceRegion?)new SharpDX.Direct3D12.ResourceRegion { Left = sourceRegion.Value.Left, Top = sourceRegion.Value.Top, Front = sourceRegion.Value.Front, Right = sourceRegion.Value.Right, Bottom = sourceRegion.Value.Bottom, Back = sourceRegion.Value.Back } : null); } else if (source is Buffer && destination is Buffer) { NativeCommandList.CopyBufferRegion(destination.NativeResource, dstX, source.NativeResource, sourceRegion?.Left ?? 0, sourceRegion.HasValue ? sourceRegion.Value.Right - sourceRegion.Value.Left : ((Buffer)source).SizeInBytes); } }
internal void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox) { ResourceRegion region; var texture = resource as Texture; if (texture != null) { region = new ResourceRegion(0, 0, 0, texture.Width, texture.Height, texture.Depth); } else { var buffer = resource as Buffer; if (buffer != null) { region = new ResourceRegion(0, 0, 0, buffer.SizeInBytes, 1, 1); } else { throw new InvalidOperationException("Unknown resource type"); } } UpdateSubresource(resource, subResourceIndex, databox, region); }
public void Copy(GraphicsResource source, GraphicsResource destination) { var sourceTexture = source as Texture; var destinationTexture = destination as Texture; if (sourceTexture != null && destinationTexture != null) { var sourceParent = sourceTexture.ParentTexture ?? sourceTexture; var destinationParent = destinationTexture.ParentTexture ?? destinationTexture; if (sourceParent.NativeResourceState != ResourceStates.CopySource) { NativeCommandList.ResourceBarrierTransition(sourceTexture.NativeResource, sourceParent.NativeResourceState, ResourceStates.CopySource); } if (destinationParent.NativeResourceState != ResourceStates.CopyDestination) { NativeCommandList.ResourceBarrierTransition(destinationTexture.NativeResource, destinationParent.NativeResourceState, ResourceStates.CopyDestination); } if (destinationTexture.Usage == GraphicsResourceUsage.Staging) { int copyOffset = 0; for (int arraySlice = 0; arraySlice < sourceParent.ArraySize; ++arraySlice) { for (int mipLevel = 0; mipLevel < sourceParent.MipLevels; ++mipLevel) { NativeCommandList.CopyTextureRegion(new TextureCopyLocation(destinationTexture.NativeResource, new PlacedSubResourceFootprint { Footprint = { Width = Texture.CalculateMipSize(destinationTexture.Width, mipLevel), Height = Texture.CalculateMipSize(destinationTexture.Height, mipLevel), Depth = Texture.CalculateMipSize(destinationTexture.Depth, mipLevel), Format = (SharpDX.DXGI.Format)destinationTexture.Format, RowPitch = destinationTexture.ComputeRowPitch(mipLevel), }, Offset = copyOffset, }), 0, 0, 0, new TextureCopyLocation(sourceTexture.NativeResource, arraySlice * sourceParent.MipLevels + mipLevel), null); copyOffset += destinationTexture.ComputeSubresourceSize(mipLevel); } } // Set a value that will destinationParent.StagingFenceValue = GraphicsDevice.NextFenceValue; } else { NativeCommandList.CopyResource(destinationTexture.NativeResource, sourceTexture.NativeResource); } if (sourceParent.NativeResourceState != ResourceStates.CopySource) { NativeCommandList.ResourceBarrierTransition(sourceTexture.NativeResource, ResourceStates.CopySource, sourceParent.NativeResourceState); } if (destinationParent.NativeResourceState != ResourceStates.CopyDestination) { NativeCommandList.ResourceBarrierTransition(destinationTexture.NativeResource, ResourceStates.CopyDestination, destinationParent.NativeResourceState); } } else { throw new NotImplementedException(); } }
internal void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox, ResourceRegion region) { var texture = resource as Texture; if (texture != null) { var width = region.Right - region.Left; var height = region.Bottom - region.Top; var depth = region.Back - region.Front; ResourceDescription resourceDescription; switch (texture.Dimension) { case TextureDimension.Texture1D: resourceDescription = ResourceDescription.Texture1D((SharpDX.DXGI.Format)texture.Format, width, 1, 1); break; case TextureDimension.Texture2D: case TextureDimension.TextureCube: resourceDescription = ResourceDescription.Texture2D((SharpDX.DXGI.Format)texture.Format, width, height, 1, 1); break; case TextureDimension.Texture3D: resourceDescription = ResourceDescription.Texture3D((SharpDX.DXGI.Format)texture.Format, width, height, (short)depth, 1); break; default: throw new ArgumentOutOfRangeException(); } // TODO D3D12 allocate in upload heap (placed resources?) var nativeUploadTexture = NativeDevice.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None, resourceDescription, ResourceStates.GenericRead); GraphicsDevice.TemporaryResources.Enqueue(new KeyValuePair<long, Pageable>(GraphicsDevice.NextFenceValue, nativeUploadTexture)); nativeUploadTexture.WriteToSubresource(0, null, databox.DataPointer, databox.RowPitch, databox.SlicePitch); var parentResource = resource.ParentResource ?? resource; // Trigger copy NativeCommandList.ResourceBarrierTransition(resource.NativeResource, parentResource.NativeResourceState, ResourceStates.CopyDestination); NativeCommandList.CopyTextureRegion(new TextureCopyLocation(resource.NativeResource, subResourceIndex), region.Left, region.Top, region.Front, new TextureCopyLocation(nativeUploadTexture, 0), null); NativeCommandList.ResourceBarrierTransition(resource.NativeResource, ResourceStates.CopyDestination, parentResource.NativeResourceState); } else { var buffer = resource as Buffer; if (buffer != null) { SharpDX.Direct3D12.Resource uploadResource; int uploadOffset; var uploadSize = region.Right - region.Left; var uploadMemory = GraphicsDevice.AllocateUploadBuffer(region.Right - region.Left, out uploadResource, out uploadOffset); Utilities.CopyMemory(uploadMemory, databox.DataPointer, uploadSize); NativeCommandList.ResourceBarrierTransition(resource.NativeResource, resource.NativeResourceState, ResourceStates.CopyDestination); NativeCommandList.CopyBufferRegion(resource.NativeResource, region.Left, uploadResource, uploadOffset, uploadSize); NativeCommandList.ResourceBarrierTransition(resource.NativeResource, ResourceStates.CopyDestination, resource.NativeResourceState); } else { throw new InvalidOperationException("Unknown resource type"); } } }
internal void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox, ResourceRegion region) { var texture = resource as Texture; if (texture != null) { var width = region.Right - region.Left; var height = region.Bottom - region.Top; var depth = region.Back - region.Front; ResourceDescription resourceDescription; switch (texture.Dimension) { case TextureDimension.Texture1D: resourceDescription = ResourceDescription.Texture1D((SharpDX.DXGI.Format)texture.Format, width, 1, 1); break; case TextureDimension.Texture2D: case TextureDimension.TextureCube: resourceDescription = ResourceDescription.Texture2D((SharpDX.DXGI.Format)texture.Format, width, height, 1, 1); break; case TextureDimension.Texture3D: resourceDescription = ResourceDescription.Texture3D((SharpDX.DXGI.Format)texture.Format, width, height, (short)depth, 1); break; default: throw new ArgumentOutOfRangeException(); } // TODO D3D12 allocate in upload heap (placed resources?) var nativeUploadTexture = NativeDevice.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None, resourceDescription, ResourceStates.GenericRead); GraphicsDevice.TemporaryResources.Enqueue(new KeyValuePair <long, Pageable>(GraphicsDevice.NextFenceValue, nativeUploadTexture)); nativeUploadTexture.WriteToSubresource(0, null, databox.DataPointer, databox.RowPitch, databox.SlicePitch); var parentResource = resource.ParentResource ?? resource; // Trigger copy NativeCommandList.ResourceBarrierTransition(resource.NativeResource, parentResource.NativeResourceState, ResourceStates.CopyDestination); NativeCommandList.CopyTextureRegion(new TextureCopyLocation(resource.NativeResource, subResourceIndex), region.Left, region.Top, region.Front, new TextureCopyLocation(nativeUploadTexture, 0), null); NativeCommandList.ResourceBarrierTransition(resource.NativeResource, ResourceStates.CopyDestination, parentResource.NativeResourceState); } else { var buffer = resource as Buffer; if (buffer != null) { SharpDX.Direct3D12.Resource uploadResource; int uploadOffset; var uploadSize = region.Right - region.Left; var uploadMemory = GraphicsDevice.AllocateUploadBuffer(region.Right - region.Left, out uploadResource, out uploadOffset); Utilities.CopyMemory(uploadMemory, databox.DataPointer, uploadSize); NativeCommandList.ResourceBarrierTransition(resource.NativeResource, resource.NativeResourceState, ResourceStates.CopyDestination); NativeCommandList.CopyBufferRegion(resource.NativeResource, region.Left, uploadResource, uploadOffset, uploadSize); NativeCommandList.ResourceBarrierTransition(resource.NativeResource, ResourceStates.CopyDestination, resource.NativeResourceState); } else { throw new InvalidOperationException("Unknown resource type"); } } }
// TODO GRAPHICS REFACTOR what should we do with this? /// <summary> /// Maps a subresource. /// </summary> /// <param name="resource">The resource.</param> /// <param name="subResourceIndex">Index of the sub resource.</param> /// <param name="mapMode">The map mode.</param> /// <param name="doNotWait">if set to <c>true</c> this method will return immediately if the resource is still being used by the GPU for writing. Default is false</param> /// <param name="offsetInBytes">The offset information in bytes.</param> /// <param name="lengthInBytes">The length information in bytes.</param> /// <returns>Pointer to the sub resource to map.</returns> public MappedResource MapSubresource(GraphicsResource resource, int subResourceIndex, MapMode mapMode, bool doNotWait = false, int offsetInBytes = 0, int lengthInBytes = 0) { if (resource == null) throw new ArgumentNullException("resource"); var rowPitch = 0; var depthStride = 0; var usage = GraphicsResourceUsage.Default; var texture = resource as Texture; if (texture != null) { usage = texture.Usage; if (lengthInBytes == 0) lengthInBytes = texture.ComputeSubresourceSize(subResourceIndex); rowPitch = texture.ComputeRowPitch(subResourceIndex % texture.MipLevels); depthStride = texture.ComputeSlicePitch(subResourceIndex % texture.MipLevels); if (texture.Usage == GraphicsResourceUsage.Staging) { // Internally it's a buffer, so adapt resource index and offset offsetInBytes = texture.ComputeBufferOffset(subResourceIndex, 0); subResourceIndex = 0; } } else { var buffer = resource as Buffer; if (buffer != null) { usage = buffer.Usage; if (lengthInBytes == 0) lengthInBytes = buffer.SizeInBytes; } } // TODO D3D12 WriteDiscard should just reallocate new buffer, and WriteNoOverwrite shouldn't use that path (for now we defer to upload buffer) if (mapMode == MapMode.WriteDiscard || mapMode == MapMode.WriteNoOverwrite) { SharpDX.Direct3D12.Resource uploadResource; int uploadOffset; var uploadMemory = GraphicsDevice.AllocateUploadBuffer(lengthInBytes, out uploadResource, out uploadOffset); return new MappedResource(resource, subResourceIndex, new DataBox(uploadMemory, rowPitch, depthStride), offsetInBytes, lengthInBytes) { UploadResource = uploadResource, UploadOffset = uploadOffset, }; } else if (mapMode == MapMode.Read || mapMode == MapMode.ReadWrite || mapMode == MapMode.Write) { // Is non-staging ever possible? if (usage != GraphicsResourceUsage.Staging) throw new InvalidOperationException(); if (mapMode != MapMode.WriteNoOverwrite) { // Need to wait? if (!GraphicsDevice.IsFenceCompleteInternal(resource.StagingFenceValue)) { if (doNotWait) { return new MappedResource(resource, subResourceIndex, new DataBox(IntPtr.Zero, 0, 0)); } // Need to flush (part of current command list) if (resource.StagingFenceValue == GraphicsDevice.NextFenceValue) FlushInternal(false); GraphicsDevice.WaitForFenceInternal(resource.StagingFenceValue); } } var mappedMemory = resource.NativeResource.Map(subResourceIndex) + offsetInBytes; return new MappedResource(resource, subResourceIndex, new DataBox(mappedMemory, rowPitch, depthStride), offsetInBytes, lengthInBytes); } else { throw new NotImplementedException(); } }
/// <summary> /// Initializes a new instance of the <see cref="GraphicsResourceLink"/> class. /// </summary> /// <param name="graphicsResource">The graphics resource.</param> /// <exception cref="System.ArgumentNullException">graphicsResource</exception> internal GraphicsResourceLink(GraphicsResource graphicsResource) { if (graphicsResource == null) throw new ArgumentNullException("graphicsResource"); this.resource = graphicsResource; }
private static ShaderResourceView GetNativeShaderResourceViewImpl(GraphicsResource resource) { return(resource.NativeShaderResourceView); }