bool DXTexture::Save(const std::string& filename, unsigned int level) { // We can't dump compressed textures currently (it would mean drawing them to a RGBA8 // framebuffer, and saving that). TextureCache does not call Save for custom textures // anyway, so this is fine for now. _assert_(m_config.format == AbstractTextureFormat::RGBA8); // Create a staging/readback texture with the dimensions of the specified mip level. u32 mip_width = std::max(m_config.width >> level, 1u); u32 mip_height = std::max(m_config.height >> level, 1u); CD3D11_TEXTURE2D_DESC staging_texture_desc(DXGI_FORMAT_R8G8B8A8_UNORM, mip_width, mip_height, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ); ID3D11Texture2D* staging_texture; HRESULT hr = D3D::device->CreateTexture2D(&staging_texture_desc, nullptr, &staging_texture); if (FAILED(hr)) { WARN_LOG(VIDEO, "Failed to create texture dumping readback texture: %X", static_cast<u32>(hr)); return false; } // Copy the selected mip level to the staging texture. CD3D11_BOX src_box(0, 0, 0, mip_width, mip_height, 1); D3D::context->CopySubresourceRegion(staging_texture, 0, 0, 0, 0, m_texture->GetTex(), D3D11CalcSubresource(level, 0, m_config.levels), &src_box); // Map the staging texture to client memory, and encode it as a .png image. D3D11_MAPPED_SUBRESOURCE map; hr = D3D::context->Map(staging_texture, 0, D3D11_MAP_READ, 0, &map); if (FAILED(hr)) { WARN_LOG(VIDEO, "Failed to map texture dumping readback texture: %X", static_cast<u32>(hr)); staging_texture->Release(); return false; } bool encode_result = TextureToPng(reinterpret_cast<u8*>(map.pData), map.RowPitch, filename, mip_width, mip_height); D3D::context->Unmap(staging_texture, 0); staging_texture->Release(); return encode_result; }
void D3D11TextureCore::writeData(const PixelData& src, UINT32 mipLevel, UINT32 face, bool discardWholeBuffer) { PixelFormat format = mProperties.getFormat(); if (mProperties.getMultisampleCount() > 1) BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly."); mipLevel = Math::clamp(mipLevel, (UINT32)mipLevel, mProperties.getNumMipmaps()); face = Math::clamp(face, (UINT32)0, mProperties.getNumFaces() - 1); if (face > 0 && mProperties.getTextureType() == TEX_TYPE_3D) BS_EXCEPT(InvalidStateException, "3D texture arrays are not supported."); if ((mProperties.getUsage() & TU_DYNAMIC) != 0) { PixelData myData = lock(discardWholeBuffer ? GBL_WRITE_ONLY_DISCARD : GBL_WRITE_ONLY, mipLevel, face); PixelUtil::bulkPixelConversion(src, myData); unlock(); } else if ((mProperties.getUsage() & TU_DEPTHSTENCIL) == 0) { D3D11RenderAPI* rs = static_cast<D3D11RenderAPI*>(RenderAPICore::instancePtr()); D3D11Device& device = rs->getPrimaryDevice(); UINT subresourceIdx = D3D11CalcSubresource(mipLevel, face, mProperties.getNumMipmaps() + 1); UINT32 rowWidth = D3D11Mappings::getSizeInBytes(format, src.getWidth()); UINT32 sliceWidth = D3D11Mappings::getSizeInBytes(format, src.getWidth(), src.getHeight()); device.getImmediateContext()->UpdateSubresource(mTex, subresourceIdx, nullptr, src.getData(), rowWidth, sliceWidth); if (device.hasError()) { String errorDescription = device.getErrorDescription(); BS_EXCEPT(RenderingAPIException, "D3D11 device cannot map texture\nError Description:" + errorDescription); } BS_INC_RENDER_STAT_CAT(ResWrite, RenderStatObject_Texture); } else { BS_EXCEPT(RenderingAPIException, "Trying to write into a buffer with unsupported usage: " + toString(mProperties.getUsage())); } }
//----------------------------------------------------------------------------- void D3D11HardwarePixelBuffer::_unmapstagingbuffer(bool copyback) { _unmap(mStagingBuffer); if(copyback) { if(mLockBox.getHeight() == mParentTexture->getHeight() && mLockBox.getWidth() == mParentTexture->getWidth()) mDevice.GetImmediateContext()->CopyResource(mParentTexture->getTextureResource(), mStagingBuffer); else { D3D11_BOX dstBoxDx11 = OgreImageBoxToDx11Box(mLockBox); dstBoxDx11.front = 0; dstBoxDx11.back = mLockBox.getDepth(); unsigned int subresource = D3D11CalcSubresource(mSubresourceIndex, mLockBox.front, mParentTexture->getNumMipmaps()+1); mDevice.GetImmediateContext()->CopySubresourceRegion(mParentTexture->getTextureResource(), subresource, mLockBox.left, mLockBox.top, mSubresourceIndex, mStagingBuffer, subresource, &dstBoxDx11); } } }
void D3D11RenderTarget::captureColorBuffer(ColorImageR8G8B8A8 &result) { auto &context = m_graphics->getContext(); context.CopyResource(m_captureTexture, m_texture); result.allocate(m_width, m_height); D3D11_MAPPED_SUBRESOURCE resource; UINT subresource = D3D11CalcSubresource(0, 0, 0); HRESULT hr = context.Map(m_captureTexture, subresource, D3D11_MAP_READ, 0, &resource); const BYTE *data = (BYTE *)resource.pData; for (UINT y = 0; y < m_height; y++) { memcpy(&result(0U, y), data + resource.RowPitch * y, m_width * sizeof(ml::vec4uc)); } context.Unmap(m_captureTexture, subresource); }
_Use_decl_annotations_ void AssetLoader::LoadMipsIntoLocation(const char* filename, uint32_t sourceStartingMip, uint32_t numMips, const ComPtr<ID3D11Texture2D>& dest, uint32_t destIndex, uint32_t destStartingMip) const { char source[MAX_PATH]; sprintf_s(source, "%s%s", GetConfig().ContentRoot, filename); ImageFileData data; LoadImageFileData(source, &data); ComPtr<ID3D11Device> device; dest->GetDevice(&device); ComPtr<ID3D11DeviceContext> context; device->GetImmediateContext(&context); D3D11_TEXTURE2D_DESC desc; dest->GetDesc(&desc); assert(destStartingMip + numMips <= desc.MipLevels); assert(sourceStartingMip + numMips <= (uint32_t)data.MipCount); uint8_t* dataSrc = (uint8_t*)data.Data; uint32_t dataHeight = data.Height; uint32_t dataPitch = data.Pitch; // advance to source starting mip for (uint32_t i = 0; i < sourceStartingMip; ++i) { dataSrc += static_cast<uint32_t>(dataPitch * dataHeight); dataHeight /= 2; dataPitch /= 2; } auto lock = GetGraphics().LockContext(); for (uint8_t i = 0; i < numMips; ++i) { context->UpdateSubresource(dest.Get(), D3D11CalcSubresource(destStartingMip + i, destIndex, numMips), nullptr, dataSrc, dataPitch, static_cast<uint32_t>(dataPitch * dataHeight)); dataSrc += static_cast<uint32_t>(dataPitch * dataHeight); dataHeight /= 2; dataPitch /= 2; } }
void DXStagingTexture::CopyToTexture(const MathUtil::Rectangle<int>& src_rect, AbstractTexture* dst, const MathUtil::Rectangle<int>& dst_rect, u32 dst_layer, u32 dst_level) { _assert_(m_type == StagingTextureType::Upload); _assert_(src_rect.GetWidth() == dst_rect.GetWidth() && src_rect.GetHeight() == dst_rect.GetHeight()); _assert_(src_rect.left >= 0 && static_cast<u32>(src_rect.right) <= m_config.width && src_rect.top >= 0 && static_cast<u32>(src_rect.bottom) <= m_config.height); _assert_(dst_rect.left >= 0 && static_cast<u32>(dst_rect.right) <= dst->GetConfig().width && dst_rect.top >= 0 && static_cast<u32>(dst_rect.bottom) <= dst->GetConfig().height); if (IsMapped()) DXStagingTexture::Unmap(); CD3D11_BOX src_box(src_rect.left, src_rect.top, 0, src_rect.right, src_rect.bottom, 1); D3D::context->CopySubresourceRegion( static_cast<const DXTexture*>(dst)->GetRawTexIdentifier()->GetTex(), D3D11CalcSubresource(dst_level, dst_layer, dst->GetConfig().levels), static_cast<u32>(dst_rect.left), static_cast<u32>(dst_rect.top), 0, m_tex, 0, &src_box); }
_Use_decl_annotations_ Texture AssetLoader::LoadTextureFromMemory(uint32_t width, uint32_t height, uint32_t pitch, const uint8_t* data, DXGI_FORMAT format, uint8_t mipCount, bool supportsMips) const { if (mipCount > 1) { assert(supportsMips); } auto& graphics = GetGraphics(); auto pool = graphics.GetPoolWithSpace(width, height, format, supportsMips, 1); uint32_t index = pool->ReserveRange(1); ComPtr<ID3D11Resource> resource; pool->Get()->GetResource(&resource); ComPtr<ID3D11Device> device; resource->GetDevice(&device); ComPtr<ID3D11DeviceContext> context; device->GetImmediateContext(&context); D3D11_SHADER_RESOURCE_VIEW_DESC desc; pool->Get()->GetDesc(&desc); uint32_t numMips = std::min(desc.Texture2DArray.MipLevels, (UINT)mipCount); uint8_t* dataSrc = (uint8_t*)data; uint32_t dataHeight = height; uint32_t dataPitch = pitch; for (uint8_t mipIndex = 0; mipIndex < numMips; mipIndex++) { context->UpdateSubresource(resource.Get(), D3D11CalcSubresource(mipIndex, index, numMips), nullptr, dataSrc, dataPitch, static_cast<uint32_t>(dataPitch * dataHeight)); dataSrc += static_cast<uint32_t>(dataPitch * dataHeight); dataHeight /= 2; dataPitch /= 2; } return Texture(pool, index); }
void DXStagingTexture::CopyFromTexture(const AbstractTexture* src, const MathUtil::Rectangle<int>& src_rect, u32 src_layer, u32 src_level, const MathUtil::Rectangle<int>& dst_rect) { _assert_(m_type == StagingTextureType::Readback); _assert_(src_rect.GetWidth() == dst_rect.GetWidth() && src_rect.GetHeight() == dst_rect.GetHeight()); _assert_(src_rect.left >= 0 && static_cast<u32>(src_rect.right) <= src->GetConfig().width && src_rect.top >= 0 && static_cast<u32>(src_rect.bottom) <= src->GetConfig().height); _assert_(dst_rect.left >= 0 && static_cast<u32>(dst_rect.right) <= m_config.width && dst_rect.top >= 0 && static_cast<u32>(dst_rect.bottom) <= m_config.height); if (IsMapped()) DXStagingTexture::Unmap(); CD3D11_BOX src_box(src_rect.left, src_rect.top, 0, src_rect.right, src_rect.bottom, 1); D3D::context->CopySubresourceRegion( m_tex, 0, static_cast<u32>(dst_rect.left), static_cast<u32>(dst_rect.top), 0, static_cast<const DXTexture*>(src)->GetRawTexIdentifier()->GetTex(), D3D11CalcSubresource(src_level, src_layer, src->GetConfig().levels), &src_box); m_needs_flush = true; }
void myD3D11DeviceContext::readTexture(ID3D11Texture2D *inputTexture, Bitmap &result) { ID3D11Texture2D *captureTexture; D3D11_TEXTURE2D_DESC renderDesc; inputTexture->GetDesc(&renderDesc); renderDesc.MipLevels = 1; renderDesc.ArraySize = 1; renderDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; renderDesc.SampleDesc.Count = 1; renderDesc.SampleDesc.Quality = 0; renderDesc.BindFlags = 0; renderDesc.MiscFlags = 0; renderDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; renderDesc.Usage = D3D11_USAGE_STAGING; assets->device->base->CreateTexture2D(&renderDesc, nullptr, &captureTexture); assets->context->base->CopyResource(captureTexture, inputTexture); result.allocate(renderDesc.Width, renderDesc.Height); D3D11_MAPPED_SUBRESOURCE resource; UINT subresource = D3D11CalcSubresource(0, 0, 0); HRESULT hr = assets->context->base->Map(captureTexture, subresource, D3D11_MAP_READ, 0, &resource); const BYTE *data = (BYTE *)resource.pData; for (UINT y = 0; y < renderDesc.Height; y++) { memcpy(&result(0U, y), data + resource.RowPitch * y, renderDesc.Width * sizeof(ml::vec4uc)); } assets->context->base->Unmap(captureTexture, subresource); captureTexture->Release(); }
gl::Error Image11::createStagingTexture() { if (mStagingTexture.valid()) { return gl::NoError(); } ASSERT(mWidth > 0 && mHeight > 0 && mDepth > 0); const DXGI_FORMAT dxgiFormat = getDXGIFormat(); const auto &formatInfo = d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); int lodOffset = 1; GLsizei width = mWidth; GLsizei height = mHeight; // adjust size if needed for compressed textures d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset); if (mTarget == GL_TEXTURE_3D) { D3D11_TEXTURE3D_DESC desc; desc.Width = width; desc.Height = height; desc.Depth = mDepth; desc.MipLevels = lodOffset + 1; desc.Format = dxgiFormat; desc.Usage = D3D11_USAGE_STAGING; desc.BindFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.MiscFlags = 0; if (formatInfo.dataInitializerFunction != nullptr) { std::vector<D3D11_SUBRESOURCE_DATA> initialData; std::vector<std::vector<BYTE>> textureData; d3d11::GenerateInitialTextureData(mInternalFormat, mRenderer->getRenderer11DeviceCaps(), width, height, mDepth, lodOffset + 1, &initialData, &textureData); ANGLE_TRY( mRenderer->allocateTexture(desc, formatInfo, initialData.data(), &mStagingTexture)); } else { ANGLE_TRY(mRenderer->allocateTexture(desc, formatInfo, &mStagingTexture)); } mStagingTexture.setDebugName("Image11::StagingTexture3D"); mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); } else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_CUBE_MAP) { D3D11_TEXTURE2D_DESC desc; desc.Width = width; desc.Height = height; desc.MipLevels = lodOffset + 1; desc.ArraySize = 1; desc.Format = dxgiFormat; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_STAGING; desc.BindFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.MiscFlags = 0; if (formatInfo.dataInitializerFunction != nullptr) { std::vector<D3D11_SUBRESOURCE_DATA> initialData; std::vector<std::vector<BYTE>> textureData; d3d11::GenerateInitialTextureData(mInternalFormat, mRenderer->getRenderer11DeviceCaps(), width, height, 1, lodOffset + 1, &initialData, &textureData); ANGLE_TRY( mRenderer->allocateTexture(desc, formatInfo, initialData.data(), &mStagingTexture)); } else { ANGLE_TRY(mRenderer->allocateTexture(desc, formatInfo, &mStagingTexture)); } mStagingTexture.setDebugName("Image11::StagingTexture2D"); mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); } else { UNREACHABLE(); } mDirty = false; return gl::NoError(); }
void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces) { AssertFatal( faces, "GFXD3D11Cubemap::initStatic - Got null GFXTexHandle!" ); AssertFatal( *faces, "empty texture passed to CubeMap::create" ); // NOTE - check tex sizes on all faces - they MUST be all same size mTexSize = faces->getWidth(); mFaceFormat = faces->getFormat(); bool compressed = isCompressed(mFaceFormat); UINT bindFlags = D3D11_BIND_SHADER_RESOURCE; UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; if (!compressed) { bindFlags |= D3D11_BIND_RENDER_TARGET; miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; } U32 mipLevels = faces->getPointer()->getMipLevels(); if (mipLevels > 1) mAutoGenMips = true; D3D11_TEXTURE2D_DESC desc; ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC)); desc.Width = mTexSize; desc.Height = mTexSize; desc.MipLevels = mAutoGenMips ? 0 : mipLevels; desc.ArraySize = 6; desc.Format = GFXD3D11TextureFormat[mFaceFormat]; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; desc.BindFlags = bindFlags; desc.MiscFlags = miscFlags; desc.CPUAccessFlags = 0; HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, &mTexture); if (FAILED(hr)) { AssertFatal(false, "GFXD3D11Cubemap:initStatic(GFXTexhandle *faces) - failed to create texcube texture"); } for (U32 i = 0; i < CubeFaces; i++) { GFXD3D11TextureObject *texObj = static_cast<GFXD3D11TextureObject*>((GFXTextureObject*)faces[i]); U32 subResource = D3D11CalcSubresource(0, i, mipLevels); D3D11DEVICECONTEXT->CopySubresourceRegion(mTexture, subResource, 0, 0, 0, texObj->get2DTex(), 0, NULL); } D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc; SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat]; SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; SMViewDesc.TextureCube.MipLevels = mAutoGenMips ? -1 : mipLevels; SMViewDesc.TextureCube.MostDetailedMip = 0; hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView); if (FAILED(hr)) { AssertFatal(false, "GFXD3D11Cubemap::initStatic(GFXTexHandle *faces) - texcube shader resource view creation failure"); } if (mAutoGenMips && !compressed) D3D11DEVICECONTEXT->GenerateMips(mSRView); }
texture_data make_texture_data(ID3D11Device* p_device, ID3D11DeviceContext* p_ctx, texture_type type, ID3D11Texture2D* p_tex) { assert(p_device); assert(p_ctx); assert(type != texture_type::unknown); assert(p_tex); // create a staging texture & fill it with p_tex data. D3D11_TEXTURE2D_DESC desc; p_tex->GetDesc(&desc); desc.Usage = D3D11_USAGE_STAGING; desc.BindFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.MiscFlags = desc.MiscFlags & (~D3D11_RESOURCE_MISC_GENERATE_MIPS); com_ptr<ID3D11Texture2D> p_tex_staging; HRESULT hr = p_device->CreateTexture2D(&desc, nullptr, &p_tex_staging.ptr); assert(hr == S_OK); p_ctx->CopyResource(p_tex_staging, p_tex); #ifdef SPARKI_DEBUG if (type == texture_type::texture_cube) assert(desc.ArraySize == 6); #endif // SPAKIR_DEBUG // create a texture_data object texture_data td(type, uint3(desc.Width, desc.Height, 1), desc.MipLevels, desc.ArraySize, make_pixel_format(desc.Format)); const size_t fmt_byte_count = byte_count(td.format); uint8_t* ptr = td.buffer.data(); // for each array slice // for each mipmap level of the slice // map p_tex_tmp[array_slice][mipmap_level] and copy its' contents into the texture_data object. for (UINT a = 0; a < desc.ArraySize; ++a) { for (UINT m = 0; m < desc.MipLevels; ++m) { const UINT index = D3D11CalcSubresource(m, a, desc.MipLevels); D3D11_MAPPED_SUBRESOURCE map; hr = p_ctx->Map(p_tex_staging, index, D3D11_MAP_READ, 0, &map); assert(hr == S_OK); const UINT w = desc.Width >> m; const UINT h = desc.Height >> m; const size_t mip_bc = w * h * fmt_byte_count; assert(mip_bc > 0); assert(mip_bc <= map.DepthPitch); if (mip_bc == map.DepthPitch) { std::memcpy(ptr, map.pData, mip_bc); ptr += mip_bc; } else { uint8_t* p_src = reinterpret_cast<uint8_t*>(map.pData); const size_t row_bc = w * fmt_byte_count; // Note(MSDN): The runtime might assign values to RowPitch and DepthPitch // that are larger than anticipated because there might be padding between rows and depth. // https://msdn.microsoft.com/en-us/library/windows/desktop/ff476182(v=vs.85).aspx for (size_t row = 0; row < h; ++row) { std::memcpy(ptr, p_src, row_bc); p_src += map.RowPitch; ptr += row_bc; } } p_ctx->Unmap(p_tex_staging, index); } } return td; }
bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int height, int depth, const void* data) { PROFILE(SetTextureData); if (!object_) { LOGERROR("No texture created, can not set data"); return false; } if (!data) { LOGERROR("Null source for setting data"); return false; } if (level >= levels_) { LOGERROR("Illegal mip level for setting data"); return false; } int levelWidth = GetLevelWidth(level); int levelHeight = GetLevelHeight(level); int levelDepth = GetLevelDepth(level); if (x < 0 || x + width > levelWidth || y < 0 || y + height > levelHeight || z < 0 || z + depth > levelDepth || width <= 0 || height <= 0 || depth <= 0) { LOGERROR("Illegal dimensions for setting data"); return false; } // If compressed, align the update region on a block if (IsCompressed()) { x &= ~3; y &= ~3; width += 3; width &= 0xfffffffc; height += 3; height &= 0xfffffffc; } unsigned char* src = (unsigned char*)data; unsigned rowSize = GetRowDataSize(width); unsigned rowStart = GetRowDataSize(x); unsigned subResource = D3D11CalcSubresource(level, 0, levels_); if (usage_ == TEXTURE_DYNAMIC) { if (IsCompressed()) { height = (height + 3) >> 2; y >>= 2; } D3D11_MAPPED_SUBRESOURCE mappedData; mappedData.pData = 0; graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)object_, subResource, D3D11_MAP_WRITE_DISCARD, 0, &mappedData); if (mappedData.pData) { for (int page = 0; page < depth; ++page) { for (int row = 0; row < height; ++row) { memcpy((unsigned char*)mappedData.pData + (page + z) * mappedData.DepthPitch + (row + y) * mappedData.RowPitch + rowStart, src + row * rowSize, rowSize); } } graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)object_, subResource); } else { LOGERROR("Failed to map texture for update"); return false; } } else { if (IsCompressed())
bool DEMO_APP::Run() { theTime.Signal(); float dt = (float)theTime.Delta(); devContext->OMSetRenderTargets(1, &anotherView, DepthStencilView); devContext->RSSetViewports(1, &viewPort); float ClearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; devContext->ClearRenderTargetView(anotherView, ClearColor); devContext->ClearDepthStencilView(DepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0); scene[0] = Inverse4x4(secondCamera); D3D11_MAPPED_SUBRESOURCE sceneMap; ZeroMemory(&sceneMap, sizeof(sceneMap)); devContext->Map(sceneMatrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &sceneMap); memcpy(sceneMap.pData, scene, sizeof(scene)); devContext->Unmap(sceneMatrixBuffer, 0); devContext->VSSetConstantBuffers(1, 1, &sceneMatrixBuffer); devContext->PSSetConstantBuffers(0, 1, &lightBuff); devContext->PSSetConstantBuffers(1, 1, &ambientBuff); devContext->PSSetConstantBuffers(2, 1, &ptltBuff); devContext->PSSetConstantBuffers(3, 1, &spotBuff); devContext->GSSetConstantBuffers(1, 1, &sceneMatrixBuffer); //Pyramid.worldMatrices[0] = RotateY(50.0f * dt) * Pyramid.worldMatrices[0]; //Pyramid.worldMatrices[1] = RotateZ(50.0f * dt) * Pyramid.worldMatrices[1]; //Pyramid.worldMatrices[2] = RotateX(50.0f * dt) * Pyramid.worldMatrices[2]; //Pyramid.worldMatrices[3] = RotateY(200.0f * dt) * RotateZ(200.0f * dt) * RotateX(200.0f * dt) * Pyramid.worldMatrices[3]; //SKYBOX RENDERING///// devContext->RSSetState(pOtherState); //SkyBox.worldMatrix = viewMatrix; SkyBox.worldMatrix.M[3][0] = secondCamera.M[3][0]; SkyBox.worldMatrix.M[3][1] = secondCamera.M[3][1]; SkyBox.worldMatrix.M[3][2] = secondCamera.M[3][2]; SkyBox.Render(); devContext->ClearDepthStencilView(DepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0); /////////////////////// devContext->RSSetState(pRasterState); Pyramid.Render(); Quad.Render(); Tree.Render(); Tree2.Render(); Tree1.Render(); devContext->ResolveSubresource(fixerTexture, D3D11CalcSubresource(0, 0, 1), renderTexture, D3D11CalcSubresource(0, 0, 1), DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); QuadSeed.Render(); devContext->GenerateMips(QuadSeed.pShaderResource); ///////////////////////////////////////////////////////////////////////////////////////////////////////// devContext->OMSetRenderTargets(1, &postProcessView, DepthStencilView); devContext->RSSetViewports(1, &viewPort); //float ClearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; devContext->ClearRenderTargetView(postProcessView, ClearColor); devContext->ClearDepthStencilView(DepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0); scene[0] = Inverse4x4(viewMatrix); //D3D11_MAPPED_SUBRESOURCE sceneMap; ZeroMemory(&sceneMap, sizeof(sceneMap)); devContext->Map(sceneMatrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &sceneMap); memcpy(sceneMap.pData, scene, sizeof(scene)); devContext->Unmap(sceneMatrixBuffer, 0); devContext->VSSetConstantBuffers(1, 1, &sceneMatrixBuffer); devContext->PSSetConstantBuffers(0, 1, &lightBuff); devContext->PSSetConstantBuffers(1, 1, &ambientBuff); devContext->PSSetConstantBuffers(2, 1, &ptltBuff); devContext->PSSetConstantBuffers(3, 1, &spotBuff); devContext->GSSetConstantBuffers(1, 1, &sceneMatrixBuffer); //Pyramid.worldMatrices[0] = RotateY(50.0f * dt) * Pyramid.worldMatrices[0]; //Pyramid.worldMatrices[1] = RotateZ(50.0f * dt) * Pyramid.worldMatrices[1]; //Pyramid.worldMatrices[2] = RotateX(50.0f * dt) * Pyramid.worldMatrices[2]; //Pyramid.worldMatrices[3] = RotateY(200.0f * dt) * RotateZ(200.0f * dt) * RotateX(200.0f * dt) * Pyramid.worldMatrices[3]; //SKYBOX RENDERING///// devContext->RSSetState(pOtherState); //SkyBox.worldMatrix = viewMatrix; SkyBox.worldMatrix.M[3][0] = viewMatrix.M[3][0]; SkyBox.worldMatrix.M[3][1] = viewMatrix.M[3][1]; SkyBox.worldMatrix.M[3][2] = viewMatrix.M[3][2]; SkyBox.Render(); devContext->ClearDepthStencilView(DepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0); /////////////////////// devContext->RSSetState(pRasterState); Pyramid.Render(); Quad.Render(); Tree.Render(); Tree1.Render(); Tree2.Render(); devContext->ResolveSubresource(fixerTexture, D3D11CalcSubresource(0, 0, 1), renderTexture, D3D11CalcSubresource(0, 0, 1), DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); QuadSeed.Render(); devContext->GenerateMips(QuadSeed.pShaderResource); devContext->ResolveSubresource(fixerTexture, D3D11CalcSubresource(0, 0, 1), postTexture, D3D11CalcSubresource(0, 0, 1), DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); PostQuad.Render(); ///////////////////////////////////////////////////////////////// devContext->OMSetRenderTargets(1, &targetView, DepthStencilView); //devContext->RSSetViewports(1, &viewPort); //float ClearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; devContext->ClearRenderTargetView(targetView, ClearColor); devContext->ClearDepthStencilView(DepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0); MoveCamera(5.0f, 200.0f, dt); D3D11_MAPPED_SUBRESOURCE ambMap; ZeroMemory(&ambMap, sizeof(ambMap)); devContext->Map(ambientBuff, 0, D3D11_MAP_WRITE_DISCARD, 0, &ambMap); memcpy(ambMap.pData, &ambientLight, sizeof(ambientLight)); devContext->Unmap(ambientBuff, 0); D3D11_MAPPED_SUBRESOURCE lightMap; ZeroMemory(&lightMap, sizeof(lightMap)); devContext->Map(lightBuff, 0, D3D11_MAP_WRITE_DISCARD, 0, &lightMap); memcpy(lightMap.pData, &theLight, sizeof(theLight)); devContext->Unmap(lightBuff, 0); D3D11_MAPPED_SUBRESOURCE ptLtMap; ZeroMemory(&ptLtMap, sizeof(ptLtMap)); devContext->Map(ptltBuff, 0, D3D11_MAP_WRITE_DISCARD, 0, &ptLtMap); memcpy(ptLtMap.pData, &thePtLight, sizeof(thePtLight)); devContext->Unmap(ptltBuff, 0); D3D11_MAPPED_SUBRESOURCE spotMap; ZeroMemory(&spotMap, sizeof(spotMap)); devContext->Map(spotBuff, 0, D3D11_MAP_WRITE_DISCARD, 0, &spotMap); memcpy(spotMap.pData, &theSpotLight, sizeof(theSpotLight)); devContext->Unmap(spotBuff, 0); scene[0] = Inverse4x4(viewMatrix); SkyBox.worldMatrix.M[3][0] = viewMatrix.M[3][0]; SkyBox.worldMatrix.M[3][1] = viewMatrix.M[3][1]; SkyBox.worldMatrix.M[3][2] = viewMatrix.M[3][2]; //D3D11_MAPPED_SUBRESOURCE sceneMap; ZeroMemory(&sceneMap, sizeof(sceneMap)); devContext->Map(sceneMatrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &sceneMap); memcpy(sceneMap.pData, scene, sizeof(scene)); devContext->Unmap(sceneMatrixBuffer, 0); devContext->VSSetConstantBuffers(1, 1, &sceneMatrixBuffer); devContext->PSSetConstantBuffers(0, 1, &lightBuff); devContext->PSSetConstantBuffers(1, 1, &ambientBuff); devContext->PSSetConstantBuffers(2, 1, &ptltBuff); devContext->PSSetConstantBuffers(3, 1, &spotBuff); devContext->GSSetConstantBuffers(1, 1, &sceneMatrixBuffer); //Pyramid.worldMatrices[0] = RotateY(50.0f * dt) * Pyramid.worldMatrices[0]; //Pyramid.worldMatrices[1] = RotateZ(50.0f * dt) * Pyramid.worldMatrices[1]; //Pyramid.worldMatrices[2] = RotateX(50.0f * dt) * Pyramid.worldMatrices[2]; //Pyramid.worldMatrices[3] = RotateY(200.0f * dt) * RotateZ(200.0f * dt) * RotateX(200.0f * dt) * Pyramid.worldMatrices[3]; //SKYBOX RENDERING///// devContext->RSSetState(pOtherState); //SkyBox.worldMatrix = viewMatrix; SkyBox.Render(); devContext->ClearDepthStencilView(DepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0); /////////////////////// devContext->RSSetState(pRasterState); Pyramid.Render(); Quad.Render(); Tree.Render(); Tree1.Render(); Tree2.Render(); devContext->ResolveSubresource(fixerTexture, D3D11CalcSubresource(0, 0, 1), renderTexture, D3D11CalcSubresource(0, 0, 1), DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); QuadSeed.Render(); devContext->GenerateMips(QuadSeed.pShaderResource); //WHY BROKEN? devContext->ResolveSubresource(fixerTexture, D3D11CalcSubresource(0, 0, 1), postTexture, D3D11CalcSubresource(0, 0, 1), DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); PostQuad.Render(); /////////////////////2nd VIEWPORT///////////////////////////////////////////////////////////////////////////////////////////////// devContext->OMSetRenderTargets(1, &anotherView, DepthStencilView); devContext->RSSetViewports(1, &otherPort); //float ClearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; devContext->ClearRenderTargetView(anotherView, ClearColor); devContext->ClearDepthStencilView(DepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0); scene[0] = secondCamera; //D3D11_MAPPED_SUBRESOURCE sceneMap; ZeroMemory(&sceneMap, sizeof(sceneMap)); devContext->Map(sceneMatrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &sceneMap); memcpy(sceneMap.pData, scene, sizeof(scene)); devContext->Unmap(sceneMatrixBuffer, 0); devContext->VSSetConstantBuffers(1, 1, &sceneMatrixBuffer); devContext->PSSetConstantBuffers(0, 1, &lightBuff); devContext->PSSetConstantBuffers(1, 1, &ambientBuff); devContext->PSSetConstantBuffers(2, 1, &ptltBuff); devContext->PSSetConstantBuffers(3, 1, &spotBuff); devContext->GSSetConstantBuffers(1, 1, &sceneMatrixBuffer); //Pyramid.worldMatrices[0] = RotateY(50.0f * dt) * Pyramid.worldMatrices[0]; //Pyramid.worldMatrices[1] = RotateZ(50.0f * dt) * Pyramid.worldMatrices[1]; //Pyramid.worldMatrices[2] = RotateX(50.0f * dt) * Pyramid.worldMatrices[2]; //Pyramid.worldMatrices[3] = RotateY(200.0f * dt) * RotateZ(200.0f * dt) * RotateX(200.0f * dt) * Pyramid.worldMatrices[3]; //SKYBOX RENDERING///// devContext->RSSetState(pOtherState); //SkyBox.worldMatrix = viewMatrix; SkyBox.worldMatrix.M[3][0] = secondCamera.M[3][0]; SkyBox.worldMatrix.M[3][1] = secondCamera.M[3][1]; SkyBox.worldMatrix.M[3][2] = secondCamera.M[3][2]; SkyBox.Render(); devContext->ClearDepthStencilView(DepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0); /////////////////////// devContext->RSSetState(pRasterState); Pyramid.Render(); Quad.Render(); Tree.Render(); Tree1.Render(); Tree2.Render(); devContext->ResolveSubresource(fixerTexture, D3D11CalcSubresource(0, 0, 1), renderTexture, D3D11CalcSubresource(0, 0, 1), DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); QuadSeed.Render(); devContext->GenerateMips(QuadSeed.pShaderResource); //PostQuad.Render(); ///////////////////////////////////////////////////////////////// devContext->OMSetRenderTargets(1, &targetView, DepthStencilView); //devContext->RSSetViewports(1, &viewPort); //float ClearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; //devContext->ClearRenderTargetView(targetView, ClearColor); devContext->ClearDepthStencilView(DepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0); //MoveCamera(5.0f, 200.0f, dt); //D3D11_MAPPED_SUBRESOURCE ambMap; ZeroMemory(&ambMap, sizeof(ambMap)); devContext->Map(ambientBuff, 0, D3D11_MAP_WRITE_DISCARD, 0, &ambMap); memcpy(ambMap.pData, &ambientLight, sizeof(ambientLight)); devContext->Unmap(ambientBuff, 0); //D3D11_MAPPED_SUBRESOURCE lightMap; ZeroMemory(&lightMap, sizeof(lightMap)); devContext->Map(lightBuff, 0, D3D11_MAP_WRITE_DISCARD, 0, &lightMap); memcpy(lightMap.pData, &theLight, sizeof(theLight)); devContext->Unmap(lightBuff, 0); //D3D11_MAPPED_SUBRESOURCE ptLtMap; ZeroMemory(&ptLtMap, sizeof(ptLtMap)); devContext->Map(ptltBuff, 0, D3D11_MAP_WRITE_DISCARD, 0, &ptLtMap); memcpy(ptLtMap.pData, &thePtLight, sizeof(thePtLight)); devContext->Unmap(ptltBuff, 0); //D3D11_MAPPED_SUBRESOURCE spotMap; ZeroMemory(&spotMap, sizeof(spotMap)); devContext->Map(spotBuff, 0, D3D11_MAP_WRITE_DISCARD, 0, &spotMap); memcpy(spotMap.pData, &theSpotLight, sizeof(theSpotLight)); devContext->Unmap(spotBuff, 0); scene[0] = secondCamera;//Inverse4x4(viewMatrix); //D3D11_MAPPED_SUBRESOURCE sceneMap; ZeroMemory(&sceneMap, sizeof(sceneMap)); devContext->Map(sceneMatrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &sceneMap); memcpy(sceneMap.pData, scene, sizeof(scene)); devContext->Unmap(sceneMatrixBuffer, 0); devContext->VSSetConstantBuffers(1, 1, &sceneMatrixBuffer); devContext->PSSetConstantBuffers(0, 1, &lightBuff); devContext->PSSetConstantBuffers(1, 1, &ambientBuff); devContext->PSSetConstantBuffers(2, 1, &ptltBuff); devContext->PSSetConstantBuffers(3, 1, &spotBuff); devContext->GSSetConstantBuffers(1, 1, &sceneMatrixBuffer); Pyramid.worldMatrices[0] = RotateY(50.0f * dt) * Pyramid.worldMatrices[0]; Pyramid.worldMatrices[1] = RotateZ(50.0f * dt) * Pyramid.worldMatrices[1]; Pyramid.worldMatrices[2] = RotateX(50.0f * dt) * Pyramid.worldMatrices[2]; Pyramid.worldMatrices[3] = RotateY(200.0f * dt) * RotateZ(200.0f * dt) * RotateX(200.0f * dt) * Pyramid.worldMatrices[3]; //SKYBOX RENDERING///// devContext->RSSetState(pOtherState); //SkyBox.worldMatrix = viewMatrix; SkyBox.worldMatrix.M[3][0] = secondCamera.M[3][0]; SkyBox.worldMatrix.M[3][1] = secondCamera.M[3][1]; SkyBox.worldMatrix.M[3][2] = secondCamera.M[3][2]; SkyBox.Render(); devContext->ClearDepthStencilView(DepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0); /////////////////////// devContext->RSSetState(pRasterState); Pyramid.Render(); Quad.Render(); Tree.Render(); Tree1.Render(); Tree2.Render(); devContext->ResolveSubresource(fixerTexture, D3D11CalcSubresource(0, 0, 1), renderTexture, D3D11CalcSubresource(0, 0, 1), DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); QuadSeed.Render(); devContext->GenerateMips(QuadSeed.pShaderResource); swapChain->Present(0, 0); return true; }
HRESULT ParticleSystem::CreateTexArray(const vector<string>& fileNames) { HRESULT hr = S_OK; // Load the texture elements individually from file. These textures // won't be used by the GPU (0 bind flags), they are just used to // load the image data from file. We use the STAGING usage so the // CPU can read the resource. this->mNrOfTextures = fileNames.size(); vector<ID3D11Texture2D*> srcTex(this->mNrOfTextures, 0); for(UINT i = 0; i < this->mNrOfTextures; i++) { D3DX11_IMAGE_LOAD_INFO loadInfo; loadInfo.Width = D3DX11_FROM_FILE; loadInfo.Height = D3DX11_FROM_FILE; loadInfo.Depth = D3DX11_FROM_FILE; loadInfo.FirstMipLevel = 0; loadInfo.MipLevels = D3DX11_FROM_FILE; loadInfo.Usage = D3D11_USAGE_STAGING; loadInfo.BindFlags = 0; loadInfo.CpuAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; loadInfo.MiscFlags = 0; loadInfo.Format = DXGI_FORMAT_R8G8B8A8_UNORM; loadInfo.Filter = D3DX11_FILTER_NONE; loadInfo.MipFilter = D3DX11_FILTER_NONE; loadInfo.pSrcInfo = 0; hr = D3DX11CreateTextureFromFile(this->gDevice, fileNames[i].c_str(), &loadInfo, 0, (ID3D11Resource**)&srcTex[i], 0); if(FAILED(hr)) { MessageBox(0, "Couldn't load particle texture(s)", "Create texture from file error", MB_ICONERROR); return hr; } } // Create the texture array. Each element in the texture // array has the same format/dimensions. D3D11_TEXTURE2D_DESC texElementDesc; srcTex[0]->GetDesc(&texElementDesc); D3D11_TEXTURE2D_DESC texArrayDesc; texArrayDesc.Width = texElementDesc.Width; texArrayDesc.Height = texElementDesc.Height; texArrayDesc.MipLevels = texElementDesc.MipLevels; texArrayDesc.ArraySize = this->mNrOfTextures; //nr of texture elements to store texArrayDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; texArrayDesc.SampleDesc.Count = 1; texArrayDesc.SampleDesc.Quality = 0; texArrayDesc.Usage = D3D11_USAGE_DEFAULT; texArrayDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; texArrayDesc.CPUAccessFlags = 0; texArrayDesc.MiscFlags = 0; ID3D11Texture2D* texArray = 0; hr = this->gDevice->CreateTexture2D( &texArrayDesc, 0, &texArray); if(FAILED(hr)) { MessageBox(0, "Couldn't create particle texture(s)", "Create texture2d error", MB_ICONERROR); return hr; } // Copy individual texture elements into texture array. // for each texture element... for(UINT i = 0; i < this->mNrOfTextures; i++) { // for each mipmap level... for(UINT j = 0; j < texElementDesc.MipLevels; ++j) { D3D11_MAPPED_SUBRESOURCE mappedSubres; UINT subResource = D3D11CalcSubresource(j, i, texElementDesc.MipLevels); //**samma för texarray?** //map this->gDeviceContext->Map(srcTex[i], subResource, D3D11_MAP_READ_WRITE, 0, &mappedSubres); //**write onödig?** //update this->gDeviceContext->UpdateSubresource(texArray, subResource, 0, mappedSubres.pData, mappedSubres.RowPitch, 0); //unmap this->gDeviceContext->Unmap(srcTex[i], subResource); /*D3D10: D3D10_MAPPED_TEXTURE2D mappedTex2D; srcTex[i]->Map(j, D3D10_MAP_READ, 0, &mappedTex2D); this->gDevice->UpdateSubresource(texArray, D3D10CalcSubresource(j, i, texElementDesc.MipLevels), 0, mappedTex2D.pData, mappedTex2D.RowPitch, 0); srcTex[i]->Unmap(j);*/ } } // Create a resource view to the texture array. D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; viewDesc.Format = texArrayDesc.Format; viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; viewDesc.Texture2DArray.MostDetailedMip = 0; viewDesc.Texture2DArray.MipLevels = texArrayDesc.MipLevels; viewDesc.Texture2DArray.FirstArraySlice = 0; viewDesc.Texture2DArray.ArraySize = this->mNrOfTextures; hr = this->gDevice->CreateShaderResourceView(texArray, &viewDesc, &this->mTexArraySRV); // Cleanup--we only need the resource view. if ( texArray ) texArray->Release(), texArray=0; for(UINT i = 0; i < this->mNrOfTextures; i++) { if(srcTex[i]) { srcTex[i]->Release(); } } return hr; }
//------------------------------------------------------------------------------------ D3D11Texture::D3D11Texture(const StringVector& vecTexNames, bool bSRGB) : Texture(eTextureType_TextureArray, 0, 0, 0, ePF_Unknown, 0, true) , m_pTexture2D(nullptr) , m_pTexture3D(nullptr) , m_pRTV(nullptr) , m_pSRV(nullptr) , m_pDSV(nullptr) , m_pTexStaging(nullptr) { _AST(!vecTexNames.empty()); HRESULT hr = S_OK; // First load all texture elements std::vector<ID3D11Texture2D*> vecTexs(vecTexNames.size()); for (size_t i=0; i<vecTexNames.size(); ++i) { D3DX11_IMAGE_LOAD_INFO loadInfo; loadInfo.Width = D3DX11_FROM_FILE; loadInfo.Height = D3DX11_FROM_FILE; loadInfo.Depth = D3DX11_FROM_FILE; loadInfo.FirstMipLevel = 0; loadInfo.BindFlags = 0; loadInfo.Usage = D3D11_USAGE_STAGING; // Local res loadInfo.MipLevels = 0; loadInfo.CpuAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; loadInfo.MiscFlags = 0; loadInfo.Format = DXGI_FORMAT_FROM_FILE; loadInfo.Filter = D3DX11_FILTER_NONE; loadInfo.MipFilter = D3DX11_FILTER_LINEAR; loadInfo.pSrcInfo = 0; if (vecTexNames[i].find(".dds") != STRING::npos) { V(DirectX::CreateDDSTextureFromFileEx(g_pRenderSys->GetDevice(), EngineToUnicode(vecTexNames[i]).c_str(), 4096, D3D11_USAGE_STAGING, 0, D3D11_CPU_ACCESS_READ, 0, bSRGB, (ID3D11Resource**)&vecTexs[i], nullptr)); } else { V(D3DX11CreateTextureFromFileA(g_pRenderSys->GetDevice(), vecTexNames[i].c_str(), &loadInfo, nullptr, (ID3D11Resource**)&vecTexs[i], nullptr)); } } // Then create the texture array object D3D11_TEXTURE2D_DESC texElementDesc; vecTexs[0]->GetDesc(&texElementDesc); // Store dimension and format m_width = texElementDesc.Width; m_height = texElementDesc.Height; m_texFormat = ConvertFromDXFormat(texElementDesc.Format); D3D11_TEXTURE2D_DESC texArrayDesc; texArrayDesc.Width = texElementDesc.Width; texArrayDesc.Height = texElementDesc.Height; texArrayDesc.MipLevels = texElementDesc.MipLevels; texArrayDesc.ArraySize = vecTexs.size(); texArrayDesc.Format = texElementDesc.Format; texArrayDesc.SampleDesc.Count = 1; texArrayDesc.SampleDesc.Quality = 0; texArrayDesc.Usage = D3D11_USAGE_DEFAULT; texArrayDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; texArrayDesc.CPUAccessFlags = 0; texArrayDesc.MiscFlags = 0; V(g_pRenderSys->GetDevice()->CreateTexture2D(&texArrayDesc, 0, &m_pTexture2D)); // Fill texture array data ID3D11DeviceContext* dc = g_pRenderSys->GetDeviceContext(); for(size_t texElement=0; texElement<vecTexs.size(); ++texElement) { vecTexs[texElement]->GetDesc(&texElementDesc); for(UINT mipLevel = 0; mipLevel < texElementDesc.MipLevels; ++mipLevel) { D3D11_MAPPED_SUBRESOURCE mappedTex2D; V(dc->Map(vecTexs[texElement], mipLevel, D3D11_MAP_READ, 0, &mappedTex2D)); dc->UpdateSubresource(m_pTexture2D, D3D11CalcSubresource(mipLevel, texElement, texElementDesc.MipLevels), 0, mappedTex2D.pData, mappedTex2D.RowPitch, mappedTex2D.DepthPitch); dc->Unmap(vecTexs[texElement], mipLevel); } } CreateSRV(); for(size_t i=0; i<vecTexs.size(); ++i) vecTexs[i]->Release(); }
ID3D11ShaderResourceView* d3dHelper::CreateTexture2DArraySRV( ID3D11Device* device, ID3D11DeviceContext* context, std::vector<std::wstring>& filenames, DXGI_FORMAT format, UINT filter, UINT mipFilter) { // // Load the texture elements individually from file. These textures // won't be used by the GPU (0 bind flags), they are just used to // load the image data from file. We use the STAGING usage so the // CPU can read the resource. // UINT size = filenames.size(); std::vector<ID3D11Texture2D*> srcTex(size); for(UINT i = 0; i < size; ++i) { D3DX11_IMAGE_LOAD_INFO loadInfo; loadInfo.Width = D3DX11_FROM_FILE; loadInfo.Height = D3DX11_FROM_FILE; loadInfo.Depth = D3DX11_FROM_FILE; loadInfo.FirstMipLevel = 0; loadInfo.MipLevels = D3DX11_FROM_FILE; loadInfo.Usage = D3D11_USAGE_STAGING; loadInfo.BindFlags = 0; loadInfo.CpuAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; loadInfo.MiscFlags = 0; loadInfo.Format = format; loadInfo.Filter = filter; loadInfo.MipFilter = mipFilter; loadInfo.pSrcInfo = 0; /* this is causing a linker error. God knows why... undo uncommet duncan help todo fix error */ HR(D3DX11CreateTextureFromFile(device, filenames[i].c_str(), &loadInfo, 0, (ID3D11Resource**)&srcTex[i], 0)); } // // Create the texture array. Each element in the texture // array has the same format/dimensions. // D3D11_TEXTURE2D_DESC texElementDesc; srcTex[0]->GetDesc(&texElementDesc); D3D11_TEXTURE2D_DESC texArrayDesc; texArrayDesc.Width = texElementDesc.Width; texArrayDesc.Height = texElementDesc.Height; texArrayDesc.MipLevels = texElementDesc.MipLevels; texArrayDesc.ArraySize = size; texArrayDesc.Format = texElementDesc.Format; texArrayDesc.SampleDesc.Count = 1; texArrayDesc.SampleDesc.Quality = 0; texArrayDesc.Usage = D3D11_USAGE_DEFAULT; texArrayDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; texArrayDesc.CPUAccessFlags = 0; texArrayDesc.MiscFlags = 0; ID3D11Texture2D* texArray = 0; HR(device->CreateTexture2D( &texArrayDesc, 0, &texArray)); // // Copy individual texture elements into texture array. // // for each texture element... for(UINT texElement = 0; texElement < size; ++texElement) { // for each mipmap level... for(UINT mipLevel = 0; mipLevel < texElementDesc.MipLevels; ++mipLevel) { D3D11_MAPPED_SUBRESOURCE mappedTex2D; HR(context->Map(srcTex[texElement], mipLevel, D3D11_MAP_READ, 0, &mappedTex2D)); context->UpdateSubresource(texArray, D3D11CalcSubresource(mipLevel, texElement, texElementDesc.MipLevels), 0, mappedTex2D.pData, mappedTex2D.RowPitch, mappedTex2D.DepthPitch); context->Unmap(srcTex[texElement], mipLevel); } } // // Create a resource view to the texture array. // D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; viewDesc.Format = texArrayDesc.Format; viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; viewDesc.Texture2DArray.MostDetailedMip = 0; viewDesc.Texture2DArray.MipLevels = texArrayDesc.MipLevels; viewDesc.Texture2DArray.FirstArraySlice = 0; viewDesc.Texture2DArray.ArraySize = size; ID3D11ShaderResourceView* texArraySRV = 0; HR(device->CreateShaderResourceView(texArray, &viewDesc, &texArraySRV)); // // Cleanup--we only need the resource view. // ReleaseCOM(texArray); for(UINT i = 0; i < size; ++i) ReleaseCOM(srcTex[i]); return texArraySRV; }
gl::Error Image11::createStagingTexture() { if (mStagingTexture) { return gl::Error(GL_NO_ERROR); } ASSERT(mWidth > 0 && mHeight > 0 && mDepth > 0); const DXGI_FORMAT dxgiFormat = getDXGIFormat(); ID3D11Device *device = mRenderer->getDevice(); HRESULT result; int lodOffset = 1; GLsizei width = mWidth; GLsizei height = mHeight; // adjust size if needed for compressed textures d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset); if (mTarget == GL_TEXTURE_3D) { ID3D11Texture3D *newTexture = NULL; D3D11_TEXTURE3D_DESC desc; desc.Width = width; desc.Height = height; desc.Depth = mDepth; desc.MipLevels = lodOffset + 1; desc.Format = dxgiFormat; desc.Usage = D3D11_USAGE_STAGING; desc.BindFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.MiscFlags = 0; if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) { std::vector<D3D11_SUBRESOURCE_DATA> initialData; std::vector< std::vector<BYTE> > textureData; d3d11::GenerateInitialTextureData(mInternalFormat, width, height, mDepth, lodOffset + 1, &initialData, &textureData); result = device->CreateTexture3D(&desc, initialData.data(), &newTexture); } else { result = device->CreateTexture3D(&desc, NULL, &newTexture); } if (FAILED(result)) { ASSERT(result == E_OUTOFMEMORY); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create staging texture, result: 0x%X.", result); } mStagingTexture = newTexture; mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); } else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_CUBE_MAP) { ID3D11Texture2D *newTexture = NULL; D3D11_TEXTURE2D_DESC desc; desc.Width = width; desc.Height = height; desc.MipLevels = lodOffset + 1; desc.ArraySize = 1; desc.Format = dxgiFormat; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_STAGING; desc.BindFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.MiscFlags = 0; if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) { std::vector<D3D11_SUBRESOURCE_DATA> initialData; std::vector< std::vector<BYTE> > textureData; d3d11::GenerateInitialTextureData(mInternalFormat, width, height, 1, lodOffset + 1, &initialData, &textureData); result = device->CreateTexture2D(&desc, initialData.data(), &newTexture); } else { result = device->CreateTexture2D(&desc, NULL, &newTexture); } if (FAILED(result)) { ASSERT(result == E_OUTOFMEMORY); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create staging texture, result: 0x%X.", result); } mStagingTexture = newTexture; mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); } else { UNREACHABLE(); } mDirty = false; return gl::Error(GL_NO_ERROR); }
static unsigned int getRTVSubresourceIndex(ID3D11Texture2D *texture, ID3D11RenderTargetView *view) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; view->GetDesc(&rtvDesc); D3D11_TEXTURE2D_DESC texDesc; texture->GetDesc(&texDesc); unsigned int mipSlice = 0; unsigned int arraySlice = 0; unsigned int mipLevels = texDesc.MipLevels; switch (rtvDesc.ViewDimension) { case D3D11_RTV_DIMENSION_TEXTURE1D: mipSlice = rtvDesc.Texture1D.MipSlice; arraySlice = 0; break; case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: mipSlice = rtvDesc.Texture1DArray.MipSlice; arraySlice = rtvDesc.Texture1DArray.FirstArraySlice; break; case D3D11_RTV_DIMENSION_TEXTURE2D: mipSlice = rtvDesc.Texture2D.MipSlice; arraySlice = 0; break; case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: mipSlice = rtvDesc.Texture2DArray.MipSlice; arraySlice = rtvDesc.Texture2DArray.FirstArraySlice; break; case D3D11_RTV_DIMENSION_TEXTURE2DMS: mipSlice = 0; arraySlice = 0; break; case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: mipSlice = 0; arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice; break; case D3D11_RTV_DIMENSION_TEXTURE3D: mipSlice = rtvDesc.Texture3D.MipSlice; arraySlice = 0; break; case D3D11_RTV_DIMENSION_UNKNOWN: case D3D11_RTV_DIMENSION_BUFFER: UNIMPLEMENTED(); break; default: UNREACHABLE(); break; } return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); }
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); }
//------------------------------------------------------------------------------------ D3D11Texture::D3D11Texture( const StringVector& vecTexNames ) :m_pTexture2D(nullptr) ,m_pTexture3D(nullptr) ,m_pRenderSystem(g_env.pRenderSystem) ,m_rtView(nullptr) ,m_pSRV(nullptr) ,m_pDSV(nullptr) ,m_usage(0) ,m_texType(eTextureType_TextureArray) ,m_bMipMap(true) { m_pd3dDevice = m_pRenderSystem->GetDevice(); if (m_pd3dDevice) m_pd3dDevice->AddRef(); assert(!vecTexNames.empty()); HRESULT hr = S_OK; // First load all texture elements std::vector<ID3D11Texture2D*> vecTexs(vecTexNames.size()); for (size_t i=0; i<vecTexNames.size(); ++i) { D3DX11_IMAGE_LOAD_INFO loadInfo; loadInfo.Width = D3DX11_FROM_FILE; loadInfo.Height = D3DX11_FROM_FILE; loadInfo.Depth = D3DX11_FROM_FILE; loadInfo.FirstMipLevel = 0; loadInfo.BindFlags = 0; loadInfo.Usage = D3D11_USAGE_STAGING; // Local res loadInfo.MipLevels = 0; loadInfo.CpuAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; loadInfo.MiscFlags = 0; loadInfo.Format = DXGI_FORMAT_FROM_FILE; loadInfo.Filter = D3DX11_FILTER_NONE; loadInfo.MipFilter = D3DX11_FILTER_LINEAR; loadInfo.pSrcInfo = 0; V(D3DX11CreateTextureFromFileA(m_pRenderSystem->GetDevice(), vecTexNames[i].c_str(), &loadInfo, nullptr, (ID3D11Resource**)&vecTexs[i], nullptr)); } // Then create the texture array object D3D11_TEXTURE2D_DESC texElementDesc; vecTexs[0]->GetDesc(&texElementDesc); // Store dimension and format m_width = texElementDesc.Width; m_height = texElementDesc.Height; m_texFormat = ConvertFromDXFormat(texElementDesc.Format); D3D11_TEXTURE2D_DESC texArrayDesc; texArrayDesc.Width = texElementDesc.Width; texArrayDesc.Height = texElementDesc.Height; texArrayDesc.MipLevels = texElementDesc.MipLevels; texArrayDesc.ArraySize = vecTexs.size(); texArrayDesc.Format = texElementDesc.Format; texArrayDesc.SampleDesc.Count = 1; texArrayDesc.SampleDesc.Quality = 0; texArrayDesc.Usage = D3D11_USAGE_DEFAULT; texArrayDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; texArrayDesc.CPUAccessFlags = 0; texArrayDesc.MiscFlags = 0; V(m_pRenderSystem->GetDevice()->CreateTexture2D( &texArrayDesc, 0, &m_pTexture2D)); // Fill texture array data ID3D11DeviceContext* dc = m_pRenderSystem->GetDeviceContext(); for(size_t texElement=0; texElement<vecTexs.size(); ++texElement) { for(UINT mipLevel = 0; mipLevel < texElementDesc.MipLevels; ++mipLevel) { D3D11_MAPPED_SUBRESOURCE mappedTex2D; V(dc->Map(vecTexs[texElement], mipLevel, D3D11_MAP_READ, 0, &mappedTex2D)); dc->UpdateSubresource(m_pTexture2D, D3D11CalcSubresource(mipLevel, texElement, texElementDesc.MipLevels), 0, mappedTex2D.pData, mappedTex2D.RowPitch, mappedTex2D.DepthPitch); dc->Unmap(vecTexs[texElement], mipLevel); } } CreateSRV(); for(size_t i=0; i<vecTexs.size(); ++i) vecTexs[i]->Release(); }
void D3D11Grab(ID3D11Texture2D *pBackBuffer) { D3D11_TEXTURE2D_DESC tex_desc; pBackBuffer->GetDesc(&tex_desc); ID3D11Device *pDev; pBackBuffer->GetDevice(&pDev); ID3D11DeviceContext * pDevContext; pDev->GetImmediateContext(&pDevContext); ID3D11Texture2D * pTexture; D3D11_MAPPED_SUBRESOURCE mappedTexture; tex_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; tex_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; tex_desc.ArraySize = 1; tex_desc.MipLevels = 1; tex_desc.BindFlags = 0; tex_desc.SampleDesc.Count = 1; tex_desc.SampleDesc.Quality = 0; tex_desc.Usage = D3D11_USAGE_STAGING; tex_desc.MiscFlags = 0; HRESULT hr = pDev->CreateTexture2D(&tex_desc, NULL, &pTexture); // reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d11 pDev->CreateTexture2D 0x%x", hr); pDevContext->CopyResource(pTexture, pBackBuffer); D3D11_BOX box = {0, 0, tex_desc.Width, tex_desc.Height, 0, 1}; pDevContext->CopySubresourceRegion(pTexture, 0, 0, 0, 0, pBackBuffer, 0, &box); DxgiFrameGrabber *dxgiFrameGrabber = DxgiFrameGrabber::getInstance(); IPCContext *ipcContext = dxgiFrameGrabber->m_ipcContext; Logger *logger = dxgiFrameGrabber->m_logger; // __asm__("int $3"); if (S_OK != (hr = pDevContext->Map(pTexture, D3D11CalcSubresource(0, 0, 1), D3D11_MAP_READ, 0, &mappedTexture))) { logger->reportLogError(L"d3d11 couldn't map texture, hresult = 0x%x", hr); goto end; } ipcContext->m_memDesc.width = tex_desc.Width; ipcContext->m_memDesc.height = tex_desc.Height; ipcContext->m_memDesc.rowPitch = mappedTexture.RowPitch; ipcContext->m_memDesc.frameId++; // reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d11 texture description. width: %u, height: %u, pitch: %u", tex_desc.Width, tex_desc.Height, mappedTexture.RowPitch); DWORD errorcode; if (WAIT_OBJECT_0 == (errorcode = WaitForSingleObject(ipcContext->m_hMutex, 0))) { // __asm__("int $3"); // reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d11 writing description to mem mapped file"); memcpy(ipcContext->m_pMemMap, &ipcContext->m_memDesc, sizeof (ipcContext->m_memDesc)); // reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d11 writing data to mem mapped file"); PVOID pMemDataMap = incPtr(ipcContext->m_pMemMap, sizeof (ipcContext->m_memDesc)); if (mappedTexture.RowPitch == tex_desc.Width * 4) { memcpy(pMemDataMap, mappedTexture.pData, tex_desc.Width * tex_desc.Height * 4); } else { UINT i = 0, cleanOffset = 0, pitchOffset = 0; while (i < tex_desc.Height) { memcpy(incPtr(pMemDataMap, cleanOffset), incPtr(mappedTexture.pData, pitchOffset), tex_desc.Width * 4); cleanOffset += tex_desc.Width * 4; pitchOffset += mappedTexture.RowPitch; i++; } } ReleaseMutex(ipcContext->m_hMutex); SetEvent(ipcContext->m_hFrameGrabbedEvent); } else { logger->reportLogError(L"d3d11 couldn't wait mutex. errocode = 0x%x", errorcode); } pDevContext->Unmap(pTexture, D3D10CalcSubresource(0, 0, 1)); end: pTexture->Release(); pDevContext->Release(); pDev->Release(); }
void SkeletonMeshShader::SetBuffer(AglMatrix pWorld, AglMatrix pView, AglMatrix pProjection, float pScale, AglSkeleton* pSkeleton, AglMaterial pMaterial) { pWorld = AglMatrix::transpose(pWorld); pView = AglMatrix::transpose(pView); pProjection = AglMatrix::transpose(pProjection); //Copy the matrix palette buffer to the gpu D3D11_MAPPED_SUBRESOURCE resource; mDeviceContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource); SkeletonMeshShaderBuffer* buffer; buffer = (SkeletonMeshShaderBuffer*)resource.pData; buffer->World = pWorld; buffer->View = pView; buffer->Projection = pProjection; buffer->Scale = pScale; buffer->TextureScale = pMaterial.textureScale; unsigned int jointCount = pSkeleton->getHeader().jointCount; for (unsigned int i = 0; i < jointCount; i++) { AglMatrix am = pSkeleton->getInverseBindMatrix(i) * pSkeleton->getGlobalTransform(i); am = AglMatrix::transpose(am); buffer->Palette[i] = am; } mDeviceContext->Unmap(mBuffer, 0); unsigned int bufferNumber = 0; mDeviceContext->VSSetConstantBuffers(bufferNumber, 1, &mBuffer); //Copy the material buffer to the gpu mDeviceContext->Map(mMaterialBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource); MaterialBuffer* matbuffer; matbuffer = (MaterialBuffer*)resource.pData; matbuffer->AmbientOpacity = AglVector4(pMaterial.ambient, pMaterial.opacity); matbuffer->DiffuseReflectivity = AglVector4(pMaterial.diffuse, pMaterial.reflectivity); matbuffer->SpecularShininess = AglVector4(pMaterial.specular, pMaterial.shininess); matbuffer->EmissiveDiffuseMapped = AglVector4(pMaterial.emissive, float(pMaterial.diffuseTextureNameIndex >= 0 && DIFFUSEON)); matbuffer->EyePositionSpecularMapped = AglVector4(Camera::GetInstance()->Position().x, Camera::GetInstance()->Position().y, Camera::GetInstance()->Position().z, float(pMaterial.specularTextureNameIndex >= 0 && SPECULARON)); matbuffer->Flags = AglVector4((float)(pMaterial.glowTextureNameIndex >= 0 && GLOWON), (float)(pMaterial.normalTextureNameIndex >= 0 && NORMALON), (float)(pMaterial.gradientDataIndex >= 0 && pMaterial.gradientTextureNameIndex >= 0), 0); if (pMaterial.gradientDataIndex >= 0) { AglGradient* g = Scene::GetInstance()->GetGradient(pMaterial.gradientDataIndex); vector<AglGradientMaterial*> layers = g->getLayers(); for (unsigned int i = 0; i < layers.size(); i++) matbuffer->gradientColors[i] = layers[i]->color; matbuffer->Flags.w = (float)layers.size(); } mDeviceContext->Unmap(mMaterialBuffer, 0); mDeviceContext->PSSetConstantBuffers(bufferNumber, 1, &mMaterialBuffer); if (pMaterial.diffuseTextureNameIndex >= 0) { string s = Scene::GetInstance()->GetName(pMaterial.diffuseTextureNameIndex); TextureData* data = TextureManager::GetInstance()->GetTexture(s); if (data) mDeviceContext->PSSetShaderResources(0, 1, &data->SRV); } if (pMaterial.specularTextureNameIndex >= 0) { string s = Scene::GetInstance()->GetName(pMaterial.specularTextureNameIndex); TextureData* data = TextureManager::GetInstance()->GetTexture(s); if (data) mDeviceContext->PSSetShaderResources(1, 1, &data->SRV); } if (pMaterial.glowTextureNameIndex >= 0) { string s = Scene::GetInstance()->GetName(pMaterial.glowTextureNameIndex); TextureData* data = TextureManager::GetInstance()->GetTexture(s); if (data) mDeviceContext->PSSetShaderResources(2, 1, &data->SRV); } if (pMaterial.normalTextureNameIndex >= 0) { string s = Scene::GetInstance()->GetName(pMaterial.normalTextureNameIndex); TextureData* data = TextureManager::GetInstance()->GetTexture(s); if (data) mDeviceContext->PSSetShaderResources(3, 1, &data->SRV); } if (pMaterial.gradientTextureNameIndex >= 0) { string s = Scene::GetInstance()->GetName(pMaterial.gradientTextureNameIndex); TextureData* data = TextureManager::GetInstance()->GetTexture(s); if (data) mDeviceContext->PSSetShaderResources(4, 1, &data->SRV); } mDeviceContext->PSSetSamplers(0, 1, &mSampler); mDeviceContext->DSSetSamplers(0, 1, &mSampler); //Bone texture data mDeviceContext->VSSetSamplers(0, 1, &mBoneTextureSampler); D3D11_MAPPED_SUBRESOURCE mappedTex; mDeviceContext->Map(mBoneTexture, D3D11CalcSubresource(0, 0, 1), D3D11_MAP_WRITE_DISCARD, 0, &mappedTex); float* values = (float*)mappedTex.pData; jointCount = pSkeleton->getHeader().jointCount; for (unsigned int i = 0; i < jointCount; i++) { AglMatrix am = pSkeleton->getInverseBindMatrix(i) * pSkeleton->getGlobalTransform(i); //am = AglMatrix::transpose(am); int pos = i*16; //Row1 values[pos] = am[0]; values[pos+1] = am[1]; values[pos+2] = am[2]; values[pos+3] = am[3]; //Row2 values[pos+4] = am[4]; values[pos+5] = am[5]; values[pos+6] = am[6]; values[pos+7] = am[7]; //Row3 values[pos+8] = am[8]; values[pos+9] = am[9]; values[pos+10] =am[10]; values[pos+11] =am[11]; //Row4 values[pos+12] = am[12]; values[pos+13] = am[13]; values[pos+14] = am[14]; values[pos+15] = am[15]; } mDeviceContext->Unmap(mBoneTexture, D3D11CalcSubresource(0, 0, 1)); mDeviceContext->VSSetShaderResources(0, 1, &mBoneSRV); }
void Texture::CreateTexture2DArray( ID3D11Device* d3dDevice, ID3D11DeviceContext* d3dDeviceContext, std::vector<std::wstring>& filenames, DXGI_FORMAT format, UINT filter, UINT mipFilter) { if (nullptr != SRV) { MessageBox(0, L"[Texture::CreateTexture2DArraySRV] This View have been created!", 0, 0); assert(false); } // // 从文件加载单独的纹理元素。这些纹理不能被GPU使用(0 bind flags), // 只是用来从文件中加载图像数据。我们使用STAGING让CPU可以访问资源。 // UINT size = filenames.size(); std::vector<ID3D11Texture2D*> srcTex(size); for (UINT i = 0; i < size; ++i) { D3DX11_IMAGE_LOAD_INFO loadInfo; loadInfo.Width = D3DX11_FROM_FILE; loadInfo.Height = D3DX11_FROM_FILE; loadInfo.Depth = D3DX11_FROM_FILE; loadInfo.FirstMipLevel = 0; loadInfo.MipLevels = D3DX11_FROM_FILE; loadInfo.Usage = D3D11_USAGE_STAGING; loadInfo.BindFlags = 0; loadInfo.CpuAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; loadInfo.MiscFlags = 0; loadInfo.Format = format; loadInfo.Filter = filter; loadInfo.MipFilter = mipFilter; loadInfo.pSrcInfo = 0; HR(D3DX11CreateTextureFromFile(d3dDevice, filenames[i].c_str(), &loadInfo, 0, (ID3D11Resource**)&srcTex[i], 0)); } // // 创建纹理数组。每个纹理元素都具有相同的格式/大小。 // D3D11_TEXTURE2D_DESC texElementDesc; srcTex[0]->GetDesc(&texElementDesc); D3D11_TEXTURE2D_DESC texArrayDesc; texArrayDesc.Width = texElementDesc.Width; texArrayDesc.Height = texElementDesc.Height; texArrayDesc.MipLevels = texElementDesc.MipLevels; texArrayDesc.ArraySize = size; texArrayDesc.Format = texElementDesc.Format; texArrayDesc.SampleDesc.Count = 1; texArrayDesc.SampleDesc.Quality = 0; texArrayDesc.Usage = D3D11_USAGE_DEFAULT; texArrayDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; texArrayDesc.CPUAccessFlags = 0; texArrayDesc.MiscFlags = 0; ID3D11Texture2D* texArray = 0; HR(d3dDevice->CreateTexture2D(&texArrayDesc, 0, &texArray)); // // 将单独的纹理元素复制到纹理数组中。 // // 处理每个纹理元素... for (UINT texElement = 0; texElement < size; ++texElement) { // 处理每个渐进纹理层... for (UINT mipLevel = 0; mipLevel < texElementDesc.MipLevels; ++mipLevel) { D3D11_MAPPED_SUBRESOURCE mappedTex2D; HR(d3dDeviceContext->Map(srcTex[texElement], mipLevel, D3D11_MAP_READ, 0, &mappedTex2D)); d3dDeviceContext->UpdateSubresource(texArray, D3D11CalcSubresource(mipLevel, texElement, texElementDesc.MipLevels), 0, mappedTex2D.pData, mappedTex2D.RowPitch, mappedTex2D.DepthPitch); d3dDeviceContext->Unmap(srcTex[texElement], mipLevel); } } // // 创建纹理数组的资源视图 // D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; viewDesc.Format = texArrayDesc.Format; viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; viewDesc.Texture2DArray.MostDetailedMip = 0; viewDesc.Texture2DArray.MipLevels = texArrayDesc.MipLevels; viewDesc.Texture2DArray.FirstArraySlice = 0; viewDesc.Texture2DArray.ArraySize = size; HR(d3dDevice->CreateShaderResourceView(texArray, &viewDesc, &SRV)); // // 清除--我们要的只是资源视图 // SafeRelease(texArray); for (UINT i = 0; i < size; ++i) SafeRelease(srcTex[i]); }
//--------------------------------------------------------------------- void D3D11RenderWindowBase::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) { if(mpBackBuffer == NULL) return; // get the backbuffer desc D3D11_TEXTURE2D_DESC BBDesc; mpBackBuffer->GetDesc( &BBDesc ); ID3D11Texture2D *backbuffer = NULL; if(BBDesc.SampleDesc.Quality > 0) { D3D11_TEXTURE2D_DESC desc = BBDesc; desc.Usage = D3D11_USAGE_DEFAULT; desc.CPUAccessFlags = 0; desc.BindFlags = 0; desc.SampleDesc.Quality = 0; desc.SampleDesc.Count = 1; HRESULT hr = mDevice->CreateTexture2D( &desc, NULL, &backbuffer); if (FAILED(hr) || mDevice.isError()) { String errorDescription = mDevice.getErrorDescription(hr); OGRE_EXCEPT_EX(Exception::ERR_RENDERINGAPI_ERROR, hr, "Error creating texture\nError Description:" + errorDescription, "D3D11RenderWindow::copyContentsToMemory" ); } mDevice.GetImmediateContext()->ResolveSubresource(backbuffer, D3D11CalcSubresource(0, 0, 1), mpBackBuffer, D3D11CalcSubresource(0, 0, 1), desc.Format); } // change the parameters of the texture so we can read it BBDesc.Usage = D3D11_USAGE_STAGING; BBDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; BBDesc.BindFlags = 0; BBDesc.SampleDesc.Quality = 0; BBDesc.SampleDesc.Count = 1; // create a temp buffer to copy to ID3D11Texture2D * pTempTexture2D; HRESULT hr = mDevice->CreateTexture2D( &BBDesc, NULL, &pTempTexture2D); if (FAILED(hr) || mDevice.isError()) { String errorDescription = mDevice.getErrorDescription(hr); OGRE_EXCEPT_EX(Exception::ERR_RENDERINGAPI_ERROR, hr, "Error creating texture\nError Description:" + errorDescription, "D3D11RenderWindow::copyContentsToMemory" ); } // copy the back buffer mDevice.GetImmediateContext()->CopyResource(pTempTexture2D, backbuffer != NULL ? backbuffer : mpBackBuffer); // map the copied texture D3D11_MAPPED_SUBRESOURCE mappedTex2D; mDevice.GetImmediateContext()->Map(pTempTexture2D, 0,D3D11_MAP_READ, 0, &mappedTex2D); // copy the the texture to the dest PixelUtil::bulkPixelConversion( PixelBox(mWidth, mHeight, 1, D3D11Mappings::_getPF(BBDesc.Format), mappedTex2D.pData), dst); // unmap the temp buffer mDevice.GetImmediateContext()->Unmap(pTempTexture2D, 0); // Release the temp buffer SAFE_RELEASE(pTempTexture2D); SAFE_RELEASE(backbuffer); }
void D3D11Texture3D::Unmap3D(uint32_t array_index, uint32_t level) { d3d_imm_ctx_->Unmap(d3dTexture3D_.get(), D3D11CalcSubresource(level, array_index, num_mip_maps_)); }
bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *pDL) { PROFILE_SCOPE(GFXD3D11TextureManager_loadTexture); GFXD3D11TextureObject *texture = static_cast<GFXD3D11TextureObject*>(aTexture); // Check with profiler to see if we can do automatic mipmap generation. const bool supportsAutoMips = GFX->getCardProfiler()->queryProfile("autoMipMapLevel", true); // Helper bool const bool isCompressedTexFmt = ImageUtil::isCompressedFormat(aTexture->mFormat); // Settings for mipmap generation U32 maxDownloadMip = pDL->getNumMipLevels(); U32 nbMipMapLevel = pDL->getNumMipLevels(); if( supportsAutoMips && !isCompressedTexFmt ) { maxDownloadMip = 1; nbMipMapLevel = aTexture->mMipLevels; } GFXD3D11Device* dev = D3D11; bool isDynamic = texture->mProfile->isDynamic(); // Fill the texture... for( U32 i = 0; i < maxDownloadMip; i++ ) { U32 subResource = D3D11CalcSubresource(i, 0, aTexture->mMipLevels); if(!isDynamic) { U8* copyBuffer = NULL; switch(texture->mFormat) { case GFXFormatR8G8B8: case GFXFormatR8G8B8_SRGB: { PROFILE_SCOPE(Swizzle24_Upload); U8* Bits = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4]; dMemcpy(Bits, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * 3); bitmapConvertRGB_to_RGBX(&Bits, pDL->getWidth(i) * pDL->getHeight(i)); copyBuffer = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4]; dev->getDeviceSwizzle32()->ToBuffer(copyBuffer, Bits, pDL->getWidth(i) * pDL->getHeight(i) * 4); dev->getDeviceContext()->UpdateSubresource(texture->get2DTex(), subResource, NULL, copyBuffer, pDL->getWidth() * 4, pDL->getHeight() *4); SAFE_DELETE_ARRAY(Bits); break; } case GFXFormatR8G8B8A8: case GFXFormatR8G8B8X8: case GFXFormatR8G8B8A8_SRGB: { PROFILE_SCOPE(Swizzle32_Upload); copyBuffer = new U8[pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel()]; dev->getDeviceSwizzle32()->ToBuffer(copyBuffer, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel()); dev->getDeviceContext()->UpdateSubresource(texture->get2DTex(), subResource, NULL, copyBuffer, pDL->getWidth() * pDL->getBytesPerPixel(), pDL->getHeight() *pDL->getBytesPerPixel()); break; } default: { // Just copy the bits in no swizzle or padding PROFILE_SCOPE(SwizzleNull_Upload); AssertFatal( pDL->getFormat() == texture->mFormat, "Format mismatch"); dev->getDeviceContext()->UpdateSubresource(texture->get2DTex(), subResource, NULL, pDL->getBits(i), pDL->getWidth() *pDL->getBytesPerPixel(), pDL->getHeight() *pDL->getBytesPerPixel()); } } SAFE_DELETE_ARRAY(copyBuffer); } else { D3D11_MAPPED_SUBRESOURCE mapping; HRESULT res = dev->getDeviceContext()->Map(texture->get2DTex(), subResource, D3D11_MAP_WRITE, 0, &mapping); AssertFatal(res, "tex2d map call failure"); switch( texture->mFormat ) { case GFXFormatR8G8B8: case GFXFormatR8G8B8_SRGB: { PROFILE_SCOPE(Swizzle24_Upload); U8* Bits = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4]; dMemcpy(Bits, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * 3); bitmapConvertRGB_to_RGBX(&Bits, pDL->getWidth(i) * pDL->getHeight(i)); dev->getDeviceSwizzle32()->ToBuffer(mapping.pData, Bits, pDL->getWidth(i) * pDL->getHeight(i) * 4); SAFE_DELETE_ARRAY(Bits); } break; case GFXFormatR8G8B8A8: case GFXFormatR8G8B8X8: case GFXFormatR8G8B8A8_SRGB: { PROFILE_SCOPE(Swizzle32_Upload); dev->getDeviceSwizzle32()->ToBuffer(mapping.pData, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel()); } break; default: { // Just copy the bits in no swizzle or padding PROFILE_SCOPE(SwizzleNull_Upload); AssertFatal( pDL->getFormat() == texture->mFormat, "Format mismatch"); dMemcpy(mapping.pData, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel()); } } dev->getDeviceContext()->Unmap(texture->get2DTex(), subResource); } } D3D11_TEXTURE2D_DESC desc; // if the texture asked for mip generation. lets generate it. texture->get2DTex()->GetDesc(&desc); if (desc.MiscFlags &D3D11_RESOURCE_MISC_GENERATE_MIPS) { dev->getDeviceContext()->GenerateMips(texture->getSRView()); //texture->mMipLevels = desc.MipLevels; } return true; }
void D3D11TextureCube::UnmapCube(uint32_t array_index, CubeFaces face, uint32_t level) { d3d_imm_ctx_->Unmap(d3dTextureCube_.get(), D3D11CalcSubresource(level, array_index * 6 + face - CF_Positive_X, num_mip_maps_)); }
HRESULT DeviceResources::RetrieveBackBuffer(char* buffer, DWORD width, DWORD height, DWORD bpp) { HRESULT hr = S_OK; char* step = ""; memset(buffer, 0, width * height * bpp); D3D11_TEXTURE2D_DESC textureDescription; this->_backBuffer->GetDesc(&textureDescription); textureDescription.BindFlags = 0; textureDescription.SampleDesc.Count = 1; textureDescription.SampleDesc.Quality = 0; ComPtr<ID3D11Texture2D> backBuffer; textureDescription.Usage = D3D11_USAGE_DEFAULT; textureDescription.CPUAccessFlags = 0; step = "Resolve BackBuffer"; if (SUCCEEDED(hr = this->_d3dDevice->CreateTexture2D(&textureDescription, nullptr, &backBuffer))) { this->_d3dDeviceContext->ResolveSubresource(backBuffer, D3D11CalcSubresource(0, 0, 1), this->_backBuffer, D3D11CalcSubresource(0, 0, 1), textureDescription.Format); step = "Staging Texture2D"; ComPtr<ID3D11Texture2D> texture; textureDescription.Usage = D3D11_USAGE_STAGING; textureDescription.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; if (SUCCEEDED(hr = this->_d3dDevice->CreateTexture2D(&textureDescription, nullptr, &texture))) { this->_d3dDeviceContext->CopyResource(texture, backBuffer); step = "Map"; D3D11_MAPPED_SUBRESOURCE map; if (SUCCEEDED(hr = this->_d3dDeviceContext->Map(texture, 0, D3D11_MAP_READ, 0, &map))) { step = "copy"; if (bpp == 4 && width == this->_backbufferWidth && height == this->_backbufferHeight) { memcpy(buffer, map.pData, width * height * 4); } else { scaleSurface(buffer, width, height, bpp, (char*)map.pData, this->_backbufferWidth, this->_backbufferHeight, 4); } this->_d3dDeviceContext->Unmap(texture, 0); } } } if (FAILED(hr)) { static bool messageShown = false; if (!messageShown) { char text[512]; strcpy_s(text, step); strcat_s(text, "\n"); strcat_s(text, _com_error(hr).ErrorMessage()); MessageBox(nullptr, text, __FUNCTION__, MB_ICONERROR); } messageShown = true; } return hr; }
//=============================================================================================================================== ID3D11ShaderResourceView* TextureManager::CreateTexture2DArraySRV(std::vector<std::string>& filenames) { // // Load the texture elements individually from file. These textures // won't be used by the GPU (0 bind flags), they are just used to // load the image data from file. We use the STAGING usage so the // CPU can read the resource. // UINT size = filenames.size(); HRESULT result; std::vector<ID3D11Texture2D*> srcTex(size); for(UINT i = 0; i < size; ++i) { unique_ptr<wchar_t> name = BetterString(filenames[i].c_str()).ToWideStr(); // ReleaseAndGetAddressOf result = CreateDDSTextureFromFileEx(mD3DSystem->GetDevice11(), name.get(), 0u, D3D11_USAGE_IMMUTABLE, D3D11_BIND_SHADER_RESOURCE, 0,//D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ, 0, false, reinterpret_cast<ID3D11Resource**>(&srcTex[i]), nullptr, nullptr); if (FAILED(result)) { return 0; } } // // Create the texture array. Each element in the texture // array has the same format/dimensions. // D3D11_TEXTURE2D_DESC texElementDesc; srcTex[0]->GetDesc(&texElementDesc); /* Usage: D3D11_USAGE_DEFAULT - Video RAM D3D11_USAGE_STAGING - in the system RAM and cannot be used by the GPU at all D3D11_USAGE_DYNAMIC - CPU- and GPU-addressable RAM D3D11_USAGE_IMMUTABLE */ D3D11_TEXTURE2D_DESC texArrayDesc; texArrayDesc.Width = texElementDesc.Width; texArrayDesc.Height = texElementDesc.Height; texArrayDesc.MipLevels = texElementDesc.MipLevels; texArrayDesc.ArraySize = size; texArrayDesc.Format = texElementDesc.Format; texArrayDesc.SampleDesc.Count = 1; texArrayDesc.SampleDesc.Quality = 0; texArrayDesc.Usage = D3D11_USAGE_DEFAULT; texArrayDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; texArrayDesc.CPUAccessFlags = 0;// D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; texArrayDesc.MiscFlags = 0; ID3D11Texture2D* texArray = 0; mD3DSystem->GetDevice11()->CreateTexture2D(&texArrayDesc, 0, &texArray); // // Copy individual texture elements into texture array. // // for each texture element... for(UINT texElement = 0; texElement < size; ++texElement) { // for each mipmap level... for(UINT mipLevel = 0; mipLevel < texElementDesc.MipLevels; ++mipLevel) { mD3DSystem->GetDeviceContext()->CopySubresourceRegion(texArray, D3D11CalcSubresource(mipLevel, texElement, texElementDesc.MipLevels), 0, 0, 0, srcTex[texElement], mipLevel, nullptr); } } // Release the temporary Video Memory used per texture for (UINT i = 0; i < size; ++i) SAFE_RELEASE(srcTex[i]); // // Create a resource view to the texture array. // D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; viewDesc.Format = texArrayDesc.Format; viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; viewDesc.Texture2DArray.MostDetailedMip = 0; viewDesc.Texture2DArray.MipLevels = texArrayDesc.MipLevels; viewDesc.Texture2DArray.FirstArraySlice = 0; viewDesc.Texture2DArray.ArraySize = size; ID3D11ShaderResourceView* texArraySRV = 0; mD3DSystem->GetDevice11()->CreateShaderResourceView(texArray, &viewDesc, &texArraySRV); // // Cleanup - we only need the resource view. // SAFE_RELEASE(texArray); // Return the new texture array return texArraySRV; }