Exemplo n.º 1
0
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);
	}
}
Exemplo n.º 2
0
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();
}
Exemplo n.º 3
0
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));
}
Exemplo n.º 4
0
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);
	}
}
Exemplo n.º 5
0
	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;
	}
Exemplo n.º 6
0
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);
}
Exemplo n.º 7
0
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();
}
Exemplo n.º 8
0
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();
}
Exemplo n.º 9
0
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());
}
Exemplo n.º 10
0
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);
}
Exemplo n.º 11
0
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();
}
Exemplo n.º 12
0
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, &params, 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());
}
Exemplo n.º 13
0
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, &params, 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());
}
Exemplo n.º 14
0
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();
}
Exemplo n.º 15
0
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;
	}
}
Exemplo n.º 16
0
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, &params, 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();
}
Exemplo n.º 18
0
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();
}
Exemplo n.º 19
0
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;
	}
Exemplo n.º 21
0
   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;
   }