Advertisement

Sampling a whole texture in HLSL

Started by February 29, 2020 02:38 PM
8 comments, last by fs1 4 years, 10 months ago

I have been looking at the SampleLevel function in https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-samplelevel

I would like to do a texture sampling of a whole texture in a Compute Shader, without doing a lookup.

Texture3D density: register(t1);

StructuredBuffer<float4> result: register(t2);

float4 lookup=density.SampleLevel(wwcSamplerState, textcoords ,0);

I would like to copy all texels to the result structured buffer.

How do I do this?

Thanks!

The “result” will have to be a RWStructuredBuffer and in “: register(u0)”, for example, not t2.

You might want to use density.Load (with whole-number texel indices) instead of density.SampleLevel (with uvw texture coordinates), because you said you want to “copy all texels”, you didn't mention any filtering.

I don't understand what you mean by “without doing a lookup”.

Also beware that your (RW)StructuredBuffer is a single-dimensional array, so you'll have to layout your 3D texture texels into it somehow. What are you trying to achieve?

Advertisement

Thanks @pcmaster .

I want to be able to read back on the CPU all lookup float4's from the whole texture, not just one point of it (retrieving one float4 is what I meant with doing a lookup)

In this example by using SampleLevel you just retrieve only one coordinate of it.

I want to be able to do this for all texels for all texcoords of the texture, and save it in the (RW) StructuredBuffer.

@fs1 Create a resource to read back to the CPU. Then copy(copybufferregion()) the resource that has your data into that CPU-read resource and read it from the CPU.

The same way you load your data from the CPU to the GPU, but backwards.

Regardless if the resource is UAV or SRV, and regardless the dimensions. You copy it into a CPU-read resource and then copy it to an array.

(in the case of DX12)

Thanks @nikito

Will the format of the CPU-read resource will have the array of float4’s I am looking for?

Thanks

@fs1 It exactly copies a region of a resource into another resource. It is up to you to define the data type of the array on the CPU side. You read the data as bare BYTEs. Every 4 consecutive 4bytes(UINT32) will be your Float4(4xUINT32).

Advertisement

Thanks @nikito

I will try it and report back. Thanks

I was able to read back my 3D Texture in the CPU, following the steps here https://www.gamedev.net/forums/topic/684155-take-a-screenshot-in-d3d12/

0. Create or use an existing graphic command list

1. Use GetCopyableFootprints to obtain the size a readback buffer you are gonna need

2. Create a commited resource buffer in copy dest state

3. Transition the image resource you want to copy to generic read

4. Use CopyTextureRegion to copy from the texture to the buffer

5. Execute the command list

6. Fence and wait for everything to have complete

7. Map on the buffer, use the result of 1 to know how to read the image ( pitch, width, height)

Now my question is, how can I now read my image?

The result of 1) is:

 

 Also, from GetCopyableFootprints call

			device->GetCopyableFootprints(
			&desc,
			0,
			1,
			0,
			&renderTargetLayout,
			&fpRowCount,
			&fpRowPitch,
			&totalResourceSize);

I get fpRowCount: 1024, fpRowPitch: 4096 and totalResourceSize: 134217728 bytes.

How do I loop over the retrieved pointer? 

Thanks

 

Thanks to @nikito for the help.

I got it working with the formula https://stackoverflow.com/questions/7367770/how-to-flatten-or-index-3d-array-in-1d-array/7367812

This topic is closed to new replies.

Advertisement