Esempio n. 1
0
D3D12_SHADER_BYTECODE ShaderCache::GetVertexShaderFromUid(const VertexShaderUid* uid)
{
  auto bytecode = s_vs_bytecode_cache.find(*uid);
  if (bytecode != s_vs_bytecode_cache.end())
    return bytecode->second;

  return D3D12_SHADER_BYTECODE();
}
Esempio n. 2
0
void TextureCache::TCacheEntry::CopyRectangleFromTexture(
	const TCacheEntryBase* source,
	const MathUtil::Rectangle<int>& src_rect,
	const MathUtil::Rectangle<int>& dst_rect)
{
	const TCacheEntry* srcentry = reinterpret_cast<const TCacheEntry*>(source);
	if (src_rect.GetWidth() == dst_rect.GetWidth()
		&& src_rect.GetHeight() == dst_rect.GetHeight())
	{
		D3D12_BOX srcbox;
		srcbox.left = src_rect.left;
		srcbox.top = src_rect.top;
		srcbox.right = src_rect.right;
		srcbox.bottom = src_rect.bottom;
		srcbox.front = 0;
		srcbox.back = srcentry->config.layers;

		if (static_cast<u32>(src_rect.GetHeight()) > config.height ||
			static_cast<u32>(src_rect.GetWidth()) > config.width)
		{
			// To mimic D3D11 behavior, we're just going to drop the clear since it is invalid.
			// This invalid copy needs to be fixed above the Backend level.

			// On D3D12, instead of silently dropping this invalid clear, the runtime throws an exception
			// so we need to filter it out ourselves.

			return;
		}

		D3D12_TEXTURE_COPY_LOCATION dst_location = CD3DX12_TEXTURE_COPY_LOCATION(m_texture->GetTex12(), 0);
		D3D12_TEXTURE_COPY_LOCATION src_location = CD3DX12_TEXTURE_COPY_LOCATION(srcentry->m_texture->GetTex12(), 0);

		m_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_COPY_DEST);
		srcentry->m_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_COPY_SOURCE);

		D3D::current_command_list->CopyTextureRegion(&dst_location, dst_rect.left, dst_rect.top, 0, &src_location, &srcbox);

		m_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
		srcentry->m_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);

		return;
	}
	else if (!config.rendertarget)
	{
		return;
	}

	D3D::SetViewportAndScissor(dst_rect.left, dst_rect.top, dst_rect.GetWidth(), dst_rect.GetHeight());

	m_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET);
	D3D::current_command_list->OMSetRenderTargets(1, &m_texture->GetRTV12(), FALSE, nullptr);

	D3D::SetLinearCopySampler();

	D3D12_RECT src_rc;
	src_rc.left = src_rect.left;
	src_rc.right = src_rect.right;
	src_rc.top = src_rect.top;
	src_rc.bottom = src_rect.bottom;

	D3D::DrawShadedTexQuad(srcentry->m_texture, &src_rc,
		srcentry->config.width, srcentry->config.height,
		StaticShaderCache::GetColorCopyPixelShader(false),
		StaticShaderCache::GetSimpleVertexShader(),
		StaticShaderCache::GetSimpleVertexShaderInputLayout(), D3D12_SHADER_BYTECODE(), 1.0, 0,
		DXGI_FORMAT_R8G8B8A8_UNORM, false, m_texture->GetMultisampled());

	m_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);

	FramebufferManager::GetEFBColorTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET);
	FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE);
	D3D::current_command_list->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV12(), FALSE, &FramebufferManager::GetEFBDepthTexture()->GetDSV12());

	g_renderer->RestoreAPIState();
}
Esempio n. 3
0
void TextureCache::TCacheEntry::CopyRectangleFromTexture(const TCacheEntryBase* source,
                                                         const MathUtil::Rectangle<int>& src_rect,
                                                         const MathUtil::Rectangle<int>& dst_rect)
{
  const TCacheEntry* srcentry = reinterpret_cast<const TCacheEntry*>(source);
  if (src_rect.GetWidth() == dst_rect.GetWidth() && src_rect.GetHeight() == dst_rect.GetHeight())
  {
    // These assertions should hold true unless the base code is passing us sizes too large, in
    // which case it should be fixed instead.
    _assert_msg_(VIDEO, static_cast<u32>(src_rect.GetWidth()) <= source->config.width &&
                            static_cast<u32>(src_rect.GetHeight()) <= source->config.height,
                 "Source rect is too large for CopyRectangleFromTexture");

    _assert_msg_(VIDEO, static_cast<u32>(dst_rect.GetWidth()) <= config.width &&
                            static_cast<u32>(dst_rect.GetHeight()) <= config.height,
                 "Dest rect is too large for CopyRectangleFromTexture");

    CD3DX12_BOX src_box(src_rect.left, src_rect.top, 0, src_rect.right, src_rect.bottom,
                        srcentry->config.layers);
    D3D12_TEXTURE_COPY_LOCATION dst_location =
        CD3DX12_TEXTURE_COPY_LOCATION(m_texture->GetTex12(), 0);
    D3D12_TEXTURE_COPY_LOCATION src_location =
        CD3DX12_TEXTURE_COPY_LOCATION(srcentry->m_texture->GetTex12(), 0);

    m_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_COPY_DEST);
    srcentry->m_texture->TransitionToResourceState(D3D::current_command_list,
                                                   D3D12_RESOURCE_STATE_COPY_SOURCE);
    D3D::current_command_list->CopyTextureRegion(&dst_location, dst_rect.left, dst_rect.top, 0,
                                                 &src_location, &src_box);

    m_texture->TransitionToResourceState(D3D::current_command_list,
                                         D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
    srcentry->m_texture->TransitionToResourceState(D3D::current_command_list,
                                                   D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);

    return;
  }
  else if (!config.rendertarget)
  {
    return;
  }

  D3D::SetViewportAndScissor(dst_rect.left, dst_rect.top, dst_rect.GetWidth(),
                             dst_rect.GetHeight());

  m_texture->TransitionToResourceState(D3D::current_command_list,
                                       D3D12_RESOURCE_STATE_RENDER_TARGET);
  D3D::current_command_list->OMSetRenderTargets(1, &m_texture->GetRTV12(), FALSE, nullptr);

  D3D::SetLinearCopySampler();

  D3D12_RECT src_rc;
  src_rc.left = src_rect.left;
  src_rc.right = src_rect.right;
  src_rc.top = src_rect.top;
  src_rc.bottom = src_rect.bottom;

  D3D::DrawShadedTexQuad(
      srcentry->m_texture, &src_rc, srcentry->config.width, srcentry->config.height,
      StaticShaderCache::GetColorCopyPixelShader(false), StaticShaderCache::GetSimpleVertexShader(),
      StaticShaderCache::GetSimpleVertexShaderInputLayout(), D3D12_SHADER_BYTECODE(), 1.0, 0,
      DXGI_FORMAT_R8G8B8A8_UNORM, false, m_texture->GetMultisampled());

  m_texture->TransitionToResourceState(D3D::current_command_list,
                                       D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);

  FramebufferManager::GetEFBColorTexture()->TransitionToResourceState(
      D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET);
  FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(
      D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE);

  g_renderer->RestoreAPIState();
}
Esempio n. 4
0
void TextureCache::TCacheEntry::CopyRectangleFromTexture(
	const TCacheEntryBase* source,
	const MathUtil::Rectangle<int>& src_rect,
	const MathUtil::Rectangle<int>& dst_rect)
{
	TCacheEntry* srcentry = (TCacheEntry*)source;
	if (src_rect.GetWidth() == dst_rect.GetWidth()
		&& src_rect.GetHeight() == dst_rect.GetHeight())
	{
		const D3D12_BOX *psrcbox = nullptr;
		D3D12_BOX srcbox;
		if (src_rect.left != 0 
			|| src_rect.top != 0 
			|| src_rect.GetWidth() != srcentry->config.width 
			|| src_rect.GetHeight() != srcentry->config.height)
		{
			srcbox.left = src_rect.left;
			srcbox.top = src_rect.top;
			srcbox.right = src_rect.right;
			srcbox.bottom = src_rect.bottom;
			srcbox.front = 0;
			srcbox.back = 1;
			psrcbox = &srcbox;
		}
		
		D3D12_TEXTURE_COPY_LOCATION dst = CD3DX12_TEXTURE_COPY_LOCATION(m_texture->GetTex12(), 0);
		D3D12_TEXTURE_COPY_LOCATION src = CD3DX12_TEXTURE_COPY_LOCATION(srcentry->m_texture->GetTex12(), 0);

		m_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_COPY_DEST);
		srcentry->m_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_COPY_SOURCE);

		D3D::current_command_list->CopyTextureRegion(&dst, dst_rect.left, dst_rect.top, 0, &src, psrcbox);

		return;
	}
	else if (!config.rendertarget)
	{
		return;
	}

	const D3D12_VIEWPORT vp12 = {
		float(dst_rect.left),
		float(dst_rect.top),
		float(dst_rect.GetWidth()),
		float(dst_rect.GetHeight()),
		D3D12_MIN_DEPTH,
		D3D12_MAX_DEPTH
	};
	D3D::current_command_list->RSSetViewports(1, &vp12);

	m_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET);
	D3D::current_command_list->OMSetRenderTargets(1, &m_texture->GetRTV12(), FALSE, nullptr);

	D3D::SetLinearCopySampler();
	D3D12_RECT srcRC;
	srcRC.left = src_rect.left;
	srcRC.right = src_rect.right;
	srcRC.top = src_rect.top;
	srcRC.bottom = src_rect.bottom;
	D3D::DrawShadedTexQuad(srcentry->m_texture, &srcRC,
		srcentry->config.width, srcentry->config.height,
		StaticShaderCache::GetColorCopyPixelShader(false),
		StaticShaderCache::GetSimpleVertexShader(),
		StaticShaderCache::GetSimpleVertexShaderInputLayout(), D3D12_SHADER_BYTECODE(), 1.0, 0,
		DXGI_FORMAT_R8G8B8A8_UNORM, false, m_texture->GetMultisampled());

	FramebufferManager::GetEFBColorTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET);
	FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE);
	D3D::current_command_list->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV12(), FALSE, &FramebufferManager::GetEFBDepthTexture()->GetDSV12());

	g_renderer->RestoreAPIState();
}
Esempio n. 5
0
void drawClearQuad(u32 Color, float z, D3D12_BLEND_DESC *pBlendDesc, D3D12_DEPTH_STENCIL_DESC *pDepthStencilDesc, bool rtMultisampled)
{
	ClearVertex coords[4] = {
		{-1.0f,  1.0f, z, Color},
		{ 1.0f,  1.0f, z, Color},
		{-1.0f, -1.0f, z, Color},
		{ 1.0f, -1.0f, z, Color},
	};

	if (clear_quad_data.col != Color || clear_quad_data.z != z)
	{
		clearq_offset = util_vbuf_clearq->AppendData(coords, sizeof(coords), sizeof(ClearVertex));

		clear_quad_data.col = Color;
		clear_quad_data.z = z;
	}

	D3D::currentCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
	D3D::commandListMgr->currentTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;

	D3D12_VERTEX_BUFFER_VIEW vbView = {
		util_vbuf_clearq->GetBuffer12()->GetGPUVirtualAddress(), // D3D12_GPU_VIRTUAL_ADDRESS BufferLocation;
		0x10000,                                                 // UINT SizeInBytes; This is the size of the entire buffer, not just the size of the vertex data for one draw call, since the offsetting is done in the draw call itself.
		sizeof(ClearVertex)                                      // UINT StrideInBytes;
	};

	D3D::currentCommandList->IASetVertexBuffers(0, 1, &vbView);
	D3D::commandListMgr->dirtyVertexBuffer = true;

	D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {
		defaultRootSignature,                             // ID3D12RootSignature *pRootSignature;
		VertexShaderCache::GetClearVertexShader12(),      // D3D12_SHADER_BYTECODE VS;
		PixelShaderCache::GetClearProgram12(),            // D3D12_SHADER_BYTECODE PS;
		{},                                               // D3D12_SHADER_BYTECODE DS;
		{},                                               // D3D12_SHADER_BYTECODE HS;
		g_ActiveConfig.iStereoMode > 0 ?
		GeometryShaderCache::GetClearGeometryShader12() :
		D3D12_SHADER_BYTECODE(),                          // D3D12_SHADER_BYTECODE GS;
		{},                                               // D3D12_STREAM_OUTPUT_DESC StreamOutput
		*pBlendDesc,                                      // D3D12_BLEND_DESC BlendState;
		UINT_MAX,                                         // UINT SampleMask;
		resetraststate12,                                 // D3D12_RASTERIZER_DESC RasterizerState
		*pDepthStencilDesc,                               // D3D12_DEPTH_STENCIL_DESC DepthStencilState
		VertexShaderCache::GetClearInputLayout12(),       // D3D12_INPUT_LAYOUT_DESC InputLayout
		D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF,        // D3D12_INDEX_BUFFER_PROPERTIES IndexBufferProperties
		D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,           // D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType
		1,                                                // UINT NumRenderTargets
		{ DXGI_FORMAT_R8G8B8A8_UNORM },                   // DXGI_FORMAT RTVFormats[8]
		DXGI_FORMAT_D24_UNORM_S8_UINT,                    // DXGI_FORMAT DSVFormat
		{ 1 /* UINT Count */, 0 /* UINT Quality */ }      // DXGI_SAMPLE_DESC SampleDesc
	};

	if (rtMultisampled)
	{
		psoDesc.SampleDesc.Count = g_ActiveConfig.iMultisamples;
	}

	ID3D12PipelineState *pPso = nullptr;
	CheckHR(DX12::gx_state_cache.GetPipelineStateObjectFromCache(&psoDesc, &pPso));

	D3D::currentCommandList->SetPipelineState(pPso);
	D3D::commandListMgr->dirtyPso = true;

	// In D3D11, the 'resetraststate' has ScissorEnable disabled. In D3D12, scissor testing is always enabled.
	// Thus, set the scissor rect to the max texture size, then reset it to the current scissor rect to avoid
	// dirtying state.

	// 2 ^ D3D12_MAX_TEXTURE_DIMENSION_2_TO_EXP = 131072	
	D3D::currentCommandList->RSSetScissorRects(1, &CD3DX12_RECT(0, 0, 131072, 131072));

	D3D::currentCommandList->DrawInstanced(4, 1, clearq_offset, 0);

	g_renderer->SetScissorRect(((Renderer*)g_renderer)->GetScissorRect());
}
Esempio n. 6
0
void PSTextureEncoder::Encode(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y, u32 memory_stride,
	PEControl::PixelFormat src_format, const EFBRectangle& src_rect,
	bool is_intensity, bool scale_by_half)
{
	if (!m_ready) // Make sure we initialized OK
		return;

	D3D::command_list_mgr->CPUAccessNotify();

	// Resolve MSAA targets before copying.
	D3DTexture2D* efb_source = (src_format == PEControl::Z24) ?
		FramebufferManager::GetResolvedEFBDepthTexture() :
		// EXISTINGD3D11TODO: 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();

	// GetResolvedEFBDepthTexture will set the render targets, when MSAA is enabled
	// (since it needs to do a manual depth resolve). So make sure to set the RTs
	// afterwards.

	const u32 words_per_row = bytes_per_row / sizeof(u32);

	D3D12_VIEWPORT vp = { 0.f, 0.f, FLOAT(words_per_row), FLOAT(num_blocks_y), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH };
	D3D::current_command_list->RSSetViewports(1, &vp);

	constexpr EFBRectangle full_src_rect(0, 0, EFB_WIDTH, EFB_HEIGHT);

	TargetRectangle target_rect = g_renderer->ConvertEFBRectangle(full_src_rect);

	D3D::ResourceBarrier(D3D::current_command_list, m_out, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET, 0);
	D3D::current_command_list->OMSetRenderTargets(1, &m_out_rtv_cpu, FALSE, nullptr);

	EFBEncodeParams params;
	params.SrcLeft = src_rect.left;
	params.SrcTop = src_rect.top;
	params.DestWidth = native_width;
	params.ScaleFactor = scale_by_half ? 2 : 1;

	memcpy(m_encode_params_buffer_data, &params, sizeof(params));
	D3D::current_command_list->SetGraphicsRootConstantBufferView(
		DESCRIPTOR_TABLE_PS_CBVONE,
		m_encode_params_buffer->GetGPUVirtualAddress()
		);

	D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PS_CBV, true);

	// Use linear filtering if (bScaleByHalf), use point filtering otherwise
	if (scale_by_half)
		D3D::SetLinearCopySampler();
	else
		D3D::SetPointCopySampler();

	D3D::DrawShadedTexQuad(efb_source,
		target_rect.AsRECT(),
		Renderer::GetTargetWidth(),
		Renderer::GetTargetHeight(),
		SetStaticShader(format, src_format, is_intensity, scale_by_half),
		StaticShaderCache::GetSimpleVertexShader(),
		StaticShaderCache::GetSimpleVertexShaderInputLayout(),
		D3D12_SHADER_BYTECODE(),
		1.0f,
		0,
		DXGI_FORMAT_B8G8R8A8_UNORM,
		false,
		false /* Render target is not multisampled */
		);

	// Copy to staging buffer
	D3D12_BOX src_box = CD3DX12_BOX(0, 0, 0, words_per_row, num_blocks_y, 1);

	D3D12_TEXTURE_COPY_LOCATION dst_location = {};
	dst_location.pResource = m_out_readback_buffer;
	dst_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
	dst_location.PlacedFootprint.Offset = 0;
	dst_location.PlacedFootprint.Footprint.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
	dst_location.PlacedFootprint.Footprint.Width = EFB_WIDTH * 4;
	dst_location.PlacedFootprint.Footprint.Height = EFB_HEIGHT / 4;
	dst_location.PlacedFootprint.Footprint.Depth = 1;
	dst_location.PlacedFootprint.Footprint.RowPitch = D3D::AlignValue(dst_location.PlacedFootprint.Footprint.Width * 4, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);

	D3D12_TEXTURE_COPY_LOCATION src_location = {};
	src_location.pResource = m_out;
	src_location.SubresourceIndex = 0;
	src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;

	D3D::ResourceBarrier(D3D::current_command_list, m_out, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE, 0);
	D3D::current_command_list->CopyTextureRegion(&dst_location, 0, 0, 0, &src_location, &src_box);

	D3D::command_list_mgr->ExecuteQueuedWork(true);

	// Transfer staging buffer to GameCube/Wii RAM

	u8* src = static_cast<u8*>(m_out_readback_buffer_data);
	u32 read_stride = std::min(bytes_per_row, dst_location.PlacedFootprint.Footprint.RowPitch);
	for (unsigned int y = 0; y < num_blocks_y; ++y)
	{
		memcpy(dst, src, read_stride);

		dst += memory_stride;
		src += dst_location.PlacedFootprint.Footprint.RowPitch;
	}

	// Restores proper viewport/scissor settings.
	g_renderer->RestoreAPIState();

	FramebufferManager::GetEFBColorTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET);
	FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE );
	D3D::current_command_list->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV12(), FALSE, &FramebufferManager::GetEFBDepthTexture()->GetDSV12());
}