Advertisement

Texture2D - MapSubResource - Strange padding

Started by November 19, 2019 02:37 PM
6 comments, last by B-Real 4 years, 9 months ago

Hi,

I have to update a texture dynamically from the CPU and this texture can have any resolution, because its loaded from a video. I am using a R8G8B8A8 format and my input data is ARGB32 so this should match perfectly. Once I am using MapSubResource it works fine for all pow2 dimensions, but once it gets to a resolution like 3600x400 it fails and I get an disturbed image. I've discovered that it only works for pixel resolution with a multiple of 32. My biggest problem is, that I can't just run through those pixels manually as it would cost to much.. So I need a way to directly get my image data into the texture fast enough. I was search for any required padding but couldn't find something.

Any Ideas?

Thx

 

It would help to have some more explanation of how exactly are you trying to do this. Are you mapping a staging texture as writable and then doing a copy into a default usage texture? 

If you can't get it to work with mapping, you could also consider just creating a buffer from your texture data, and use a compute shader to load pixel elements from the 1D buffer and write into a RWTexture2D to the 2D pixel location.

Advertisement

I am using a texture with Dynamic as Usage flag. Thought this is what "dynamic" offers?

Using a sep. staging texture with a copy to a default texture give same results. I've also made a small test code with a texture resolution at 3600 x 400 and just "drawing" a straight line with:


Dim A(width*height*4 - 1) As Byte
  For y As Integer = 0 To height-1
      Dim x As Integer = width / 2
      Dim p As Integer = (x * 4) + (y * width * 4)
      A(p) = 255
      A(p + 1) = 255
      A(p + 2) = 255
      A(p + 3) = 255
  Next
 

then uploading this byte buffer using Map.. It does everything but no straight line. When using a resolution of f.e. 1024x1024 it works fine.

BTW: Using a compute shader and additional buffer could work, but actually I am looking for the most efficient method because the whole process happens several times.

 

EDIT:
While debugging I was having a look at the DataBox Object (Using SlimDX) returned by MapSubResource.. With my 3600px Texture with R8G8B8A8.. it tells me a rowpitch of 14.464.. which would mean that he just added 16 pixels to the row? Is it just me wondering about this, as I couldn't find any clear documentation about this behaviour.

 

 

Why the -1 in the first line? Show more code. You might have byte array alignment issues but I don't use basic much, or whatever that source is.

 

You always have to pay attention to the pitch, the driver/hardware is allowed to add padding that you need to respect. Rather than using (y * width * 4), use (y * pitch).

Advertisement
20 minutes ago, TeaTreeTim said:

Why the -1 in the first line? Show more code. You might have byte array alignment issues but I don't use basic much, or whatever that source is.

 

In VB arrays has to be dimensioned with the highest index instead of length ;)

1 minute ago, SoldierOfLight said:

You always have to pay attention to the pitch, the driver/hardware is allowed to add padding that you need to respect. Rather than using (y * width * 4), use (y * pitch).

Yes, I think this is an very important point which should be definitely documented somewhere. Of course, when generating the image data manually you can respect this.. but in my case I am getting a "ready-to-use" image buffer from a DirectShow filter graph.. so it just feels like wasting performance for nothing.. I actually made a work around by writing the data line-by-line and just offsetting after my line with the given padding.

This topic is closed to new replies.

Advertisement