bool Texture::Create(UINT w, UINT h, const void* bits) { bool ret = false; mWidth = w; mHeight = h; ID3D11Device* device = gCore.GetDevice(); CHECK(device); D3D11_TEXTURE2D_DESC textureDesc; ZeroMemory(&textureDesc, sizeof(textureDesc)); textureDesc.Width = w; textureDesc.Height = h; textureDesc.MipLevels = 1; textureDesc.ArraySize = 1; textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; textureDesc.SampleDesc.Count = 1; textureDesc.Usage = D3D11_USAGE_DEFAULT; textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; textureDesc.CPUAccessFlags = 0; textureDesc.MiscFlags = 0; if (bits) { D3D11_SUBRESOURCE_DATA subres; subres.pSysMem = bits; subres.SysMemPitch = w * 4; subres.SysMemSlicePitch = 0; // Not needed since this is a 2d texture CHECK(SUCCEEDED(device->CreateTexture2D(&textureDesc, &subres, &mPtr))); } else { CHECK(SUCCEEDED(device->CreateTexture2D(&textureDesc, nullptr, &mPtr))); } D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc; shaderResourceViewDesc.Format = textureDesc.Format; shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; shaderResourceViewDesc.Texture2D.MostDetailedMip = 0; shaderResourceViewDesc.Texture2D.MipLevels = 1; CHECK(SUCCEEDED(device->CreateShaderResourceView(mPtr, &shaderResourceViewDesc, &mSRV))); D3D11_SAMPLER_DESC samplerDesc; ZeroMemory(&samplerDesc, sizeof(samplerDesc)); samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; samplerDesc.MinLOD = 0; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; CHECK(SUCCEEDED(device->CreateSamplerState(&samplerDesc, &mSampler))); ret = true; Exit0: return ret; }
void initAll(ID3D11Device& device, ID3D11DeviceContext& context, ShaderResources& shaderResources) { assert(shaderResources.mDiffuseMapSRV == nullptr); assert(shaderResources.mCSResultsSRV == nullptr); assert(shaderResources.mCSResultsUAV == nullptr); ID3D11Resource* texture = nullptr; // // Diffuse Map // HRESULT result = CreateDDSTextureFromFile(&device, L"Resources/Textures/brick.dds", &texture, &shaderResources.mDiffuseMapSRV); DxErrorChecker(result); texture->Release(); // // Create compute shader texture // D3D11_TEXTURE2D_DESC groupResultsTexDesc; groupResultsTexDesc.Width = 512; groupResultsTexDesc.Height = 512; groupResultsTexDesc.MipLevels = 1; groupResultsTexDesc.ArraySize = 1; groupResultsTexDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; groupResultsTexDesc.SampleDesc.Count = 1; groupResultsTexDesc.SampleDesc.Quality = 0; groupResultsTexDesc.Usage = D3D11_USAGE_DEFAULT; groupResultsTexDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS; groupResultsTexDesc.CPUAccessFlags = 0; groupResultsTexDesc.MiscFlags = 0; ID3D11Texture2D* groupResultsTex = nullptr; assert(Globals::gDirect3DData.mDevice); result = device.CreateTexture2D(&groupResultsTexDesc, 0, &groupResultsTex); DxErrorChecker(result); D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = 1; result = device.CreateTexture2D(&groupResultsTexDesc, 0, &groupResultsTex); result = device.CreateShaderResourceView(groupResultsTex, &srvDesc, &shaderResources.mCSResultsSRV); D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; uavDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; uavDesc.Texture2D.MipSlice = 0; result = device.CreateUnorderedAccessView(groupResultsTex, &uavDesc, &shaderResources.mCSResultsUAV); // Views save a reference to the texture so we can release our reference. groupResultsTex->Release(); }
void D11State::newTexture(unsigned int w, unsigned int h) { HRESULT hr; ods("D3D11: newTex %d %d", w, h); if (pTexture) { pTexture->Release(); pTexture = NULL; } if (pSRView) { pSRView->Release(); pSRView = NULL; } D3D11_TEXTURE2D_DESC desc; ZeroMemory(&desc, sizeof(desc)); desc.Width = w; desc.Height = h; desc.MipLevels = desc.ArraySize = 1; desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.SampleDesc.Count = 1; desc.Usage = D3D11_USAGE_DYNAMIC; desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; hr = pDevice->CreateTexture2D(&desc, NULL, &pTexture); if (FAILED(hr)) { pTexture = NULL; ods("D3D11: Failed to create texture."); return; } D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; ZeroMemory(&srvDesc, sizeof(srvDesc)); srvDesc.Format = desc.Format; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = desc.MipLevels; hr = pDevice->CreateShaderResourceView(pTexture, &srvDesc, &pSRView); if (FAILED(hr)) { pSRView = NULL; pTexture->Release(); pTexture = NULL; ods("D3D11: Failed to create resource view."); return; } }
ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat) { BufferStorage *storage = getBufferStorage(BUFFER_USAGE_PIXEL_UNPACK); if (!storage) { // Storage out-of-memory return NULL; } ASSERT(HAS_DYNAMIC_TYPE(NativeStorage*, storage)); ID3D11Buffer *buffer = static_cast<NativeStorage*>(storage)->getNativeStorage(); auto bufferSRVIt = mBufferResourceViews.find(srvFormat); if (bufferSRVIt != mBufferResourceViews.end()) { if (bufferSRVIt->second.first == buffer) { return bufferSRVIt->second.second; } else { // The underlying buffer has changed since the SRV was created: recreate the SRV. SafeRelease(bufferSRVIt->second.second); } } ID3D11Device *device = mRenderer->getDevice(); ID3D11ShaderResourceView *bufferSRV = NULL; const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(srvFormat); D3D11_SHADER_RESOURCE_VIEW_DESC bufferSRVDesc; bufferSRVDesc.Buffer.ElementOffset = 0; bufferSRVDesc.Buffer.ElementWidth = mSize / dxgiFormatInfo.pixelBytes; bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; bufferSRVDesc.Format = srvFormat; HRESULT result = device->CreateShaderResourceView(buffer, &bufferSRVDesc, &bufferSRV); UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); mBufferResourceViews[srvFormat] = BufferSRVPair(buffer, bufferSRV); return bufferSRV; }
template <class T> void initialize(std::vector<T> const & src, DXGI_FORMAT format, ID3D11DeviceContext *deviceContext) { size_t size = src.size()*sizeof(T); if (size==0) { buffer = 0; srv = 0; return; } ID3D11Device *device = 0; deviceContext->GetDevice(&device); assert(device); D3D11_BUFFER_DESC bd; bd.ByteWidth = (unsigned int)size; bd.Usage = D3D11_USAGE_IMMUTABLE; bd.BindFlags = D3D11_BIND_SHADER_RESOURCE; bd.CPUAccessFlags = 0; bd.MiscFlags = 0; bd.StructureByteStride = 0; D3D11_SUBRESOURCE_DATA initData; initData.pSysMem = &src.at(0); HRESULT hr = device->CreateBuffer(&bd, &initData, &buffer); if (FAILED(hr)) { Far::Error(Far::FAR_RUNTIME_ERROR, "Error creating compute table buffer\n"); return; } D3D11_SHADER_RESOURCE_VIEW_DESC srvd; ZeroMemory(&srvd, sizeof(srvd)); srvd.Format = format; srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; srvd.Buffer.FirstElement = 0; srvd.Buffer.NumElements = (unsigned int)src.size(); hr = device->CreateShaderResourceView(buffer, &srvd, &srv); if (FAILED(hr)) { Far::Error(Far::FAR_RUNTIME_ERROR, "Error creating compute table shader resource view\n"); return; } }
bool TextureCube<RendererTypeDX11>::LoadTextureData(std::vector<const BYTE *> &buffers) { TEXTURE_DESC &desc = this->GetDesc(); const Size &size = this->GetSize(); mTextureParams.Width = size.width; mTextureParams.Height = size.height; int faceSize = size.width * size.height * 4; D3D11_SUBRESOURCE_DATA textureData[6]; for(int i = 0; i < 6; i++) { textureData[i].pSysMem = &buffers[0][faceSize * i]; textureData[i].SysMemPitch = size.width * TextureFormatNumComponents[desc.Format]; textureData[i].SysMemSlicePitch = faceSize; } ID3D11Device *device = this->GetDevice()->GetD3D11Device(); HRESULT hr = device->CreateTexture2D(&mTextureParams, textureData, &mDXTexture); if(hr != S_OK) { // TODO: Error handling throw "Error Creating D3D11 Texture!"; } ID3D11ShaderResourceView *resourceView; D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc; memset(&resourceViewDesc, 0, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC)); resourceViewDesc.Format = mTextureParams.Format; resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; resourceViewDesc.TextureCube.MipLevels = 1; resourceViewDesc.TextureCube.MostDetailedMip = 0; hr = device->CreateShaderResourceView(mDXTexture, &resourceViewDesc, &resourceView); if(hr != S_OK) { // TODO: Error handling throw "Error Creating D3D11 Texture Resource View!"; } this->SetTextureResource(resourceView); }
void CCoherentViewListener::CreateShaderResourceViewForDX11Texture() { if ( gEnv->pRenderer->GetRenderType() != eRT_DX11 || m_pTexture == NULL ) { return; } ID3D11Texture2D* pTexture = static_cast<ID3D11Texture2D*>( m_pTexture ); ID3D11Device* pDevice = static_cast<ID3D11Device*>( gD3DDevice ); ID3D11DeviceContext* pContext = NULL; pDevice->GetImmediateContext( &pContext ); D3D11_TEXTURE2D_DESC texDesc; pTexture->GetDesc( &texDesc ); D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = texDesc.Format; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MipLevels = texDesc.MipLevels; srvDesc.Texture2D.MostDetailedMip = 0; pDevice->CreateShaderResourceView( pTexture, &srvDesc, &m_pTextureSRV ); }
void MultiRenderTarget::Initialise( u32 count, u32 width, u32 height ) { // Store the width and height of the render texture. mWidth = width; mHeight = height; // Initialize the render target texture description. D3D11_TEXTURE2D_DESC textureDesc; ZeroMemory( &textureDesc, sizeof( textureDesc ) ); // Setup the render target texture description. textureDesc.Width = width; textureDesc.Height = height; textureDesc.MipLevels = 1; textureDesc.ArraySize = 1; textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; textureDesc.SampleDesc.Count = 1; textureDesc.Usage = D3D11_USAGE_DEFAULT; textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; textureDesc.CPUAccessFlags = 0; textureDesc.MiscFlags = 0; // Create the render target textures. ID3D11Device * device = GRAPHICS.GetPipeline()->GetDevice(); mRenderTargetTextures.resize( count, nullptr ); for( u32 i = 0; i < count; ++i ) { HRESULT result = device->CreateTexture2D( &textureDesc, nullptr, mRenderTargetTextures.data() + i ); if( FAILED( result ) ) { return; } } // Setup the description of the render target view. D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc; renderTargetViewDesc.Format = textureDesc.Format; renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; renderTargetViewDesc.Texture2D.MipSlice = 0; // Create the render target views. mRenderTargetViews.resize( count, nullptr ); for( u32 i = 0; i < count; ++i ) { HRESULT result = device->CreateRenderTargetView( mRenderTargetTextures[i], &renderTargetViewDesc, mRenderTargetViews.data() + i ); if( FAILED( result ) ) { return; } } // Setup the description of the shader resource view. D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc; shaderResourceViewDesc.Format = textureDesc.Format; shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; shaderResourceViewDesc.Texture2D.MostDetailedMip = 0; shaderResourceViewDesc.Texture2D.MipLevels = 1; // Create the shader resource views. mShaderResourceViews.resize( count, nullptr ); for( u32 i = 0; i < count; ++i ) { HRESULT result = device->CreateShaderResourceView( mRenderTargetTextures[i], &shaderResourceViewDesc, mShaderResourceViews.data() + i ); if( FAILED( result ) ) { return; } } // Initialize the description of the depth buffer. D3D11_TEXTURE2D_DESC depthBufferDesc; ZeroMemory( &depthBufferDesc, sizeof( depthBufferDesc ) ); // Set up the description of the depth buffer. depthBufferDesc.Width = width; depthBufferDesc.Height = height; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; // Create the texture for the depth buffer using the filled out description. HRESULT result = device->CreateTexture2D( &depthBufferDesc, NULL, &mDepthStencilBuffer ); if( FAILED( result ) ) { return; } // Initailze the depth stencil view description. D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; ZeroMemory( &depthStencilViewDesc, sizeof( depthStencilViewDesc ) ); // Set up the depth stencil view description. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; // Create the depth stencil view. result = device->CreateDepthStencilView( mDepthStencilBuffer, &depthStencilViewDesc, &mDepthStencilView ); if( FAILED( result ) ) { return; } // Setup the viewport for rendering. mViewport.Width = static_cast<float>( width ); mViewport.Height = static_cast<float>( height ); mViewport.MinDepth = 0.0f; mViewport.MaxDepth = 1.0f; mViewport.TopLeftX = 0.0f; mViewport.TopLeftY = 0.0f; }
int _tmain(int /*argc*/, _TCHAR* /*argv[]*/) { // GROUP_SIZE_X defined in kernel.hlsl must match the // groupSize declared here. size_t const groupSize = 512; size_t const numGroups = 16; size_t const dimension = numGroups*groupSize; // Create a D3D11 device and immediate context. // TODO: The code below uses the default video adapter, with the // default set of feature levels. Please see the MSDN docs if // you wish to control which adapter and feature level are used. D3D_FEATURE_LEVEL featureLevel; ID3D11Device* device = nullptr; ID3D11DeviceContext* context = nullptr; HRESULT hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, 0, D3D11_SDK_VERSION, &device, &featureLevel, &context); if (FAILED(hr)) { printf("D3D11CreateDevice failed with return code %x\n", hr); return hr; } // Create system memory and fill it with our initial data. Note that // these data structures aren't really necessary , it's just a demonstration // of how you can take existing data structures you might have and copy // their data to/from GPU computations. std::vector<float> x(dimension); std::vector<float> y(dimension); std::vector<float> z(dimension); float const a = 2.0f; for (size_t i = 0; i < dimension; ++ i) { x[i] = static_cast<float>(i); y[i] = 100 - static_cast<float>(i); } // Create structured buffers for the "x" and "y" vectors. D3D11_BUFFER_DESC inputBufferDesc; inputBufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; // The buffers are read-only by the GPU, writeable by the CPU. // TODO: If you will never again upate the data in a GPU buffer, // you might want to look at using a D3D11_SUBRESOURCE_DATA here to // provide the initialization data instead of doing the mapping // and copying that happens below. inputBufferDesc.Usage = D3D11_USAGE_DYNAMIC; inputBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; inputBufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; inputBufferDesc.StructureByteStride = sizeof(float); inputBufferDesc.ByteWidth = sizeof(float) * dimension; ID3D11Buffer* xBuffer = nullptr; hr = device->CreateBuffer(&inputBufferDesc, NULL, &xBuffer); if (FAILED(hr)) { printf("CreateBuffer failed for x buffer with return code %x\n", hr); return hr; } // We can re-use inputBufferDesc here because the layout and usage of the x // and y buffers is exactly the same. ID3D11Buffer* yBuffer = nullptr; hr = device->CreateBuffer(&inputBufferDesc, NULL, &yBuffer); if (FAILED(hr)) { printf("CreateBuffer failed for x buffer with return code %x\n", hr); return hr; } // Create shader resource views for the "x" and "y" buffers. // TODO: You can optionally provide a D3D11_SHADER_RESOURCE_VIEW_DESC // as the second parameter if you need to use only part of the buffer // inside the compute shader. ID3D11ShaderResourceView* xSRV = nullptr; hr = device->CreateShaderResourceView(xBuffer, NULL, &xSRV); if (FAILED(hr)) { printf("CreateShaderResourceView failed for x buffer with return code %x\n", hr); return hr; } ID3D11ShaderResourceView* ySRV = nullptr; hr = device->CreateShaderResourceView(yBuffer, NULL, &ySRV); if (FAILED(hr)) { printf("CreateShaderResourceView failed for y buffer with return code %x\n", hr); return hr; } // Create a structured buffer for the "z" vector. This buffer needs to be // writeable by the GPU, so we can't create it with CPU read/write access. D3D11_BUFFER_DESC outputBufferDesc; outputBufferDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE; outputBufferDesc.Usage = D3D11_USAGE_DEFAULT; outputBufferDesc.CPUAccessFlags = 0; outputBufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; outputBufferDesc.StructureByteStride = sizeof(float); outputBufferDesc.ByteWidth = sizeof(float) * dimension; ID3D11Buffer* zBuffer = nullptr; hr = device->CreateBuffer(&outputBufferDesc, NULL, &zBuffer); if (FAILED(hr)) { printf("CreateBuffer failed for z buffer with return code %x\n", hr); return hr; } // Create an unordered access view for the "z" vector. D3D11_UNORDERED_ACCESS_VIEW_DESC outputUAVDesc; outputUAVDesc.Buffer.FirstElement = 0; outputUAVDesc.Buffer.Flags = 0; outputUAVDesc.Buffer.NumElements = dimension; outputUAVDesc.Format = DXGI_FORMAT_UNKNOWN; outputUAVDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; ID3D11UnorderedAccessView* zBufferUAV; hr = device->CreateUnorderedAccessView(zBuffer, &outputUAVDesc, &zBufferUAV); if (FAILED(hr)) { printf("CreateUnorderedAccessView failed for z buffer with return code %x\n", hr); return hr; } // Create a staging buffer, which will be used to copy back from zBuffer. D3D11_BUFFER_DESC stagingBufferDesc; stagingBufferDesc.BindFlags = 0; stagingBufferDesc.Usage = D3D11_USAGE_STAGING; stagingBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; stagingBufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; stagingBufferDesc.StructureByteStride = sizeof(float); stagingBufferDesc.ByteWidth = sizeof(float) * dimension; ID3D11Buffer* stagingBuffer; hr = device->CreateBuffer(&stagingBufferDesc, NULL, &stagingBuffer); if (FAILED(hr)) { printf("CreateBuffer failed for staging buffer with return code %x\n", hr); return hr; } // Create a constant buffer (this buffer is used to pass the constant // value 'a' to the kernel as cbuffer Constants). D3D11_BUFFER_DESC cbDesc; cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; cbDesc.Usage = D3D11_USAGE_DYNAMIC; cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; cbDesc.MiscFlags = 0; // Even though the constant buffer only has one float, DX expects // ByteWidth to be a multiple of 4 floats (i.e., one 128-bit register). cbDesc.ByteWidth = sizeof(float)*4; ID3D11Buffer* constantBuffer = nullptr; hr = device->CreateBuffer( &cbDesc, NULL, &constantBuffer); if (FAILED(hr)) { printf("CreateBuffer failed for constant buffer with return code %x\n", hr); return hr; } // Map the constant buffer and set the constant value 'a'. D3D11_MAPPED_SUBRESOURCE mappedResource; context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); float* constants = reinterpret_cast<float*>(mappedResource.pData); constants[0] = a; constants = nullptr; context->Unmap(constantBuffer, 0); // Map the x buffer and copy our data into it. context->Map(xBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); float* xvalues = reinterpret_cast<float*>(mappedResource.pData); memcpy(xvalues, &x[0], sizeof(float)*x.size()); xvalues = nullptr; context->Unmap(xBuffer, 0); // Map the y buffer and copy our data into it. context->Map(yBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); float* yvalues = reinterpret_cast<float*>(mappedResource.pData); memcpy(yvalues, &y[0], sizeof(float)*y.size()); yvalues = nullptr; context->Unmap(yBuffer, 0); // Compile the compute shader into a blob. ID3DBlob* errorBlob = nullptr; ID3DBlob* shaderBlob = nullptr; hr = D3DX11CompileFromFile(L"kernel.hlsl", NULL, NULL, "saxpy", "cs_4_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL, &shaderBlob, &errorBlob, NULL); if (FAILED(hr)) { // Print out the error message if there is one. if (errorBlob) { char const* message = (char*)errorBlob->GetBufferPointer(); printf("kernel.hlsl failed to compile; error message:\n"); printf("%s\n", message); errorBlob->Release(); } return hr; } // Create a shader object from the compiled blob. ID3D11ComputeShader* computeShader; hr = device->CreateComputeShader(shaderBlob->GetBufferPointer(), shaderBlob->GetBufferSize(), NULL, &computeShader); if (FAILED(hr)) { printf("CreateComputeShader failed with return code %x\n", hr); return hr; } // Make the shader active. context->CSSetShader(computeShader, NULL, 0); // Attach the z buffer to the output via its unordered access view. UINT initCounts = 0xFFFFFFFF; context->CSSetUnorderedAccessViews(0, 1, &zBufferUAV, &initCounts); // Attach the input buffers via their shader resource views. context->CSSetShaderResources(0, 1, &xSRV); context->CSSetShaderResources(1, 1, &ySRV); // Attach the constant buffer context->CSSetConstantBuffers(0, 1, &constantBuffer); // Execute the shader, in 'numGroups' groups of 'groupSize' threads each. context->Dispatch(numGroups, 1, 1); // Copy the z buffer to the staging buffer so that we can // retrieve the data for accesss by the CPU. context->CopyResource(stagingBuffer, zBuffer); // Map the staging buffer for reading. context->Map(stagingBuffer, 0, D3D11_MAP_READ, 0, &mappedResource); float* zData = reinterpret_cast<float*>(mappedResource.pData); memcpy(&z[0], zData, sizeof(float)*z.size()); zData = nullptr; context->Unmap(stagingBuffer, 0); // Now compare the GPU results against expected values. bool resultOK = true; for (size_t i = 0; i < x.size(); ++ i) { // NOTE: This comparison assumes the GPU produces *exactly* the // same result as the CPU. In general, this will not be the case // with floating-point calculations. float const expected = a*x[i] + y[i]; if (z[i] != expected) { printf("Unexpected result at position %lu: expected %.7e, got %.7e\n", i, expected, z[i]); resultOK = false; } } if (!resultOK) { printf("GPU results differed from the CPU results.\n"); OutputDebugStringA("GPU results differed from the CPU results.\n"); return 1; } printf("GPU output matched the CPU results.\n"); OutputDebugStringA("GPU output matched the CPU results.\n"); // Disconnect everything from the pipeline. ID3D11UnorderedAccessView* nullUAV = nullptr; context->CSSetUnorderedAccessViews( 0, 1, &nullUAV, &initCounts); ID3D11ShaderResourceView* nullSRV = nullptr; context->CSSetShaderResources(0, 1, &nullSRV); context->CSSetShaderResources(1, 1, &nullSRV); ID3D11Buffer* nullBuffer = nullptr; context->CSSetConstantBuffers(0, 1, &nullBuffer); // Release resources. Again, note that none of the error checks above // release resources that have been allocated up to this point, so the // sample doesn't clean up after itself correctly unless everything succeeds. computeShader->Release(); shaderBlob->Release(); constantBuffer->Release(); stagingBuffer->Release(); zBufferUAV->Release(); zBuffer->Release(); xSRV->Release(); xBuffer->Release(); ySRV->Release(); yBuffer->Release(); context->Release(); device->Release(); return 0; }
EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHeight) { ID3D11Device *device = mRenderer->getDevice(); ASSERT(device != NULL); // D3D11 does not allow zero size textures ASSERT(backbufferWidth >= 1); ASSERT(backbufferHeight >= 1); // Preserve the render target content ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture; if (previousOffscreenTexture) { previousOffscreenTexture->AddRef(); } const int previousWidth = mWidth; const int previousHeight = mHeight; releaseOffscreenTexture(); // If the app passed in a share handle, open the resource // See EGL_ANGLE_d3d_share_handle_client_buffer if (mAppCreatedShareHandle) { ID3D11Resource *tempResource11; HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource), (void**)&tempResource11); if (FAILED(result)) { ERR("Failed to open the swap chain pbuffer share handle: %08lX", result); release(); return EGL_BAD_PARAMETER; } result = tempResource11->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&mOffscreenTexture); tempResource11->Release(); if (FAILED(result)) { ERR("Failed to query texture2d interface in pbuffer share handle: %08lX", result); release(); return EGL_BAD_PARAMETER; } // Validate offscreen texture parameters D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; mOffscreenTexture->GetDesc(&offscreenTextureDesc); if (offscreenTextureDesc.Width != (UINT)backbufferWidth || offscreenTextureDesc.Height != (UINT)backbufferHeight || offscreenTextureDesc.Format != gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat) || offscreenTextureDesc.MipLevels != 1 || offscreenTextureDesc.ArraySize != 1) { ERR("Invalid texture parameters in the shared offscreen texture pbuffer"); release(); return EGL_BAD_PARAMETER; } } else { const bool useSharedResource = !mWindow && mRenderer->getShareHandleSupport(); D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; offscreenTextureDesc.Width = backbufferWidth; offscreenTextureDesc.Height = backbufferHeight; offscreenTextureDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat); offscreenTextureDesc.MipLevels = 1; offscreenTextureDesc.ArraySize = 1; offscreenTextureDesc.SampleDesc.Count = 1; offscreenTextureDesc.SampleDesc.Quality = 0; offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT; offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; offscreenTextureDesc.CPUAccessFlags = 0; offscreenTextureDesc.MiscFlags = useSharedResource ? D3D11_RESOURCE_MISC_SHARED : 0; HRESULT result = device->CreateTexture2D(&offscreenTextureDesc, NULL, &mOffscreenTexture); if (FAILED(result)) { ERR("Could not create offscreen texture: %08lX", result); release(); if (d3d11::isDeviceLostError(result)) { return EGL_CONTEXT_LOST; } else { return EGL_BAD_ALLOC; } } d3d11::SetDebugName(mOffscreenTexture, "Offscreen texture"); // EGL_ANGLE_surface_d3d_texture_2d_share_handle requires that we store a share handle for the client if (useSharedResource) { IDXGIResource *offscreenTextureResource = NULL; result = mOffscreenTexture->QueryInterface(__uuidof(IDXGIResource), (void**)&offscreenTextureResource); // Fall back to no share handle on failure if (FAILED(result)) { ERR("Could not query offscreen texture resource: %08lX", result); } else { result = offscreenTextureResource->GetSharedHandle(&mShareHandle); offscreenTextureResource->Release(); if (FAILED(result)) { mShareHandle = NULL; ERR("Could not get offscreen texture shared handle: %08lX", result); } } } } HRESULT result = device->CreateRenderTargetView(mOffscreenTexture, NULL, &mOffscreenRTView); ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mOffscreenRTView, "Offscreen render target"); result = device->CreateShaderResourceView(mOffscreenTexture, NULL, &mOffscreenSRView); ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mOffscreenSRView, "Offscreen shader resource"); if (mDepthBufferFormat != GL_NONE) { D3D11_TEXTURE2D_DESC depthStencilDesc = {0}; depthStencilDesc.Width = backbufferWidth; depthStencilDesc.Height = backbufferHeight; depthStencilDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mDepthBufferFormat); depthStencilDesc.MipLevels = 1; depthStencilDesc.ArraySize = 1; depthStencilDesc.SampleDesc.Count = 1; depthStencilDesc.SampleDesc.Quality = 0; depthStencilDesc.Usage = D3D11_USAGE_DEFAULT; depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthStencilDesc.CPUAccessFlags = 0; depthStencilDesc.MiscFlags = 0; result = device->CreateTexture2D(&depthStencilDesc, NULL, &mDepthStencilTexture); if (FAILED(result)) { ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result); release(); if (d3d11::isDeviceLostError(result)) { return EGL_CONTEXT_LOST; } else { return EGL_BAD_ALLOC; } } d3d11::SetDebugName(mDepthStencilTexture, "Depth stencil texture"); result = device->CreateDepthStencilView(mDepthStencilTexture, NULL, &mDepthStencilDSView); ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mDepthStencilDSView, "Depth stencil view"); } mWidth = backbufferWidth; mHeight = backbufferHeight; if (previousOffscreenTexture != NULL) { D3D11_BOX sourceBox = {0}; sourceBox.left = 0; sourceBox.right = std::min(previousWidth, mWidth); sourceBox.top = std::max(previousHeight - mHeight, 0); sourceBox.bottom = previousHeight; sourceBox.front = 0; sourceBox.back = 1; ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); const int yoffset = std::max(mHeight - previousHeight, 0); deviceContext->CopySubresourceRegion(mOffscreenTexture, 0, 0, yoffset, 0, previousOffscreenTexture, 0, &sourceBox); previousOffscreenTexture->Release(); if (mSwapChain) { swapRect(0, 0, mWidth, mHeight); } } return EGL_SUCCESS; }
void D3D11hud::Init(int width, int height) { Hud::Init(width, height); ID3D11Device *device = NULL; _deviceContext->GetDevice(&device); // define font texture D3D11_TEXTURE2D_DESC texDesc; texDesc.Width = FONT_TEXTURE_WIDTH; texDesc.Height = FONT_TEXTURE_HEIGHT; texDesc.MipLevels = 1; texDesc.ArraySize = 1; texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; texDesc.SampleDesc.Count = 1; texDesc.SampleDesc.Quality = 0; texDesc.Usage = D3D11_USAGE_DEFAULT; texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; texDesc.CPUAccessFlags = 0; texDesc.MiscFlags = 0; D3D11_SUBRESOURCE_DATA subData; subData.pSysMem = font_image; subData.SysMemPitch = FONT_TEXTURE_WIDTH*4; subData.SysMemSlicePitch = FONT_TEXTURE_WIDTH*FONT_TEXTURE_HEIGHT*4; HRESULT hr = device->CreateTexture2D(&texDesc, &subData, &_fontTexture); assert(_fontTexture); // shader resource view D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; ZeroMemory(&srvDesc, sizeof(srvDesc)); srvDesc.Format = texDesc.Format; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = texDesc.MipLevels; device->CreateShaderResourceView(_fontTexture, &srvDesc, &_shaderResourceView); assert(_shaderResourceView); D3D11_SAMPLER_DESC samplerDesc; ZeroMemory(&samplerDesc, sizeof(samplerDesc)); samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; samplerDesc.AddressU = samplerDesc.AddressV = samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.MaxAnisotropy = 1; samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; device->CreateSamplerState(&samplerDesc, &_samplerState); assert(_samplerState); ID3DBlob* pVSBlob; ID3DBlob* pPSBlob; pVSBlob = d3d11CompileShader(s_VS, "vs_main", "vs_4_0"); pPSBlob = d3d11CompileShader(s_PS, "ps_main", "ps_4_0"); assert(pVSBlob); assert(pPSBlob); D3D11_INPUT_ELEMENT_DESC inputElementDesc[] = { { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, sizeof(float)*2, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, sizeof(float)*5, D3D11_INPUT_PER_VERTEX_DATA, 0 } }; device->CreateInputLayout(inputElementDesc, ARRAYSIZE(inputElementDesc), pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &_inputLayout); assert(_inputLayout); device->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &_vertexShader); assert(_vertexShader); device->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &_pixelShader); assert(_pixelShader); D3D11_RASTERIZER_DESC rasDesc; rasDesc.FillMode = D3D11_FILL_SOLID; rasDesc.CullMode = D3D11_CULL_NONE; rasDesc.FrontCounterClockwise = FALSE; rasDesc.DepthBias = 0; rasDesc.DepthBiasClamp = 0; rasDesc.SlopeScaledDepthBias = 0.0f; rasDesc.DepthClipEnable = FALSE; rasDesc.ScissorEnable = FALSE; rasDesc.MultisampleEnable = FALSE; rasDesc.AntialiasedLineEnable = FALSE; device->CreateRasterizerState(&rasDesc, &_rasterizerState); assert(_rasterizerState); // constant buffer D3D11_BUFFER_DESC cbDesc; cbDesc.Usage = D3D11_USAGE_DYNAMIC; cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; cbDesc.MiscFlags = 0; cbDesc.ByteWidth = sizeof(CB_HUD_PROJECTION); device->CreateBuffer(&cbDesc, NULL, &_constantBuffer); assert(_constantBuffer); }
void AnimSetBufferGPU::createGPUBufferForAnimationCSResult(PE::GameContext &ctx) { #if APIABSTRACTION_D3D9 #elif APIABSTRACTION_D3D11 D3D11Renderer *pD3D11Renderer = static_cast<D3D11Renderer *>(ctx.getGPUScreen()); ID3D11Device *pDevice = pD3D11Renderer->m_pD3DDevice; ID3D11DeviceContext *pDeviceContext = pD3D11Renderer->m_pD3DContext; { #if PE_STORE_CS_MAP_RESULT_AS_MATRIX typedef Matrix4x4 ElementType; #else typedef BoneTQ ElementType; #endif int numElements = PE_MAX_BONE_COUNT_IN_DRAW_CALL * PE_MAX_SKINED_INSTANCE_COUNT_IN_COMPUTE_CALL; int byteSize = sizeof(ElementType) * numElements; // Create the buffer itself D3D11_BUFFER_DESC vbd; vbd.Usage = D3D11_USAGE_DEFAULT; // specify D3D11_USAGE_DEFAULT if not needed to access with cpu map() vbd.CPUAccessFlags = 0; vbd.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS; //D3D11_BIND_UNORDERED_ACCESS allows writing to resource and reading from resource at the same draw call vbd.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; vbd.ByteWidth = byteSize; vbd.StructureByteStride = sizeof(ElementType); void *ptr = malloc(byteSize); memset(ptr, -1, byteSize); D3D11_SUBRESOURCE_DATA vinitData; vinitData.pSysMem = ptr; vinitData.SysMemPitch = 0; vinitData.SysMemSlicePitch = 0; HRESULT hr = pDevice->CreateBuffer(&vbd, &vinitData, &s_pAnimationCSResultBuffer); PEASSERT(SUCCEEDED(hr), "Error creating buffer"); free(ptr); { vbd.Usage = D3D11_USAGE_STAGING; vbd.BindFlags = 0; vbd.ByteWidth = byteSize; vbd.CPUAccessFlags = D3D11_CPU_ACCESS_READ; hr = pDevice->CreateBuffer(&vbd, NULL, &s_pAnimationCSResultBufferCpuMirror); PEASSERT(SUCCEEDED(hr), "Error creating staging buffer"); s_pAnimationCSResultBufferCpuMirrorMem = malloc(byteSize); s_pAnimationCSResultBufferCpuMirrorMemSize = byteSize; } // animation compute shader Map stage result UAV (used by the Map) and View use by succeeding shaders { D3D11_SHADER_RESOURCE_VIEW_DESC vdesc; vdesc.Format = DXGI_FORMAT_UNKNOWN; // since using StructuredBuffer, has to be UNKNOWN vdesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; vdesc.Buffer.ElementOffset = 0; vdesc.Buffer.NumElements = numElements; hr = pDevice->CreateShaderResourceView(s_pAnimationCSResultBuffer, &vdesc, &s_pAnimationCSMapResultShaderResourceView); PEASSERT(SUCCEEDED(hr), "Error creating shader resource view"); D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; uavDesc.Format = DXGI_FORMAT_UNKNOWN; uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; uavDesc.Buffer.FirstElement = 0; uavDesc.Buffer.Flags = 0; // could specify D3D11_BUFFER_UAV_FLAG_APPEND uavDesc.Buffer.NumElements = numElements; hr = pDevice->CreateUnorderedAccessView(s_pAnimationCSResultBuffer, &uavDesc, &s_pAnimationCSMapResultShaderUAView); PEASSERT(SUCCEEDED(hr), "Error creating UAV"); } for (int i = 0; i < PE_MAX_NUM_OF_BUFFER_STEPS; ++i) { vbd.Usage = D3D11_USAGE_STAGING; vbd.BindFlags = 0; vbd.ByteWidth = byteSize / PE_MAX_NUM_OF_BUFFER_STEPS; vbd.CPUAccessFlags = D3D11_CPU_ACCESS_READ; hr = pDevice->CreateBuffer(&vbd, NULL, &s_pAnimationCSResultBuffersCpuStaging[i]); PEASSERT(SUCCEEDED(hr), "Error creating staging buffer"); } } { typedef Matrix4x4 ElementType; int numElements = PE_MAX_BONE_COUNT_IN_DRAW_CALL * PE_MAX_SKINED_INSTANCE_COUNT_IN_COMPUTE_CALL; int byteSize = sizeof(ElementType) * numElements; // Create the buffer itself D3D11_BUFFER_DESC vbd; vbd.Usage = D3D11_USAGE_DEFAULT; // specify D3D11_USAGE_DEFAULT if not needed to access with cpu map() vbd.CPUAccessFlags = 0; vbd.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS; //D3D11_BIND_UNORDERED_ACCESS allows writing to resource and reading from resource at the same draw call vbd.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; vbd.ByteWidth = byteSize; vbd.StructureByteStride = sizeof(ElementType); void *ptr = malloc(byteSize); memset(ptr, -1, byteSize); D3D11_SUBRESOURCE_DATA vinitData; vinitData.pSysMem = ptr; vinitData.SysMemPitch = 0; vinitData.SysMemSlicePitch = 0; HRESULT hr = pDevice->CreateBuffer(&vbd, &vinitData, &s_pCSReduceComputeTargetBuffer); PEASSERT(SUCCEEDED(hr), "Error creating buffer"); free(ptr); { vbd.Usage = D3D11_USAGE_STAGING; vbd.BindFlags = 0; vbd.ByteWidth = byteSize; vbd.CPUAccessFlags = D3D11_CPU_ACCESS_READ; hr = pDevice->CreateBuffer(&vbd, NULL, &s_pCSReduceComputeTargetStagingBuffer); PEASSERT(SUCCEEDED(hr), "Error creating staging buffer"); s_pCSReduceComputeTargetCpuMem = malloc(byteSize); s_pCSReduceComputeTargetCpuMemSize = byteSize; } // animation compute shader Map stage result UAV (used by the Map) and View use by succeeding shaders { D3D11_SHADER_RESOURCE_VIEW_DESC vdesc; vdesc.Format = DXGI_FORMAT_UNKNOWN; // since using StructuredBuffer, has to be UNKNOWN vdesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; vdesc.Buffer.ElementOffset = 0; vdesc.Buffer.NumElements = numElements; hr = pDevice->CreateShaderResourceView(s_pCSReduceComputeTargetBuffer, &vdesc, &s_pCSReduceComputeTargetView); PEASSERT(SUCCEEDED(hr), "Error creating shader resource view"); D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; uavDesc.Format = DXGI_FORMAT_UNKNOWN; uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; uavDesc.Buffer.FirstElement = 0; uavDesc.Buffer.Flags = 0; // could specify D3D11_BUFFER_UAV_FLAG_APPEND uavDesc.Buffer.NumElements = numElements; hr = pDevice->CreateUnorderedAccessView(s_pCSReduceComputeTargetBuffer, &uavDesc, &s_pCSReduceComputeTargetUAV); PEASSERT(SUCCEEDED(hr), "Error creating UAV"); } } #endif }
EGLint SwapChain11::resetOffscreenDepthBuffer(int backbufferWidth, int backbufferHeight) { releaseOffscreenDepthBuffer(); if (mDepthBufferFormat != GL_NONE) { const d3d11::Format &depthBufferFormatInfo = d3d11::Format::Get(mDepthBufferFormat, mRenderer->getRenderer11DeviceCaps()); D3D11_TEXTURE2D_DESC depthStencilTextureDesc; depthStencilTextureDesc.Width = backbufferWidth; depthStencilTextureDesc.Height = backbufferHeight; depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat; depthStencilTextureDesc.MipLevels = 1; depthStencilTextureDesc.ArraySize = 1; depthStencilTextureDesc.SampleDesc.Count = 1; depthStencilTextureDesc.SampleDesc.Quality = 0; depthStencilTextureDesc.Usage = D3D11_USAGE_DEFAULT; depthStencilTextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; if (depthBufferFormatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) { depthStencilTextureDesc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; } depthStencilTextureDesc.CPUAccessFlags = 0; depthStencilTextureDesc.MiscFlags = 0; ID3D11Device *device = mRenderer->getDevice(); HRESULT result = device->CreateTexture2D(&depthStencilTextureDesc, NULL, &mDepthStencilTexture); if (FAILED(result)) { ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result); release(); if (d3d11::isDeviceLostError(result)) { return EGL_CONTEXT_LOST; } else { return EGL_BAD_ALLOC; } } d3d11::SetDebugName(mDepthStencilTexture, "Offscreen depth stencil texture"); D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilDesc; depthStencilDesc.Format = depthBufferFormatInfo.dsvFormat; depthStencilDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilDesc.Flags = 0; depthStencilDesc.Texture2D.MipSlice = 0; result = device->CreateDepthStencilView(mDepthStencilTexture, &depthStencilDesc, &mDepthStencilDSView); ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mDepthStencilDSView, "Offscreen depth stencil view"); if (depthBufferFormatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) { D3D11_SHADER_RESOURCE_VIEW_DESC depthStencilSRVDesc; depthStencilSRVDesc.Format = depthBufferFormatInfo.srvFormat; depthStencilSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; depthStencilSRVDesc.Texture2D.MostDetailedMip = 0; depthStencilSRVDesc.Texture2D.MipLevels = static_cast<UINT>(-1); result = device->CreateShaderResourceView(mDepthStencilTexture, &depthStencilSRVDesc, &mDepthStencilSRView); ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mDepthStencilSRView, "Offscreen depth stencil shader resource"); } } return EGL_SUCCESS; }
EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbufferHeight) { ASSERT(mNeedsOffscreenTexture); TRACE_EVENT0("gpu.angle", "SwapChain11::resetOffscreenTexture"); ID3D11Device *device = mRenderer->getDevice(); ASSERT(device != NULL); // D3D11 does not allow zero size textures ASSERT(backbufferWidth >= 1); ASSERT(backbufferHeight >= 1); // Preserve the render target content ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture; if (previousOffscreenTexture) { previousOffscreenTexture->AddRef(); } const int previousWidth = mWidth; const int previousHeight = mHeight; releaseOffscreenColorBuffer(); const d3d11::Format &backbufferFormatInfo = d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps()); // If the app passed in a share handle, open the resource // See EGL_ANGLE_d3d_share_handle_client_buffer if (mAppCreatedShareHandle) { ID3D11Resource *tempResource11; HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource), (void**)&tempResource11); if (FAILED(result)) { ERR("Failed to open the swap chain pbuffer share handle: %08lX", result); release(); return EGL_BAD_PARAMETER; } result = tempResource11->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&mOffscreenTexture); SafeRelease(tempResource11); if (FAILED(result)) { ERR("Failed to query texture2d interface in pbuffer share handle: %08lX", result); release(); return EGL_BAD_PARAMETER; } // Validate offscreen texture parameters D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; mOffscreenTexture->GetDesc(&offscreenTextureDesc); if (offscreenTextureDesc.Width != (UINT)backbufferWidth || offscreenTextureDesc.Height != (UINT)backbufferHeight || offscreenTextureDesc.Format != backbufferFormatInfo.texFormat || offscreenTextureDesc.MipLevels != 1 || offscreenTextureDesc.ArraySize != 1) { ERR("Invalid texture parameters in the shared offscreen texture pbuffer"); release(); return EGL_BAD_PARAMETER; } } else { const bool useSharedResource = !mNativeWindow->getNativeWindow() && mRenderer->getShareHandleSupport(); D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; offscreenTextureDesc.Width = backbufferWidth; offscreenTextureDesc.Height = backbufferHeight; offscreenTextureDesc.Format = backbufferFormatInfo.texFormat; offscreenTextureDesc.MipLevels = 1; offscreenTextureDesc.ArraySize = 1; offscreenTextureDesc.SampleDesc.Count = 1; offscreenTextureDesc.SampleDesc.Quality = 0; offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT; offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; offscreenTextureDesc.CPUAccessFlags = 0; offscreenTextureDesc.MiscFlags = useSharedResource ? ANGLE_RESOURCE_SHARE_TYPE : 0; HRESULT result = device->CreateTexture2D(&offscreenTextureDesc, NULL, &mOffscreenTexture); if (FAILED(result)) { ERR("Could not create offscreen texture: %08lX", result); release(); if (d3d11::isDeviceLostError(result)) { return EGL_CONTEXT_LOST; } else { return EGL_BAD_ALLOC; } } d3d11::SetDebugName(mOffscreenTexture, "Offscreen back buffer texture"); // EGL_ANGLE_surface_d3d_texture_2d_share_handle requires that we store a share handle for the client if (useSharedResource) { IDXGIResource *offscreenTextureResource = NULL; result = mOffscreenTexture->QueryInterface(__uuidof(IDXGIResource), (void**)&offscreenTextureResource); // Fall back to no share handle on failure if (FAILED(result)) { ERR("Could not query offscreen texture resource: %08lX", result); } else { result = offscreenTextureResource->GetSharedHandle(&mShareHandle); SafeRelease(offscreenTextureResource); if (FAILED(result)) { mShareHandle = NULL; ERR("Could not get offscreen texture shared handle: %08lX", result); } } } } // This may return null if the original texture was created without a keyed mutex. mKeyedMutex = d3d11::DynamicCastComObject<IDXGIKeyedMutex>(mOffscreenTexture); D3D11_RENDER_TARGET_VIEW_DESC offscreenRTVDesc; offscreenRTVDesc.Format = backbufferFormatInfo.rtvFormat; offscreenRTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; offscreenRTVDesc.Texture2D.MipSlice = 0; HRESULT result = device->CreateRenderTargetView(mOffscreenTexture, &offscreenRTVDesc, &mOffscreenRTView); ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mOffscreenRTView, "Offscreen back buffer render target"); D3D11_SHADER_RESOURCE_VIEW_DESC offscreenSRVDesc; offscreenSRVDesc.Format = backbufferFormatInfo.srvFormat; offscreenSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; offscreenSRVDesc.Texture2D.MostDetailedMip = 0; offscreenSRVDesc.Texture2D.MipLevels = static_cast<UINT>(-1); result = device->CreateShaderResourceView(mOffscreenTexture, &offscreenSRVDesc, &mOffscreenSRView); ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mOffscreenSRView, "Offscreen back buffer shader resource"); if (previousOffscreenTexture != nullptr) { D3D11_BOX sourceBox = {0}; sourceBox.left = 0; sourceBox.right = std::min(previousWidth, backbufferWidth); sourceBox.top = std::max(previousHeight - backbufferHeight, 0); sourceBox.bottom = previousHeight; sourceBox.front = 0; sourceBox.back = 1; ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); const int yoffset = std::max(backbufferHeight - previousHeight, 0); deviceContext->CopySubresourceRegion(mOffscreenTexture, 0, 0, yoffset, 0, previousOffscreenTexture, 0, &sourceBox); SafeRelease(previousOffscreenTexture); if (mSwapChain) { swapRect(0, 0, backbufferWidth, backbufferHeight); } } return EGL_SUCCESS; }
// |----------------------------------------------------------------------------| // | Initialize | // |----------------------------------------------------------------------------| bool Texture::Initialize(int textureWidth, int textureHeight) { DebugLog ("Texture::Initialize() called.", DB_GRAPHICS, 1); D3D11_TEXTURE2D_DESC textureDesc; HRESULT result; D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc; D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; // Get D3D infor ID3D11Device* device = D3DManager::GetRef()->GetDevice(); // Store the width and height of the render texture. m_width = textureWidth; m_height = textureHeight; // Initialize the render target texture description. ZeroMemory(&textureDesc, sizeof(textureDesc)); // Setup the render target texture description. textureDesc.Width = textureWidth; textureDesc.Height = textureHeight; textureDesc.MipLevels = 1; textureDesc.ArraySize = 1; textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; textureDesc.SampleDesc.Count = 1; textureDesc.Usage = D3D11_USAGE_DEFAULT; textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; textureDesc.CPUAccessFlags = 0; textureDesc.MiscFlags = 0; // Create the render target texture. result = device->CreateTexture2D(&textureDesc, NULL, &m_renderTargetTexture); if(FAILED(result)) { return false; } // Setup the description of the render target view. renderTargetViewDesc.Format = textureDesc.Format; renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; renderTargetViewDesc.Texture2D.MipSlice = 0; // Create the render target view. result = device->CreateRenderTargetView(m_renderTargetTexture, &renderTargetViewDesc, &m_renderTargetView); if(FAILED(result)) { return false; } // Setup the description of the shader resource view. shaderResourceViewDesc.Format = textureDesc.Format; shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; shaderResourceViewDesc.Texture2D.MostDetailedMip = 0; shaderResourceViewDesc.Texture2D.MipLevels = 1; // Create the shader resource view. result = device->CreateShaderResourceView(m_renderTargetTexture, &shaderResourceViewDesc, &m_shaderResourceView); if(FAILED(result)) { return false; } // Initialize the description of the depth buffer. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); // Set up the description of the depth buffer. depthBufferDesc.Width = textureWidth; depthBufferDesc.Height = textureHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; // Create the texture for the depth buffer using the filled out description. result = device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if(FAILED(result)) { return false; } // Initialize the depth stencil view. ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); // Set up the depth stencil view description. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; // Create the depth stencil view. result = device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if(FAILED(result)) { return false; } // Setup the viewport for rendering. m_viewport.Width = (float)textureWidth; m_viewport.Height = (float)textureHeight; m_viewport.MinDepth = 0.0f; m_viewport.MaxDepth = 1.0f; m_viewport.TopLeftX = 0.0f; m_viewport.TopLeftY = 0.0f; // Setup the projection matrix. D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, ((float)D3DX_PI / 4.0f), ((float)textureWidth / (float)textureHeight), SCREEN_NEAR, SCREEN_DEPTH); // Create an orthographic projection matrix for 2D rendering. D3DXMatrixOrthoLH(&m_orthoMatrix, (float)textureWidth, (float)textureHeight, SCREEN_NEAR, SCREEN_DEPTH); return true; }
EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) { TRACE_EVENT0("gpu.angle", "SwapChain11::resize"); ID3D11Device *device = mRenderer->getDevice(); if (device == NULL) { return EGL_BAD_ACCESS; } // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains if (backbufferWidth < 1 || backbufferHeight < 1) { return EGL_SUCCESS; } // Don't resize unnecessarily if (mWidth == backbufferWidth && mHeight == backbufferHeight) { return EGL_SUCCESS; } // Can only call resize if we have already created our swap buffer and resources ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView && mBackBufferSRView); SafeRelease(mBackBufferTexture); SafeRelease(mBackBufferRTView); SafeRelease(mBackBufferSRView); // Resize swap chain DXGI_SWAP_CHAIN_DESC desc; HRESULT result = mSwapChain->GetDesc(&desc); if (FAILED(result)) { ERR("Error reading swap chain description: 0x%08X", result); release(); return EGL_BAD_ALLOC; } result = mSwapChain->ResizeBuffers(desc.BufferCount, backbufferWidth, backbufferHeight, getSwapChainNativeFormat(), 0); if (FAILED(result)) { ERR("Error resizing swap chain buffers: 0x%08X", result); release(); if (d3d11::isDeviceLostError(result)) { return EGL_CONTEXT_LOST; } else { return EGL_BAD_ALLOC; } } result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture); ASSERT(SUCCEEDED(result)); if (SUCCEEDED(result)) { d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture"); result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView); ASSERT(SUCCEEDED(result)); if (SUCCEEDED(result)) { d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target"); } result = device->CreateShaderResourceView(mBackBufferTexture, nullptr, &mBackBufferSRView); ASSERT(SUCCEEDED(result)); if (SUCCEEDED(result)) { d3d11::SetDebugName(mBackBufferSRView, "Back buffer shader resource"); } } mFirstSwap = true; return resetOffscreenBuffers(backbufferWidth, backbufferHeight); }
EGLint SwapChain11::reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) { mSwapInterval = static_cast<unsigned int>(swapInterval); if (mSwapInterval > 4) { // IDXGISwapChain::Present documentation states that valid sync intervals are in the [0,4] // range return EGL_BAD_PARAMETER; } // If the swap chain already exists, just resize if (mSwapChain != nullptr) { return resize(backbufferWidth, backbufferHeight); } TRACE_EVENT0("gpu.angle", "SwapChain11::reset"); ID3D11Device *device = mRenderer->getDevice(); if (device == NULL) { return EGL_BAD_ACCESS; } // Release specific resources to free up memory for the new render target, while the // old render target still exists for the purpose of preserving its contents. SafeRelease(mSwapChain1); SafeRelease(mSwapChain); SafeRelease(mBackBufferTexture); SafeRelease(mBackBufferRTView); // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains if (backbufferWidth < 1 || backbufferHeight < 1) { releaseOffscreenColorBuffer(); return EGL_SUCCESS; } if (mNativeWindow->getNativeWindow()) { HRESULT result = mNativeWindow->createSwapChain(device, mRenderer->getDxgiFactory(), getSwapChainNativeFormat(), backbufferWidth, backbufferHeight, &mSwapChain); if (FAILED(result)) { ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); release(); if (d3d11::isDeviceLostError(result)) { return EGL_CONTEXT_LOST; } else { return EGL_BAD_ALLOC; } } if (mRenderer->getRenderer11DeviceCaps().supportsDXGI1_2) { mSwapChain1 = d3d11::DynamicCastComObject<IDXGISwapChain1>(mSwapChain); } result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture); ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture"); result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView); ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target"); result = device->CreateShaderResourceView(mBackBufferTexture, nullptr, &mBackBufferSRView); ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mBackBufferSRView, "Back buffer shader resource view"); } mFirstSwap = true; return resetOffscreenBuffers(backbufferWidth, backbufferHeight); }
void AnimSetBufferGPU::createGPUBufferFromAnimSet(AnimationSetCPU &animSetCpu) { #if APIABSTRACTION_D3D9 #elif APIABSTRACTION_D3D11 D3D11Renderer *pD3D11Renderer = static_cast<D3D11Renderer *>(m_pContext->getGPUScreen()); ID3D11Device *pDevice = pD3D11Renderer->m_pD3DDevice; ID3D11DeviceContext *pDeviceContext = pD3D11Renderer->m_pD3DContext; int numElements = PE_MAX_BONE_COUNT_IN_DRAW_CALL * PE_MAX_FRAMES_IN_ANIMATION * PE_MAX_ANIMATIONS_IN_BUFFER; int byteSize = sizeof(BoneTQ) * numElements; Array<BoneTQ> data(*m_pContext, m_arena); data.reset(numElements); data.m_size = numElements; int numAnims = animSetCpu.m_animations.m_size; if (numAnims > PE_MAX_ANIMATIONS_IN_BUFFER) { PEWARN("Will not fit all anims in AnimSetBuffer"); numAnims = PE_MAX_ANIMATIONS_IN_BUFFER; } for (int iAnim = 0; iAnim < numAnims; ++iAnim) { BoneTQ *pAnimData = &data[PE_MAX_BONE_COUNT_IN_DRAW_CALL * PE_MAX_FRAMES_IN_ANIMATION * iAnim]; AnimationCPU &anim = animSetCpu.m_animations[iAnim]; PEASSERT(anim.m_numJoints <= PE_MAX_BONE_COUNT_IN_DRAW_CALL, "Too big skeleton!"); int numFrames = anim.m_frames.m_size; if (numFrames > PE_MAX_FRAMES_IN_ANIMATION) { PEWARN("Will not fit all animation frames in animation"); numFrames = PE_MAX_FRAMES_IN_ANIMATION; } for (int iFrame = 0; iFrame < numFrames; ++iFrame) { BoneTQ *pFrameData = pAnimData + (PE_MAX_BONE_COUNT_IN_DRAW_CALL * iFrame); Array<TSQ> &frame = anim.m_frames[iFrame]; for (int iBone = 0; iBone < anim.m_numJoints; ++iBone, ++pFrameData) { pFrameData->m_quat = frame[iBone].m_quat; pFrameData->m_translation = frame[iBone].m_translation; } } for (int iFrame = numFrames; iFrame < PE_MAX_FRAMES_IN_ANIMATION; ++iFrame) { BoneTQ *pFrameData = pAnimData + (PE_MAX_BONE_COUNT_IN_DRAW_CALL * iFrame); Array<TSQ> &frame = anim.m_frames[numFrames-1]; for (int iBone = 0; iBone < anim.m_numJoints; ++iBone, ++pFrameData) { pFrameData->m_quat = frame[iBone].m_quat; pFrameData->m_translation = frame[iBone].m_translation; } } } // Create the buffer itself D3D11_BUFFER_DESC vbd; vbd.Usage = D3D11_USAGE_DEFAULT; vbd.CPUAccessFlags = 0; vbd.BindFlags = D3D11_BIND_SHADER_RESOURCE/* | D3D11_BIND_UNORDERED_ACCESS*/; vbd.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; vbd.ByteWidth = byteSize; vbd.StructureByteStride = sizeof(BoneTQ); ID3D11Buffer *pBuffer; D3D11_SUBRESOURCE_DATA vinitData; vinitData.pSysMem = data.getFirstPtr(); vinitData.SysMemPitch = 0; vinitData.SysMemSlicePitch = 0; HRESULT hr = pDevice->CreateBuffer(&vbd, &vinitData, &pBuffer); PEASSERT(SUCCEEDED(hr), "Error creating buffer"); m_pBuf = pBuffer; D3D11_SHADER_RESOURCE_VIEW_DESC vdesc; vdesc.Format = DXGI_FORMAT_UNKNOWN; vdesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; vdesc.Buffer.ElementOffset = 0; vdesc.Buffer.NumElements = numElements; ID3D11ShaderResourceView *pShaderResourceView = NULL; hr = pDevice->CreateShaderResourceView(pBuffer, &vdesc, &pShaderResourceView); PEASSERT(SUCCEEDED(hr), "Error creating shader resource view"); m_pShaderResourceView = pShaderResourceView; /* if(useAsUAV) { D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; uavDesc.Format = DXGI_FORMAT_UNKNOWN; uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; uavDesc.Buffer.FirstElement = 0; uavDesc.Buffer.Flags = appendConsume ? D3D11_BUFFER_UAV_FLAG_APPEND : 0; uavDesc.Buffer.NumElements = numElements; DXCall(device->CreateUnorderedAccessView(Buffer, &uavDesc, &UAView)); } */ #endif }
RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth) { mRenderer = Renderer11::makeRenderer11(renderer); mTexture = NULL; mRenderTarget = NULL; mDepthStencil = NULL; mShaderResource = NULL; DXGI_FORMAT requestedFormat = gl_d3d11::ConvertRenderbufferFormat(format); int supportedSamples = mRenderer->getNearestSupportedSamples(requestedFormat, samples); if (supportedSamples < 0) { gl::error(GL_OUT_OF_MEMORY); return; } if (width > 0 && height > 0) { // Create texture resource D3D11_TEXTURE2D_DESC desc; desc.Width = width; desc.Height = height; desc.MipLevels = 1; desc.ArraySize = 1; desc.Format = requestedFormat; desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; desc.CPUAccessFlags = 0; desc.MiscFlags = 0; desc.BindFlags = (depth ? D3D11_BIND_DEPTH_STENCIL : (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE)); ID3D11Device *device = mRenderer->getDevice(); HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); if (result == E_OUTOFMEMORY) { gl::error(GL_OUT_OF_MEMORY); return; } ASSERT(SUCCEEDED(result)); if (depth) { D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; dsvDesc.Format = requestedFormat; dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS; dsvDesc.Texture2D.MipSlice = 0; dsvDesc.Flags = 0; result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil); if (result == E_OUTOFMEMORY) { mTexture->Release(); mTexture = NULL; gl::error(GL_OUT_OF_MEMORY); } ASSERT(SUCCEEDED(result)); } else { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; rtvDesc.Format = requestedFormat; rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS; rtvDesc.Texture2D.MipSlice = 0; result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget); if (result == E_OUTOFMEMORY) { mTexture->Release(); mTexture = NULL; gl::error(GL_OUT_OF_MEMORY); return; } ASSERT(SUCCEEDED(result)); D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = requestedFormat; srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = 1; result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource); if (result == E_OUTOFMEMORY) { mTexture->Release(); mTexture = NULL; mRenderTarget->Release(); mRenderTarget = NULL; gl::error(GL_OUT_OF_MEMORY); return; } ASSERT(SUCCEEDED(result)); } } mWidth = width; mHeight = height; mInternalFormat = format; mSamples = supportedSamples; mActualFormat = d3d11_gl::ConvertTextureInternalFormat(requestedFormat); mSubresourceIndex = D3D11CalcSubresource(0, 0, 1); }
void init_for_dimensions(unsigned width, unsigned height) { if(zsv) zsv->Release(); ID3D11Texture2D* zsbuf; D3D11_TEXTURE2D_DESC zsbufd; memset(&zsbufd, 0, sizeof(zsbufd)); zsbufd.Width = width; zsbufd.Height = height; zsbufd.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; zsbufd.ArraySize = 1; zsbufd.MipLevels = 1; zsbufd.SampleDesc.Count = 1; zsbufd.BindFlags = D3D11_BIND_DEPTH_STENCIL; ensure(dev->CreateTexture2D(&zsbufd, 0, &zsbuf)); ensure(dev->CreateDepthStencilView(zsbuf, 0, &zsv)); zsbuf->Release(); ID3D11Texture2D* offscreen; if(offscreen_rtv) { offscreen_rtv->Release(); offscreen_srv->Release(); offscreen_rtv = 0; offscreen_srv = 0; } if(impressions > 1) { DXGI_FORMAT formats[] = { DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R10G10B10A2_UNORM, }; DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM; // this won't work well at all unsigned needed_support = D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D11_FORMAT_SUPPORT_BLENDABLE | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE; for(unsigned i = 0; i < sizeof(formats); ++i) { unsigned support; dev->CheckFormatSupport(DXGI_FORMAT_R32G32B32A32_FLOAT, &support); if((support & needed_support) == needed_support) { format = formats[i]; break; } } D3D11_TEXTURE2D_DESC offscreend; memset(&offscreend, 0, sizeof(offscreend)); offscreend.Width = width; offscreend.Height = height; offscreend.Format = format; offscreend.MipLevels = 1; offscreend.ArraySize = 1; offscreend.SampleDesc.Count = 1; offscreend.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; ensure(dev->CreateTexture2D(&offscreend, 0, &offscreen)); ensure(dev->CreateRenderTargetView(offscreen, 0, &offscreen_rtv)); ensure(dev->CreateShaderResourceView(offscreen, 0, &offscreen_srv)); offscreen->Release(); } cur_width = width; cur_height = height; }
CRendertarget* CTextureManager::GetRendertarget(const Vector2ui& aSize) { HRESULT hr = S_OK; ID3D11Device* device = myDirect3D->GetDevice(); D3D11_TEXTURE2D_DESC textureDesc; textureDesc.Width = aSize.x; textureDesc.Height = aSize.y; textureDesc.MipLevels = 1; textureDesc.ArraySize = 1; textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; textureDesc.SampleDesc.Count = 1; textureDesc.SampleDesc.Quality = 0; textureDesc.Usage = D3D11_USAGE_DEFAULT; textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; textureDesc.CPUAccessFlags = 0; textureDesc.MiscFlags = 0; ID3D11Texture2D* temporaryTexture = nullptr; hr = device->CreateTexture2D(&textureDesc, nullptr, &temporaryTexture); if (FAILED(hr)) { ERROR_AUTO_PRINT("%s %s", "Failed to create texture"); } ID3D11ShaderResourceView* resource = nullptr; hr = device->CreateShaderResourceView(temporaryTexture, nullptr, &resource); if (FAILED(hr)) { ERROR_AUTO_PRINT("%s %s", "Failed to create resource"); } ID3D11RenderTargetView* target = nullptr; hr = device->CreateRenderTargetView(temporaryTexture, nullptr, &target); if (FAILED(hr)) { ERROR_AUTO_PRINT("%s %s", "Failed to create target"); } D3D11_TEXTURE2D_DESC depthDesc = textureDesc; depthDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; ID3D11Texture2D* temporaryDepth = nullptr; hr = device->CreateTexture2D(&depthDesc, nullptr, &temporaryDepth); if (FAILED(hr)) { ERROR_AUTO_PRINT("%s %s", "Failed to create depthtexture"); return false; } CRendertarget* newTarget = new CRendertarget(); newTarget->myResource = resource; newTarget->myTarget = target; newTarget->mySize = GetTextureSize(resource, false); temporaryTexture->Release(); temporaryDepth->Release(); return newTarget; }