static void GetTextureData(ID3D11Device* device, ID3D11ShaderResourceView* textureSRV, DXGI_FORMAT outFormat, TextureData<T>& texData) { static ComputeShaderPtr decodeTextureCS; static ComputeShaderPtr decodeTextureArrayCS; static const uint32 TGSize = 16; if(decodeTextureCS.Valid() == false) { CompileOptions opts; opts.Add("TGSize_", TGSize); const std::wstring shaderPath = SampleFrameworkDir() + L"Shaders\\DecodeTextureCS.hlsl"; decodeTextureCS = CompileCSFromFile(device, shaderPath.c_str(), "DecodeTextureCS", "cs_5_0", opts); decodeTextureArrayCS = CompileCSFromFile(device, shaderPath.c_str(), "DecodeTextureArrayCS", "cs_5_0", opts); } ID3D11Texture2DPtr texture; textureSRV->GetResource(reinterpret_cast<ID3D11Resource**>(&texture)); D3D11_TEXTURE2D_DESC texDesc; texture->GetDesc(&texDesc); D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; textureSRV->GetDesc(&srvDesc); ID3D11ShaderResourceViewPtr sourceSRV = textureSRV; uint32 arraySize = texDesc.ArraySize; if(srvDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURECUBE || srvDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURECUBEARRAY) { srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; srvDesc.Texture2DArray.ArraySize = arraySize; srvDesc.Texture2DArray.FirstArraySlice = 0; srvDesc.Texture2DArray.MostDetailedMip = 0; srvDesc.Texture2DArray.MipLevels = -1; DXCall(device->CreateShaderResourceView(texture, &srvDesc, &sourceSRV)); } D3D11_TEXTURE2D_DESC decodeTextureDesc; decodeTextureDesc.Width = texDesc.Width; decodeTextureDesc.Height = texDesc.Height; decodeTextureDesc.ArraySize = arraySize; decodeTextureDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; decodeTextureDesc.Format = outFormat; decodeTextureDesc.MipLevels = 1; decodeTextureDesc.MiscFlags = 0; decodeTextureDesc.SampleDesc.Count = 1; decodeTextureDesc.SampleDesc.Quality = 0; decodeTextureDesc.Usage = D3D11_USAGE_DEFAULT; decodeTextureDesc.CPUAccessFlags = 0; ID3D11Texture2DPtr decodeTexture; DXCall(device->CreateTexture2D(&decodeTextureDesc, nullptr, &decodeTexture)); ID3D11UnorderedAccessViewPtr decodeTextureUAV; DXCall(device->CreateUnorderedAccessView(decodeTexture, nullptr, &decodeTextureUAV)); ID3D11DeviceContextPtr context; device->GetImmediateContext(&context); SetCSInputs(context, sourceSRV); SetCSOutputs(context, decodeTextureUAV); SetCSShader(context, arraySize > 1 ? decodeTextureArrayCS : decodeTextureCS); context->Dispatch(DispatchSize(TGSize, texDesc.Width), DispatchSize(TGSize, texDesc.Height), arraySize); ClearCSInputs(context); ClearCSOutputs(context); StagingTexture2D stagingTexture; stagingTexture.Initialize(device, texDesc.Width, texDesc.Height, outFormat, 1, 1, 0, arraySize); context->CopyResource(stagingTexture.Texture, decodeTexture); texData.Init(texDesc.Width, texDesc.Height, arraySize); for(uint32 slice = 0; slice < arraySize; ++slice) { uint32 pitch = 0; const uint8* srcData = reinterpret_cast<const uint8*>(stagingTexture.Map(context, slice, pitch)); Assert_(pitch >= texDesc.Width * sizeof(T)); const uint32 sliceOffset = texDesc.Width * texDesc.Height * slice; for(uint32 y = 0; y < texDesc.Height; ++y) { const T* rowData = reinterpret_cast<const T*>(srcData); for(uint32 x = 0; x < texDesc.Width; ++x) texData.Texels[y * texDesc.Width + x + sliceOffset] = rowData[x]; srcData += pitch; } } }
void ClearCSOutputs(ID3D11DeviceContext* context) { SetCSOutputs(context, nullptr, nullptr, nullptr, nullptr); }