void MeshRenderer::OnResize(uint32 width, uint32 height) { depthReductionTargets.clear(); uint32 w = width; uint32 h = height; while(w > 1 || h > 1) { w = DispatchSize(ReductionTGSize, w); h = DispatchSize(ReductionTGSize, h); RenderTarget2D rt; rt.Initialize(device, w, h, DXGI_FORMAT_R16G16_UNORM, 1, 1, 0, false, true); depthReductionTargets.push_back(rt); } }
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; } } }
SH9Color ProjectCubemapToSH9Color(ID3D11DeviceContext* context, ID3D11ShaderResourceView* cubeMap) { ID3D11Texture2DPtr srcTexture; cubeMap->GetResource(reinterpret_cast<ID3D11Resource**>(&srcTexture)); D3D11_TEXTURE2D_DESC srcDesc; srcTexture->GetDesc(&srcDesc); ID3D11DevicePtr device; context->GetDevice(&device); ID3D11Texture2DPtr tempTexture; D3D11_TEXTURE2D_DESC tempDesc = srcDesc; tempDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; tempDesc.MipLevels = 1; tempDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; tempDesc.Usage = D3D11_USAGE_DEFAULT; DXCall(device->CreateTexture2D(&tempDesc, NULL, &tempTexture)); ID3D11UnorderedAccessViewPtr tempUAV; DXCall(device->CreateUnorderedAccessView(tempTexture, NULL, &tempUAV)); ID3D11ShaderResourceViewPtr tempSRV; D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = srcDesc.Format; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; srvDesc.Texture2DArray.MostDetailedMip = 0; srvDesc.Texture2DArray.MipLevels = srcDesc.MipLevels; srvDesc.Texture2DArray.FirstArraySlice = 0; srvDesc.Texture2DArray.ArraySize = 6; DXCall(device->CreateShaderResourceView(srcTexture, &srvDesc, &tempSRV)); static const UINT32 TGSize = 1024; static ID3D11ComputeShaderPtr decodeShader; if(decodeShader.GetInterfacePtr() == NULL) { CompileOptions opts; opts.Add("TGSize_", TGSize); decodeShader.Attach(CompileCSFromFile(device, L"SampleFramework11\\Shaders\\DecodeTextureCS.hlsl", "DecodeTextureCS", "cs_5_0", opts.Defines())); } ID3D11ShaderResourceView* srvs[1] = { tempSRV }; context->CSSetShaderResources(0, 1, srvs); ID3D11UnorderedAccessView* uavs[1] = { tempUAV }; context->CSSetUnorderedAccessViews(0, 1, uavs, NULL); context->CSSetShader(decodeShader, NULL, 0); context->Dispatch(DispatchSize(TGSize, srcDesc.Width), srcDesc.Height, 6); float red[9]; float green[9]; float blue[9]; DXCall(D3DX11SHProjectCubeMap(context, 3, tempTexture, red, green, blue)); SH9Color sh; for(UINT_PTR i = 0; i < 9; ++i) sh.c[i] = XMVectorSet(red[i], green[i], blue[i], 0.0f); return sh; }
void ConvertAndReadbackTexture(const Texture& texture, DXGI_FORMAT outputFormat, ReadbackBuffer& readbackBuffer) { Assert_(convertCmdList != nullptr); Assert_(texture.Valid()); Assert_(texture.Depth == 1); // Create a buffer for the CS to write flattened, converted texture data into FormattedBufferInit init; init.Format = outputFormat; init.NumElements = texture.Width * texture.Height * texture.ArraySize; init.CreateUAV = true; FormattedBuffer convertBuffer; convertBuffer.Initialize(init); convertBuffer.Transition(convertCmdList, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); // Run the conversion compute shader DX12::SetDescriptorHeaps(convertCmdList); convertCmdList->SetComputeRootSignature(convertRootSignature); convertCmdList->SetPipelineState(texture.ArraySize > 1 ? convertArrayPSO : convertPSO); D3D12_CPU_DESCRIPTOR_HANDLE descriptors[2] = { texture.SRV.CPUHandle, convertBuffer.UAV() }; BindShaderResources(convertCmdList, 0, ArraySize_(descriptors), descriptors, CmdListMode::Compute, ShaderResourceType::SRV_UAV_CBV); uint32 dispatchX = DispatchSize(convertTGSize, texture.Width); uint32 dispatchY = DispatchSize(convertTGSize, texture.Height); uint32 dispatchZ = texture.ArraySize; convertCmdList->Dispatch(dispatchX, dispatchY, dispatchZ); convertBuffer.Transition(convertCmdList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); // Execute the conversion command list and signal a fence DXCall(convertCmdList->Close()); ID3D12CommandList* cmdLists[1] = { convertCmdList }; convertCmdQueue->ExecuteCommandLists(1, cmdLists); convertFence.Signal(convertCmdQueue, 1); // Have the readback wait for conversion finish, and then have it copy the data to a readback buffer ID3D12CommandQueue* readbackQueue = UploadCmdQueue; readbackQueue->Wait(convertFence.D3DFence, 1); readbackBuffer.Shutdown(); readbackBuffer.Initialize(convertBuffer.InternalBuffer.Size); readbackCmdList->CopyResource(readbackBuffer.Resource, convertBuffer.InternalBuffer.Resource); // Execute the readback command list and signal a fence DXCall(readbackCmdList->Close()); cmdLists[0] = readbackCmdList; readbackQueue->ExecuteCommandLists(1, cmdLists); readbackFence.Signal(readbackQueue, 1); readbackFence.Wait(1); // Clean up convertFence.Clear(0); readbackFence.Clear(0); DXCall(convertCmdAllocator->Reset()); DXCall(convertCmdList->Reset(convertCmdAllocator, nullptr)); DXCall(readbackCmdAllocator->Reset()); DXCall(readbackCmdList->Reset(readbackCmdAllocator, nullptr)); convertBuffer.Shutdown(); }