Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please add support of Texture.CopyTexture() #215

Open
JohnMasen opened this issue Mar 31, 2022 · 6 comments
Open

Please add support of Texture.CopyTexture() #215

JohnMasen opened this issue Mar 31, 2022 · 6 comments
Labels
need more info 🔍 An issue that needs more info to be investigated proposal 💡 A proposal for a new feature

Comments

@JohnMasen
Copy link

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 ->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 to upload the stream then copy it to ReadOnlyTexture2D .

Proposed API

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

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(ReadonlySpan buffer, int w, int h, DXGITypeMapper mapper );

Thanks

@JohnMasen JohnMasen added proposal 💡 A proposal for a new feature untriaged 🧰 A new issue that needs initial triage labels Mar 31, 2022
@Sergio0694
Copy link
Owner

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 Sergio0694 added need more info 🔍 An issue that needs more info to be investigated and removed untriaged 🧰 A new issue that needs initial triage labels Apr 23, 2022
@JohnMasen
Copy link
Author

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
Copy link
Author

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

@rickbrew
Copy link
Collaborator

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.

@Sergio0694
Copy link
Owner

@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:

public static ReadOnlyTexture2D<T, TPixel> AllocateReadOnlyTexture2D<T, TPixel>(this GraphicsDevice device, T[,] source)
where T : unmanaged, IPixel<T, TPixel>
where TPixel : unmanaged
{
Guard.IsNotNull(device);
Guard.IsNotNull(source);
ReadOnlyTexture2D<T, TPixel> texture = new(device, source.GetLength(1), source.GetLength(0), AllocationMode.Default);
texture.CopyFrom(source);
return texture;
}

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

public static unsafe void CopyFrom<T>(this Texture2D<T> destination, T[,] source)
where T : unmanaged
{
Guard.IsNotNull(destination);
Guard.IsNotNull(source);
Guard.IsEqualTo(source.GetLength(0), destination.Height, nameof(source));
Guard.IsEqualTo(source.GetLength(1), destination.Width, nameof(source));
destination.CopyFrom(ref source[0, 0], source.Length, 0, 0, destination.Width, destination.Height);
}

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?

@JohnMasen
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
need more info 🔍 An issue that needs more info to be investigated proposal 💡 A proposal for a new feature
Projects
None yet
Development

No branches or pull requests

3 participants