• Advertisement
Sign in to follow this  

SlimDX and Texture.LockRectangle

This topic is 3831 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

First off, I'm not sure if this is the right place to post SlimDX questions, so my apologies if I'm posting in the wrong place. Coming down to my problem, I need to write values to a texture (that can be used as a RenderTarget). Here is the snippet of source I use to create and lock the texture, so I can write values into it.
_texture = new Texture(provider.Device, width, height, 1, Usage.RenderTarget, Format.A32B32G32R32F, Pool.Default);
LockedRect rect = _texture.LockRectangle(0, LockFlags.None);

The texture creates ok, but as soon as I call LockRectangle, I get an exception like so
TestCase 'Brahma.DirectX.Tests.SimpleQueries.IdentityDataTransform' 
failed: SlimDX.Direct3D9.InvalidCallException : Invalid call
   at SlimDX.Direct3D9.GraphicsException.CheckHResult(Int32 hr, String dataKey, Object dataValue)
   at SlimDX.Direct3D9.GraphicsException.CheckHResult(Int32 hr)
   at SlimDX.Direct3D9.Texture.LockRectangle(Int32 level, LockFlags flags)
   at Brahma.DirectX.DataParallelArray2D`1..ctor(GPUComputationProvider provider, Expression expression, Int32 width, Int32 height, ProvideValue values) in D:\Projects\Brahma\Source\Brahma.DirectX\DataParallelArray2D.cs:line 61
   at Brahma.DirectX.DataParallelArray2D`1..ctor(GPUComputationProvider provider, Int32 width, Int32 height, ProvideValue values) in D:\Projects\Brahma\Source\Brahma.DirectX\DataParallelArray2D.cs:line 49
   at Brahma.DirectX.Tests.SimpleQueries.IdentityDataTransform() in D:\Projects\Brahma\Source\Brahma.DirectX.Tests\SimpleQueries.cs:line 62	D:\Projects\Brahma\Source\Brahma.DirectX\DataParallelArray2D.cs	61	

What am I doing wrong? Also, once I get a valid LockedRect, can I simply write to it using
rect.Data.Write<float>(this[x, y]);
? Thanks in advance

Share this post


Link to post
Share on other sites
Advertisement
First thing is you can't lock a texture created with the Pool.Default flag, unless it uses the Usage.Dynamic flag.

From DXSDK..
Quote:

Using Dynamic Textures
To find out if the driver supports dynamic textures, check the D3DCAPS2_DYNAMICTEXTURES flag of the D3DCAPS9 structure.

Keep the following things in mind when working with dynamic textures.

They cannot be managed. For example, their pool cannot be D3DPOOL_MANAGED.
Dynamic textures can be locked, even if they are created in D3DPOOL_DEFAULT.
D3DLOCK_DISCARD is a valid lock flag for dynamic textures.
It is a good idea to create only one dynamic texture per format and possibly per size. Dynamic mipmaps, cubes, and volumes are not recommended because of the additional overhead in locking every level. For mipmaps, D3DLOCK_DISCARD is allowed only on the top level. All levels are discarded by locking just the top level. This behavior is the same for volumes and cubes. For cubes, the top level and face 0 are locked.

The following pseudocode shows an example of using a dynamic texture.

DrawProceduralTexture(pTex)
{
// pTex should not be very small because overhead of
// calling driver every D3DLOCK_DISCARD will not
// justify the performance gain. Experimentation is encouraged.
pTex->Lock(D3DLOCK_DISCARD);
<Overwrite *entire* texture>
pTex->Unlock();
pDev->SetTexture();
pDev->DrawPrimitive();
}

Share this post


Link to post
Share on other sites
Thanks, GrasshopperDotNet! That works. But only if I remove the "Usage.RenderTarget" flag. Unfortunately, I need this texture to also be usable as a RenderTarget. What can I do?

Thanks!

Share this post


Link to post
Share on other sites
Quote:
Original post by ananth__b
Thanks, GrasshopperDotNet! That works. But only if I remove the "Usage.RenderTarget" flag. Unfortunately, I need this texture to also be usable as a RenderTarget. What can I do?

- You can use UpdateSurface (or is it UpdateTexture?) which should succeed, though would require loading the entire surface.
- You can use LoadSurfaceFromSurface, but again, it loads the whole thing.
- You can use a dynamic texture to upload your data to, and then either StretchRect or simply render it onto the rendertarget you want.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement