title: DirectX: rendering to Texture2DArray, and Loading from it in compute shader
body: <p>I want to render several images to a Texture2DArray, and access the resulting images in a compute shader. However, the <code>Load</code> method in the compute shader returns <code>[0.0, 0.0, 0.0, 0.0]</code> rather than the image data.</p>
  
  <p>Currently, I am doing the following:</p>
  
  <h2>1. Setup</h2>
  
  <p>I first prepare a set of "render slots" by creating a <strong>Texture2DArray</strong> using <code>CreateTexture2D</code> with <code>texArrayDesc.ArraySize = numRenderSlots</code>:</p>
  
  <pre><code>texArrayDesc.Width = width;
  texArrayDesc.Height = height;
  texArrayDesc.MipLevels = 1;
  texArrayDesc.ArraySize = numRenderSlots;
  texArrayDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  texArrayDesc.Usage = D3D11_USAGE_DEFAULT;
  texArrayDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
  texArrayDesc.CPUAccessFlags = 0;
  m_device-&gt;CreateTexture2D(&amp;texArrayDesc, NULL, &amp;m_renderSlotsTexArray);
  </code></pre>
  
  <p>I then create a <strong>ShaderResourceView</strong> for this texture array so I can access it from a compute shader:</p>
  
  <pre><code>srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
  srvDesc.Texture2DArray.FirstArraySlice = 0;
  srvDesc.Texture2DArray.MostDetailedMip = 0;
  srvDesc.Texture2DArray.MipLevels = 1;
  srvDesc.Texture2DArray.ArraySize = numRenderSlots;
  m_device-&gt;CreateShaderResourceView(m_renderSlotsTexArray, &amp;srvDesc, &amp;m_renderSlotsSrv);
  </code></pre>
  
  <p>For each slice in the Texture2DArray, I create a <strong>RenderTargetView</strong> so I can render to it.</p>
  
  <pre><code>rtvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
  rtvDesc.Texture2DArray.MipSlice = 0;
  rtvDesc.Texture2DArray.ArraySize = 1;
  
  for (int i = 0; i &lt; numRenderSlots; i++) {
  
      // Change slot RTV desc to choose correct slice from array
      rtvDesc.Texture2DArray.FirstArraySlice = D3D11CalcSubresource(0, i, 1);
  
      // Create the RTV for the slot in m_renderSlotsTexArray
      ID3D11RenderTargetView* slotRtv;
      m_device-&gt;CreateRenderTargetView(m_renderSlotsTexArray, &amp;rtvDesc, &amp;slotRtv);
  
      // Add the RenderTargetView to a list
      m_slotRtvs.push_back(slotRtv);
  }
  </code></pre>
  
  <h2>2. Usage</h2>
  
  <p>I then render a set of different images by setting the associated render slot as a render target. Note that the background color is not <code>[0,0,0,0]</code>. Code simplified:</p>
  
  <pre><code>for (int i = 0; i &lt; numRenderSlots; i++) {
      setupScene(i);
      deviceContext-&gt;OMSetRenderTargets(1, &amp;m_slotRtvs[i], depthStencilView);
      deviceContext-&gt;ClearRenderTargetView(m_slotRtvs[slotIdx], {0.2,0.2,0.2,0.0});
      deviceContext-&gt;ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
      render();
  }
  </code></pre>
  
  <p>I then setup a compute shader with a StructuredBuffer for shader output with associated UnorderedAccessView. I pass this into the shader, along with the SRV of the render slots Texture2DArray. I finally dispatch the shader, to operate over the image in 32x32 sized chunks.</p>
  
  <pre><code>deviceContext-&gt;CSSetShader(m_computeShader, NULL, 0);
  deviceContext-&gt;CSSetShaderResources(0, 1, &amp;renderSlotsSrv);
  deviceContext-&gt;CSSetUnorderedAccessViews(0, 1, &amp;outputUav, nullptr);
  deviceContext-&gt;Dispatch(img_width / 32, img_height / 32, numParams);
  </code></pre>
  
  <p>I then try to access the rendered image data in the compute shader. <strong>However,  <code>imgs.Load</code> always seems to return <code>[0.0, 0.0, 0.0, 0.0]</code>.</strong></p>
  
  <pre><code>Texture2DArray&lt;float4&gt; imgs : register(t0);
  RWStructuredBuffer&lt;float3&gt; output : register(u0);
  
  [numthreads(32,32,1)]
  void ComputeShaderMain(
      uint3 gID : SV_GroupID,
      uint3 dtID : SV_DispatchThreadID,
      uint3 tID : SV_GroupThreadID, 
      uint gi : SV_GroupIndex )
  {  
      int idx_x = (gID.x * 32 + tID.x);
      int idx_y = (gID.y * 32 + tID.y);
      float4 px = imgs.Load(int4(idx_x,idx_y,gID.z,0));
      ...
      output[outIdx] = float3(px.x, px.y, px.z);
  }
  </code></pre>
  
  <p>I know the render slots are working, as I can access each render slot by doing CopySubresourceRegion into a staging texture to view the byte data. However, this <code>GPU-&gt;CPU</code> transfer is what I'm trying to avoid.</p>
  
  <p>Also, I know the compute shader output is working as I can map the output buffer and inspect some basic test data.</p>
  
  <hr>
  
  <p>What am I doing wrong? Thanks in advance.</p>