读取纹理颜色数据中的一行而不是 Silk.Net 中的所有行

问题描述 投票:0回答:1

我正在测试从纹理读取数据。问题是我的最终数组的数据不完整。

我使用自己的类创建源纹理来简化代码(https://github.com/Kordi3112/BasicSilkDirect3D11Template/blob/main/Engine/Video/Texture.cs

 texture = new Texture();

 texture.Create(videoManager.Device, new Vector2i(3, 2), [
     new Color(1, 2, 3, 4), new Color(5, 6, 7, 8), new Color(9, 10, 11, 12), 
     new Color(13, 14, 15, 16), new Color(17, 18, 19, 20), new Color(21, 22, 23, 24)
     ]);

然后我创建分段纹理:

var testTexture = Texture.CreateStagged(videoManager.Device, texture.Size);

|纹理创建代码|:


        public unsafe static ComPtr<ID3D11Texture2D> CreateStagged(ComPtr<ID3D11Device> device, Vector2i size)
        {
            ComPtr<ID3D11Texture2D> texture = default;

            var texture2DDesc = new Texture2DDesc()
            {
                Width = (uint)size.X,
                Height = (uint)size.Y,
                ArraySize = 1,
                BindFlags = (uint)BindFlag.None,
                Usage = Usage.Staging,
                CPUAccessFlags = (uint)CpuAccessFlag.Read,
                Format = Format.FormatR8G8B8A8Unorm,
                MipLevels = 1,
                MiscFlags = (uint)ResourceMiscFlag.None,
                SampleDesc = new SampleDesc(1, 0),
            };

            CrashHandler.CheckForError(device.CreateTexture2D(texture2DDesc, Unsafe.NullRef<SubresourceData>(), ref texture), "Stagged Texture creation error");

            return texture;
        }

然后我将“texture”复制到“testTexture”,映射资源,并将映射的源数据复制到字节数组:

videoManager.DeviceContext.CopyResource(testTexture, texture.texture);

var mappedSubresource = new MappedSubresource();

mappedSubresource.RowPitch = (uint)texture.Size.X * 4; // im not sure if its neccesary

videoManager.DeviceContext.Map(testTexture, 0, Map.Read, 0, ref mappedSubresource);

byte[] data = new byte[texture.Size.X * texture.Size.Y * 4];

fixed (byte* pData = data)
{

    System.Buffer.MemoryCopy(mappedSubresource.PData, pData , data.Length, data.Length);
           
}

videoManager.DeviceContext.Unmap(testTexture, 0);

当我尝试查看数据数组的内容时,我看到的数字是 0-12 而不是 0-24:

            for (int i = 0; i < data.Length; i++)
            {
                Console.WriteLine((int)data[i]);
            }

image1

我确信我的源纹理是正确的,它甚至显示在屏幕上: image2

当我将纹理大小更改为 [2,3] 时,它将显示 0-8 的数据,所以我认为以下两件事之一可能是错误的:

  1. 映射资源仅将一维复制到 MappedSubresource 数据
  2. 我在将数据从mappedSubresource.PData复制到pData时犯了错误
buffer directx-11 .net-8.0 silk
1个回答
0
投票

虽然 Silk 将其定义为

ref
,但
mappedSubresource
实际上是一个“out”参数,正如您在相应的 D3D11 ID3D11DeviceContext::Map 方法 定义中看到的那样

HRESULT Map(
  [in]            ID3D11Resource           *pResource,
  [in]            UINT                     Subresource,
  [in]            D3D11_MAP                MapType,
  [in]            UINT                     MapFlags,
  [out, optional] D3D11_MAPPED_SUBRESOURCE *pMappedResource
);

(它是丝绸中的

ref
,允许您传递空指针,因为它也标记为
optional

当您映射资源时,您必须使用GPU上定义的行间距,它可能与您在CPU中使用的行间距不同,因此要将其从GPU复制回来,您可以这样做:

var mappedSubresource = new MappedSubresource();
videoManager.DeviceContext.Map(testTexture, 0, Map.Read, 0, ref mappedSubresource);

var dataRowSize = 4 * texture.Size.X;
byte[] data = new byte[dataRowSize * texture.Size.Y];

// we must copy row by row
fixed (byte* pData = data)
{
    for (var i = 0; i < texture.Size.Y; i++)
    {
        System.Buffer.MemoryCopy((byte*)mappedSubresource.PData + i * mappedSubresource.RowPitch, pData + i * dataRowSize, dataRowSize, dataRowSize);
    }
}

videoManager.DeviceContext.Unmap(testTexture, 0);
© www.soinside.com 2019 - 2024. All rights reserved.