void MyD3DAssets::loadPSTexture(int textureIndex) { ID3D11ShaderResourceView *view = nullptr; context->base->PSGetShaderResources(textureIndex, 1, &view); if (view == nullptr) { PSTexture.free(); } else { ID3D11Resource *textureResource = nullptr; view->GetResource(&textureResource); ID3D11Texture2D* texture = nullptr; HRESULT hr = textureResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&texture)); if (texture == nullptr || FAILED(hr)) { PSTexture.free(); g_logger->logErrorFile << "textureResource->QueryInterface failed" << endl; } else { readTexture(texture, PSTexture); texture->Release(); } textureResource->Release(); view->Release(); } }
_Use_decl_annotations_ void EffectFactory::Impl::CreateTexture( const WCHAR* name, ID3D11DeviceContext* deviceContext, ID3D11ShaderResourceView** textureView ) { if ( !name || !textureView ) throw std::exception("invalid arguments"); auto it = mTextureCache.find( name ); if ( mSharing && it != mTextureCache.end() ) { ID3D11ShaderResourceView* srv = it->second.Get(); srv->AddRef(); *textureView = srv; } else { WCHAR fullName[MAX_PATH]={0}; wcscpy_s( fullName, mPath ); wcscat_s( fullName, name ); #if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) WCHAR ext[_MAX_EXT]; _wsplitpath_s( name, nullptr, 0, nullptr, 0, nullptr, 0, ext, _MAX_EXT ); if ( _wcsicmp( ext, L".dds" ) == 0 ) { ThrowIfFailed( CreateDDSTextureFromFile( device.Get(), fullName, nullptr, textureView ) ); } else if ( deviceContext ) { std::lock_guard<std::mutex> lock(mutex); DirectX::ThrowIfFailed( CreateWICTextureFromFile( device.Get(), deviceContext, fullName, nullptr, textureView ) ); } else { DirectX::ThrowIfFailed( CreateWICTextureFromFile( device.Get(), nullptr, fullName, nullptr, textureView ) ); } #else UNREFERENCED_PARAMETER( deviceContext ); ThrowIfFailed( CreateDDSTextureFromFile( device.Get(), fullName, nullptr, textureView ) ); #endif if ( mSharing && *name && it == mTextureCache.end() ) { std::lock_guard<std::mutex> lock(mutex); mTextureCache.insert( TextureCache::value_type( name, *textureView ) ); } } }
void MFTexture_DestroyPlatformSpecific(MFTexture *pTexture) { MFCALLSTACK; if(pTexture->pInternalData) { ID3D11ShaderResourceView *pSRV = (ID3D11ShaderResourceView*)pTexture->pInternalData; pSRV->Release(); } }
int TextureResourcer::createTextureFromWIC(ID3D11Device* device, ID3D11DeviceContext* deviceContext, const char* filename, TextureHandle* texHandle) { ID3D11Resource* texture = nullptr; ID3D11ShaderResourceView* textureView = nullptr; WCHAR* wfilename = convertMultiByteToWCHAR(filename); HRESULT hr = CreateWICTextureFromFile(device, deviceContext, wfilename, &texture, &textureView); delete[] wfilename; //HRESULT hr = DirectX::CreateDDSTextureFromFile( device, , nullptr, &textureView ); if(!textureView) { assert(false); DebugAssert(textureView, "Failed to load texture: ", filename); } D3D11_SHADER_RESOURCE_VIEW_DESC desc; textureView->GetDesc(&desc); if(hr) return hr; //generate id (which is really an array index) int index = generateID(); //get size unsigned int width; unsigned int height; GetTextureSizeD3D(texture, &width, &height); //ensure sizing in textures storage if(textures.size() <= (unsigned int)index) textures.resize(index+1); //add to storage TextureData& data = textures[index]; data.ID = index; data.name = filename; data.width = width; data.height = height; data.textureResource = texture; data.textureView = textureView; //reference by name textureNameToId[filename] = index; TextureHandle hTex = {index}; *texHandle = hTex; return hr; }
XMFLOAT2 const ShaderResourceView::CalPicSize(std::wstring filePath) const { ID3D11ShaderResourceView* pISpriteSRV = GetSRV(filePath); ID3D11Texture2D* pISpriteTex; float TextureWidth = 0.0f,TextureHeight = 0.0f; pISpriteSRV->GetResource( (ID3D11Resource**) &pISpriteTex); D3D11_TEXTURE2D_DESC SpriteTexDesc; pISpriteTex->GetDesc(&SpriteTexDesc); TextureWidth = static_cast<float>(SpriteTexDesc.Width); TextureHeight = static_cast<float>(SpriteTexDesc.Height); SAFE_RELEASE(pISpriteTex); return XMFLOAT2(TextureWidth,TextureHeight); }
//----------------------------------------------------------------------------- CPUTTexture *CPUTTextureDX11::CreateTexture( const cString &name, const cString &absolutePathAndFilename, bool loadAsSRGB ) { // TODO: Delegate to derived class. We don't currently have CPUTTextureDX11 ID3D11ShaderResourceView *pShaderResourceView = NULL; ID3D11Resource *pTexture = NULL; ID3D11Device *pD3dDevice= CPUT_DX11::GetDevice(); CPUTResult result = CreateNativeTexture( pD3dDevice, absolutePathAndFilename, &pShaderResourceView, &pTexture, loadAsSRGB ); ASSERT( CPUTSUCCESS(result), _L("Error loading texture: '")+absolutePathAndFilename ); CPUTTextureDX11 *pNewTexture = new CPUTTextureDX11(); pNewTexture->mName = name; pNewTexture->SetTextureAndShaderResourceView( pTexture, pShaderResourceView ); pTexture->Release(); pShaderResourceView->Release(); CPUTAssetLibrary::GetAssetLibrary()->AddTexture( absolutePathAndFilename, pNewTexture); return pNewTexture; }
virtual void Unload( void* source ){ for (auto it = resources.begin(); it != resources.end(); it++) { if (it->second.texture == source) { it->second.referenceCount--; if (it->second.referenceCount <= 0) { if (g_RendererType == kUnityGfxRendererD3D11) { // ID3D11Texture2Dに戻してUnityにアンロードしてもらう ID3D11Resource* resourceDX11 = nullptr; ID3D11ShaderResourceView* resView = (ID3D11ShaderResourceView*)source; resView->GetResource(&resourceDX11); resView->Release(); } unload( it->first.c_str() ); resources.erase(it); } } } }
int TextureResourcer::createTextureFromWIC(ID3D11Device* device, ID3D11DeviceContext* deviceContext, const uint8_t * binaryData, int binaryLength, TextureHandle* texHandle) { ID3D11Resource* texture = nullptr; ID3D11ShaderResourceView* textureView = nullptr; HRESULT hr = CreateWICTextureFromMemory(device, deviceContext, binaryData ,binaryLength, &texture, &textureView); //HRESULT hr = DirectX::CreateDDSTextureFromFile( device, , nullptr, &textureView ); D3D11_SHADER_RESOURCE_VIEW_DESC desc; textureView->GetDesc(&desc); if(hr) return hr; //generate id (which is really an array index) int index = generateID(); //get size unsigned int width; unsigned int height; GetTextureSizeD3D(texture, &width, &height); //ensure sizing in textures storage if(textures.size() <= (unsigned int)index) textures.resize(index+1); //add to storage TextureData& data = textures[index]; data.ID = index; data.name = ""; data.width = width; data.height = height; data.textureResource = texture; data.textureView = textureView; TextureHandle hTex = {index}; *texHandle = hTex; return hr; }
void MT_Texture::Clean() { for (int i = m_textures.size() - 1; i >= 0; i--) { ID3D11Texture2D* texture = m_textures[i]; m_textures.pop_back(); texture->Release(); texture = 0; } for (int i = m_shaderResourceViews.size() - 1; i >= 0; i--) { ID3D11ShaderResourceView* shaderResourceView = m_shaderResourceViews[i]; m_shaderResourceViews.pop_back(); shaderResourceView->Release(); shaderResourceView = 0; } if (m_samplerState) m_samplerState->Release(); m_samplerState = 0; }
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; } }
// // Draw frame into backbuffer // DUPL_RETURN OUTPUTMANAGER::DrawFrame() { HRESULT hr; // If window was resized, resize swapchain if (m_NeedsResize) { DUPL_RETURN Ret = ResizeSwapChain(); if (Ret != DUPL_RETURN_SUCCESS) { return Ret; } m_NeedsResize = false; } // Vertices for drawing whole texture VERTEX Vertices[NUMVERTICES] = { {XMFLOAT3(-1.0f, -1.0f, 0), XMFLOAT2(0.0f, 1.0f)}, {XMFLOAT3(-1.0f, 1.0f, 0), XMFLOAT2(0.0f, 0.0f)}, {XMFLOAT3(1.0f, -1.0f, 0), XMFLOAT2(1.0f, 1.0f)}, {XMFLOAT3(1.0f, -1.0f, 0), XMFLOAT2(1.0f, 1.0f)}, {XMFLOAT3(-1.0f, 1.0f, 0), XMFLOAT2(0.0f, 0.0f)}, {XMFLOAT3(1.0f, 1.0f, 0), XMFLOAT2(1.0f, 0.0f)}, }; D3D11_TEXTURE2D_DESC FrameDesc; m_SharedSurf->GetDesc(&FrameDesc); D3D11_SHADER_RESOURCE_VIEW_DESC ShaderDesc; ShaderDesc.Format = FrameDesc.Format; ShaderDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; ShaderDesc.Texture2D.MostDetailedMip = FrameDesc.MipLevels - 1; ShaderDesc.Texture2D.MipLevels = FrameDesc.MipLevels; // Create new shader resource view ID3D11ShaderResourceView* ShaderResource = nullptr; hr = m_Device->CreateShaderResourceView(m_SharedSurf, &ShaderDesc, &ShaderResource); if (FAILED(hr)) { return ProcessFailure(m_Device, L"Failed to create shader resource when drawing a frame", L"Error", hr, SystemTransitionsExpectedErrors); } // Set resources UINT Stride = sizeof(VERTEX); UINT Offset = 0; FLOAT blendFactor[4] = {0.f, 0.f, 0.f, 0.f}; m_DeviceContext->OMSetBlendState(nullptr, blendFactor, 0xffffffff); m_DeviceContext->OMSetRenderTargets(1, &m_RTV, nullptr); m_DeviceContext->VSSetShader(m_VertexShader, nullptr, 0); m_DeviceContext->PSSetShader(m_PixelShader, nullptr, 0); m_DeviceContext->PSSetShaderResources(0, 1, &ShaderResource); m_DeviceContext->PSSetSamplers(0, 1, &m_SamplerLinear); m_DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); D3D11_BUFFER_DESC BufferDesc; RtlZeroMemory(&BufferDesc, sizeof(BufferDesc)); BufferDesc.Usage = D3D11_USAGE_DEFAULT; BufferDesc.ByteWidth = sizeof(VERTEX) * NUMVERTICES; BufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; BufferDesc.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA InitData; RtlZeroMemory(&InitData, sizeof(InitData)); InitData.pSysMem = Vertices; ID3D11Buffer* VertexBuffer = nullptr; // Create vertex buffer hr = m_Device->CreateBuffer(&BufferDesc, &InitData, &VertexBuffer); if (FAILED(hr)) { ShaderResource->Release(); ShaderResource = nullptr; return ProcessFailure(m_Device, L"Failed to create vertex buffer when drawing a frame", L"Error", hr, SystemTransitionsExpectedErrors); } m_DeviceContext->IASetVertexBuffers(0, 1, &VertexBuffer, &Stride, &Offset); // Draw textured quad onto render target m_DeviceContext->Draw(NUMVERTICES, 0); VertexBuffer->Release(); VertexBuffer = nullptr; // Release shader resource ShaderResource->Release(); ShaderResource = nullptr; return DUPL_RETURN_SUCCESS; }
Playable2D::~Playable2D() { ID3D11ShaderResourceView* tex = m_texture.release(); tex->Release(); }
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; }
_Use_decl_annotations_ void DGSLEffectFactory::Impl::CreateTexture( const WCHAR* name, ID3D11DeviceContext* deviceContext, ID3D11ShaderResourceView** textureView ) { if ( !name || !textureView ) throw std::exception("invalid arguments"); #if defined(_XBOX_ONE) && defined(_TITLE) UNREFERENCED_PARAMETER(deviceContext); #endif auto it = mTextureCache.find( name ); if ( mSharing && it != mTextureCache.end() ) { ID3D11ShaderResourceView* srv = it->second.Get(); srv->AddRef(); *textureView = srv; } else { WCHAR fullName[MAX_PATH] = {0}; wcscpy_s( fullName, mPath ); wcscat_s( fullName, name ); #if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (_WIN32_WINNT > _WIN32_WINNT_WIN8) WCHAR ext[_MAX_EXT]; _wsplitpath_s( name, nullptr, 0, nullptr, 0, nullptr, 0, ext, _MAX_EXT ); if ( _wcsicmp( ext, L".dds" ) == 0 ) { HRESULT hr = CreateDDSTextureFromFile( device.Get(), fullName, nullptr, textureView ); if ( FAILED(hr) ) { DebugTrace( "CreateDDSTextureFromFile failed (%08X) for '%S'\n", hr, fullName ); throw std::exception( "CreateDDSTextureFromFile" ); } } #if !defined(_XBOX_ONE) || !defined(_TITLE) else if ( deviceContext ) { std::lock_guard<std::mutex> lock(mutex); HRESULT hr = CreateWICTextureFromFile( device.Get(), deviceContext, fullName, nullptr, textureView ); if ( FAILED(hr) ) { DebugTrace( "CreateWICTextureFromFile failed (%08X) for '%S'\n", hr, fullName ); throw std::exception( "CreateWICTextureFromFile" ); } } #endif else { HRESULT hr = CreateWICTextureFromFile( device.Get(), fullName, nullptr, textureView ); if ( FAILED(hr) ) { DebugTrace( "CreateWICTextureFromFile failed (%08X) for '%S'\n", hr, fullName ); throw std::exception( "CreateWICTextureFromFile" ); } } #else UNREFERENCED_PARAMETER( deviceContext ); HRESULT hr = CreateDDSTextureFromFile( device.Get(), fullName, nullptr, textureView ); if ( FAILED(hr) ) { DebugTrace( "CreateDDSTextureFromFile failed (%08X) for '%S'\n", hr, fullName ); throw std::exception( "CreateDDSTextureFromFile" ); } #endif if ( mSharing && *name && it == mTextureCache.end() ) { std::lock_guard<std::mutex> lock(mutex); mTextureCache.insert( TextureCache::value_type( name, *textureView ) ); } } }
HTEXTURE HGE_CALL HGE_Impl::Texture_Load(const char *filename, hgeU32 size, bool bMipmap) { HRESULT hr; void *data; hgeU32 _size; ID3D11Resource* pRes; ID3D11Resource* pStagingRes; ID3D11Texture2D* pTex; ID3D11ShaderResourceView* pSRV; //D3DXIMAGE_INFO info; CTextureList *texItem; //load file to buffer if (size) { //If argument is already the buffer data = (void *)filename; _size = size; } else { data = pHGE->Resource_Load(filename, &_size); if (!data) return NULL; } //Get image info D3DX11_IMAGE_INFO imgInfo; hr = D3DX11GetImageInfoFromMemory( (LPCSTR)data, _size, NULL, &imgInfo, NULL); if (hr) { _PostError("Cannot get image info.\n"); if (!size) Resource_Free(data); return NULL; } D3DX11_IMAGE_LOAD_INFO loadImgInfo; loadImgInfo.MipLevels = bMipmap ? 0 : 1; loadImgInfo.Format = DXGI_FORMAT_R8G8B8A8_UNORM; loadImgInfo.Usage = D3D11_USAGE_STAGING; loadImgInfo.BindFlags = 0;// (autogen) ? (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET) : (D3D11_BIND_SHADER_RESOURCE); loadImgInfo.CpuAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; loadImgInfo.MiscFlags = 0; //Create Staging texture first hr = D3DX11CreateTextureFromMemory( m_pD3DDevice, (LPCVOID)data, _size, &loadImgInfo, NULL, &pStagingRes, 0); if (hr) { _PostError("Can't create texture"); if (!size) Resource_Free(data); return NULL; } //shouldn't access the file buffer anymore if (!size) Resource_Free(data); //Convert 0xFF00FFFF to transparent color D3D11_TEXTURE2D_DESC TDesc; ((ID3D11Texture2D*)pStagingRes)->GetDesc(&TDesc); if (bUseTransparentColor) { DWORD* pLockPtr = (DWORD*)Texture_Lock((HTEXTURE)pStagingRes, false); int end = TDesc.Width * TDesc.Height; for (int i = 0; i < end; i++) { DWORD& currentPixel = pLockPtr[i]; if (GETR(currentPixel) == 0xFF && GETG(currentPixel) == 0x00 && GETB(currentPixel) == 0xFF) { currentPixel = ARGB(0x00, 0x00, 0x00, 0x00); } } //Create default texture with data //from the staging texture TDesc.Usage = D3D11_USAGE_DEFAULT; TDesc.CPUAccessFlags = 0; TDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; TDesc.MipLevels = bMipmap ? 0 : 1; D3D11_SUBRESOURCE_DATA sr; sr.pSysMem = pLockPtr; sr.SysMemPitch = TDesc.Width * 4; sr.SysMemSlicePitch = TDesc.Width * TDesc.Height * 4; hr = m_pD3DDevice->CreateTexture2D(&TDesc, &sr, &pTex); if (hr) { _PostError("Can't create texture"); if (!size) Resource_Free(data); pStagingRes->Release(); return NULL; } Texture_Unlock((HTEXTURE)pStagingRes); SAFE_RELEASE(pStagingRes); } D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; memset(&SRVDesc, 0, sizeof(SRVDesc)); SRVDesc.Format = TDesc.Format; SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; SRVDesc.Texture2D.MipLevels = bMipmap ? 0 : 1; hr = m_pD3DDevice->CreateShaderResourceView(pTex, &SRVDesc, &pSRV); if (hr) { _PostError("Can't create texture"); if (!size) Resource_Free(data); return NULL; } pSRV->GetResource(&pRes); // hr = CreateWICTextureFromMemory( // pd3dDevice, // pd3dImmediateContext, // (uint8_t*)data, // _size, // &pRes, // &pSRV, // 0); texItem = new CTextureList; texItem->tex = (HTEXTURE)pTex; texItem->m_pSRV = pSRV; texItem->width = TDesc.Width; texItem->height = TDesc.Height; texItem->next = textures; textures = texItem; return (HTEXTURE)texItem; }
_Use_decl_annotations_ void EffectFactory::Impl::CreateTexture(const wchar_t* name, ID3D11DeviceContext* deviceContext, ID3D11ShaderResourceView** textureView) { if (!name || !textureView) throw std::exception("invalid arguments"); #if defined(_XBOX_ONE) && defined(_TITLE) UNREFERENCED_PARAMETER(deviceContext); #endif auto it = mTextureCache.find(name); if (mSharing && it != mTextureCache.end()) { ID3D11ShaderResourceView* srv = it->second.Get(); srv->AddRef(); *textureView = srv; } else { wchar_t fullName[MAX_PATH] = {}; wcscpy_s(fullName, mPath); wcscat_s(fullName, name); WIN32_FILE_ATTRIBUTE_DATA fileAttr = {}; if (!GetFileAttributesExW(fullName, GetFileExInfoStandard, &fileAttr)) { // Try Current Working Directory (CWD) wcscpy_s(fullName, name); if (!GetFileAttributesExW(fullName, GetFileExInfoStandard, &fileAttr)) { DebugTrace("EffectFactory could not find texture file '%ls'\n", name); throw std::exception("CreateTexture"); } } wchar_t ext[_MAX_EXT]; _wsplitpath_s(name, nullptr, 0, nullptr, 0, nullptr, 0, ext, _MAX_EXT); if (_wcsicmp(ext, L".dds") == 0) { HRESULT hr = CreateDDSTextureFromFileEx( mDevice.Get(), fullName, 0, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, mForceSRGB, nullptr, textureView); if (FAILED(hr)) { DebugTrace("CreateDDSTextureFromFile failed (%08X) for '%ls'\n", hr, fullName); throw std::exception("CreateDDSTextureFromFile"); } } #if !defined(_XBOX_ONE) || !defined(_TITLE) else if (deviceContext) { std::lock_guard<std::mutex> lock(mutex); HRESULT hr = CreateWICTextureFromFileEx( mDevice.Get(), deviceContext, fullName, 0, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, mForceSRGB ? WIC_LOADER_FORCE_SRGB : WIC_LOADER_DEFAULT, nullptr, textureView); if (FAILED(hr)) { DebugTrace("CreateWICTextureFromFile failed (%08X) for '%ls'\n", hr, fullName); throw std::exception("CreateWICTextureFromFile"); } } #endif else { HRESULT hr = CreateWICTextureFromFileEx( mDevice.Get(), fullName, 0, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, mForceSRGB ? WIC_LOADER_FORCE_SRGB : WIC_LOADER_DEFAULT, nullptr, textureView); if (FAILED(hr)) { DebugTrace("CreateWICTextureFromFile failed (%08X) for '%ls'\n", hr, fullName); throw std::exception("CreateWICTextureFromFile"); } } if (mSharing && *name && it == mTextureCache.end()) { std::lock_guard<std::mutex> lock(mutex); TextureCache::value_type v(name, *textureView); mTextureCache.insert(v); } } }
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; }
//-------------------------------------------------------------------------------------- // Encode the source texture to BC7 and store the result in a buffer // The source texture can only have 1 sub resource, i.e. it must be a signle 2D texture which has only 1 mip level // The job of breaking down texture arrays, or texture with multiple mip levels is taken care of in the base class //-------------------------------------------------------------------------------------- HRESULT CGPUBC7Encoder::GPU_Encode( ID3D11Device* pDevice, ID3D11DeviceContext* pContext, ID3D11Texture2D* pSrcTexture, DXGI_FORMAT dstFormat, ID3D11Buffer** ppDstTextureAsBufOut ) { ID3D11ShaderResourceView* pSRV = nullptr; ID3D11Buffer* pErrBestModeBuffer[2] = { nullptr, nullptr }; ID3D11UnorderedAccessView* pUAV = nullptr; ID3D11UnorderedAccessView* pErrBestModeUAV[2] = { nullptr, nullptr }; ID3D11ShaderResourceView* pErrBestModeSRV[2] = { nullptr, nullptr }; ID3D11Buffer* pCBCS = nullptr; if ( !(dstFormat == DXGI_FORMAT_BC7_UNORM || dstFormat == DXGI_FORMAT_BC7_UNORM_SRGB) || !ppDstTextureAsBufOut ) { return E_INVALIDARG; } D3D11_TEXTURE2D_DESC texSrcDesc; pSrcTexture->GetDesc( &texSrcDesc ); HRESULT hr = S_OK; // Create a SRV for input texture { D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = {}; SRVDesc.Texture2D.MipLevels = texSrcDesc.MipLevels; SRVDesc.Texture2D.MostDetailedMip = 0; SRVDesc.Format = texSrcDesc.Format; SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; V_GOTO( pDevice->CreateShaderResourceView( pSrcTexture, &SRVDesc, &pSRV ) ); #if defined(_DEBUG) || defined(PROFILE) if ( pSRV ) { pSRV->SetPrivateData( WKPDID_D3DDebugObjectName, sizeof( "BC7 SRV" ) - 1, "BC7 SRV" ); } #endif } // Create output buffer D3D11_BUFFER_DESC sbOutDesc; { sbOutDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE; sbOutDesc.CPUAccessFlags = 0; sbOutDesc.Usage = D3D11_USAGE_DEFAULT; sbOutDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; sbOutDesc.StructureByteStride = sizeof( BufferBC6HBC7 ); sbOutDesc.ByteWidth = texSrcDesc.Height * texSrcDesc.Width * sizeof( BufferBC6HBC7 ) / BLOCK_SIZE; //+ texSrcDesc.Height * texSrcDesc.Width * sizeof( BufferBC7 ) * 5;//For dump V_GOTO( pDevice->CreateBuffer(&sbOutDesc, nullptr, ppDstTextureAsBufOut) ); V_GOTO( pDevice->CreateBuffer(&sbOutDesc, nullptr, &pErrBestModeBuffer[0]) ); V_GOTO( pDevice->CreateBuffer(&sbOutDesc, nullptr, &pErrBestModeBuffer[1]) ); _Analysis_assume_( pErrBestModeBuffer[0] != 0 ); #if defined(_DEBUG) || defined(PROFILE) if ( *ppDstTextureAsBufOut ) { (*ppDstTextureAsBufOut)->SetPrivateData( WKPDID_D3DDebugObjectName, sizeof( "BC7 Dest" ) - 1, "BC7 Dest" ); } if ( pErrBestModeBuffer[0] ) { pErrBestModeBuffer[0]->SetPrivateData( WKPDID_D3DDebugObjectName, sizeof( "BC7 ErrBest0" ) - 1, "BC7 ErrBest0" ); } if ( pErrBestModeBuffer[1] ) { pErrBestModeBuffer[1]->SetPrivateData( WKPDID_D3DDebugObjectName, sizeof( "BC7 ErrBest1" ) - 1, "BC7 ErrBest1" ); } #endif } // Create UAV of the output texture { D3D11_UNORDERED_ACCESS_VIEW_DESC UAVDesc = {}; UAVDesc.Buffer.FirstElement = 0; UAVDesc.Buffer.NumElements = sbOutDesc.ByteWidth / sbOutDesc.StructureByteStride; UAVDesc.Format = DXGI_FORMAT_UNKNOWN; UAVDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; #pragma warning (push) #pragma warning (disable:6387) V_GOTO( pDevice->CreateUnorderedAccessView( *ppDstTextureAsBufOut, &UAVDesc, &pUAV ) ); V_GOTO( pDevice->CreateUnorderedAccessView( pErrBestModeBuffer[0], &UAVDesc, &pErrBestModeUAV[0] ) ); V_GOTO( pDevice->CreateUnorderedAccessView( pErrBestModeBuffer[1], &UAVDesc, &pErrBestModeUAV[1] ) ); #pragma warning (pop) #if defined(_DEBUG) || defined(PROFILE) if ( pUAV ) { pUAV->SetPrivateData( WKPDID_D3DDebugObjectName, sizeof( "BC7 Dest UAV" ) - 1, "BC7 Dest UAV" ); } if ( pErrBestModeUAV[0] ) { pErrBestModeUAV[0]->SetPrivateData( WKPDID_D3DDebugObjectName, sizeof( "BC7 ErrBest0 UAV" ) - 1, "BC7 ErrBest0 UAV" ); } if ( pErrBestModeUAV[1] ) { pErrBestModeUAV[1]->SetPrivateData( WKPDID_D3DDebugObjectName, sizeof( "BC7 ErrBest1 UAV" ) - 1, "BC7 ErrBest1 UAV" ); } #endif } { D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = {}; SRVDesc.Buffer.FirstElement = 0; SRVDesc.Buffer.NumElements = texSrcDesc.Height * texSrcDesc.Width / BLOCK_SIZE; SRVDesc.Format = DXGI_FORMAT_UNKNOWN; SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; #pragma warning (push) #pragma warning (disable:6387) V_GOTO( pDevice->CreateShaderResourceView( pErrBestModeBuffer[0], &SRVDesc, &pErrBestModeSRV[0]) ); V_GOTO( pDevice->CreateShaderResourceView( pErrBestModeBuffer[1], &SRVDesc, &pErrBestModeSRV[1]) ); #pragma warning (pop) #if defined(_DEBUG) || defined(PROFILE) if ( pErrBestModeSRV[0] ) { pErrBestModeSRV[0]->SetPrivateData( WKPDID_D3DDebugObjectName, sizeof( "BC7 ErrBest0 SRV" ) - 1, "BC7 ErrBest0 SRV" ); } if ( pErrBestModeSRV[1] ) { pErrBestModeSRV[1]->SetPrivateData( WKPDID_D3DDebugObjectName, sizeof( "BC7 ErrBest1 SRV" ) - 1, "BC7 ErrBest1 SRV" ); } #endif } // Create 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( UINT ) * 8; V_GOTO( pDevice->CreateBuffer( &cbDesc, nullptr, &pCBCS ) ); #if defined(_DEBUG) || defined(PROFILE) if ( pCBCS ) { pCBCS->SetPrivateData( WKPDID_D3DDebugObjectName, sizeof( "BC7Encode" ) - 1, "BC7Encode" ); } #endif } int const MAX_BLOCK_BATCH = 64; int num_total_blocks = texSrcDesc.Width / BLOCK_SIZE_X * texSrcDesc.Height / BLOCK_SIZE_Y; int num_blocks = num_total_blocks; int start_block_id = 0; while (num_blocks > 0) { int n = min(num_blocks, MAX_BLOCK_BATCH); UINT uThreadGroupCount = n; { D3D11_MAPPED_SUBRESOURCE cbMapped; pContext->Map( pCBCS, 0, D3D11_MAP_WRITE_DISCARD, 0, &cbMapped ); UINT param[8]; param[0] = texSrcDesc.Width; param[1] = texSrcDesc.Width / BLOCK_SIZE_X; param[2] = dstFormat; param[3] = 0; param[4] = start_block_id; param[5] = num_total_blocks; *((float*)¶m[6]) = m_fAlphaWeight; memcpy( cbMapped.pData, param, sizeof( param ) ); pContext->Unmap( pCBCS, 0 ); } ID3D11ShaderResourceView* pSRVs[] = { pSRV, nullptr }; RunComputeShader( pContext, m_pTryMode456CS, pSRVs, 2, pCBCS, pErrBestModeUAV[0], __max(uThreadGroupCount / 4, 1), 1, 1 ); for (int i = 0; i < 3; ++ i) { int modes[] = { 1, 3, 7 }; { D3D11_MAPPED_SUBRESOURCE cbMapped; pContext->Map( pCBCS, 0, D3D11_MAP_WRITE_DISCARD, 0, &cbMapped ); UINT param[8]; param[0] = texSrcDesc.Width; param[1] = texSrcDesc.Width / BLOCK_SIZE_X; param[2] = dstFormat; param[3] = modes[i]; param[4] = start_block_id; param[5] = num_total_blocks; *((float*)¶m[6]) = m_fAlphaWeight; memcpy( cbMapped.pData, param, sizeof( param ) ); pContext->Unmap( pCBCS, 0 ); } pSRVs[1] = pErrBestModeSRV[i & 1]; RunComputeShader( pContext, m_pTryMode137CS, pSRVs, 2, pCBCS, pErrBestModeUAV[!(i & 1)], uThreadGroupCount, 1, 1 ); } for (int i = 0; i < 2; ++ i) { int modes[] = { 0, 2 }; { D3D11_MAPPED_SUBRESOURCE cbMapped; pContext->Map( pCBCS, 0, D3D11_MAP_WRITE_DISCARD, 0, &cbMapped ); UINT param[8]; param[0] = texSrcDesc.Width; param[1] = texSrcDesc.Width / BLOCK_SIZE_X; param[2] = dstFormat; param[3] = modes[i]; param[4] = start_block_id; param[5] = num_total_blocks; *((float*)¶m[6]) = m_fAlphaWeight; memcpy( cbMapped.pData, param, sizeof( param ) ); pContext->Unmap( pCBCS, 0 ); } pSRVs[1] = pErrBestModeSRV[!(i & 1)]; RunComputeShader( pContext, m_pTryMode02CS, pSRVs, 2, pCBCS, pErrBestModeUAV[i & 1], uThreadGroupCount, 1, 1 ); } pSRVs[1] = pErrBestModeSRV[1]; RunComputeShader( pContext, m_pEncodeBlockCS, pSRVs, 2, pCBCS, pUAV, __max(uThreadGroupCount / 4, 1), 1, 1 ); start_block_id += n; num_blocks -= n; } quit: SAFE_RELEASE(pSRV); SAFE_RELEASE(pUAV); SAFE_RELEASE(pErrBestModeSRV[0]); SAFE_RELEASE(pErrBestModeSRV[1]); SAFE_RELEASE(pErrBestModeUAV[0]); SAFE_RELEASE(pErrBestModeUAV[1]); SAFE_RELEASE(pErrBestModeBuffer[0]); SAFE_RELEASE(pErrBestModeBuffer[1]); SAFE_RELEASE(pCBCS); return hr; }
~Texture() { m_ResourceView->Release(); m_SamplerState->Release(); }