void D3D11Device::SetViewports( const std::vector<Viewport>& vps ) { static CD3D11_VIEWPORT vpD3D11[4]; size_t numViewports = vps.size(); // Only check first one if (numViewports == 1) { if (vpD3D11[0].TopLeftX != vps[0].Left || vpD3D11[0].TopLeftY != vps[0].Top || vpD3D11[0].Width != vps[0].Width || vpD3D11[0].Height != vps[0].Height) { vpD3D11[0] = CD3D11_VIEWPORT(vps[0].Left, vps[0].Top, vps[0].Width, vps[0].Height); DeviceContextD3D11->RSSetViewports(numViewports, vpD3D11); } } else { assert(numViewports <= 4); for (size_t i = 0; i < vps.size(); ++i) vpD3D11[i] = CD3D11_VIEWPORT(vps[i].Left, vps[i].Top, vps[i].Width, vps[i].Height); DeviceContextD3D11->RSSetViewports(numViewports, vpD3D11); } }
void DXTexture::ScaleRectangleFromTexture(const AbstractTexture* source, const MathUtil::Rectangle<int>& srcrect, const MathUtil::Rectangle<int>& dstrect) { const DXTexture* srcentry = static_cast<const DXTexture*>(source); _assert_(m_config.rendertarget); g_renderer->ResetAPIState(); // reset any game specific settings const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(float(dstrect.left), float(dstrect.top), float(dstrect.GetWidth()), float(dstrect.GetHeight())); D3D::stateman->UnsetTexture(m_texture->GetSRV()); D3D::stateman->Apply(); D3D::context->OMSetRenderTargets(1, &m_texture->GetRTV(), nullptr); D3D::context->RSSetViewports(1, &vp); D3D::SetLinearCopySampler(); D3D11_RECT srcRC; srcRC.left = srcrect.left; srcRC.right = srcrect.right; srcRC.top = srcrect.top; srcRC.bottom = srcrect.bottom; D3D::drawShadedTexQuad(srcentry->m_texture->GetSRV(), &srcRC, srcentry->m_config.width, srcentry->m_config.height, PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), GeometryShaderCache::GetCopyGeometryShader(), 1.0, 0); FramebufferManager::BindEFBRenderTarget(); g_renderer->RestoreAPIState(); }
void DX11::BackbufferSurface::Resize(ID3D11Texture2D * texture, unsigned width, unsigned height) { this->width = width; this->height = height; device->CreateRenderTargetView(texture, 0, &renderTargetView); CD3D11_TEXTURE2D_DESC depthStencilTextureDesc( DXGI_FORMAT_D24_UNORM_S8_UINT, width, height, 1, 1, D3D11_BIND_DEPTH_STENCIL); ID3D11Texture2D* depthStencilBuffer; device->CreateTexture2D( &depthStencilTextureDesc, 0, &depthStencilBuffer); device->CreateDepthStencilView( depthStencilBuffer, &CD3D11_DEPTH_STENCIL_VIEW_DESC(D3D11_DSV_DIMENSION_TEXTURE2DMS), &depthStencilView); depthStencilBuffer->Release(); viewport = CD3D11_VIEWPORT( 0.0f, 0.0f, static_cast<float>(width), static_cast<float>(height)); }
void TextureCache::TCacheEntry::FromRenderTarget(u8* dst, unsigned int dstFormat, u32 dstStride, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf, u32 cbufid, const float *colmat) { g_renderer->ResetAPIState(); // stretch picture with increased internal resolution const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)config.width, (float)config.height); D3D::context->RSSetViewports(1, &vp); // set transformation if (nullptr == efbcopycbuf[cbufid].get()) { const D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(28 * sizeof(float), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT); D3D11_SUBRESOURCE_DATA data; data.pSysMem = colmat; HRESULT hr = D3D::device->CreateBuffer(&cbdesc, &data, D3D::ToAddr(efbcopycbuf[cbufid])); CHECK(SUCCEEDED(hr), "Create efb copy constant buffer %d", cbufid); D3D::SetDebugObjectName(efbcopycbuf[cbufid].get(), "a constant buffer used in TextureCache::CopyRenderTargetToTexture"); } D3D::stateman->SetPixelConstants(efbcopycbuf[cbufid].get()); const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect); // TODO: try targetSource.asRECT(); const D3D11_RECT sourcerect = CD3D11_RECT(targetSource.left, targetSource.top, targetSource.right, targetSource.bottom); // Use linear filtering if (bScaleByHalf), use point filtering otherwise if (scaleByHalf) D3D::SetLinearCopySampler(); else D3D::SetPointCopySampler(); // if texture is currently in use, it needs to be temporarily unset u32 textureSlotMask = D3D::stateman->UnsetTexture(texture->GetSRV()); D3D::stateman->Apply(); D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), nullptr); // Create texture copy D3D::drawShadedTexQuad( ((srcFormat == PEControl::Z24) ? FramebufferManager::GetEFBDepthTexture() : FramebufferManager::GetEFBColorTexture())->GetSRV(), &sourcerect, Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), (srcFormat == PEControl::Z24) ? PixelShaderCache::GetDepthMatrixProgram(true) : PixelShaderCache::GetColorMatrixProgram(true), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), (g_Config.iStereoMode > 0) ? GeometryShaderCache::GetCopyGeometryShader() : nullptr); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); g_renderer->RestoreAPIState(); if (g_ActiveConfig.bSkipEFBCopyToRam) { this->Zero(dst); } else { s_encoder->Encode(dst, this, srcFormat, srcRect, isIntensity, scaleByHalf); } }
static void dx11_setup_back_buffer(RenderDevice* dev) { dev->default_context->native->OMSetRenderTargets(1, &dev->backbuffer_rtv, dev->depthstencil_dsv); D3D11_VIEWPORT viewport = CD3D11_VIEWPORT(dev->backbuffer_tex, dev->backbuffer_rtv); dev->default_context->native->RSSetViewports(1, &viewport); dev->default_context->current_rtv = dev->backbuffer_rtv; dev->default_context->current_dsv = dev->depthstencil_dsv; }
void Renderer::beginFrame() { // Bind render target m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, nullptr); // Set viewport auto viewport = CD3D11_VIEWPORT(0.f, 0.f, (float) m_backBufferDesc.Width, (float) m_backBufferDesc.Height); m_deviceContext->RSSetViewports(1, &viewport); // Set the background color float clearColor[] = { .25f, .5f, 1, 1 }; m_deviceContext->ClearRenderTargetView(m_renderTargetView, clearColor); }
void TextureCache::TCacheEntry::FromRenderTarget(u8* dst, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool scaleByHalf, unsigned int cbufid, const float *colmat) { g_renderer->ResetAPIState(); // stretch picture with increased internal resolution const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)config.width, (float)config.height); D3D::context->RSSetViewports(1, &vp); // set transformation if (nullptr == efbcopycbuf[cbufid]) { const D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(28 * sizeof(float), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT); D3D11_SUBRESOURCE_DATA data; data.pSysMem = colmat; HRESULT hr = D3D::device->CreateBuffer(&cbdesc, &data, &efbcopycbuf[cbufid]); CHECK(SUCCEEDED(hr), "Create efb copy constant buffer %d", cbufid); D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopycbuf[cbufid], "a constant buffer used in TextureCache::CopyRenderTargetToTexture"); } D3D::stateman->SetPixelConstants(efbcopycbuf[cbufid]); const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect); // TODO: try targetSource.asRECT(); const D3D11_RECT sourcerect = CD3D11_RECT(targetSource.left, targetSource.top, targetSource.right, targetSource.bottom); // Use linear filtering if (bScaleByHalf), use point filtering otherwise if (scaleByHalf) D3D::SetLinearCopySampler(); else D3D::SetPointCopySampler(); // Make sure we don't draw with the texture set as both a source and target. // (This can happen because we don't unbind textures when we free them.) D3D::stateman->UnsetTexture(texture->GetSRV()); D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), nullptr); // Create texture copy D3D::drawShadedTexQuad( (srcFormat == PEControl::Z24 ? FramebufferManager::GetEFBDepthTexture() : FramebufferManager::GetEFBColorTexture())->GetSRV(), &sourcerect, Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), srcFormat == PEControl::Z24 ? PixelShaderCache::GetDepthMatrixProgram(true) : PixelShaderCache::GetColorMatrixProgram(true), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), GeometryShaderCache::GetCopyGeometryShader()); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); g_renderer->RestoreAPIState(); }
void DXTexture::CopyRectangleFromTexture(const AbstractTexture* source, const MathUtil::Rectangle<int>& srcrect, const MathUtil::Rectangle<int>& dstrect) { const DXTexture* srcentry = static_cast<const DXTexture*>(source); if (srcrect.GetWidth() == dstrect.GetWidth() && srcrect.GetHeight() == dstrect.GetHeight()) { D3D11_BOX srcbox; srcbox.left = srcrect.left; srcbox.top = srcrect.top; srcbox.right = srcrect.right; srcbox.bottom = srcrect.bottom; srcbox.front = 0; srcbox.back = srcentry->m_config.layers; D3D::context->CopySubresourceRegion(m_texture->GetTex(), 0, dstrect.left, dstrect.top, 0, srcentry->m_texture->GetTex(), 0, &srcbox); return; } else if (!m_config.rendertarget) { return; } g_renderer->ResetAPIState(); // reset any game specific settings const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(float(dstrect.left), float(dstrect.top), float(dstrect.GetWidth()), float(dstrect.GetHeight())); D3D::stateman->UnsetTexture(m_texture->GetSRV()); D3D::stateman->Apply(); D3D::context->OMSetRenderTargets(1, &m_texture->GetRTV(), nullptr); D3D::context->RSSetViewports(1, &vp); D3D::SetLinearCopySampler(); D3D11_RECT srcRC; srcRC.left = srcrect.left; srcRC.right = srcrect.right; srcRC.top = srcrect.top; srcRC.bottom = srcrect.bottom; D3D::drawShadedTexQuad(srcentry->m_texture->GetSRV(), &srcRC, srcentry->m_config.width, srcentry->m_config.height, PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), GeometryShaderCache::GetCopyGeometryShader(), 1.0, 0); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); g_renderer->RestoreAPIState(); }
void XFBSource::CopyEFB(float Gamma) { // Copy EFB data to XFB and restore render target again const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)texWidth, (float)texHeight); D3D::context->RSSetViewports(1, &vp); D3D::context->OMSetRenderTargets(1, &tex->GetRTV(), NULL); D3D::SetLinearCopySampler(); D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), sourceRc.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(true), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(),Gamma); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); }
DX11::TextureSurface::TextureSurface(DX11::Api * gpu, ID3D11Device * device, ID3D11DeviceContext * context, Format format, PlatformWindow * relativeWindow, float width, float height, bool mips) : DrawSurface(device, context), gpu(gpu), texture(0), relativeWindow(relativeWindow), renderTargetView(0), depthStencilTexture(0), depthStencilView(0), format(format), widthFactor(width), heightFactor(height), generateMips(mips) { viewport = CD3D11_VIEWPORT(0.0f, 0.0f, width, height); OnResetDevice(gpu); }
void XFBSource::CopyEFB(float Gamma) { g_renderer->ResetAPIState(); // reset any game specific settings // Copy EFB data to XFB and restore render target again const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)texWidth, (float)texHeight); const D3D11_RECT rect = CD3D11_RECT(0, 0, texWidth, texHeight); D3D::context->RSSetViewports(1, &vp); D3D::context->OMSetRenderTargets(1, &tex->GetRTV(), nullptr); D3D::SetPointCopySampler(); D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), &rect, Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(true), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), GeometryShaderCache::GetCopyGeometryShader(), Gamma); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); g_renderer->RestoreAPIState(); }
void PSTextureEncoder::Encode(u8* dst, const EFBCopyFormat& format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y, u32 memory_stride, bool is_depth_copy, const EFBRectangle& src_rect, bool scale_by_half) { if (!m_ready) // Make sure we initialized OK return; HRESULT hr; // Resolve MSAA targets before copying. // FIXME: Instead of resolving EFB, it would be better to pick out a // single sample from each pixel. The game may break if it isn't // expecting the blurred edges around multisampled shapes. ID3D11ShaderResourceView* pEFB = is_depth_copy ? FramebufferManager::GetResolvedEFBDepthTexture()->GetSRV() : FramebufferManager::GetResolvedEFBColorTexture()->GetSRV(); // Reset API g_renderer->ResetAPIState(); // Set up all the state for EFB encoding { const u32 words_per_row = bytes_per_row / sizeof(u32); D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, FLOAT(words_per_row), FLOAT(num_blocks_y)); D3D::context->RSSetViewports(1, &vp); constexpr EFBRectangle fullSrcRect(0, 0, EFB_WIDTH, EFB_HEIGHT); TargetRectangle targetRect = g_renderer->ConvertEFBRectangle(fullSrcRect); D3D::context->OMSetRenderTargets(1, &m_outRTV, nullptr); EFBEncodeParams params; params.SrcLeft = src_rect.left; params.SrcTop = src_rect.top; params.DestWidth = native_width; params.ScaleFactor = scale_by_half ? 2 : 1; D3D::context->UpdateSubresource(m_encodeParams, 0, nullptr, ¶ms, 0, 0); D3D::stateman->SetPixelConstants(m_encodeParams); // We also linear filtering for both box filtering and downsampling higher resolutions to 1x // TODO: This only produces perfect downsampling for 1.5x and 2x IR, other resolution will // need more complex down filtering to average all pixels and produce the correct result. // Also, box filtering won't be correct for anything other than 1x IR if (scale_by_half || g_ActiveConfig.iEFBScale != SCALE_1X) D3D::SetLinearCopySampler(); else D3D::SetPointCopySampler(); D3D::drawShadedTexQuad(pEFB, targetRect.AsRECT(), g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), GetEncodingPixelShader(format), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); // Copy to staging buffer D3D11_BOX srcBox = CD3D11_BOX(0, 0, 0, words_per_row, num_blocks_y, 1); D3D::context->CopySubresourceRegion(m_outStage, 0, 0, 0, 0, m_out, 0, &srcBox); // Transfer staging buffer to GameCube/Wii RAM D3D11_MAPPED_SUBRESOURCE map = {0}; hr = D3D::context->Map(m_outStage, 0, D3D11_MAP_READ, 0, &map); CHECK(SUCCEEDED(hr), "map staging buffer (0x%x)", hr); u8* src = (u8*)map.pData; u32 readStride = std::min(bytes_per_row, map.RowPitch); for (unsigned int y = 0; y < num_blocks_y; ++y) { memcpy(dst, src, readStride); dst += memory_stride; src += map.RowPitch; } D3D::context->Unmap(m_outStage, 0); } // Restore API g_renderer->RestoreAPIState(); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); }
void XFBEncoder::Encode(u8* dst, u32 width, u32 height, const EFBRectangle& srcRect, float gamma) { HRESULT hr; // Reset API g_renderer->ResetAPIState(); // Set up all the state for XFB encoding D3D::stateman->SetPixelShader(m_pShader); D3D::stateman->SetVertexShader(m_vShader); D3D::stateman->SetGeometryShader(nullptr); D3D::stateman->PushBlendState(m_xfbEncodeBlendState); D3D::stateman->PushDepthState(m_xfbEncodeDepthState); D3D::stateman->PushRasterizerState(m_xfbEncodeRastState); D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, FLOAT(width/4), FLOAT(height)); D3D::context->RSSetViewports(1, &vp); D3D::stateman->SetInputLayout(m_quadLayout); D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); UINT stride = sizeof(QuadVertex); UINT offset = 0; D3D::stateman->SetVertexBuffer(m_quad, stride, offset); TargetRectangle targetRect = g_renderer->ConvertEFBRectangle(srcRect); XFBEncodeParams params = { 0 }; params.Width = FLOAT(width/2); params.Height = FLOAT(height); params.TexLeft = FLOAT(targetRect.left) / g_renderer->GetTargetWidth(); params.TexTop = FLOAT(targetRect.top) / g_renderer->GetTargetHeight(); params.TexRight = FLOAT(targetRect.right) / g_renderer->GetTargetWidth(); params.TexBottom = FLOAT(targetRect.bottom) / g_renderer->GetTargetHeight(); params.Gamma = gamma; D3D::context->UpdateSubresource(m_encodeParams, 0, nullptr, ¶ms, 0, 0); D3D::context->OMSetRenderTargets(1, &m_outRTV, nullptr); ID3D11ShaderResourceView* pEFB = FramebufferManager::GetResolvedEFBColorTexture()->GetSRV(); D3D::stateman->SetVertexConstants(m_encodeParams); D3D::stateman->SetPixelConstants(m_encodeParams); D3D::stateman->SetTexture(0, pEFB); D3D::stateman->SetSampler(0, m_efbSampler); // Encode! D3D::stateman->Apply(); D3D::context->Draw(4, 0); // Copy to staging buffer D3D11_BOX srcBox = CD3D11_BOX(0, 0, 0, width/4, height, 1); D3D::context->CopySubresourceRegion(m_outStage, 0, 0, 0, 0, m_out, 0, &srcBox); // Clean up state D3D::context->OMSetRenderTargets(0, nullptr, nullptr); D3D::stateman->SetSampler(0, nullptr); D3D::stateman->SetTexture(0, nullptr); D3D::stateman->SetPixelConstants(nullptr); D3D::stateman->SetVertexConstants(nullptr); D3D::stateman->SetPixelShader(nullptr); D3D::stateman->SetVertexShader(nullptr); D3D::stateman->PopRasterizerState(); D3D::stateman->PopDepthState(); D3D::stateman->PopBlendState(); // Transfer staging buffer to GameCube/Wii RAM D3D11_MAPPED_SUBRESOURCE map = { 0 }; hr = D3D::context->Map(m_outStage, 0, D3D11_MAP_READ, 0, &map); CHECK(SUCCEEDED(hr), "map staging buffer"); u8* src = (u8*)map.pData; for (unsigned int y = 0; y < height; ++y) { memcpy(dst, src, width); dst += bpmem.copyMipMapStrideChannels*32; src += map.RowPitch; } D3D::context->Unmap(m_outStage, 0); // Restore API g_renderer->RestoreAPIState(); D3D::stateman->Apply(); // force unbind efb texture as shader resource D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); }
void PSTextureEncoder::Encode(u8* dst, const EFBCopyParams& params, u32 native_width, u32 bytes_per_row, u32 num_blocks_y, u32 memory_stride, const EFBRectangle& src_rect, bool scale_by_half) { // Resolve MSAA targets before copying. // FIXME: Instead of resolving EFB, it would be better to pick out a // single sample from each pixel. The game may break if it isn't // expecting the blurred edges around multisampled shapes. ID3D11ShaderResourceView* pEFB = params.depth ? FramebufferManager::GetResolvedEFBDepthTexture()->GetSRV() : FramebufferManager::GetResolvedEFBColorTexture()->GetSRV(); // Reset API g_renderer->ResetAPIState(); // Set up all the state for EFB encoding { const u32 words_per_row = bytes_per_row / sizeof(u32); D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, FLOAT(words_per_row), FLOAT(num_blocks_y)); D3D::context->RSSetViewports(1, &vp); constexpr EFBRectangle fullSrcRect(0, 0, EFB_WIDTH, EFB_HEIGHT); TargetRectangle targetRect = g_renderer->ConvertEFBRectangle(fullSrcRect); D3D::context->OMSetRenderTargets( 1, &static_cast<DXTexture*>(m_encoding_render_texture.get())->GetRawTexIdentifier()->GetRTV(), nullptr); EFBEncodeParams encode_params; encode_params.SrcLeft = src_rect.left; encode_params.SrcTop = src_rect.top; encode_params.DestWidth = native_width; encode_params.ScaleFactor = scale_by_half ? 2 : 1; encode_params.y_scale = params.y_scale; D3D::context->UpdateSubresource(m_encode_params, 0, nullptr, &encode_params, 0, 0); D3D::stateman->SetPixelConstants(m_encode_params); // We also linear filtering for both box filtering and downsampling higher resolutions to 1x // TODO: This only produces perfect downsampling for 2x IR, other resolutions will need more // complex down filtering to average all pixels and produce the correct result. // Also, box filtering won't be correct for anything other than 1x IR if (scale_by_half || g_renderer->GetEFBScale() != 1 || params.y_scale > 1.0f) D3D::SetLinearCopySampler(); else D3D::SetPointCopySampler(); D3D::drawShadedTexQuad(pEFB, targetRect.AsRECT(), g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), GetEncodingPixelShader(params), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); // Copy to staging buffer MathUtil::Rectangle<int> copy_rect(0, 0, words_per_row, num_blocks_y); m_encoding_readback_texture->CopyFromTexture(m_encoding_render_texture.get(), copy_rect, 0, 0, copy_rect); m_encoding_readback_texture->Flush(); if (m_encoding_readback_texture->Map()) { m_encoding_readback_texture->ReadTexels(copy_rect, dst, memory_stride); m_encoding_readback_texture->Unmap(); } } // Restore API FramebufferManager::BindEFBRenderTarget(); g_renderer->RestoreAPIState(); }
void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFormat, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf, unsigned int cbufid, const float *colmat) { if (type != TCET_EC_DYNAMIC || g_ActiveConfig.bCopyEFBToTexture) { g_renderer->ResetAPIState(); // stretch picture with increased internal resolution const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)virtual_width, (float)virtual_height); D3D::context->RSSetViewports(1, &vp); // set transformation if (nullptr == efbcopycbuf[cbufid]) { const D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(28 * sizeof(float), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT); D3D11_SUBRESOURCE_DATA data; data.pSysMem = colmat; HRESULT hr = D3D::device->CreateBuffer(&cbdesc, &data, &efbcopycbuf[cbufid]); CHECK(SUCCEEDED(hr), "Create efb copy constant buffer %d", cbufid); D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopycbuf[cbufid], "a constant buffer used in TextureCache::CopyRenderTargetToTexture"); } D3D::stateman->SetPixelConstants(efbcopycbuf[cbufid]); const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect); // TODO: try targetSource.asRECT(); const D3D11_RECT sourcerect = CD3D11_RECT(targetSource.left, targetSource.top, targetSource.right, targetSource.bottom); // Use linear filtering if (bScaleByHalf), use point filtering otherwise if (scaleByHalf) D3D::SetLinearCopySampler(); else D3D::SetPointCopySampler(); // if texture is currently in use, it needs to be temporarily unset u32 textureSlotMask = D3D::stateman->UnsetTexture(texture->GetSRV()); D3D::stateman->Apply(); D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), nullptr); // Create texture copy D3D::drawShadedTexQuad( (srcFormat == PEControl::Z24) ? FramebufferManager::GetEFBDepthTexture()->GetSRV() : FramebufferManager::GetEFBColorTexture()->GetSRV(), &sourcerect, Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), (srcFormat == PEControl::Z24) ? PixelShaderCache::GetDepthMatrixProgram(true) : PixelShaderCache::GetColorMatrixProgram(true), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), GeometryShaderCache::GetCopyGeometryShader()); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); g_renderer->RestoreAPIState(); // Restore old texture in all previously used slots, if any D3D::stateman->SetTextureByMask(textureSlotMask, texture->GetSRV()); } if (!g_ActiveConfig.bCopyEFBToTexture) { u8* dst = Memory::GetPointer(dstAddr); size_t encoded_size = g_encoder->Encode(dst, dstFormat, srcFormat, srcRect, isIntensity, scaleByHalf); u64 hash = GetHash64(dst, (int)encoded_size, g_ActiveConfig.iSafeTextureCache_ColorSamples); // Mark texture entries in destination address range dynamic unless caching is enabled and the texture entry is up to date if (!g_ActiveConfig.bEFBCopyCacheEnable) TextureCache::MakeRangeDynamic(addr, (u32)encoded_size); else if (!TextureCache::Find(addr, hash)) TextureCache::MakeRangeDynamic(addr, (u32)encoded_size); this->hash = hash; } }
size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf) { if (!m_ready) // Make sure we initialized OK return 0; // Clamp srcRect to 640x528. BPS: The Strike tries to encode an 800x600 // texture, which is invalid. EFBRectangle correctSrc = srcRect; correctSrc.ClampUL(0, 0, EFB_WIDTH, EFB_HEIGHT); // Validate source rect size if (correctSrc.GetWidth() <= 0 || correctSrc.GetHeight() <= 0) return 0; HRESULT hr; unsigned int blockW = BLOCK_WIDTHS[dstFormat]; unsigned int blockH = BLOCK_HEIGHTS[dstFormat]; // Round up source dims to multiple of block size unsigned int actualWidth = correctSrc.GetWidth() / (scaleByHalf ? 2 : 1); actualWidth = (actualWidth + blockW-1) & ~(blockW-1); unsigned int actualHeight = correctSrc.GetHeight() / (scaleByHalf ? 2 : 1); actualHeight = (actualHeight + blockH-1) & ~(blockH-1); unsigned int numBlocksX = actualWidth/blockW; unsigned int numBlocksY = actualHeight/blockH; unsigned int cacheLinesPerRow; if (dstFormat == 0x6) // RGBA takes two cache lines per block; all others take one cacheLinesPerRow = numBlocksX*2; else cacheLinesPerRow = numBlocksX; _assert_msg_(VIDEO, cacheLinesPerRow*32 <= MAX_BYTES_PER_BLOCK_ROW, "cache lines per row sanity check"); unsigned int totalCacheLines = cacheLinesPerRow * numBlocksY; _assert_msg_(VIDEO, totalCacheLines*32 <= MAX_BYTES_PER_ENCODE, "total encode size sanity check"); size_t encodeSize = 0; // Reset API g_renderer->ResetAPIState(); // Set up all the state for EFB encoding { D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, FLOAT(cacheLinesPerRow * 8), FLOAT(numBlocksY)); D3D::context->RSSetViewports(1, &vp); EFBRectangle fullSrcRect; fullSrcRect.left = 0; fullSrcRect.top = 0; fullSrcRect.right = EFB_WIDTH; fullSrcRect.bottom = EFB_HEIGHT; TargetRectangle targetRect = g_renderer->ConvertEFBRectangle(fullSrcRect); D3D::context->OMSetRenderTargets(1, &m_outRTV, nullptr); ID3D11ShaderResourceView* pEFB = (srcFormat == PEControl::Z24) ? FramebufferManager::GetResolvedEFBDepthTexture()->GetSRV() : // FIXME: Instead of resolving EFB, it would be better to pick out a // single sample from each pixel. The game may break if it isn't // expecting the blurred edges around multisampled shapes. FramebufferManager::GetResolvedEFBColorTexture()->GetSRV(); EFBEncodeParams params; params.SrcLeft = correctSrc.left; params.SrcTop = correctSrc.top; params.DestWidth = actualWidth; params.ScaleFactor = scaleByHalf ? 2 : 1; D3D::context->UpdateSubresource(m_encodeParams, 0, nullptr, ¶ms, 0, 0); D3D::stateman->SetPixelConstants(m_encodeParams); // Use linear filtering if (bScaleByHalf), use point filtering otherwise if (scaleByHalf) D3D::SetLinearCopySampler(); else D3D::SetPointCopySampler(); D3D::drawShadedTexQuad(pEFB, targetRect.AsRECT(), Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), SetStaticShader(dstFormat, srcFormat, isIntensity, scaleByHalf), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); // Copy to staging buffer D3D11_BOX srcBox = CD3D11_BOX(0, 0, 0, cacheLinesPerRow * 8, numBlocksY, 1); D3D::context->CopySubresourceRegion(m_outStage, 0, 0, 0, 0, m_out, 0, &srcBox); // Transfer staging buffer to GameCube/Wii RAM D3D11_MAPPED_SUBRESOURCE map = { 0 }; hr = D3D::context->Map(m_outStage, 0, D3D11_MAP_READ, 0, &map); CHECK(SUCCEEDED(hr), "map staging buffer (0x%x)", hr); u8* src = (u8*)map.pData; for (unsigned int y = 0; y < numBlocksY; ++y) { memcpy(dst, src, cacheLinesPerRow*32); dst += bpmem.copyMipMapStrideChannels*32; src += map.RowPitch; } D3D::context->Unmap(m_outStage, 0); encodeSize = bpmem.copyMipMapStrideChannels*32 * numBlocksY; } // Restore API g_renderer->RestoreAPIState(); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); return encodeSize; }
void D3D11CanvasWindowGraphics::Render() { RECT clientRc; GetClientRect(m_hWnd, &clientRc); RectF clientRcf((float)clientRc.left, (float)clientRc.top, (float)clientRc.right, (float)clientRc.bottom); D2D1_RECT_F clientRectf = D2D1::RectF((FLOAT)clientRc.left, (FLOAT)clientRc.top, (FLOAT)clientRc.right, (FLOAT)clientRc.bottom); ID3D11DeviceContext* pContext = m_driver->GetD3D11Context(); // Clear to black static const float BG_COLOR[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; pContext->ClearRenderTargetView(m_backBufferRTV, BG_COLOR); // TODO: CLEAN UP THIS MESS!!! if (m_image) { // Set up rasterizer RECT clientRc; GetClientRect(m_hWnd, &clientRc); RectF clientRcf((float)clientRc.left, (float)clientRc.top, (float)clientRc.right, (float)clientRc.bottom); D3D11_VIEWPORT vp = CD3D11_VIEWPORT( clientRcf.left, clientRcf.top, clientRcf.right - clientRcf.left, clientRcf.bottom - clientRcf.top); pContext->RSSetViewports(1, &vp); // Set up output merger ID3D11RenderTargetView* rtv = m_backBufferRTV; pContext->OMSetRenderTargets(1, &rtv, NULL); pContext->OMSetBlendState(m_driver->GetOverBlend(), NULL, 0xFFFFFFFF); D3D11ImagePtr d3d11Image = std::static_pointer_cast<D3D11Image, DriverImage>( m_image->GetDriverImage()); ID3D11ShaderResourceView* srv = d3d11Image->GetSRV(); ID3D11SamplerState* ss = m_driver->GetBilinearSampler(); // Set up pixel shader pContext->PSSetShader(m_driver->GetTexturedPixelShader(), NULL, 0); pContext->PSSetShaderResources(0, 1, &srv); pContext->PSSetSamplers(0, 1, &ss); m_driver->RenderQuad(m_camera->GetCanvasToClip(clientRcf), m_image->GetCanvasRect()); srv = NULL; pContext->PSSetShaderResources(0, 1, &srv); } // Render something into Direct2D target ComPtr<ID2D1RenderTarget> pD2DTarget = m_d2dTarget->AcquireTarget(); pD2DTarget->BeginDraw(); // Clear to transparent black pD2DTarget->Clear(D2D1::ColorF(D2D1::ColorF::Black, 0.0f)); // Create brush for drawing stuff ID2D1SolidColorBrush* brush; pD2DTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Blue), &brush); Matrix3x2f canvasToViewport = m_camera->GetCanvasToViewport(clientRcf); // Draw the extensible image's tile structure const ExtensibleImage::TileMap& tiles = m_extensibleImage->GetTileMap(); for (ExtensibleImage::TileMap::const_iterator it = tiles.begin(); it != tiles.end(); ++it) { const RectF& canvasRect = it->second->GetCanvasRect(); ID2D1Factory* d2dFactory; pD2DTarget->GetFactory(&d2dFactory); ID2D1RectangleGeometry* rectGeom; d2dFactory->CreateRectangleGeometry( D2D1::RectF(canvasRect.left, canvasRect.top, canvasRect.right, canvasRect.bottom), &rectGeom); ID2D1TransformedGeometry* transGeom; d2dFactory->CreateTransformedGeometry(rectGeom, D2D1::Matrix3x2F(canvasToViewport.m11, canvasToViewport.m12, canvasToViewport.m21, canvasToViewport.m22, canvasToViewport.m31, canvasToViewport.m32), &transGeom); rectGeom->Release(); pD2DTarget->DrawGeometry(transGeom, brush); transGeom->Release(); d2dFactory->Release(); } // Draw some text RenderPrintf(pD2DTarget, m_textFormat, clientRectf, brush, L"Welcome to Paint Sandbox!"); brush->Release(); pD2DTarget->EndDraw(); m_d2dTarget->ReleaseTarget(); // Transfer Direct2D target to display //m_driver->RenderD2DTarget(m_d2dTarget); // Set up rasterizer D3D11_VIEWPORT vp = CD3D11_VIEWPORT( clientRcf.left, clientRcf.top, clientRcf.right - clientRcf.left, clientRcf.bottom - clientRcf.top); pContext->RSSetViewports(1, &vp); // Set up output merger ID3D11RenderTargetView* rtv = m_backBufferRTV; pContext->OMSetRenderTargets(1, &rtv, NULL); pContext->OMSetBlendState(m_driver->GetOverBlend(), NULL, 0xFFFFFFFF); ID3D11ShaderResourceView* srv = m_d2dTarget->AcquireSRV(); ID3D11SamplerState* ss = m_driver->GetBilinearSampler(); // Set up pixel shader pContext->PSSetShader(m_driver->GetTexturedPixelShader(), NULL, 0); pContext->PSSetShaderResources(0, 1, &srv); pContext->PSSetSamplers(0, 1, &ss); m_driver->RenderQuad(Matrix3x2f::IDENTITY, RectF(-1.0f, 1.0f, 1.0f, -1.0f)); srv = NULL; pContext->PSSetShaderResources(0, 1, &srv); m_d2dTarget->ReleaseSRV(); }
void TextureCache::TCacheEntry::CopyRectangleFromTexture( const TCacheEntryBase* source, const MathUtil::Rectangle<int> &srcrect, const MathUtil::Rectangle<int> &dstrect) { TCacheEntry* srcentry = (TCacheEntry*)source; if (srcrect.GetWidth() == dstrect.GetWidth() && srcrect.GetHeight() == dstrect.GetHeight()) { const D3D11_BOX *psrcbox = nullptr; D3D11_BOX srcbox; if (srcrect.left != 0 || srcrect.top != 0) { srcbox.left = srcrect.left; srcbox.top = srcrect.top; srcbox.right = srcrect.right; srcbox.bottom = srcrect.bottom; psrcbox = &srcbox; } D3D::context->CopySubresourceRegion( texture->GetTex(), 0, dstrect.left, dstrect.top, 0, srcentry->texture->GetTex(), 0, psrcbox); return; } else if (!config.rendertarget) { return; } g_renderer->ResetAPIState(); // reset any game specific settings const D3D11_VIEWPORT vp = CD3D11_VIEWPORT( float(dstrect.left), float(dstrect.top), float(dstrect.GetWidth()), float(dstrect.GetHeight())); D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), nullptr); D3D::context->RSSetViewports(1, &vp); D3D::SetLinearCopySampler(); D3D11_RECT srcRC; srcRC.left = srcrect.left; srcRC.right = srcrect.right; srcRC.top = srcrect.top; srcRC.bottom = srcrect.bottom; D3D::drawShadedTexQuad(srcentry->texture->GetSRV(), &srcRC, srcentry->config.width, srcentry->config.height, PixelShaderCache::GetColorCopyProgram(false), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), nullptr, 1.0, 0); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); g_renderer->RestoreAPIState(); }
void DX11::TextureSurface::OnResetDevice(Gpu::Api * gpu) { OnLostDevice(gpu); unsigned width = unsigned(viewport.Width); unsigned height = unsigned(viewport.Height); bool typeless = (format == Gpu::DrawSurface::Format_Typeless); if(relativeWindow) { gpu->GetBackbufferSize(width, height, relativeWindow); width = unsigned(widthFactor * float(width)); height = unsigned(heightFactor * float(height)); } viewport = CD3D11_VIEWPORT(0.0f, 0.0f, float(width), float(height)); static const DXGI_FORMAT SURFACE_FORMAT_TO_DXGI_FORMAT[Format_Total] = { DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R24G8_TYPELESS }; DXGI_FORMAT dxgiFormat = SURFACE_FORMAT_TO_DXGI_FORMAT[format]; unsigned mipLevels = generateMips ? min(width, height) / 4 : 1; D3D11_BIND_FLAG bindFlag = typeless ? D3D11_BIND_DEPTH_STENCIL : D3D11_BIND_RENDER_TARGET; ID3D11Texture2D * texture2D = 0; CD3D11_TEXTURE2D_DESC textureDesc( dxgiFormat, width, height, 1, mipLevels, // MIP LEVELS - *MUST NEVER* BE GREATER THAN log2(width) OR log2(height) bindFlag | D3D11_BIND_SHADER_RESOURCE); device->CreateTexture2D(&textureDesc, 0, &texture2D); if(typeless) dxgiFormat = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; ID3D11ShaderResourceView * shaderView; CD3D11_SHADER_RESOURCE_VIEW_DESC shaderViewDesc( texture2D, D3D11_SRV_DIMENSION_TEXTURE2D, dxgiFormat, 0, mipLevels); device->CreateShaderResourceView(texture2D, &shaderViewDesc, &shaderView); if(!typeless) { CD3D11_RENDER_TARGET_VIEW_DESC renderViewDesc( texture2D, D3D11_RTV_DIMENSION_TEXTURE2D, dxgiFormat); device->CreateRenderTargetView(texture2D, &renderViewDesc, &renderTargetView); CD3D11_TEXTURE2D_DESC depthStencilTextureDesc( DXGI_FORMAT_D24_UNORM_S8_UINT, width, height, 1, 1, D3D11_BIND_DEPTH_STENCIL); device->CreateTexture2D(&depthStencilTextureDesc, 0, &depthStencilTexture); device->CreateDepthStencilView( depthStencilTexture, &CD3D11_DEPTH_STENCIL_VIEW_DESC(D3D11_DSV_DIMENSION_TEXTURE2D), &depthStencilView); } else { device->CreateDepthStencilView( texture2D, &CD3D11_DEPTH_STENCIL_VIEW_DESC(D3D11_DSV_DIMENSION_TEXTURE2D, DXGI_FORMAT_D24_UNORM_S8_UINT), &depthStencilView); } texture = new DX11::Texture(texture2D, shaderView, textureDesc); Clear(); }
// TODO create software window bool RenderWindowD11_2::Create(const _lParametor& config) { _lParametor::const_iterator parametor; HRESULT hr = S_FALSE; auto divace = m_pRSystem->GetD3DDevice(); auto context = m_pRSystem->GetD3DDeviceContext(); // Î÷èñòèòü ïðåäûäóùàÿ ðàçìåð îêíà êîíêðåòíîãî êîíòåêñòà. ID3D11RenderTargetView* nullViews[] = { nullptr }; context->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr); m_d3dRenderTargetView = nullptr; m_d3dDepthStencilView = nullptr; context->Flush(); parametor = config.find("window_name"); if (parametor != config.end()) { mObjectName = parametor->second; } _32un bit = 0; parametor = config.find("display_mode"); if (parametor != config.end()) { StringConverter::ParseDisplyaMode(parametor->second, m_nWidth, m_nHeight, bit); } else { DrawLine("~RenderWindowD11_2: not set display_mode", MT_ERROR); return false; } parametor = config.find("full_screan_mode"); if (parametor != config.end()) { m_bFullScrean = StringConverter::Parse_bool(parametor->second); } else { DrawLine("~RenderWindowD11_2: not set full_screan_mode set in false"); m_bFullScrean = false; } parametor = config.find("window_handle"); if (parametor != config.end()) { m_hWnd = StringConverter::Parse_int(parametor->second); } else { DrawLine("~RenderWindowD11_2: not set window_handle", MT_ERROR); return false; } DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 }; swapChainDesc.Width = m_nWidth; swapChainDesc.Height = m_nHeight; swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // Ýòî íàèáîëåå ðàñïðîñòðàíåííûé ôîðìàò swap chain. swapChainDesc.Stereo = false; swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling. swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = 2; // Use double-buffering to minimize latency. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect. swapChainDesc.Flags = 0; swapChainDesc.Scaling = DXGI_SCALING_NONE; swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; ComPtr<IDXGIDevice2> dxgiDevice; divace->QueryInterface(IID_PPV_ARGS(&dxgiDevice)); ComPtr<IDXGIAdapter> dxgiAdapter; dxgiDevice->GetAdapter(&dxgiAdapter); ComPtr<IDXGIFactory2> dxgiFactory; dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory)); hr = dxgiFactory->CreateSwapChainForHwnd( divace, // pDevice [in] (HWND)m_hWnd, // hWnd [in] &swapChainDesc, // pDesc [in] nullptr, // pFullscreenDesc [in, optional] nullptr, // pRestrictToOutput [in, optional] &m_swapChain // ppSwapChain [out] ); if (FAILED(hr)) { DrawLine("~RenderWindowD11_2: " + RenderSystemD11_2::GetErrorHR(hr), MT_ERROR); return false; } // Óáåäèòåñü, ÷òî DXGI íå ñòîÿòü â î÷åðåäè áîëüøå, ÷åì îäèí êàäð çà îäèí ðàç. Ýòî è ñîêðàùàåò çàäåðæêè è // Ãàðàíòèðóåò, ÷òî ïðèëîæåíèå áóäåò îêàçûâàòü òîëüêî ïîñëå êàæäîãî VSync, ìèíèìèçèðóÿ ïîòðåáëåíèå ýíåðãèè. dxgiDevice->SetMaximumFrameLatency(1); // Create a render target view of the swap chain back buffer. ComPtr<ID3D11Texture2D> backBuffer; m_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer)); divace->CreateRenderTargetView( backBuffer.Get(), nullptr, &m_d3dRenderTargetView ); // Create a depth stencil view for use with 3D rendering if needed. CD3D11_TEXTURE2D_DESC depthStencilDesc( DXGI_FORMAT_D24_UNORM_S8_UINT, m_nWidth, m_nHeight, 1, // This depth stencil view has only one texture. 1, // Use a single mipmap level. D3D11_BIND_DEPTH_STENCIL ); ComPtr<ID3D11Texture2D> depthStencil; divace->CreateTexture2D( &depthStencilDesc, nullptr, &depthStencil ); CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D); divace->CreateDepthStencilView( depthStencil.Get(), &depthStencilViewDesc, &m_d3dDepthStencilView ); // Set the 3D rendering viewport to target the entire window. m_screenViewport = CD3D11_VIEWPORT( 0.0f, 0.0f, (FLOAT)m_nWidth, (FLOAT)m_nHeight ); context->RSSetViewports(1, &m_screenViewport); m_bInit = true; return true; }
bool D3D11Device::createWindowSizeDependendResources(int width, int height) { D3D11RenderContext& context = static_cast<D3D11RenderContext&>(getContext()); context.release(); // Clear the previous window size specific context. ID3D11RenderTargetView* nullViews[] = { nullptr }; m_d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr); DX::SafeRelease(&m_d3dRenderTargetView); m_d2dContext->SetTarget(nullptr); DX::SafeRelease(&m_d2dTargetBitmap); m_d3dContext->Flush1(D3D11_CONTEXT_TYPE_ALL, nullptr); ASSERT(m_swapChain != nullptr); HRESULT hr = m_swapChain->ResizeBuffers(2, width, height, DXGI_FORMAT_B8G8R8A8_UNORM, 0); if ( FAILED(hr) ) { return false; } // create & set the rendertarget view ID3D11Texture2D* pbackbuffer = NULL; hr = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*) & pbackbuffer); if ( FAILED(hr) ) { return false; } m_d3dDevice->CreateRenderTargetView1(pbackbuffer, NULL, &m_d3dRenderTargetView); DX::SafeRelease(&pbackbuffer); ID3D11RenderTargetView* const targets[1] = { m_d3dRenderTargetView }; m_d3dContext->OMSetRenderTargets(1, targets, NULL); // Set the 3D rendering viewport to target the entire window. m_screenViewport = CD3D11_VIEWPORT(0.0f, 0.0f, width, height); m_d3dContext->RSSetViewports(1, &m_screenViewport); // Create a Direct2D target bitmap associated with the // swap chain back buffer and set it as the current target. D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1( D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED), m_dpi, m_dpi ); IDXGISurface2* dxgiBackBuffer; m_swapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer)); hr = m_d2dContext->CreateBitmapFromDxgiSurface( dxgiBackBuffer, &bitmapProperties, &m_d2dTargetBitmap ); if ( FAILED(hr) ) { return false; } DX::SafeRelease(&dxgiBackBuffer); m_d2dContext->SetTarget(m_d2dTargetBitmap); m_d2dContext->SetDpi(m_dpi, m_dpi); // Grayscale text anti-aliasing is recommended for all Windows Store apps. m_d2dContext->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE); context.setTargetView(m_d3dRenderTargetView); return true; }