ComputeSharp icon indicating copy to clipboard operation
ComputeSharp copied to clipboard

Please add support of Texture.CopyTexture()

Open JohnMasen opened this issue 3 years ago • 6 comments

Description (optional)

I found the library is using texture copy inside AllocateReadOnlyTexture2D<T,TPixel>(), however the texture copy method is not exposed to public. The idea is able to create a texture processing pipleline like this: Upload<MyPixel> ->CopyTo Texture -> Process Texture ->Readback result

Rationale

I'm trying to use ComputeSharp to build a fast image resize/resample pipeline for AI Model(ONNX) inference, the stream from video source is RGBA32 format, I wish I could use UploadTexutre2D<RGBA32> to upload the stream then copy it to ReadOnlyTexture2D .

Proposed API

Add CopyTexture<TSource,TTarget>(Texture<TTarget> texture) to UploadTexture<TSource>.

Drawbacks

TBD

Alternatives

Other thoughts

It is also suggested add a customer type mapper to allow map user data structure to DXPixelFormat just like DXGIFormatHelper. User can create UploadTexture/ReadOnlyTexture with the custom mapper to

  1. Map ImageSharp pixel formats directly to DirectX PixelFormats without MemoryMarshal.Cast()
  2. use DXGI_FORMAT_NV12 directly from DXVA GPU decoded video frame

example: device.AllocateUploadTexture2D<NV12>(ReadonlySpan<NV12> buffer, int w, int h, DXGITypeMapper mapper );

Thanks

JohnMasen avatar Mar 31 '22 07:03 JohnMasen

I'm not sure I understand the proposal (also the actual API proposal isn't really an API either). You can already do this:

using UploadTexture2D<float> upload = GraphicsDevice.Default.AllocateUploadTexture2D<float>(64, 64);
using ReadOnlyTexture2D<float> texture = GraphicsDevice.Default.AllocateReadOnlyTexture2D<float>(64, 64);

upload.CopyTo(texture);

// Run the shader...

using ReadBackTexture2D<float> readback = GraphicsDevice.Default.AllocateReadBackTexture2D<float>(64, 64);

texture.CopyTo(readback);

Am I missing something? Could you clarify what you're trying to do that's not working for you? 🤔 Thanks!

Sergio0694 avatar Apr 23 '22 21:04 Sergio0694

The idea is CopyTexture will automatically convert the pixel format from source to target, it will be a large cost to convert it in CPU. The suggestion in alternatives is allowing user to upload a user mapped pixel format, this allows me to upload pixel memory directly from DXGI_FORMAT_NV12 formatted memory data. My target is I can upload a NV12 frame data to GPU, then CopyTexture to a RGBA32 Texture for later processing.

JohnMasen avatar Apr 30 '22 14:04 JohnMasen

Another target is I can upload a RGBA image data to GPU, then CopyTexture to a BGRA32 Texture for later processing

JohnMasen avatar Apr 30 '22 14:04 JohnMasen

I've had to do something similar when working with Direct2D so I can render on the GPU at RGBA Float32 precision (128-bits per pixel), and then pull data back to the CPU-side at BGRA U8 precision (32-bits per pixel). I render to a RGBA F32 target, then I copy to a second GPU-side bitmap that is BGRA U8, which means the conversion happens on the GPU. Very useful because otherwise, as you state, the cost to do it on the CPU is much higher. This also lets me do un-premultiplication on the GPU at full Float32, which avoids smashing low-alpha color values.

rickbrew avatar Apr 30 '22 15:04 rickbrew

@JohnMasen I'm still not sure I understand the proposal, could you clarify exactly what API you're asking for? In the first message, you say:

"I found the library is using texture copy inside AllocateReadOnlyTexture2D<T,TPixel>(), however the texture copy method is not exposed to public."

But... That doesn't seem to be true? That API is this:

https://github.com/Sergio0694/ComputeSharp/blob/1da016a8478f489f954ef976b75e4d380676c5d5/src/ComputeSharp/Graphics/Extensions/GraphicsDeviceExtensions.Resources.cs#L326-L338

But that texture.CopyFrom is a public API as well:

https://github.com/Sergio0694/ComputeSharp/blob/1da016a8478f489f954ef976b75e4d380676c5d5/src/ComputeSharp/Graphics/Extensions/Texture2DExtensions.cs#L357-L366

So I'm not sure what API you're referring to exactly as not being public here? 🤔

"Add CopyTexture<TSource,TTarget>(Texture texture) to UploadTexture."

If the ask is for a new API to copy to a texture with a different pixel format, then I can understand that, I'm just not sure how the two things are related. Like, this just seems like a request for a new API, but not to make an existing one public?

Sergio0694 avatar Aug 28 '22 20:08 Sergio0694

The native api allows user copy texture with a pixel format mapping, this enables user copy and transfer pixelformat with single operation. In my program, I'm looking for a way to upload a RGBA32 format texture and copy it to a BGR texutre without manually transfer the pixels. The best way I can think is expose the CopyTexture() function with pixelmapping parameter.

JohnMasen avatar Sep 20 '22 04:09 JohnMasen